]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fill in a bunch of amd64-specific crud. Still won't link though.
authorJulian Seward <jseward@acm.org>
Wed, 16 Mar 2005 22:04:40 +0000 (22:04 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 16 Mar 2005 22:04:40 +0000 (22:04 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3382

12 files changed:
coregrind/amd64-linux/core_platform.h
coregrind/amd64-linux/syscalls.c
coregrind/amd64/Makefile.am
coregrind/amd64/core_arch.h
coregrind/amd64/helpers.S
coregrind/amd64/jmp_with_stack.c
coregrind/amd64/signals.c
coregrind/amd64/state.c
coregrind/vg_mylibc.c
coregrind/vg_signals.c
coregrind/x86-linux/syscalls.c
include/amd64-linux/vki_arch.h

index 7d236e26040b5d26cf901c7bd18164c9d0f0faf0..d1d7acc110d706b493469537c05194e25c91cf55 100644 (file)
@@ -103,6 +103,14 @@ extern Addr VG_(do_useseg) ( UInt seg_selector, Addr virtual_addr );
    I_die_here; \
 } while (0)
 
+
+/* Use libc setjmp/longjmp.  longjmp must not restore signal mask
+   state, but does need to pass though "val". */
+#include <setjmp.h>       /* for jmp_buf         */
+
+#define SETJMP(env)            setjmp(env)
+#define LONGJMP(env, val)      longjmp(env, val)
+
 #endif   // __AMD64_LINUX_CORE_PLATFORM_H
 
 /*--------------------------------------------------------------------*/
index 4efad8c0c033cb72a86d33a6da7cafff8acdfd58..098a6e0f60b3119d348b3406ab9df5c0eaaea596 100644 (file)
@@ -147,6 +147,91 @@ void VGA_(restart_syscall)(ThreadArchState *arch)
 #endif
 }
 
+/* ---------------------------------------------------------------------
+   Stacks, thread wrappers, clone
+   Note.  Why is this stuff here?
+   ------------------------------------------------------------------ */
+
+/* 
+   Allocate a stack for this thread.
+
+   They're allocated lazily, but never freed.
+ */
+#define FILL   0xdeadbeef
+
+
+/* NB: this is identical the the x86 version. */
+/* Return how many bytes of this stack have not been used */
+Int VGA_(stack_unused)(ThreadId tid)
+{
+   ThreadState *tst = VG_(get_ThreadState)(tid);
+   UInt *p;
+
+   for (p = tst->os_state.stack; 
+       p && (p < (tst->os_state.stack + tst->os_state.stacksize)); 
+       p++)
+      if (*p != FILL)
+        break;
+
+   if (0)
+      VG_(printf)("p=%p %x tst->os_state.stack=%p\n", p, *p, tst->os_state.stack);
+
+   return (p - tst->os_state.stack) * sizeof(*p);
+}
+
+static ULong *allocstack(ThreadId tid)
+{
+   ThreadState *tst = VG_(get_ThreadState)(tid);
+   ULong* rsp;
+   UInt*  pUInt;
+
+   if (tst->os_state.stack == NULL) {
+      void *stk = VG_(mmap)(0, VG_STACK_SIZE_W * sizeof(Int) + VKI_PAGE_SIZE,
+                           VKI_PROT_READ|VKI_PROT_WRITE,
+                           VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS,
+                           SF_VALGRIND,
+                           -1, 0);
+
+      if (stk != (void *)-1) {
+        VG_(mprotect)(stk, VKI_PAGE_SIZE, VKI_PROT_NONE); /* guard page */
+        tst->os_state.stack = (UInt *)stk + VKI_PAGE_SIZE/sizeof(UInt);
+        tst->os_state.stacksize = VG_STACK_SIZE_W;
+      } else 
+        return (ULong *)-1;
+   }
+
+   for (pUInt = tst->os_state.stack; 
+        pUInt < (tst->os_state.stack + tst->os_state.stacksize); 
+        pUInt++)
+      *pUInt = FILL;
+   /* rsp is left at top of stack */
+   rsp = pUInt;
+
+   if (0)
+      VG_(printf)("stack for tid %d at %p (%x); esp=%p\n",
+                 tid, tst->os_state.stack, *tst->os_state.stack,
+                 rsp);
+
+   return rsp;
+}
+
+
+/*
+   Allocate a stack for the main thread, and call VGA_(thread_wrapper)
+   on that stack.
+ */
+void VGA_(main_thread_wrapper)(ThreadId tid)
+{
+   ULong *rsp = allocstack(tid);
+
+   vg_assert(tid == VG_(master_tid));
+
+   VG_(threads)[tid].arch.vex.guest_RDI = (ULong)tid; /* set arg */
+   *--rsp = 0;                 /* bogus return address */
+   jmp_with_stack((void (*)(void))VGA_(thread_wrapper), (Addr)rsp);
+}
+
+
 /* ---------------------------------------------------------------------
    PRE/POST wrappers for AMD64/Linux-specific syscalls
    ------------------------------------------------------------------ */
