[Top][All Lists]
[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);
+}
- Re: [Qemu-devel] [ADD] PPC processor emulation, (continued)
- Re: [Qemu-devel] [ADD] PPC processor emulation, J. Mayer, 2003/11/18
- Re: [Qemu-devel] [ADD] PPC processor emulation, J. Mayer, 2003/11/18
- Re: [Qemu-devel] [ADD] PPC processor emulation, J. Mayer, 2003/11/18
- Re: [Qemu-devel] [ADD] PPC processor emulation, J. Mayer, 2003/11/18
- Re: [Qemu-devel] [ADD] PPC processor emulation, J. Mayer, 2003/11/18
- Re: [Qemu-devel] [ADD] PPC processor emulation, J. Mayer, 2003/11/18
- Re: [Qemu-devel] [ADD] tests for PPC target., J. Mayer, 2003/11/18
- Re: [Qemu-devel] [ADD] tests for PPC target., J. Mayer, 2003/11/18
- Re: [Qemu-devel] [ADD] tests for PPC target., J. Mayer, 2003/11/18
- Re: [Qemu-devel] [ADD] tests for PPC target., J. Mayer, 2003/11/18
- Re: [Qemu-devel] [ADD] tests for PPC target.,
J. Mayer <=
- Re: [Qemu-devel] [ADD] tests for PPC target., J. Mayer, 2003/11/18
- Re: [Qemu-devel] [ADD] tests for PPC target., J. Mayer, 2003/11/18
- Re: [Qemu-devel] [ADD] PPC processor emulation, Gwenole Beauchesne, 2003/11/18
- Re: [Qemu-devel] [ADD] PPC processor emulation, J. Mayer, 2003/11/18
- Re: [Qemu-devel] [ADD] PPC processor emulation, Raymond W . Lucke IV, 2003/11/18
- Re: [Qemu-devel] [ADD] PPC processor emulation, J. Mayer, 2003/11/18
- Re: [Qemu-devel] [ADD] PPC processor emulation, Raymond W . Lucke IV, 2003/11/18
- Re: [Qemu-devel] [ADD] PPC processor emulation, Jocelyn Mayer, 2003/11/18
- Re: [Qemu-devel] [ADD] PPC processor emulation, Chad Page, 2003/11/18
- Re: [Qemu-devel] [ADD] PPC processor emulation, J. Mayer, 2003/11/18