diff mbox series

[05/22] Implement shm_open2(2) system call

Message ID 20230819094806.14965-6-kariem.taha2.7@gmail.com
State New
Headers show
Series Implement the mmap system call for FreeBSD. | expand

Commit Message

Karim Taha Aug. 19, 2023, 9:47 a.m. UTC
From: Kyle Evans <kevans@FreeBSD.org>

Signed-off-by: Kyle Evans <kevans@FreeBSD.org>
Signed-off-by: Karim Taha <kariem.taha2.7@gmail.com>
---
 bsd-user/freebsd/os-misc.h    | 52 +++++++++++++++++++++++++++++++++++
 bsd-user/freebsd/os-syscall.c | 13 +++++++++
 2 files changed, 65 insertions(+)

Comments

Richard Henderson Aug. 19, 2023, 3:10 p.m. UTC | #1
On 8/19/23 02:47, Karim Taha wrote:
> From: Kyle Evans <kevans@FreeBSD.org>
> 
> Signed-off-by: Kyle Evans <kevans@FreeBSD.org>
> Signed-off-by: Karim Taha <kariem.taha2.7@gmail.com>
> ---
>   bsd-user/freebsd/os-misc.h    | 52 +++++++++++++++++++++++++++++++++++
>   bsd-user/freebsd/os-syscall.c | 13 +++++++++
>   2 files changed, 65 insertions(+)
> 
> diff --git a/bsd-user/freebsd/os-misc.h b/bsd-user/freebsd/os-misc.h
> index 8436ccb2f7..993e4598f9 100644
> --- a/bsd-user/freebsd/os-misc.h
> +++ b/bsd-user/freebsd/os-misc.h
> @@ -24,5 +24,57 @@
>   #include <sys/random.h>
>   #include <sched.h>
>   
> +int shm_open2(const char *path, int flags, mode_t mode, int shmflags,
> +    const char *);
> +
> +#if defined(__FreeBSD_version) && __FreeBSD_version >= 1300048
> +/* shm_open2(2) */
> +static inline abi_long do_freebsd_shm_open2(abi_ulong pathptr, abi_ulong flags,
> +    abi_long mode, abi_ulong shmflags, abi_ulong nameptr)
> +{
> +    int ret;
> +    void *uname, *upath;
> +
> +#ifdef SHM_ANON

Why would SHM_ANON not be defined?  You've already restricted the function to freebsd13+ 
(presumably so that shm_open2() is in libc.a).


> +#define SHM_PATH(p) (p) == SHM_ANON ? (p) : path(p)
> +    if (pathptr == (uintptr_t)SHM_ANON) {
> +        upath = SHM_ANON;
> +    } else
> +#else
> +#define SHM_PATH(p) path(p)
> +#endif
> +    {
> +        upath = lock_user_string(pathptr);
> +        if (upath == NULL) {
> +            return -TARGET_EFAULT;
> +        }
> +    }
> +
> +    uname = NULL;
> +    if (nameptr != 0) {
> +        uname = lock_user_string(nameptr);
> +        if (uname == NULL) {
> +            unlock_user(upath, pathptr, 0);
> +            return -TARGET_EFAULT;
> +        }
> +    }
> +    ret = get_errno(shm_open2(SHM_PATH(upath),

There is no need for SHM_PATH because you've already handled the condition while setting 
upath above.



r~
Warner Losh Aug. 20, 2023, 4:16 a.m. UTC | #2
On Sat, Aug 19, 2023 at 9:10 AM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 8/19/23 02:47, Karim Taha wrote:
> > From: Kyle Evans <kevans@FreeBSD.org>
> >
> > Signed-off-by: Kyle Evans <kevans@FreeBSD.org>
> > Signed-off-by: Karim Taha <kariem.taha2.7@gmail.com>
> > ---
> >   bsd-user/freebsd/os-misc.h    | 52 +++++++++++++++++++++++++++++++++++
> >   bsd-user/freebsd/os-syscall.c | 13 +++++++++
> >   2 files changed, 65 insertions(+)
> >
> > diff --git a/bsd-user/freebsd/os-misc.h b/bsd-user/freebsd/os-misc.h
> > index 8436ccb2f7..993e4598f9 100644
> > --- a/bsd-user/freebsd/os-misc.h
> > +++ b/bsd-user/freebsd/os-misc.h
> > @@ -24,5 +24,57 @@
> >   #include <sys/random.h>
> >   #include <sched.h>
> >
> > +int shm_open2(const char *path, int flags, mode_t mode, int shmflags,
> > +    const char *);
> > +
> > +#if defined(__FreeBSD_version) && __FreeBSD_version >= 1300048
> > +/* shm_open2(2) */
> > +static inline abi_long do_freebsd_shm_open2(abi_ulong pathptr,
> abi_ulong flags,
> > +    abi_long mode, abi_ulong shmflags, abi_ulong nameptr)
> > +{
> > +    int ret;
> > +    void *uname, *upath;
> > +
> > +#ifdef SHM_ANON
>
> Why would SHM_ANON not be defined?  You've already restricted the function
> to freebsd13+
> (presumably so that shm_open2() is in libc.a).
>

Good catch Richard. It's like this in the bsd-user fork, but after talking
it over with Kyle, we're
sure that's due to a cut and past from shm_open when this was implemented.
We should change
it before we submit it upstream absolutely. It's always defined on FreeBSD
and that will make
this code simpler.

Warner


> > +#define SHM_PATH(p) (p) == SHM_ANON ? (p) : path(p)
> > +    if (pathptr == (uintptr_t)SHM_ANON) {
> > +        upath = SHM_ANON;
> > +    } else
> > +#else
> > +#define SHM_PATH(p) path(p)
> > +#endif
> > +    {
> > +        upath = lock_user_string(pathptr);
> > +        if (upath == NULL) {
> > +            return -TARGET_EFAULT;
> > +        }
> > +    }
> > +
> > +    uname = NULL;
> > +    if (nameptr != 0) {
> > +        uname = lock_user_string(nameptr);
> > +        if (uname == NULL) {
> > +            unlock_user(upath, pathptr, 0);
> > +            return -TARGET_EFAULT;
> > +        }
> > +    }
> > +    ret = get_errno(shm_open2(SHM_PATH(upath),
>
> There is no need for SHM_PATH because you've already handled the condition
> while setting
> upath above.
>
>
>
> r~
>
diff mbox series

Patch

diff --git a/bsd-user/freebsd/os-misc.h b/bsd-user/freebsd/os-misc.h
index 8436ccb2f7..993e4598f9 100644
--- a/bsd-user/freebsd/os-misc.h
+++ b/bsd-user/freebsd/os-misc.h
@@ -24,5 +24,57 @@ 
 #include <sys/random.h>
 #include <sched.h>
 
+int shm_open2(const char *path, int flags, mode_t mode, int shmflags,
+    const char *);
+
+#if defined(__FreeBSD_version) && __FreeBSD_version >= 1300048
+/* shm_open2(2) */
+static inline abi_long do_freebsd_shm_open2(abi_ulong pathptr, abi_ulong flags,
+    abi_long mode, abi_ulong shmflags, abi_ulong nameptr)
+{
+    int ret;
+    void *uname, *upath;
+
+#ifdef SHM_ANON
+#define SHM_PATH(p) (p) == SHM_ANON ? (p) : path(p)
+    if (pathptr == (uintptr_t)SHM_ANON) {
+        upath = SHM_ANON;
+    } else
+#else
+#define SHM_PATH(p) path(p)
+#endif
+    {
+        upath = lock_user_string(pathptr);
+        if (upath == NULL) {
+            return -TARGET_EFAULT;
+        }
+    }
+
+    uname = NULL;
+    if (nameptr != 0) {
+        uname = lock_user_string(nameptr);
+        if (uname == NULL) {
+            unlock_user(upath, pathptr, 0);
+            return -TARGET_EFAULT;
+        }
+    }
+    ret = get_errno(shm_open2(SHM_PATH(upath),
+                target_to_host_bitmask(flags, fcntl_flags_tbl), mode,
+                target_to_host_bitmask(shmflags, shmflag_flags_tbl), uname));
+
+#ifdef SHM_ANON
+    if (upath != SHM_ANON)
+#endif
+    {
+        unlock_user(upath, pathptr, 0);
+    }
+    if (uname != NULL) {
+        unlock_user(uname, nameptr, 0);
+    }
+    return ret;
+}
+#undef SHM_PATH
+#endif /* __FreeBSD_version >= 1300048 */
+
 
 #endif /* OS_MISC_H */
diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index 2224a280ea..b4311db578 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -33,9 +33,13 @@ 
 #include "signal-common.h"
 #include "user/syscall-trace.h"
 
+/* BSD independent syscall shims */
 #include "bsd-file.h"
 #include "bsd-proc.h"
 
+/* *BSD dependent syscall shims */
+#include "os-misc.h"
+
 /* I/O */
 safe_syscall3(int, open, const char *, path, int, flags, mode_t, mode);
 safe_syscall4(int, openat, int, fd, const char *, path, int, flags, mode_t,
@@ -482,6 +486,15 @@  static abi_long freebsd_syscall(void *cpu_env, int num, abi_long arg1,
         ret = do_bsd_undelete(arg1);
         break;
 
+        /*
+         * Memory management system calls.
+         */
+#if defined(__FreeBSD_version) && __FreeBSD_version >= 1300048
+    case TARGET_FREEBSD_NR_shm_open2: /* shm_open2(2) */
+        ret = do_freebsd_shm_open2(arg1, arg2, arg3, arg4, arg5);
+        break;
+#endif
+
         /*
          * sys{ctl, arch, call}
          */