index c87e43b4bfa0aad8409c5387212e402d9699f096..c464e8484d50f4aeb3eb3585ef7b4bdf69eceb46 100644 (file)
@@ -12,8 +12,7 @@ noinst_HEADERS = \
 noinst_LIBRARIES = libarch.a
 
 EXTRA_DIST = \
-       jmp_with_stack.c \
-       libpthread.c
+       jmp_with_stack.c
 
 BUILT_SOURCES = stage2.lds
 CLEANFILES = stage2.lds
@@ -23,6 +22,7 @@ libarch_a_SOURCES = \
        helpers.S \
        dispatch.S \
        signals.c \
+       jmp_with_stack.c \
        state.c
 
 # Extract ld's default linker script and hack it to our needs
index c6ad3d467da533cfbc2fbd4d75ed855d7705b8dd..1c079c697dd0a42cbb405e7686624bf278a24050 100644 (file)
@@ -113,9 +113,9 @@ typedef VexGuestAMD64State VexGuestArchState;
 
 // ToDo XXX???  not at all sure about this...
 struct _ThreadArchAux {
-   void*         tls_data;
-   int           tls_segment;
-   unsigned long sysinfo;
+  //   void*         tls_data;
+  //   int           tls_segment;
+  //   unsigned long sysinfo;
 };
 
 /* ---------------------------------------------------------------------
@@ -125,6 +125,9 @@ struct _ThreadArchAux {
 // Valgrind's signal stack size, in words.
 #define VG_SIGSTACK_SIZE_W    10000
 
+// Valgrind's stack size, in words.
+#define VG_STACK_SIZE_W    16384
+
 // Base address of client address space.
 #define CLIENT_BASE    0x00000000ul
 
index b1d44c56a05c27c7bc09ff10e62186c1be2c35bb..4543e23f1f0934d63524616722d415d62d413ea1 100644 (file)
@@ -28,6 +28,7 @@
 */
 
 #include "core_asm.h"
+#include "vki_unistd.h"
 
 /* ------------------ SIMULATED CPU HELPERS ------------------ */
 /* A stubs for a return which we want to catch: a signal return.
 .global VG_(tramp_syscall_offset)
        
 VG_(trampoline_code_start):
-sigreturn_start:       
-       subl    $20, %esp       # allocate arg block
-       movl    %esp, %edx      # %edx == &_zzq_args[0]
-       movl    $VG_USERREQ__SIGNAL_RETURNS, 0(%edx)    # request
-       movl    $0, 4(%edx)     # arg1
-       movl    $0, 8(%edx)     # arg2
-       movl    $0, 12(%edx)    # arg3
-       movl    $0, 16(%edx)    # arg4
-       movl    %edx, %eax
-       # and now the magic sequence itself:
-       roll $29, %eax
-       roll $3, %eax
-       rorl $27, %eax
-       rorl $5, %eax
-       roll $13, %eax
-       roll $19, %eax
-       # should never get here
-       ud2
+sigreturn_start:
+        /* This is a very specific sequence which GDB uses to
+           recognize signal handler frames. */
+        popq    %rax
+        movq    $__NR_rt_sigreturn, %rax
+        syscall
+        ud2
+
+rt_sigreturn_start:
+        /* Likewise for rt signal frames */
+        movq    $__NR_rt_sigreturn, %rax
+        syscall
+        ud2
 
        # We can point our sysinfo stuff here
        .align 16
