Source-Changes-HG archive

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

[src/trunk]: src/sys/kern Rework how syscall compat is handled for rump sysca...



details:   https://anonhg.NetBSD.org/src/rev/6c3f8acb3f95
branches:  trunk
changeset: 760943:6c3f8acb3f95
user:      pooka <pooka%NetBSD.org@localhost>
date:      Mon Jan 17 16:16:54 2011 +0000

description:
Rework how syscall compat is handled for rump syscalls.  The old
one had the problem of bypassing the syscall layer and doing a
function call into the kernel directly.  Therefore there was no
way for users of librumpclient to specify compat.  The new model
pushes the compat handling in the kernel and leaves only the task
of selecting the right syscall number to the client.

This change also introduces a stable ABI for rump syscalls, i.e.
it is possible to use the same syscall client library both on NetBSD
5.0 and -current and get the syscalls resolved to the right place
depending on the ABI at the time the client binary is compiled.

A list of what to be called when will have to maintained separately
simply because this information is not available in syscalls.master
-- in the case of the normal kernel we always want to resolve a
newly linked syscall to the latest version, whereas in rump we
might want to resolve a syscall to a -current kernel to the 5.0
compat call (because our client namespace is 5.0).  This information
in maintained in rump_syscalls_compat.h with the current format:

/* time_t change */
#if !__NetBSD_Prereq__(5,99,7)
#define RUMP_SYS_RENAME_STAT rump___sysimpl_stat30
....

If no compat override is given, a syscall resolves automatically
to the latest version of the syscall.

Also, this change autogenerates forward declarations for all syscall
types where it is possible (i.e. ones without typedef insanity).
This makes it possible to include rump_syscalls.h without including
rump.h.

diffstat:

 sys/kern/makesyscalls.sh |  158 ++++++++++++++++++++++++++++++++++++----------
 1 files changed, 122 insertions(+), 36 deletions(-)

diffs (293 lines):

diff -r e85b6d0cbe99 -r 6c3f8acb3f95 sys/kern/makesyscalls.sh
--- a/sys/kern/makesyscalls.sh  Mon Jan 17 16:13:39 2011 +0000
+++ b/sys/kern/makesyscalls.sh  Mon Jan 17 16:16:54 2011 +0000
@@ -1,5 +1,5 @@
 #! /bin/sh -
-#      $NetBSD: makesyscalls.sh,v 1.108 2010/12/30 20:09:53 pooka Exp $
+#      $NetBSD: makesyscalls.sh,v 1.109 2011/01/17 16:16:54 pooka Exp $
 #
 # Copyright (c) 1994, 1996, 2000 Christopher G. Demetriou
 # All rights reserved.
@@ -73,8 +73,10 @@
 syscompat_pref="sysent."
 sysent="sysent.switch"
 sysnamesbottom="sysnames.bottom"
+rumptypes="rumphdr.types"
+rumpprotos="rumphdr.protos"
 
-trap "rm $sysdcl $sysprotos $sysent $sysnamesbottom $rumpsysent" 0
+trap "rm $sysdcl $sysprotos $sysent $sysnamesbottom $rumpsysent $rumptypes $rumpprotos" 0
 
 # Awk program (must support nawk extensions)
 # Use "awk" at Berkeley, "nawk" or "gawk" elsewhere.
@@ -152,6 +154,8 @@
        syscompat_pref = \"$syscompat_pref\"
        sysent = \"$sysent\"
        sysnamesbottom = \"$sysnamesbottom\"
+       rumpprotos = \"$rumpprotos\"
+       rumptypes = \"$rumptypes\"
        sys_nosys = \"$sys_nosys\"
        maxsysargs = \"$maxsysargs\"
        infile = \"$2\"
@@ -276,9 +280,10 @@
        printf "#ifdef _KERNEL\n" > rumpcallshdr
        printf "#error Interface not supported inside kernel\n" > rumpcallshdr
        printf "#endif /* _KERNEL */\n\n" > rumpcallshdr
-       printf "#include <sys/types.h>\n" > rumpcallshdr
-       printf "#include <sys/select.h>\n\n" > rumpcallshdr
-       printf "#include <signal.h>\n\n" > rumpcallshdr
+       printf "#include <sys/types.h> /* typedefs */\n" > rumpcallshdr
+       printf "#include <sys/select.h> /* typedefs */\n\n" > rumpcallshdr
+       printf "#include <signal.h> /* typedefs */\n\n" > rumpcallshdr
+       printf "#include <rump/rump_syscalls_compat.h>\n\n" > rumpcallshdr
 
        printf "%s", sysarghdrextra > sysarghdr
        # Write max number of system call arguments to both headers
@@ -308,6 +313,14 @@
                    "[sizeof (struct call##_args) \\\n" \
                "\t\t<= %sMAXSYSARGS * sizeof (%s) ? 1 : -1];\n", \
                constprefix, registertype) >sysarghdr
