]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Clear a few more AMD64 start-up hurdles:
authorNicholas Nethercote <njn@valgrind.org>
Tue, 30 Nov 2004 16:04:58 +0000 (16:04 +0000)
committerNicholas Nethercote <njn@valgrind.org>
Tue, 30 Nov 2004 16:04:58 +0000 (16:04 +0000)
- implemented VG_(clone)()
- implemented PLATFORM_DO_MMAP()
- implemented VG_(init_thread1state)()  [will need to be updated as the
  Vex AMD64 guest state is updated]
- implemented OYNK, because it's useful

Also a couple of general cleaning up things.

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

coregrind/amd64-linux/core_platform.h
coregrind/amd64-linux/syscall.S
coregrind/amd64/core_arch_asm.h
coregrind/amd64/state.c
coregrind/vg_main.c
coregrind/x86/state.c

index c6f5a681ac43be219509a1b94b97089264dce6bc..568d80f212a0a9ecb1f54b12a8bc72a8993087ee 100644 (file)
@@ -95,7 +95,8 @@ extern Addr VG_(do_useseg) ( UInt seg_selector, Addr virtual_addr );
    ------------------------------------------------------------------ */
 
 #define PLATFORM_DO_MMAP(ret, start, length, prot, flags, fd, offset) { \
-   I_die_here; \
+   ret = VG_(do_syscall6)(__NR_mmap, (UWord)(start), (length),          \
+                         (prot), (flags), (fd), (offset));              \
 } while (0)
 
 #define PLATFORM_GET_MMAP_ARGS(tst, a1, a2, a3, a4, a5, a6) do {\
index 2b01fdc41c7a485a0ae9c2d34f6857b8e9532bc0..3282b9057d31eb90115c84d413df87705ed46596 100644 (file)
@@ -65,12 +65,59 @@ VG_(do_syscall):
        ret
 
 
-
-# XXX: must reinstate comments also -- see x86-linux/syscall.S
-
+/*
+        Perform a clone system call.  clone is strange because it has
+        fork()-like return-twice semantics, so it needs special
+        handling here.
+
+       Upon entry, we have:
+
+           int (*fn)(void*)    in %rdi
+           void*  child_stack  in %rsi
+           int    flags        in %rdx
+           void*  arg          in %rcx
+           pid_t* child_tid    in %r8
+           pid_t* parent_tid   in %r9
+ */
 .globl VG_(clone)
 VG_(clone):
-       ud2
+        // set up child stack, temporarily preserving fn and arg
+        subq    $16, %rsi               // make space on stack
+        movq    %rcx, 8(%rsi)           // save arg
+        movq    %rdi, 0(%rsi)           // save fn 
+        
+        // setup syscall
+        movl    $__NR_clone, %eax       // syscall number
+        movq    %rdx, %rdi              // syscall arg1: flags
+        // %rsi already setup           // syscall arg2: child_stack
+        movq    %r9,  %rdx              // syscall arg3: parent_tid
+        movq    %r8,  %rcx              // syscall arg4: child_tid
+
+        syscall                         // clone()
+
+        testq   %rax, %rax              // child if retval == 0
+        jnz     1f
+
+        // CHILD - call thread function
+        pop     %rax                    // pop fn
+        pop     %rdi                    // pop fn arg1: arg
+        call    *%eax                   // call fn
+
+        // exit with result
+        movq    %rax, %rdi              // arg1: return value from fn
+        movl    $__NR_exit, %eax
+
+        syscall
+
+        // Exit returned?!
+        ud2
+
+1:      // PARENT or ERROR
+        ret
+
+
+
+# XXX: must reinstate comments also -- see x86-linux/syscall.S
 
 .globl VG_(sigreturn)
 VG_(sigreturn):
index a00b01123070fea102eac2666c2e50781f8b6a8e..ddcdcda578128597d6827f7b7996e6593320b457 100644 (file)
 #ifndef __AMD64_CORE_ARCH_ASM_H
 #define __AMD64_CORE_ARCH_ASM_H
 
+// Print a constant from asm code.
+#define OYNK(nnn) push %r8 ; push %r9 ; push %r10; push %r11; \
+                  push %rax; push %rbx; push %rcx; push %rdx; \
+                  push %rsi; push %rdi; \
+                  movl $nnn, %edi; call VG_(oynk); \
+                  pop %rdi; pop %rsi; pop %rdx; pop %rcx; \
+                  pop %rbx; pop %rax; pop %r11; pop %r10; \
+                  pop %r9 ; pop %r8
+
 #endif   // __AMD64_CORE_ARCH_ASM_H
 
 /*--------------------------------------------------------------------*/
