use kernel like macros for user access (will be useful someday to have a better error...
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 22 Feb 2004 13:40:13 +0000 (13:40 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 22 Feb 2004 13:40:13 +0000 (13:40 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@634 c046a42c-6fe2-441c-8c8c-71466251a162

linux-user/elfload.c
linux-user/qemu.h
linux-user/signal.c
linux-user/syscall.c

index 7105525..980ab6b 100644 (file)
@@ -263,19 +263,11 @@ struct exec
 
 #define DLINFO_ITEMS 11
 
-#define put_user(x,ptr) (void)(*(ptr) = (typeof(*ptr))(x))
-#define get_user(ptr) (typeof(*ptr))(*(ptr))
-
 static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
 {
        memcpy(to, from, n);
 }
 
-static inline void memcpy_tofs(void * to, const void * from, unsigned long n)
-{
-       memcpy(to, from, n);
-}
-
 extern unsigned long x86_stack_size;
 
 static int load_aout_interp(void * exptr, int interp_fd);
@@ -373,11 +365,13 @@ static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
        return 0;       /* bullet-proofing */
     }
     while (argc-- > 0) {
-       if (!(tmp1 = tmp = get_user(argv+argc))) {
+        tmp = argv[argc];
+        if (!tmp) {
            fprintf(stderr, "VFS: argc is wrong");
            exit(-1);
        }
-       while (get_user(tmp++));
+        tmp1 = tmp;
+       while (*tmp++);
        len = tmp - tmp1;
        if (p < len) {  /* this shouldn't happen - 128kB */
                return 0;
@@ -395,7 +389,7 @@ static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
                }
            }
            if (len == 0 || offset == 0) {
-               *(pag + offset) = get_user(tmp);
+               *(pag + offset) = *tmp;
            }
            else {
              int bytes_to_copy = (len > offset) ? offset : len;
@@ -599,7 +593,8 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc,
 {
         target_ulong *argv, *envp;
         target_ulong *sp, *csp;
-        
+        int v;
+
        /*
         * Force 16 byte _final_ alignment here for generality.
         */
@@ -616,8 +611,8 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc,
             sp -= ((unsigned long)csp & 15UL) / sizeof(*sp);
         
 #define NEW_AUX_ENT(nr, id, val) \
-          put_user (tswapl(id), sp + (nr * 2)); \
-          put_user (tswapl(val), sp + (nr * 2 + 1))
+          put_user (id, sp + (nr * 2)); \
+          put_user (val, sp + (nr * 2 + 1))
         sp -= 2;
         NEW_AUX_ENT (0, AT_NULL, 0);
 
@@ -647,20 +642,26 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc,
         sp -= argc+1;
         argv = sp;
         if (!ibcs) {
-                put_user(tswapl((target_ulong)envp),--sp);
-                put_user(tswapl((target_ulong)argv),--sp);
+                put_user((target_ulong)envp,--sp);
+                put_user((target_ulong)argv,--sp);
         }
-        put_user(tswapl(argc),--sp);
+        put_user(argc,--sp);
         info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff);
         while (argc-->0) {
-                put_user(tswapl((target_ulong)p),argv++);
-                while (get_user(p++)) /* nothing */ ;
+                put_user((target_ulong)p,argv++);
+                do {
+                    get_user(v, p);
+                    p++;
+                } while (v != 0);
         }
         put_user(0,argv);
         info->arg_end = info->env_start = (unsigned int)((unsigned long)p & 0xffffffff);
         while (envc-->0) {
-                put_user(tswapl((target_ulong)p),envp++);
-                while (get_user(p++)) /* nothing */ ;
+                put_user((target_ulong)p,envp++);
+                do {
+                    get_user(v, p);
+                    p++;
+                } while (v != 0);
         }
         put_user(0,envp);
         info->env_end = (unsigned int)((unsigned long)p & 0xffffffff);
index 1a3ad62..be95ff9 100644 (file)
@@ -4,6 +4,7 @@
 #include "thunk.h"
 
 #include <signal.h>
+#include <string.h>
 #include "syscall_defs.h"
 
 #include "cpu.h"
@@ -120,4 +121,121 @@ long target_mremap(unsigned long old_addr, unsigned long old_size,
                    unsigned long new_addr);
 int target_msync(unsigned long start, unsigned long len, int flags);
 
+/* user access */
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+#define access_ok(type,addr,size) (1)
+
+#define __put_user(x,ptr)\
+({\
+    int size = sizeof(*ptr);\
+    switch(size) {\
+    case 1:\
+        stb(ptr, (typeof(*ptr))(x));\
+        break;\
+    case 2:\
+        stw(ptr, (typeof(*ptr))(x));\
+        break;\
+    case 4:\
+        stl(ptr, (typeof(*ptr))(x));\
+        break;\
+    case 8:\
+        stq(ptr, (typeof(*ptr))(x));\
+        break;\
+    default:\
+        abort();\
+    }\
+    0;\
+})
+
+#define __get_user(x, ptr) \
+({\
+    int size = sizeof(*ptr);\
+    switch(size) {\
+    case 1:\
+        x = (typeof(*ptr))ldub(ptr);\
+        break;\
+    case 2:\
+        x = (typeof(*ptr))lduw(ptr);\
+        break;\
+    case 4:\
+        x = (typeof(*ptr))ldl(ptr);\
+        break;\
+    case 8:\
+        x = (typeof(*ptr))ldq(ptr);\
+        break;\
+    default:\
+        abort();\
+    }\
+    0;\
+})
+
+static inline unsigned long __copy_to_user(void *dst, const void *src, 
+                                           unsigned long size)
+{
+    memcpy(dst, src, size);
+    return 0;
+}
+
+static inline unsigned long __copy_from_user(void *dst, const void *src, 
+                                             unsigned long size)
+{
+    memcpy(dst, src, size);
+    return 0;
+}
+
+static inline unsigned long __clear_user(void *dst, unsigned long size)
+{
+    memset(dst, 0, size);
+    return 0;
+}
+
+#define put_user(x,ptr)\
+({\
+    int __ret;\
+    if (access_ok(VERIFY_WRITE, ptr, sizeof(*ptr)))\
+        __ret = __put_user(x, ptr);\
+    else\
+        __ret = -EFAULT;\
+    __ret;\
+})
+
+#define get_user(x,ptr)\
+({\
+    int __ret;\
+    if (access_ok(VERIFY_READ, ptr, sizeof(*ptr)))\
+        __ret = __get_user(x, ptr);\
+    else\
+        __ret = -EFAULT;\
+    __ret;\
+})
+
+static inline unsigned long copy_to_user(void *dst, const void *src, 
+                                         unsigned long size)
+{
+    if (access_ok(VERIFY_WRITE, dst, size))
+        return __copy_to_user(dst, src, size);
+    else
+        return size;
+}
+
+static inline unsigned long copy_from_user(void *dst, const void *src, 
+                                             unsigned long size)
+{
+    if (access_ok(VERIFY_READ, src, size))
+        return __copy_from_user(dst, src, size);
+    else
+        return size;
+}
+
+static inline unsigned long clear_user(void *dst, unsigned long size)
+{
+    if (access_ok(VERIFY_WRITE, dst, size))
+        return __clear_user(dst, size);
+    else
+        return size;
+}
+
 #endif
index 666d6e1..41affb5 100644 (file)
@@ -450,69 +450,6 @@ int do_sigaction(int sig, const struct target_sigaction *act,
     return 0;
 }
 
-#define __put_user(x,ptr)\
-({\
-    int size = sizeof(*ptr);\
-    switch(size) {\
-    case 1:\
-        stb(ptr, (typeof(*ptr))(x));\
-        break;\
-    case 2:\
-        stw(ptr, (typeof(*ptr))(x));\
-        break;\
-    case 4:\
-        stl(ptr, (typeof(*ptr))(x));\
-        break;\
-    case 8:\
-        stq(ptr, (typeof(*ptr))(x));\
-        break;\
-    default:\
-        abort();\
-    }\
-    0;\
-})
-
-#define __get_user(x, ptr) \
-({\
-    int size = sizeof(*ptr);\
-    switch(size) {\
-    case 1:\
-        x = (typeof(*ptr))ldub(ptr);\
-        break;\
-    case 2:\
-        x = (typeof(*ptr))lduw(ptr);\
-        break;\
-    case 4:\
-        x = (typeof(*ptr))ldl(ptr);\
-        break;\
-    case 8:\
-        x = (typeof(*ptr))ldq(ptr);\
-        break;\
-    default:\
-        abort();\
-    }\
-    0;\
-})
-
-
-#define __copy_to_user(dst, src, size)\
-({\
-    memcpy(dst, src, size);\
-    0;\
-})
-
-#define __copy_from_user(dst, src, size)\
-({\
-    memcpy(dst, src, size);\
-    0;\
-})
-
-#define __clear_user(dst, size)\
-({\
-    memset(dst, 0, size);\
-    0;\
-})
-
 #ifndef offsetof
 #define offsetof(type, field) ((size_t) &((type *)0)->field)
 #endif
@@ -707,10 +644,8 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
 
        frame = get_sigframe(ka, env, sizeof(*frame));
 
-#if 0
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
                goto give_sigsegv;
-#endif
        err |= __put_user((/*current->exec_domain
                           && current->exec_domain->signal_invmap
                           && sig < 32
@@ -773,10 +708,8 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
 
        frame = get_sigframe(ka, env, sizeof(*frame));
 
-#if 0
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
                goto give_sigsegv;
-#endif
 
        err |= __put_user((/*current->exec_domain
                           && current->exec_domain->signal_invmap
@@ -1172,10 +1105,9 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
        struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame));
        int err = 0;
 
-#if 0
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
-            return 1;
-#endif
+            return /* 1 */;
+
        __put_user_error(&frame->info, (target_ulong *)&frame->pinfo, err);
        __put_user_error(&frame->uc, (target_ulong *)&frame->puc, err);
        err |= copy_siginfo_to_user(&frame->info, info);
index 9ac9572..6fae50d 100644 (file)
@@ -239,27 +239,6 @@ extern int setresgid(gid_t, gid_t, gid_t);
 extern int getresgid(gid_t *, gid_t *, gid_t *);
 extern int setgroups(int, gid_t *);
 
-#define put_user(x,ptr)\
-({\
-    int size = sizeof(*ptr);\
-    switch(size) {\
-    case 1:\
-        stb(ptr, (typeof(*ptr))(x));\
-        break;\
-    case 2:\
-        stw(ptr, (typeof(*ptr))(x));\
-        break;\
-    case 4:\
-        stl(ptr, (typeof(*ptr))(x));\
-        break;\
-    case 8:\
-        stq(ptr, (typeof(*ptr))(x));\
-        break;\
-    default:\
-        abort();\
-    }\
-    0;\
-})
 static inline long get_errno(long ret)
 {
     if (ret == -1)