From: Julian Seward Date: Wed, 16 Mar 2005 22:04:40 +0000 (+0000) Subject: Fill in a bunch of amd64-specific crud. Still won't link though. X-Git-Tag: svn/VALGRIND_3_0_0~936 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3f507c5e4eed01bbd60248e9dd287e3ce84a1586;p=thirdparty%2Fvalgrind.git Fill in a bunch of amd64-specific crud. Still won't link though. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3382 --- diff --git a/coregrind/amd64-linux/core_platform.h b/coregrind/amd64-linux/core_platform.h index 7d236e2604..d1d7acc110 100644 --- a/coregrind/amd64-linux/core_platform.h +++ b/coregrind/amd64-linux/core_platform.h @@ -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 /* for jmp_buf */ + +#define SETJMP(env) setjmp(env) +#define LONGJMP(env, val) longjmp(env, val) + #endif // __AMD64_LINUX_CORE_PLATFORM_H /*--------------------------------------------------------------------*/ diff --git a/coregrind/amd64-linux/syscalls.c b/coregrind/amd64-linux/syscalls.c index 4efad8c0c0..098a6e0f60 100644 --- a/coregrind/amd64-linux/syscalls.c +++ b/coregrind/amd64-linux/syscalls.c @@ -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 ------------------------------------------------------------------ */ diff --git a/coregrind/amd64/Makefile.am b/coregrind/amd64/Makefile.am index c87e43b4bf..c464e8484d 100644 --- a/coregrind/amd64/Makefile.am +++ b/coregrind/amd64/Makefile.am @@ -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 diff --git a/coregrind/amd64/core_arch.h b/coregrind/amd64/core_arch.h index c6ad3d467d..1c079c697d 100644 --- a/coregrind/amd64/core_arch.h +++ b/coregrind/amd64/core_arch.h @@ -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 diff --git a/coregrind/amd64/helpers.S b/coregrind/amd64/helpers.S index b1d44c56a0..4543e23f1f 100644 --- a/coregrind/amd64/helpers.S +++ b/coregrind/amd64/helpers.S @@ -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. @@ -47,24 +48,19 @@ .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 diff --git a/coregrind/amd64/jmp_with_stack.c b/coregrind/amd64/jmp_with_stack.c index fc34eff6a9..87ddb8f47f 100644 --- a/coregrind/amd64/jmp_with_stack.c +++ b/coregrind/amd64/jmp_with_stack.c @@ -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 diff --git a/coregrind/amd64/signals.c b/coregrind/amd64/signals.c index 423bc3a648..012434ff9a 100644 --- a/coregrind/amd64/signals.c +++ b/coregrind/amd64/signals.c @@ -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 diff --git a/coregrind/amd64/state.c b/coregrind/amd64/state.c index 69a2a4ca38..ac08691e32 100644 --- a/coregrind/amd64/state.c +++ b/coregrind/amd64/state.c @@ -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 ---*/ diff --git a/coregrind/vg_mylibc.c b/coregrind/vg_mylibc.c index d03e01330d..e049a8f665 100644 --- a/coregrind/vg_mylibc.c +++ b/coregrind/vg_mylibc.c @@ -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; } diff --git a/coregrind/vg_signals.c b/coregrind/vg_signals.c index 2670708dc2..6774b399f1 100644 --- a/coregrind/vg_signals.c +++ b/coregrind/vg_signals.c @@ -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 */ diff --git a/coregrind/x86-linux/syscalls.c b/coregrind/x86-linux/syscalls.c index 4bd9941dfe..b47e07a00c 100644 --- a/coregrind/x86-linux/syscalls.c +++ b/coregrind/x86-linux/syscalls.c @@ -36,6 +36,12 @@ #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) { diff --git a/include/amd64-linux/vki_arch.h b/include/amd64-linux/vki_arch.h index 02520f5491..2cda2f69d3 100644 --- a/include/amd64-linux/vki_arch.h +++ b/include/amd64-linux/vki_arch.h @@ -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! //----------------------------------------------------------------------