qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [ADD] tests for PPC target.


From: J. Mayer
Subject: Re: [Qemu-devel] [ADD] tests for PPC target.
Date: 18 Nov 2003 09:08:47 +0100

target-ppc__tests__env-test.c.diff

Tiny test programs which dumps its environment.

diff -urNbB -x CVS qemu-current/target-ppc/tests/env-test.c 
qemu/target-ppc/tests/env-test.c
--- qemu-current/target-ppc/tests/env-test.c    Thu Jan  1 01:00:00 1970
+++ qemu/target-ppc/tests/env-test.c    Wed Nov 12 10:47:39 2003
@@ -0,0 +1,368 @@
+/*
+ * This test only wants to dump the stack and environment
+ * at process start time. This allows to check that qemu env
+ * is valid, compared to kernel env.
+ */
+
+static const char logfname[] = "/tmp/env-test.log";
+static const char first_mess[] = "Qemu execution environment test\n";
+
+#if defined (__i386__)
+/* ix86 definitions */
+
+register unsigned long __spp  __asm__ ("ebp");
+
+#define __syscall_return(type, res) \
+do { \
+       if ((unsigned long)(res) >= (unsigned long)(-125)) { \
+               errno = -(res); \
+               res = -1; \
+       } \
+       return (type) (res); \
+} while (0)
+
+#define _syscall0(type,name) \
+type name(void) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+       : "=a" (__res) \
+       : "0" (__NR_##name)); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall1(type,name,type1,arg1) \
+type name(type1 arg1) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+       : "=a" (__res) \
+       : "0" (__NR_##name),"b" ((long)(arg1))); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+type name(type1 arg1,type2 arg2) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+       : "=a" (__res) \
+       : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type name(type1 arg1,type2 arg2,type3 arg3) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+       : "=a" (__res) \
+       : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+                 "d" ((long)(arg3))); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+       : "=a" (__res) \
+       : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+         "d" ((long)(arg3)),"S" ((long)(arg4))); \
+__syscall_return(type,__res); \
+} 
+
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+         type5,arg5) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+       : "=a" (__res) \
+       : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+         "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+         type5,arg5,type6,arg6) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
+{ \
+long __res; \
+__asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; int $0x80 ; 
pop %%ebp" \
+       : "=a" (__res) \
+       : "i" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+         "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)), \
+         "0" ((long)(arg6))); \
+__syscall_return(type,__res); \
+}
+
+#elif defined (__powerpc__)
+/* PowerPC definitions */
+
+register unsigned long __spp  __asm__ ("r1");
+
+#define __syscall_nr(nr, type, name, args...)                           \
+        unsigned long __sc_ret, __sc_err = 0;                           \
+        {                                                               \
+                register unsigned long __sc_0  __asm__ ("r0");          \
+                register unsigned long __sc_3  __asm__ ("r3");          \
+                register unsigned long __sc_4  __asm__ ("r4");          \
+                register unsigned long __sc_5  __asm__ ("r5");          \
+                register unsigned long __sc_6  __asm__ ("r6");          \
+                register unsigned long __sc_7  __asm__ ("r7");          \
+                                                                        \
+                __sc_loadargs_##nr(name, args);                         \
+                __asm__ __volatile__                                    \
+                        ("sc           \n\t"                            \
+                         "mfcr %0      "                                \
+                        : "=&r" (__sc_0),                               \
+                          "=&r" (__sc_3),  "=&r" (__sc_4),              \
+                          "=&r" (__sc_5),  "=&r" (__sc_6),              \
+                          "=&r" (__sc_7)                                \
+                        : __sc_asm_input_##nr                           \
+                        : "cr0", "ctr", "memory",                       \
+                          "r8", "r9", "r10","r11", "r12");              \
+                __sc_ret = __sc_3;                                      \
+        }                                                               \
+        if (__sc_err & 0x10000000)                                      \
+        {                                                               \
+                errno = __sc_ret;                                       \
+                __sc_ret = -1;                                          \
+        }                                                               \
+        return (type) __sc_ret
+
+#define __sc_loadargs_0(name, dummy...)                                 \
+        __sc_0 = __NR_##name
+#define __sc_loadargs_1(name, arg1)                                     \
+        __sc_loadargs_0(name);                                          \
+        __sc_3 = (unsigned long) (arg1)
+#define __sc_loadargs_2(name, arg1, arg2)                               \
+        __sc_loadargs_1(name, arg1);                                    \
+        __sc_4 = (unsigned long) (arg2)
+#define __sc_loadargs_3(name, arg1, arg2, arg3)                         \
+        __sc_loadargs_2(name, arg1, arg2);                              \
+        __sc_5 = (unsigned long) (arg3)
+#define __sc_loadargs_4(name, arg1, arg2, arg3, arg4)                   \
+        __sc_loadargs_3(name, arg1, arg2, arg3);                        \
+        __sc_6 = (unsigned long) (arg4)
+#define __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5)             \
+        __sc_loadargs_4(name, arg1, arg2, arg3, arg4);                  \
+        __sc_7 = (unsigned long) (arg5)
+
+#define __sc_asm_input_0 "0" (__sc_0)
+#define __sc_asm_input_1 __sc_asm_input_0, "1" (__sc_3)
+#define __sc_asm_input_2 __sc_asm_input_1, "2" (__sc_4)
+#define __sc_asm_input_3 __sc_asm_input_2, "3" (__sc_5)
+#define __sc_asm_input_4 __sc_asm_input_3, "4" (__sc_6)
+#define __sc_asm_input_5 __sc_asm_input_4, "5" (__sc_7)
+
+#define _syscall0(type,name)                                            \
+type name(void)                                                         \
+{                                                                       \
+        __syscall_nr(0, type, name);                                    \
+}
+
+#define _syscall1(type,name,type1,arg1)                                 \
+type name(type1 arg1)                                                   \
+{                                                                       \
+        __syscall_nr(1, type, name, arg1);                              \
+}
+
+#define _syscall2(type,name,type1,arg1,type2,arg2)                      \
+type name(type1 arg1, type2 arg2)                                       \
+{                                                                       \
+        __syscall_nr(2, type, name, arg1, arg2);                        \
+}
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)           \
+type name(type1 arg1, type2 arg2, type3 arg3)                           \
+{                                                                       \
+        __syscall_nr(3, type, name, arg1, arg2, arg3);                  \
+}
+
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)               \
+{                                                                       \
+        __syscall_nr(4, type, name, arg1, arg2, arg3, arg4);            \
+}
+
+#define 
_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)   \
+{                                                                       \
+        __syscall_nr(5, type, name, arg1, arg2, arg3, arg4, arg5);      \
+}
+#else
+#error "Architecture not supported by now."
+#endif
+
+#define NULL ((void *)0)
+
+#define O_ACCMODE          0003
+#define O_RDONLY             00
+#define O_WRONLY             01
+#define O_RDWR               02
+#define O_CREAT            0100 /* not fcntl */
+
+#define __NR_exit                 1
+#define __NR_read                 3
+#define __NR_write                4
+#define __NR_open                 5
+#define __NR_close                6
+#define __NR_unlink              10
+#define __NR_sync                36
+#define __NR_fsync              118
+
+int errno;
+unsigned long *__sp;
+
+_syscall1(void, exit, int, status);
+static inline _syscall3(int, read, int, fd, void *, buf, int, count);
+static inline _syscall3(int, write, int, fd, const void *, buf, int, count);
+static inline _syscall3(int, open, const unsigned char *, pathname, int, 
flags, int, mode);
+static inline _syscall1(int, close, int, fd);
+static inline _syscall1(int, unlink, const unsigned char *, pathname);
+static inline _syscall0(int, sync);
+static inline _syscall1(int, fsync, int, fd);
+
+static int strlen (const unsigned char *string)
+{
+    int len;
+
+    for (len = 0; string[len] != '\0'; len++)
+        continue;
+
+    return len;
+}
+
+static int outstr (int fd, const unsigned char *string, int len)
+{
+    return write(fd, string, len);
+}
+
+static int outhex (int fd, unsigned long value)
+{
+    char tmpbuf[9], *pos = tmpbuf;
+    unsigned long tmp;
+    int i;
+
+    for (i = 28; i >= 0; i -=4 , pos++) {
+        tmp = (value >> i) & 0xf;
+        if (tmp < 0xa) {
+            *pos = '0' + tmp;
+        } else {
+            *pos = ('a' - 10) + tmp;
+        }
+    }
+    *pos = '\0';
+
+    return write(fd, tmpbuf, 8);
+}
+
+/* We walk through the stack until we reach a page-aligned address */
+static void dump_stack (int fd, int argc, char *const *argv, char *const *envp)
+{
+    unsigned long sp, *cur;
+    int i, j;
+
+    __asm__ __volatile__ ("mr %0, 1" : "=r"(sp));
+    /* Dump stack, argv and envp pointers */
+    outstr(fd, "Stack: ", strlen("Stack: "));
+    outhex(fd, sp);
+    outstr(fd, " ", 1);
+    outhex(fd, (unsigned long)__sp);
+    outstr(fd, "\n", 1);
+    fsync(fd);
+    cur = __sp - 32;
+    for (i = 0; ((unsigned long)cur & 0xff0) != 0xff0 && i < 256; i++) {
+        outhex(fd, (unsigned long)cur);
+        outstr(fd, ": ", 2);
+        for (j = 0; j < 4; j++) {
+            outhex(fd, *cur++);
+            outstr(fd, " ", 1);
+        }
+        outstr(fd, "\n", 1);
+    }
+}
+
+static void dump_env (int fd, int argc, char *const *argv, char *const *envp)
+{
+    int i;
+
+    outstr(fd, " argv: ", strlen(" argv: "));
+    outhex(fd, (unsigned long)argv);
+    outstr(fd, " envp: ", strlen(" envp: "));
+    outhex(fd, (unsigned long)envp);
+    outstr(fd, "\n", 1);
+    /* Dump args and environment */
+    outhex(fd, argc);
+    outstr(fd, " args\n", strlen(" args\n"));
+    for (i = 0; i < argc; i++) {
+        outstr(fd, " arg ", 5);
+        outhex(fd, i);
+        outstr(fd, " : ", 3);
+        outstr(fd, argv[i], strlen(argv[i]));
+        outstr(fd, "\n", 1);
+    }
+    outstr(fd, "Env\n", strlen("Env\n"));
+    for (i = 0; envp[i] != NULL; i++) {
+        outstr(fd, "envstr ", 7);
+        outhex(fd, i);
+        outstr(fd, " : ", 3);
+        outstr(fd, envp[i], strlen(envp[i]));
+        outstr(fd, "\n", 1);
+    }
+}
+
+int main (int argc, char **argv, char **envp)
+{
+    int logfile;
+
+    unlink(logfname);
+    logfile = open(logfname, O_WRONLY | O_CREAT, 0644);
+    if (logfile < 0)
+        return 1;
+    sync();
+    outstr(logfile, first_mess, strlen(first_mess));
+    fsync(logfile);
+    dump_stack(logfile, argc, argv, envp);
+    fsync(logfile);
+    dump_env(logfile, argc, argv, envp);
+    fsync(logfile);
+    close(logfile);
+
+    return 0;
+}
+
+/* Here's the program's entry point.
+ * As one can see, no asm is needed here.
+ */
+void _start (void)
+{
+    unsigned long *cur;
+    unsigned long *__argv, *__envp, __argc;
+    int __status, i;
+    
+    __sp = (unsigned long *)*((unsigned long *)__spp);
+    cur = __sp;
+    __argc = *cur;
+    __argv = cur + 1;
+    __envp = cur + 2 + __argc;
+    /* Linux is *STILL* buggy and doesn't respect the API */
+    if (*__argv == 0) {
+        unsigned long tmp = *__envp;
+
+        while (*(unsigned long *)tmp != 0)
+            tmp--;
+        tmp += 4;
+        for (i = 0; i < __argc; i++) {
+            __argv[i] = (unsigned long)tmp;
+            while (*(unsigned char *)tmp)
+                tmp++;
+            tmp++;
+        }
+    }
+    __status = main(__argc, (char **)__argv, (char **)__envp);
+    exit(__status);
+}






reply via email to

[Prev in Thread] Current Thread [Next in Thread]