+
+       # compat types from syscalls.master.  this is slightly ugly,
+       # but given that we have so few compats from over 17 years,
+       # a more complicated solution is not currently warranted.
+       uncompattypes["struct timeval50"] = "struct timeval";
+       uncompattypes["struct timespec50"] = "struct timespec";
+       uncompattypes["struct stat30"] = "struct stat";
+
        next
 }
 NF == 0 || $1 ~ /^;/ {
@@ -459,13 +472,10 @@
                rumphaspipe = 1;
        }
 
-       funcstdname=fprefix "_" fbase
        if (fcompat != "") {
                funcname=fprefix "___" fbase "" fcompat
-               wantrename=1
        } else {
-               funcname=funcstdname
-               wantrename=0
+               funcname=fprefix "_" fbase
        }
        if (returntype == "quad_t" || returntype == "off_t") {
                if (sycall_flags == "0")
@@ -477,7 +487,11 @@
        if (funcalias == "") {
                funcalias=funcname
                sub(/^([^_]+_)*sys_/, "", funcalias)
+               realname=fbase
+       } else {
+               realname=funcalias
        }
+       rumpfname=realname "" fcompat
        f++
 
        if ($f != "(")
@@ -571,20 +585,39 @@
        if (!rumpable)
                return
 
-       if (wantrename)
-               printf("%s rump_%s(", returntype, funcstdname) > rumpcallshdr
-       else
-               printf("%s rump_sys_%s(", returntype, funcalias) > rumpcallshdr
+       # accumulate fbases we have seen.  we want the last
+       # occurence for the default __RENAME()
+       seen = funcseen[fbase]
+       funcseen[fbase] = rumpfname
+       if (seen)
+               return
+
+       printf("%s rump_sys_%s(", returntype, realname) > rumpprotos
+
        for (i = 1; i < varargc; i++)
                if (argname[i] != "PAD")
-                       printf("%s, ", argtype[i]) > rumpcallshdr
+                       printf("%s, ", uncompattype(argtype[i])) > rumpprotos
+
        if (isvarargs)
-               printf("%s, ...)", argtype[varargc]) > rumpcallshdr
+               printf("%s, ...)", uncompattype(argtype[varargc]))>rumpprotos
        else
-               printf("%s)", argtype[argc]) > rumpcallshdr
-       if (wantrename)
-               printf(" __RENAME(rump_%s)", funcname) > rumpcallshdr
-       printf(";\n") > rumpcallshdr
+               printf("%s)", uncompattype(argtype[argc])) > rumpprotos
+
+       printf(" __RENAME(RUMP_SYS_RENAME_%s)", toupper(fbase))> rumpprotos
+       printf(";\n") > rumpprotos
+
+       # generate forward-declares for types, apart from the
+       # braindead typedef jungle we cannot easily handle here
+       for (i = 1; i <= varargc; i++) {
+               type=uncompattype(argtype[i])
+               sub("const ", "", type)
+               if (!typeseen[type] && \
+                   match(type, "struct") && match(type, "\\*")) {
+                       typeseen[type] = 1
+                       sub(" *\\*", "", type);
+                       printf("%s;\n", type) > rumptypes
+               }
+       }
 }
 
 function printrumpsysent(insysent, compatwrap) {
@@ -604,14 +637,45 @@
        if (argc == 0) {
                printf("0, 0, ") > rumpsysent
        } else {
-               printf("ns(struct sys_%s%s_args), ", compatwrap_, funcalias) > rumpsysent
+               printf("ns(struct %ssys_%s_args), ", compatwrap_, funcalias) > rumpsysent
        }
-       printf("0,\n\t    %s },", wfn) > rumpsysent
-       for (i = 0; i < (33 - length(wfn)) / 8; i++)
+
+       if (compatwrap == "") {
+               if (modular)
+                       rfn = "(sy_call_t *)sys_nomodule"
+               else
+                       rfn = "(sy_call_t *)" funcname
+       } else {
+               rfn = "(sy_call_t *)" compatwrap "_" funcname
+       }
+
+       printf("0,\n\t    %s },", rfn) > rumpsysent
+       for (i = 0; i < (33 - length(rfn)) / 8; i++)
                printf("\t") > rumpsysent
        printf("/* %d = %s%s */\n", syscall, compatwrap_, funcalias) > rumpsysent
 }
 
+function iscompattype(type) {
+       for (var in uncompattypes) {
+               if (match(type, var)) {
+                       return 1
+               }
+       }
+
+       return 0
+}
+
+function uncompattype(type) {
+       for (var in uncompattypes) {
+               if (match(type, var)) {
+                       sub(var, uncompattypes[var], type)
+                       return type
+               }
+       }
+
+       return type
+}
+
 function putent(type, compatwrap) {
        # output syscall declaration for switch table.
        if (compatwrap == "")
@@ -696,19 +760,22 @@
        }
 
        # need a local prototype, we export the re-re-named one in .h
-       printf("\n%s rump_sys_%s(", returntype, funcalias) > rumpcalls
+       printf("\n%s rump___sysimpl_%s(", returntype, rumpfname) \
+           > rumpcalls
        for (i = 1; i < argc; i++) {
                if (argname[i] != "PAD")
-                       printf("%s, ", argtype[i]) > rumpcalls
+                       printf("%s, ", uncompattype(argtype[i])) > rumpcalls
        }