index fc34eff6a9545fa556a1c3f1efa76b9d2a30ebdb..87ddb8f47f72ab8bbf4a0cf180238c61bc2bdab6 100644 (file)
@@ -26,7 +26,7 @@
 
 #include "ume.h"
 
-void jmp_with_stack(Addr rip, Addr rsp)
+void jmp_with_stack(void(*rip)(void), Addr rsp)
 {
    asm volatile (
       "movq  %1, %%rsp;"       // set rsp
index 423bc3a6480317b00cec0e8668e0273a6088abe1..012434ff9a90fba9de0ef522a35f64efe95625a2 100644 (file)
@@ -157,7 +157,8 @@ static void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,
 void VGA_(push_signal_frame)(ThreadId tid, Addr esp_top_of_frame,
                              const vki_siginfo_t *siginfo,
                              void *handler, UInt flags,
-                             const vki_sigset_t *mask)
+                             const vki_sigset_t *mask,
+                             void* restorer)
 {
    I_die_here;
 #if 0
index 69a2a4ca38991031b228bfb716e1f3a10f2f8ad4..ac08691e320f38bb099caa6cf77021665eeefcd7 100644 (file)
@@ -91,24 +91,54 @@ void VGA_(cleanup_thread) ( ThreadArchState *arch )
 }  
 
 
-void VGA_(setup_child) ( ThreadArchState *arch, ThreadArchState *parent_arch )
+void VGA_(setup_child) ( /*OUT*/ ThreadArchState *child, 
+                         /*IN*/  ThreadArchState *parent )
 {  
    I_die_here;
 #if 0
+   /* We inherit our parent's guest state. */
+   child->vex = parent->vex;
+   child->vex_shadow = parent->vex_shadow;
    /* We inherit our parent's LDT. */
-   if (parent_arch->ldt == NULL) {
+   if (parent->vex.guest_LDT == (HWord)NULL) {
       /* We hope this is the common case. */
-      arch->ldt = NULL;
+      child->vex.guest_LDT = (HWord)NULL;
    } else {
       /* No luck .. we have to take a copy of the parent's. */
-      arch->ldt = VG_(allocate_LDT_for_thread)( parent_arch->ldt );
+      child->vex.guest_LDT = (HWord)VG_(alloc_zeroed_x86_LDT)();
+      copy_LDT_from_to( (VexGuestX86SegDescr*)parent->vex.guest_LDT, 
+                        (VexGuestX86SegDescr*)child->vex.guest_LDT );
    }
 
-   /* Initialise the thread's TLS array */
-   VG_(clear_TLS_for_thread)( arch->tls );
+   /* We need an empty GDT. */
+   child->vex.guest_GDT = (HWord)NULL;
 #endif
 }  
 
+void VGA_(mark_from_registers)(ThreadId tid, void (*marker)(Addr))
+{
+   ThreadState *tst = VG_(get_ThreadState)(tid);
+   ThreadArchState *arch = &tst->arch;
+
+   /* XXX ask tool about validity? */
+   (*marker)(arch->vex.guest_RAX);
+   (*marker)(arch->vex.guest_RCX);
+   (*marker)(arch->vex.guest_RDX);
+   (*marker)(arch->vex.guest_RBX);
+   (*marker)(arch->vex.guest_RSI);
+   (*marker)(arch->vex.guest_RDI);
+   (*marker)(arch->vex.guest_RSP);
+   (*marker)(arch->vex.guest_RBP);
+   (*marker)(arch->vex.guest_R8);
+   (*marker)(arch->vex.guest_R9);
+   (*marker)(arch->vex.guest_R10);
+   (*marker)(arch->vex.guest_R11);
+   (*marker)(arch->vex.guest_R12);
+   (*marker)(arch->vex.guest_R13);
+   (*marker)(arch->vex.guest_R14);
+   (*marker)(arch->vex.guest_R15);
+}
+
 
 /*------------------------------------------------------------*/
 /*--- Symtab stuff                                         ---*/
index d03e01330d9d8604e30b96d9cb55eed3a69effba..e049a8f66578db2e4bc52f96d5adc42e5fb02292 100644 (file)
@@ -1455,12 +1455,14 @@ Char *VG_(getenv)(Char *varname)
 /* Support for getrlimit. */
 Int VG_(getrlimit) (Int resource, struct vki_rlimit *rlim)
 {
-   Int res;
+   Int res = -VKI_ENOSYS;
    /* res = getrlimit( resource, rlim ); */
+#  ifdef __NR_ugetrlimit
    res = VG_(do_syscall2)(__NR_ugetrlimit, resource, (UWord)rlim);
+#  endif
    if (res == -VKI_ENOSYS)
       res = VG_(do_syscall2)(__NR_getrlimit, resource, (UWord)rlim);
-   if(VG_(is_kerror)(res)) res = -1;
+   if (VG_(is_kerror)(res)) res = -1;
    return res;
 }
 
@@ -1471,7 +1473,7 @@ Int VG_(setrlimit) (Int resource, const struct vki_rlimit *rlim)
    Int res;
    /* res = setrlimit( resource, rlim ); */
    res = VG_(do_syscall2)(__NR_setrlimit, resource, (UWord)rlim);
-   if(VG_(is_kerror)(res)) res = -1;
+   if (VG_(is_kerror)(res)) res = -1;
    return res;
 }
 
index 2670708dc29f4b825f0b7064fe6170fb3f4ad5b1..6774b399f1d0f0f24b6f4f75d30596a5e69ec93d 100644 (file)
@@ -1928,7 +1928,7 @@ void vg_sync_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext
                   "si_code=%x Fault EIP: %p%s; Faulting address: %p",
                   info->si_code, context_ip, buf, info->_sifields._sigfault._addr);
       VG_(message)(Vg_DebugMsg, 
-                  "  esp=%p\n", uc->uc_mcontext.esp);
+                  "  sp=%p\n", UCONTEXT_STACK_PTR(uc));
 
       if (0)
         VG_(kill_self)(sigNo);         /* generate a core dump */