index 56570b44f8ebc4f64992fa503135d8b902a76b08..0143dd092b3ad3dffbf1e9003582446b0b67cb33 100644 (file)
    thread), initialise the VEX guest state, and copy in essential
    starting values.
 */
-void VGA_(init_thread1state) ( Addr client_eip, 
-                               Addr esp_at_startup,
+void VGA_(init_thread1state) ( Addr client_rip, 
+                               Addr rsp_at_startup,
                               /*MOD*/ ThreadArchState* arch )
 {
-   I_die_here;
-#if 0
-   vg_assert(0 == sizeof(VexGuestX86State) % 8);
+   vg_assert(0 == sizeof(VexGuestAMD64State) % 8);
 
    /* Zero out the initial state, and set up the simulated FPU in a
       sane way. */
-   LibVEX_GuestX86_initialise(&arch->vex);
+   LibVEX_GuestAMD64_initialise(&arch->vex);
 
    /* Zero out the shadow area. */
-   VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestX86State));
+   VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestAMD64State));
 
    /* Put essential stuff into the new state. */
+
+   arch->vex.guest_RSP = rsp_at_startup;
+   arch->vex.guest_RIP = client_rip;
+
+   // XXX: something will probably have to be done with the segment
+   // registers, once they're added to Vex-AMD64.
+#if 0
    /* initialise %cs, %ds and %ss to point at the operating systems
       default code, data and stack segments */
-   arch->vex.guest_ESP = esp_at_startup;
-   arch->vex.guest_EIP = client_eip;
-
    asm volatile("movw %%cs, %0"
                 :
                 : "m" (arch->vex.guest_CS));
@@ -72,21 +74,6 @@ void VGA_(init_thread1state) ( Addr client_eip,
    asm volatile("movw %%ss, %0"
                 :
                 : "m" (arch->vex.guest_SS));
-
-   VG_TRACK( post_reg_write, Vg_CoreStartup, /*tid*/1, /*offset*/0,
-             sizeof(VexGuestArchState));
-
-   /* I assume that if we have SSE2 we also have SSE */
-   VG_(have_ssestate) = False;
-   //      VG_(cpu_has_feature)(VG_X86_FEAT_FXSR) &&
-   //   VG_(cpu_has_feature)(VG_X86_FEAT_SSE);
-
-   if (0) {
-      if (VG_(have_ssestate))
-         VG_(printf)("Looks like a SSE-capable CPU\n");
-      else
-         VG_(printf)("Looks like a MMX-only CPU\n");
-   }
 #endif
 }
 
index 04005ab96cec67181c37177b84bae35dd3ec691f..ad8247cb3d87d45a2debf0d68947c8a6dcd341a2 100644 (file)
@@ -319,6 +319,12 @@ Addr VG_(get_stack_pointer) ( ThreadId tid )
    return STACK_PTR( VG_(threads)[tid].arch );
 }
 
+/* Debugging thing .. can be called from assembly with OYNK macro. */
+void VG_(oynk) ( Int n )
+{
+   OINK(n);
+}
+
 /* Initialize the PID and PGRP of scheduler LWP; this is also called
    in any new children after fork. */
 static void newpid(ThreadId unused)
@@ -2605,6 +2611,12 @@ int main(int argc, char **argv)
    //      setup_scheduler()      [for the rest of state 1 stuff]
    //--------------------------------------------------------------
    VGA_(init_thread1state)(client_eip, sp_at_startup, &VG_(threads)[1].arch );
+
+   // Tell the tool that we just wrote to the registers.
+   VG_TRACK( post_reg_write, Vg_CoreStartup, /*tid*/1, /*offset*/0,
+             sizeof(VexGuestArchState));
+
+   // Record the instr ptr offset, for use by asm code.
    VG_(instr_ptr_offset) = offsetof(VexGuestArchState, ARCH_INSTR_PTR);
 
    //--------------------------------------------------------------
index 024bc4e80c83c48769a05086a75e704b58a04d77..3b6df205357f302b65391ce43a4454de63f1411e 100644 (file)
@@ -56,11 +56,12 @@ void VGA_(init_thread1state) ( Addr client_eip,
    VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestX86State));
 
    /* Put essential stuff into the new state. */
-   /* initialise %cs, %ds and %ss to point at the operating systems
-      default code, data and stack segments */
+
    arch->vex.guest_ESP = esp_at_startup;
    arch->vex.guest_EIP = client_eip;
 
+   /* initialise %cs, %ds and %ss to point at the operating systems
+      default code, data and stack segments */
    asm volatile("movw %%cs, %0"
                 :
                 : "m" (arch->vex.guest_CS));