[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCH 1/3] lib/syscall_shim: UK_LLSYSCALL_(R_)_DEFINE variants



Some system calls have different signatures and return types on the
libC API and the Linux system call ABI (e.g., brk, mount). In order
to support implementing such libc-style wrappers manually on top of
the syscall_shim library, we introduce so called low-level variants
for the UK_SYSCALL_(R_)_DEFINE macros that only provide the
uk_syscall_(e|r)_<syscall name> symbols: UK_LLSYSCALL_(R_)_DEFINE

Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
---
 doc/guides/developers-app.rst         | 35 ++++++++++-
 lib/syscall_shim/include/uk/syscall.h | 91 ++++++++++++++++++++-------
 2 files changed, 102 insertions(+), 24 deletions(-)

diff --git a/doc/guides/developers-app.rst b/doc/guides/developers-app.rst
index 5b5f0918..2e6e7757 100644
--- a/doc/guides/developers-app.rst
+++ b/doc/guides/developers-app.rst
@@ -419,10 +419,39 @@ Both macros create the following three symbols:
     <return_type> <syscall_name>(<arg1_type> <arg1_name>,
                                  <arg2_type> <arg2_name>, ...);
 
+For the case that the libc-style wrapper does not match the signature and 
return
+type of the underlying system call, a so called low-level variant of these two
+macros are available: ``UK_LLSYSCALL_DEFINE``, ``UK_LLSYSCALL_R_DEFINE``.
+These macros only generate the ``uk_syscall_e_<syscall_name>`` and
+``uk_syscall_r_<syscall_name>`` symbols. You can then provide the custom
+libc-style wrapper on top:
+
+.. code-block:: c
+
+    #include <uk/syscall.h>
+
+    UK_LLSYSCALL_R_DEFINE(ssize_t, write, int, fd, const void *, buf, size_t, 
count)
+    {
+        long ret;
+
+        ret = (long) vfs_do_write(fd, buf, count);
+        if (ret < 0) {
+            return -EFAULT;
+        }
+        return ret;
+    }
+
+    ssize_t write(int fd, const void *buf, size_t count)
+    {
+        return (ssize_t) uk_syscall_e_write((long) fd,
+                                            (long) buf, (long) count);
+    }
+
 Note: When `syscall_shim` library is not enabled, the original design idea was
-that the macros provide the libc-style wrapper only. However, both macros
-provide always all three variants. This is done to support the case that a
-system call is implemented on top of another.
+that the macros provide the libc-style wrapper only. However, all the
+described macros are still available and populate the symbols as documented
+here. This is done to support the case that a system call is implemented by
+calling another.
 
 If your library uses an ``exportsyms.uk`` file, you need to add the three
 symbols for making them public available: ::
diff --git a/lib/syscall_shim/include/uk/syscall.h 
b/lib/syscall_shim/include/uk/syscall.h
index cd5c6e67..a219365b 100644
--- a/lib/syscall_shim/include/uk/syscall.h
+++ b/lib/syscall_shim/include/uk/syscall.h
@@ -37,6 +37,7 @@
 #ifndef __UK_SYSCALL_H__
 #define __UK_SYSCALL_H__
 
+#include <uk/config.h>
 #include <uk/essentials.h>
 #include <errno.h>
 #include <uk/print.h>
@@ -94,56 +95,83 @@ typedef long uk_syscall_arg_t;
 /* TODO: `void` as return type is currently not supported.
  * NOTE: Workaround is to use `int` instead.
  */
-#define __UK_SYSCALL_DEFINE(x, rtype, name, ename, rname, ...)         \
-       rtype name(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL, __VA_ARGS__));       \
+/*
+ * UK_LLSYSCALL_DEFINE()
+ * Low-level variant, does not provide a libc-style wrapper
+ */
+#define __UK_LLSYSCALL_DEFINE(x, rtype, name, ename, rname, ...)       \
+       long ename(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__));         \
        long rname(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__))          \
        {                                                               \
                int _errno = errno;                                     \
                long ret;                                               \
                                                                        \
                errno = 0;                                              \
-               ret = (long) name(                                      \
-                       UK_ARG_MAPx(x, UK_S_ARG_CAST_ACTUAL, __VA_ARGS__)); \
+               ret = ename(                                            \
+                       UK_ARG_MAPx(x, UK_S_ARG_CAST_LONG, __VA_ARGS__)); \
                if (ret == -1)                                          \
                        ret = errno ? -errno : -EFAULT;                 \
                errno = _errno;                                         \
                return ret;                                             \
        }                                                               \
+       static inline rtype __##ename(UK_ARG_MAPx(x,                    \
+                                       UK_S_ARG_ACTUAL, __VA_ARGS__)); \
        long ename(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__))          \
        {                                                               \
-               return (long) name(                                     \
+               return (long) __##ename(                                \
                        UK_ARG_MAPx(x, UK_S_ARG_CAST_ACTUAL, __VA_ARGS__)); \
        }                                                               \
