]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Mucho buggering about jmp_with_stack and its kin. Jeez. Now the
authorJulian Seward <jseward@acm.org>
Tue, 22 Mar 2005 01:55:35 +0000 (01:55 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 22 Mar 2005 01:55:35 +0000 (01:55 +0000)
amd64 version is broken again.  Writing code with undocumented
assumptions should be a firable offense.  At the very least.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3402

coregrind/amd64-linux/syscalls.c
coregrind/amd64/jmp_with_stack.c
coregrind/stage1.c
coregrind/ume.h
coregrind/x86-linux/syscalls.c
coregrind/x86/jmp_with_stack.c

index 9ed1eb4cd49489154506e1185352777418bd44a0..fb0516b8715d690a8a9fdc3b098e641e60e061a8 100644 (file)
@@ -246,8 +246,6 @@ static ULong *allocstack(ThreadId tid)
 void VGA_(main_thread_wrapper)(ThreadId tid)
 {
    ULong *rsp = allocstack(tid);
-
-   VG_(printf)("m-t-r: %d\n", (int)tid);
    vg_assert(tid == VG_(master_tid));
 
    call_on_new_stack_0_1( 
index dacf37a4ab53478ad62efaf254344a35bb37f1a9..068b52450bd5eabd15c1a988aa32526982e04016 100644 (file)
 
 #include "ume.h"
 
-void jmp_with_stack(void(*rip)(void), Addr rsp)
-{
-   asm volatile (
-      "movq  %1, %%rsp;"       // set rsp
-      "pushq %%rax;"          // push rsp
-      "xorq  %%rax,%%rax;"    // clear registers
-      "xorq  %%rbx,%%rbx;"
-      "xorq  %%rcx,%%rcx;"
-      "xorq  %%rdx,%%rdx;"
-      "xorq  %%rsi,%%rsi;"
-      "xorq  %%rdi,%%rdi;"
-      "xorq  %%rbp,%%rbp;"
-      "xorq  %%r8, %%r8;"
-      "xorq  %%r9, %%r9;"
-      "xorq  %%r10,%%r10;"
-      "xorq  %%r11,%%r11;"
-      "xorq  %%r12,%%r12;"
-      "xorq  %%r13,%%r13;"
-      "xorq  %%r14,%%r14;"
-      "xorq  %%r15,%%r15;"
-      "ret"                   // return into entry
-      : : "a" (rip), "r" (rsp));
-
-   // we should never get here
-   for(;;)
-      asm volatile("ud2");
-} 
-
-
 
 #define ZERO_ALL_INT_REGS \
    "   movq $0, %rax\n"  \
@@ -73,6 +44,7 @@ void jmp_with_stack(void(*rip)(void), Addr rsp)
    "   movq $0, %r14\n"  \
    "   movq $0, %r15\n"
 
+
 /* Call f(), but first switch stacks, using 'stack' as the new stack,
    and use 'retaddr' as f's return-to address.  Also, clear all the
    integer registers before entering f. */
index 2c10edb796204bca0e3537533d381c72daf782ce..6ab8c93cd424053044767e5f8b5d3cf12e550cc6 100644 (file)
@@ -255,6 +255,7 @@ static int prmap(char *start, char *end, const char *perm, off_t off, int maj,
    return 1;
 }
 
+
 static void main2(void)
 {
    int err, padfile;
@@ -262,7 +263,7 @@ static void main2(void)
    extern char _end;
    int *esp;
    char buf[strlen(valgrind_lib) + sizeof(stage2) + 16];
-
+   printf("& local = %p\n", &esp);
    info.exe_end  = PGROUNDDN(init_sp);
 #ifdef HAVE_PIE
    info.exe_base = ROUNDDN(info.exe_end - 0x02000000, 0x10000000);
@@ -300,9 +301,16 @@ static void main2(void)
       foreach_map(prmap, /*dummy*/NULL);
    }
 
-   jmp_with_stack((void (*)(void))info.init_eip, (Addr)esp);   
+   jump_and_switch_stacks(
+      (Addr) esp,           /* stack */
+      (Addr) info.init_eip  /* where to */
+   );
+
+   /*NOTREACHED*/
+   assert(0); 
 }
 
+
 int main(int argc, char** argv)
 {
    struct rlimit rlim;
@@ -328,7 +336,13 @@ int main(int argc, char** argv)
    setrlimit(RLIMIT_AS, &rlim);
 
    /* move onto another stack so we can play with the main one */
-   jmp_with_stack(main2, (Addr)stack + sizeof(stack));
+   jump_and_switch_stacks(
+      (Addr)stack + sizeof(stack),  /* stack */
+      main2                         /* where to */
+   );
+
+   /*NOTREACHED*/
+   assert(0); 
 }
 
 /*--------------------------------------------------------------------*/
index e91f0301fa7f512203aef19914525e259c1a8afd..39818e204d6a07c4e09da814ac8b548556ccdba9 100644 (file)
@@ -47,22 +47,18 @@ void foreach_map(int (*fn)(char *start, char *end,
                           int maj, int min, int ino, void* extra),
                  void* extra);
 
-// Jump to a new 'ip' with the stack 'sp'.  This is intended
-// to simulate the initial CPU state when the kernel starts an program
-// after exec; and so should clear all the other registers.
+/* Jump to 'dst', but first set the stack pointer to 'stack'.  Also,
+   clear all the integer registers before entering 'dst'.  It's
+   important that the stack pointer is set to exactly 'stack' and not
+   (eg) stack - apparently_harmless_looking_small_offset.  Basically
+   because the code at 'dst' might be wanting to scan the area above
+   'stack' (viz, the auxv array), and putting spurious words on the
+   stack confuses it.
+*/
 extern
 __attribute__((noreturn))
-void jmp_with_stack(void (*eip)(void), Addr sp);
-
+void jump_and_switch_stacks ( Addr stack, Addr dst );
 
-/* Call f(), but first switch stacks, using 'stack' as the new stack,
-   and use 'retaddr' as f's return-to address.  Also, clear all the
-   integer registers before entering f. */
-extern
-__attribute__((noreturn))
-void call_on_new_stack_0_0 ( Addr stack,
-                            Addr retaddr,
-                            void (*f)(void) );
 
 /* Call f(arg1), but first switch stacks, using 'stack' as the new
    stack, and use 'retaddr' as f's return-to address.  Also, clear all
index ff246a26359b60a7678e4e33f46072fd54cddbd9..a7120d5b0c7e6e02c50286c8f697a5b50bd30f5e 100644 (file)
@@ -241,9 +241,15 @@ void VGA_(main_thread_wrapper)(ThreadId tid)
 
    vg_assert(tid == VG_(master_tid));
 
-   *--esp = tid;               /* set arg */
-   *--esp = 0;                 /* bogus return address */
-   jmp_with_stack((void (*)(void))VGA_(thread_wrapper), (Addr)esp);
+   call_on_new_stack_0_1( 
+      (Addr)esp,             /* stack */
+      0,                     /*bogus return address*/
+      VGA_(thread_wrapper),  /* fn to call */
+      (Word)tid              /* arg to give it */
+   );
+
+   /*NOTREACHED*/
+   vg_assert(0);
 }
 
 static Int start_thread(void *arg)
index 7328e6998f7d86be0bc9891506622799fee0ee04..17ce451898b4a91a51532ba9316b9d27cdc33273 100644 (file)
 
 #include "ume.h"
 
-/* 
-   Jump to a particular IP with a particular SP.  This is intended
-   to simulate the initial CPU state when the kernel starts an program
-   after exec; it therefore also clears all the other registers.
- */
-void jmp_with_stack(void (*eip)(void), Addr esp)
-{
-   asm volatile (
-      "movl  %1, %%esp;"      // set esp */
-      "pushl %%eax;"          // push esp */
-      "xorl  %%eax,%%eax;"    // clear registers
-      "xorl  %%ebx,%%ebx;"
-      "xorl  %%ecx,%%ecx;"
-      "xorl  %%edx,%%edx;"
-      "xorl  %%esi,%%esi;"
-      "xorl  %%edi,%%edi;"
-      "xorl  %%ebp,%%ebp;"
-      "ret"                   // return into entry
-      : : "a" (eip), "r" (esp));
-
-   // we should never get here
-   for(;;)
-      asm volatile("ud2");
-} 
+
+#define ZERO_ALL_INT_REGS \
+   "   movl $0, %eax\n"  \
+   "   movl $0, %ebx\n"  \
+   "   movl $0, %ecx\n"  \
+   "   movl $0, %edx\n"  \
+   "   movl $0, %esi\n"  \
+   "   movl $0, %edi\n"  \
+   "   movl $0, %ebp\n"
+
+
+/* Jump to 'dst', but first set the stack pointer to 'stack'.  Also,
+   clear all the integer registers before entering 'dst'.  It's
+   important that the stack pointer is set to exactly 'stack' and not
+   (eg) stack - apparently_harmless_looking_small_offset.  Basically
+   because the code at 'dst' might be wanting to scan the area above
+   'stack' (viz, the auxv array), and putting spurious words on the
+   stack confuses it.
+*/
+/*
+__attribute__((noreturn))
+void jump_and_switch_stacks ( Addr stack, Addr dst );
+
+   4(%esp) == stack
+   8(%esp) == f
+*/
+asm(
+".global jump_and_switch_stacks\n"
+"jump_and_switch_stacks:\n"
+"   movl   %esp, %esi\n"    /* remember old stack pointer */
+"   movl   4(%esi), %esp\n" /* set stack */
+"   pushl  8(%esi)\n"       /* f to stack*/
+    ZERO_ALL_INT_REGS
+"   ret\n"                  /* jump to f */
+"   ud2\n"                  /* should never get here */
+);
+
+
+
+/* Call f(arg1), but first switch stacks, using 'stack' as the new
+   stack, and use 'retaddr' as f's return-to address.  Also, clear all
+   the integer registers before entering f.*/
+/*
+__attribute__((noreturn))
+void call_on_new_stack_0_1 ( Addr stack,
+                            Addr retaddr,
+                            void (*f)(Word),
+                             Word arg1 );
+    4(%esp) == stack
+    8(%esp) == retaddr
+   12(%esp) == f
+   16(%esp) == arg1
+*/
+asm(
+".global call_on_new_stack_0_1\n"
+"call_on_new_stack_0_1:\n"
+"   movl %esp, %esi\n"      /* remember old stack pointer */
+"   movl 4(%esi), %esp\n"   /* set stack */
+"   pushl 16(%esi)\n"       /* arg1 to stack */
+"   pushl  8(%esi)\n"       /* retaddr to stack */
+"   pushl 12(%esi)\n"       /* f to stack */
+    ZERO_ALL_INT_REGS
+"   ret\n"                  /* jump to f */
+"   ud2\n"                  /* should never get here */
+);
+
+
+#undef ZERO_ALL_INT_REGS