-       printf("%s);", argtype[argc]) > rumpcalls
+       printf("%s);", uncompattype(argtype[argc])) > rumpcalls
 
-       printf("\n%s\nrump_sys_%s(", returntype, funcalias) > rumpcalls
+       printf("\n%s\nrump___sysimpl_%s(", returntype, rumpfname) > rumpcalls
        for (i = 1; i < argc; i++) {
                if (argname[i] != "PAD")
-                       printf("%s %s, ", argtype[i], argname[i]) > rumpcalls
+                       printf("%s %s, ", uncompattype(argtype[i]), \
+                           argname[i]) > rumpcalls
        }
-       printf("%s %s)\n", argtype[argc], argname[argc]) > rumpcalls
+       printf("%s %s)\n", uncompattype(argtype[argc]), argname[argc]) \
+           > rumpcalls
        printf("{\n\tregister_t rval[2] = {0, 0};\n\tint error = 0;\n") \
            > rumpcalls
 
@@ -724,16 +791,22 @@
                                printf("\tSPARG(&callarg, %s) = 0;\n", \
                                    argname[i]) > rumpcalls
                        } else {
-                               printf("\tSPARG(&callarg, %s) = %s;\n", \
-                                   argname[i], argname[i]) > rumpcalls
+                               if (iscompattype(argtype[i])) {
+                                       printf("\tSPARG(&callarg, %s) = "    \
+                                       "(%s)%s;\n", argname[i], argtype[i], \
+                                       argname[i]) > rumpcalls
+                               } else {
+                                       printf("\tSPARG(&callarg, %s) = %s;\n",\
+                                           argname[i], argname[i]) > rumpcalls
+                               }
                        }
                }
                printf("\n") > rumpcalls
        } else {
                printf("\n") > rumpcalls
        }
-       printf("\terror = rsys_syscall(%s%s, " \
-           "%s, %s, rval);\n", constprefix, funcalias, \
+       printf("\terror = rsys_syscall(%s%s%s, " \
+           "%s, %s, rval);\n", constprefix, compatwrap_, funcalias, \
            argarg, argsize) > rumpcalls
        printf("\tif (error) {\n\t\trval[0] = -1;\n") > rumpcalls
        if (returntype != "void") {
@@ -743,7 +816,8 @@
                printf("\t}\n") > rumpcalls
        }
        printf("}\n") > rumpcalls
-       printf("rsys_alias(%s,rump_enosys)\n", funcname) > rumpcalls
+       printf("rsys_alias(%s%s,rump_enosys)\n", \
+           compatwrap_, funcname) > rumpcalls
 
 }
 $2 == "STD" || $2 == "NODEF" || $2 == "NOARGS" || $2 == "INDIR" {
@@ -795,7 +869,7 @@
 END {
        # output pipe() syscall with its special rval[2] handling
        if (rumphaspipe) {
-               printf("int rump_sys_pipe(int *);\n") > rumpcallshdr
+               printf("int rump_sys_pipe(int *);\n") > rumpprotos
                printf("\nint rump_sys_pipe(int *);\n") > rumpcalls
                printf("int\nrump_sys_pipe(int *fd)\n{\n") > rumpcalls
                printf("\tregister_t rval[2] = {0, 0};\n") > rumpcalls
@@ -809,6 +883,15 @@
                printf("\treturn error ? -1 : 0;\n}\n") > rumpcalls
        }
 
+       # print default rump syscall interfaces
+       for (var in funcseen) {
+               printf("#ifndef RUMP_SYS_RENAME_%s\n", \
+                   toupper(var)) > rumpcallshdr
+               printf("#define RUMP_SYS_RENAME_%s rump___sysimpl_%s\n", \
+                   toupper(var), funcseen[var]) > rumpcallshdr
+               printf("#endif\n\n") > rumpcallshdr
+       }
+
        maxsyscall = syscall
        if (nsysent) {
                if (syscall > nsysent) {
@@ -838,10 +921,13 @@
 cat $sysprotos >> $sysarghdr
 echo "#endif /* _${constprefix}SYSCALL_H_ */" >> $sysnumhdr
 echo "#endif /* _${constprefix}SYSCALLARGS_H_ */" >> $sysarghdr
-printf "\n#include <rump/rump_syscalls_compat.h>\n" >> $rumpcallshdr
-printf "\n#endif /* _RUMP_RUMP_SYSCALLS_H_ */\n" >> $rumpcallshdr
+printf "\n#endif /* _RUMP_RUMP_SYSCALLS_H_ */\n" >> $rumpprotos
 cat $sysdcl $sysent > $syssw
 cat $sysnamesbottom >> $sysnames
 cat $rumpsysent >> $rumpcalls
 
+cat $rumptypes >> $rumpcallshdr
+echo >> $rumpcallshdr
+cat $rumpprotos >> $rumpcallshdr
+
 #chmod 444 $sysnames $sysnumhdr $syssw



Home | Main Index | Thread Index | Old Index