-       rtype name(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL, __VA_ARGS__))
+       static inline rtype __##ename(UK_ARG_MAPx(x,                    \
+                                                 UK_S_ARG_ACTUAL, __VA_ARGS__))
+#define _UK_LLSYSCALL_DEFINE(...) __UK_LLSYSCALL_DEFINE(__VA_ARGS__)
+#define UK_LLSYSCALL_DEFINE(rtype, name, ...)                          \
+       _UK_LLSYSCALL_DEFINE(__UK_SYSCALL_DEF_NARGS(__VA_ARGS__),       \
+                            rtype,                                     \
+                            name,                                      \
+                            __UK_NAME2SCALLE_FN(name),                 \
+                            __UK_NAME2SCALLR_FN(name),                 \
+                            __VA_ARGS__)
+
+/*
+ * UK_SYSCALL_DEFINE()
+ * Based on UK_LLSYSCALL_DEFINE and provides a libc-style wrapper
+ */
+#define __UK_SYSCALL_DEFINE(x, rtype, name, ename, rname, ...)         \
+       long ename(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__));         \
+       rtype name(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL, __VA_ARGS__))        \
+       {                                                               \
+               return (rtype) ename(                                   \
+                       UK_ARG_MAPx(x, UK_S_ARG_CAST_LONG, __VA_ARGS__)); \
+       }                                                               \
+       __UK_LLSYSCALL_DEFINE(x, rtype, name, ename, rname, __VA_ARGS__)
 #define _UK_SYSCALL_DEFINE(...) __UK_SYSCALL_DEFINE(__VA_ARGS__)
-#define UK_SYSCALL_DEFINE(rtype, name, ...)                           \
-       _UK_SYSCALL_DEFINE(__UK_SYSCALL_DEF_NARGS(__VA_ARGS__),        \
-                          rtype,                                      \
-                          name,                                       \
-                          __UK_NAME2SCALLE_FN(name),                  \
-                          __UK_NAME2SCALLR_FN(name),                  \
+#define UK_SYSCALL_DEFINE(rtype, name, ...)                            \
+       _UK_SYSCALL_DEFINE(__UK_SYSCALL_DEF_NARGS(__VA_ARGS__),         \
+                          rtype,                                       \
+                          name,                                        \
+                          __UK_NAME2SCALLE_FN(name),                   \
+                          __UK_NAME2SCALLR_FN(name),                   \
                           __VA_ARGS__)
 
 /* Raw system call implementation that is returning negative codes on errors */
 /* TODO: `void` as return type is currently not supported.
  * NOTE: Workaround is to use `int` instead.
  */
-#define __UK_SYSCALL_R_DEFINE(x, rtype, name, ename, rname, ...)       \
+/*
+ * UK_LLSYSCALL_R_DEFINE()
+ * Low-level variant, does not provide a libc-style wrapper
+ */
+#define __UK_LLSYSCALL_R_DEFINE(x, rtype, name, ename, rname, ...)     \
        long rname(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__));         \
-       rtype name(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL, __VA_ARGS__))        \
+       long ename(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__))          \
        {                                                               \
                long ret = rname(                                       \
                        UK_ARG_MAPx(x, UK_S_ARG_CAST_LONG, __VA_ARGS__)); \
                if (ret < 0) {                                          \
                        errno = (int) -ret;                             \
-                       return (rtype) -1;                              \
+                       return -1;                                      \
                }                                                       \
-               return (rtype) ret;                                     \
-       }                                                               \
-       long ename(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__))          \
-       {                                                               \
-               return (long) name(                                     \
-                       UK_ARG_MAPx(x, UK_S_ARG_CAST_ACTUAL, __VA_ARGS__)); \
+               return ret;                                             \
        }                                                               \
        static inline long __##rname(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL,    \
                                                 __VA_ARGS__));         \
@@ -154,6 +182,27 @@ typedef long uk_syscall_arg_t;
        }                                                               \
        static inline long __##rname(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL,    \
                                                 __VA_ARGS__))
+#define _UK_LLSYSCALL_R_DEFINE(...) __UK_LLSYSCALL_R_DEFINE(__VA_ARGS__)
+#define UK_LLSYSCALL_R_DEFINE(rtype, name, ...)                                
\
+       _UK_LLSYSCALL_R_DEFINE(__UK_SYSCALL_DEF_NARGS(__VA_ARGS__),     \
+                              rtype,                                   \
+                              name,                                    \
+                              __UK_NAME2SCALLE_FN(name),               \
+                              __UK_NAME2SCALLR_FN(name),               \
+                              __VA_ARGS__)
+
+/*
+ * UK_SYSCALL_R_DEFINE()
+ * Based on UK_LLSYSCALL_R_DEFINE and provides a libc-style wrapper
+ */
+#define __UK_SYSCALL_R_DEFINE(x, rtype, name, ename, rname, ...)       \
+       long ename(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__));         \
+       rtype name(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL, __VA_ARGS__))        \
+       {                                                               \
+               return (rtype) ename(                                   \
+                       UK_ARG_MAPx(x, UK_S_ARG_CAST_LONG, __VA_ARGS__)); \
+       }                                                               \
+       __UK_LLSYSCALL_R_DEFINE(x, rtype, name, ename, rname, __VA_ARGS__)
 #define _UK_SYSCALL_R_DEFINE(...) __UK_SYSCALL_R_DEFINE(__VA_ARGS__)
 #define UK_SYSCALL_R_DEFINE(rtype, name, ...)                          \
        _UK_SYSCALL_R_DEFINE(__UK_SYSCALL_DEF_NARGS(__VA_ARGS__),       \
-- 
2.20.1


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.