index 4bd9941dfe569134bba4d0c9a24ede57aedd5166..b47e07a00cf9fa669b027a0bfa21faa96273ff78 100644 (file)
 #include "core.h"
 #include "ume.h"                /* for jmp_with_stack */
 
+
+/* ---------------------------------------------------------------------
+   Stacks, thread wrappers, clone
+   Note.  Why is this stuff here?
+   ------------------------------------------------------------------ */
+
 /* These are addresses within VGA_(client_syscall).  See syscall.S for details. */
 extern const Word VGA_(blksys_setup);
 extern const Word VGA_(blksys_restart);
@@ -204,6 +210,7 @@ static UInt *allocstack(ThreadId tid)
    return esp;
 }
 
+/* NB: this is identical the the amd64 version. */
 /* Return how many bytes of this stack have not been used */
 Int VGA_(stack_unused)(ThreadId tid)
 {
index 02520f5491f07d43219d6003c4ef61d2685ffe00..2cda2f69d3039d09b756c9e45f52f2cf37922d82 100644 (file)
@@ -214,7 +214,7 @@ struct vki_sigcontext {
 #define VKI_PROT_READ  0x1             /* page can be read */
 #define VKI_PROT_WRITE 0x2             /* page can be written */
 #define VKI_PROT_EXEC  0x4             /* page can be executed */
-//#define VKI_PROT_NONE        0x0             /* page can not be accessed */
+#define VKI_PROT_NONE  0x0             /* page can not be accessed */
 
 #define VKI_MAP_SHARED 0x01            /* Share changes */
 #define VKI_MAP_PRIVATE        0x02            /* Changes are private */
@@ -517,6 +517,8 @@ struct vki_user_desc {
 typedef struct vki_user_desc vki_modify_ldt_t;
 #endif
 
+typedef void vki_modify_ldt_t;
+
 //----------------------------------------------------------------------
 // And that's it!
 //----------------------------------------------------------------------