From: Nicholas Nethercote Date: Wed, 24 Nov 2004 16:30:22 +0000 (+0000) Subject: Removed all uses of register numbers (eg. arch-specific ones like R_EAX, and X-Git-Tag: svn/VALGRIND_3_0_0~1224 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=feb4fbaef5517a031673ed1ca72801a8b12a241c;p=thirdparty%2Fvalgrind.git Removed all uses of register numbers (eg. arch-specific ones like R_EAX, and arch-neutral ones like R_STACK_PTR). Where they were used, we now always talk about an offset into the Vex guest state, and an offset. As a result, the shadow register get/set functions had to change. They now also use an offset and size, and in an arch-neutral way. Also, I combined the five the post_reg_write* functions into a single one that takes a 'CorePart' parameter (plus also a ThreadId). Also, I added more arguments (the CorePart, and the ThreadId) to the post_mem_write event, for consistency with the pre_mem_* events. Also, I reduced the number of register names that must be specified by each arch, by factoring out duplication; and shortened their names for the core (eg. ARCH_STACK_PTR is now STACK_PTR). Plus some related minor cleanups in syscall wrappers. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3094 --- diff --git a/addrcheck/ac_main.c b/addrcheck/ac_main.c index 12ae62abca..22d8169abe 100644 --- a/addrcheck/ac_main.c +++ b/addrcheck/ac_main.c @@ -630,6 +630,12 @@ void ac_set_perms (Addr a, SizeT len, Bool rr, Bool ww, Bool xx) } } +static +void ac_post_mem_write(CorePart part, ThreadId tid, Addr a, SizeT len) +{ + ac_make_accessible(a, len); +} + /*------------------------------------------------------------*/ /*--- Functions called directly from generated code. ---*/ diff --git a/coregrind/core.h b/coregrind/core.h index 8fac3b1724..9d7302d5dc 100644 --- a/coregrind/core.h +++ b/coregrind/core.h @@ -913,26 +913,26 @@ extern void VG_(scheduler_handle_fatal_signal)( Int sigNo ); // Write a value to a client's thread register, and shadow (if necessary). // Note that there are some further similar macros in the arch- and // platform-specific parts; these ones are the totally generic ones. -#define SET_THREAD_REG( zztid, zzval, zzGETREG, zzREG, zzevent, zzargs... ) \ - do { zzGETREG(VG_(threads)[zztid].arch) = (zzval); \ - VG_TRACK( zzevent, zztid, zzREG, ##zzargs ); \ +#define SET_THREAD_REG( zztid, zzval, zzGETREG, zzevent, zzargs... ) \ + do { zzGETREG(VG_(threads)[zztid].arch) = (zzval); \ + VG_TRACK( zzevent, ##zzargs ); \ } while (0) #define SET_CLREQ_RETVAL(zztid, zzval) \ - SET_THREAD_REG(zztid, zzval, ARCH_CLREQ_RET, R_CLREQ_RET, \ - post_reg_write_clientreq_return) + SET_THREAD_REG(zztid, zzval, CLREQ_RET, post_reg_write, \ + Vg_CoreClientReq, zztid, O_CLREQ_RET, sizeof(UWord)) #define SET_CLCALL_RETVAL(zztid, zzval, f) \ - SET_THREAD_REG(zztid, zzval, ARCH_CLREQ_RET, R_CLREQ_RET, \ - post_reg_write_clientcall_return, f) + SET_THREAD_REG(zztid, zzval, CLREQ_RET, post_reg_write_clientcall_return, \ + zztid, O_CLREQ_RET, sizeof(UWord), f) #define SET_PTHREQ_ESP(zztid, zzval) \ - SET_THREAD_REG(zztid, zzval, ARCH_STACK_PTR, R_STACK_PTR, \ - post_reg_write_pthread_return) + SET_THREAD_REG(zztid, zzval, STACK_PTR, post_reg_write, \ + Vg_CorePThread, zztid, O_STACK_PTR, sizeof(Addr)) #define SET_PTHREQ_RETVAL(zztid, zzval) \ - SET_THREAD_REG(zztid, zzval, ARCH_PTHREQ_RET, R_PTHREQ_RET, \ - post_reg_write_pthread_return) + SET_THREAD_REG(zztid, zzval, PTHREQ_RET, post_reg_write, \ + Vg_CorePThread, zztid, O_PTHREQ_RET, sizeof(UWord)) /* --------------------------------------------------------------------- @@ -1630,10 +1630,10 @@ GEN_SYSCALL_WRAPPER(sys_mq_getsetattr); // * P? #define PRRSN \ TL_(pre_reg_read)(Vg_CoreSysCall, tid, "(syscallno)", \ - R_SYSCALL_NUM, sizeof(UWord)); + O_SYSCALL_NUM, sizeof(UWord)); #define PRRAn(n,s,t,a) \ TL_(pre_reg_read)(Vg_CoreSysCall, tid, s"("#a")", \ - R_SYSCALL_ARG##n, sizeof(t)); + O_SYSCALL_ARG##n, sizeof(t)); #define PRE_REG_READ0(tr, s) \ if (VG_(defined_pre_reg_read)()) { \ PRRSN; \ @@ -1682,7 +1682,7 @@ GEN_SYSCALL_WRAPPER(sys_mq_getsetattr); // * P? VG_TRACK( pre_mem_write, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen) #define POST_MEM_WRITE(zzaddr, zzlen) \ - VG_TRACK( post_mem_write, zzaddr, zzlen) + VG_TRACK( post_mem_write, Vg_CoreSysCall, tid, zzaddr, zzlen) /* --------------------------------------------------------------------- Exports of vg_transtab.c @@ -1754,6 +1754,23 @@ extern void VG_(missing_tool_func) ( const Char* fn ); // Architecture-specific things defined in eg. x86/*.c // --------------------------------------------------------------------- +// Accessors for the ThreadArchState +#define INSTR_PTR(regs) ((regs).vex.ARCH_INSTR_PTR) +#define STACK_PTR(regs) ((regs).vex.ARCH_STACK_PTR) +#define FRAME_PTR(regs) ((regs).vex.ARCH_FRAME_PTR) + +#define CLREQ_ARGS(regs) ((regs).vex.ARCH_CLREQ_ARGS) +#define PTHREQ_RET(regs) ((regs).vex.ARCH_PTHREQ_RET) +#define CLREQ_RET(regs) ((regs).vex.ARCH_CLREQ_RET) + +// Offsets for the shadow state +#define O_STACK_PTR (offsetof(VexGuestArchState, ARCH_STACK_PTR)) +#define O_FRAME_PTR (offsetof(VexGuestArchState, ARCH_FRAME_PTR)) + +#define O_CLREQ_RET (offsetof(VexGuestArchState, ARCH_CLREQ_RET)) +#define O_PTHREQ_RET (offsetof(VexGuestArchState, ARCH_PTHREQ_RET)) + + // Setting up the initial thread (1) state extern void VGA_(init_thread1state) ( Addr client_eip, @@ -1769,7 +1786,7 @@ extern void VGA_(set_arg_and_bogus_ret) ( ThreadId tid, UWord arg, Addr ret ); extern void VGA_(thread_initial_stack) ( ThreadId tid, UWord arg, Addr ret ); // Symtab stuff -extern UInt* VGA_(reg_addr_from_tst) ( Int reg, ThreadArchState* ); +extern UInt* VGA_(reg_addr_from_tst) ( Int regno, ThreadArchState* ); // Pointercheck extern Bool VGA_(setup_pointercheck) ( void ); @@ -1818,6 +1835,26 @@ extern void VG_(user_assert_fail) ( const Char* expr, const Char* file, // Platform-specific things defined in eg. x86/*.c // --------------------------------------------------------------------- +// Accessors for the ThreadArchState +#define SYSCALL_NUM(regs) ((regs).vex.PLATFORM_SYSCALL_NUM) +#define SYSCALL_ARG1(regs) ((regs).vex.PLATFORM_SYSCALL_ARG1) +#define SYSCALL_ARG2(regs) ((regs).vex.PLATFORM_SYSCALL_ARG2) +#define SYSCALL_ARG3(regs) ((regs).vex.PLATFORM_SYSCALL_ARG3) +#define SYSCALL_ARG4(regs) ((regs).vex.PLATFORM_SYSCALL_ARG4) +#define SYSCALL_ARG5(regs) ((regs).vex.PLATFORM_SYSCALL_ARG5) +#define SYSCALL_ARG6(regs) ((regs).vex.PLATFORM_SYSCALL_ARG6) +#define SYSCALL_RET(regs) ((regs).vex.PLATFORM_SYSCALL_RET) + +// Offsets for the shadow state +#define O_SYSCALL_NUM (offsetof(VexGuestArchState, PLATFORM_SYSCALL_ARG6)) +#define O_SYSCALL_ARG1 (offsetof(VexGuestArchState, PLATFORM_SYSCALL_ARG1)) +#define O_SYSCALL_ARG2 (offsetof(VexGuestArchState, PLATFORM_SYSCALL_ARG2)) +#define O_SYSCALL_ARG3 (offsetof(VexGuestArchState, PLATFORM_SYSCALL_ARG3)) +#define O_SYSCALL_ARG4 (offsetof(VexGuestArchState, PLATFORM_SYSCALL_ARG4)) +#define O_SYSCALL_ARG5 (offsetof(VexGuestArchState, PLATFORM_SYSCALL_ARG5)) +#define O_SYSCALL_ARG6 (offsetof(VexGuestArchState, PLATFORM_SYSCALL_ARG6)) +#define O_SYSCALL_RET (offsetof(VexGuestArchState, PLATFORM_SYSCALL_RET)) + struct SyscallTableEntry { UInt *flags_ptr; void (*before)(ThreadId tid, ThreadState *tst); diff --git a/coregrind/linux/syscalls.c b/coregrind/linux/syscalls.c index 2832e4fd83..e731c82be5 100644 --- a/coregrind/linux/syscalls.c +++ b/coregrind/linux/syscalls.c @@ -43,14 +43,14 @@ #define POST(x) \ void VGA_(linux_##x##_after) (ThreadId tid, ThreadState *tst) -#define SYSNO PLATFORM_SYSCALL_NUM(tst->arch) // in PRE(x) -#define res PLATFORM_SYSCALL_RET(tst->arch) // in POST(x) -#define arg1 PLATFORM_SYSCALL_ARG1(tst->arch) -#define arg2 PLATFORM_SYSCALL_ARG2(tst->arch) -#define arg3 PLATFORM_SYSCALL_ARG3(tst->arch) -#define arg4 PLATFORM_SYSCALL_ARG4(tst->arch) -#define arg5 PLATFORM_SYSCALL_ARG5(tst->arch) -#define arg6 PLATFORM_SYSCALL_ARG6(tst->arch) +#define SYSNO SYSCALL_NUM(tst->arch) // in PRE(x) +#define res SYSCALL_RET(tst->arch) // in POST(x) +#define arg1 SYSCALL_ARG1(tst->arch) +#define arg2 SYSCALL_ARG2(tst->arch) +#define arg3 SYSCALL_ARG3(tst->arch) +#define arg4 SYSCALL_ARG4(tst->arch) +#define arg5 SYSCALL_ARG5(tst->arch) +#define arg6 SYSCALL_ARG6(tst->arch) #define set_result(val) PLATFORM_SET_SYSCALL_RESULT(tst->arch, (val)) @@ -127,7 +127,7 @@ PRE(sys_adjtimex, 0) POST(sys_adjtimex) { - VG_TRACK(post_mem_write, arg1, sizeof(struct vki_timex)); + POST_MEM_WRITE( arg1, sizeof(struct vki_timex) ); } PRE(sys_setfsuid16, 0) diff --git a/coregrind/toolfuncs.def b/coregrind/toolfuncs.def index 1fa39ef8db..cf60f1c7c0 100644 --- a/coregrind/toolfuncs.def +++ b/coregrind/toolfuncs.def @@ -204,33 +204,21 @@ void, die_mem_stack, Addr a, SizeT len void, ban_mem_stack, Addr a, SizeT len ## These ones occur around syscalls, signal handling, etc -void, pre_mem_read, CorePart part, ThreadId tid, Char* s, Addr a, SizeT size -void, pre_mem_read_asciiz, CorePart part, ThreadId tid, Char* s, Addr a -void, pre_mem_write, CorePart part, ThreadId tid, Char* s, Addr a, SizeT size -## Not implemented yet -- have to add in lots of places, which is a -## pain. Won't bother unless/until there's a need. -## void (*post_mem_read) ( ThreadState* tst, Char* s, Addr a, SizeT size ); -void, post_mem_write, Addr a, SizeT size +void, pre_mem_read, CorePart part, ThreadId tid, Char* s, Addr a, SizeT size +void, pre_mem_read_asciiz,CorePart part, ThreadId tid, Char* s, Addr a +void, pre_mem_write, CorePart part, ThreadId tid, Char* s, Addr a, SizeT size +void, post_mem_write, CorePart part, ThreadId tid, Addr a, SizeT size -## Register events -- if `shadow_regs' need is set, all should probably be -## used. Use VG_(set_thread_shadow_archreg)() to set the shadow of the -## changed register. - -void, pre_reg_read, CorePart part, ThreadId tid, Char* s, UInt reg, SizeT size +## Register events -- if `shadow_regs' need is set, these should probably be +## used. Use VG_(set_shadow_state_area)() to set the shadow regs for these +## events. -## Use VG_(set_shadow_archreg)() to set the eight general purpose regs, -## and use VG_(set_shadow_eflags)() to set eflags. -void, post_regs_write_init, void +void, pre_reg_read, CorePart part, ThreadId tid, Char* s, OffT guest_state_offset, SizeT size +void, post_reg_write, CorePart part, ThreadId tid, OffT guest_state_offset, SizeT size -## Use VG_(set_thread_shadow_archreg)() to set the shadow regs for these -## events. -void, post_reg_write_syscall_return, ThreadId tid, UInt reg -void, post_reg_write_deliver_signal, ThreadId tid, UInt reg -void, post_reg_write_pthread_return, ThreadId tid, UInt reg -void, post_reg_write_clientreq_return, ThreadId tid, UInt reg ## This one is called for malloc() et al if they are replaced by a tool. -void, post_reg_write_clientcall_return, ThreadId tid, UInt reg, Addr f +void, post_reg_write_clientcall_return, ThreadId tid, OffT guest_state_offset, SizeT size, Addr f ## Scheduler events (not exhaustive) diff --git a/coregrind/vg_execontext.c b/coregrind/vg_execontext.c index 371d26e568..8f53fc484a 100644 --- a/coregrind/vg_execontext.c +++ b/coregrind/vg_execontext.c @@ -306,9 +306,9 @@ void get_needed_regs(ThreadId tid, Addr* ip, Addr* fp, Addr* sp, Addr* stack_highest_word) { ThreadState* tst = & VG_(threads)[ tid ]; - *ip = ARCH_INSTR_PTR(tst->arch); - *fp = ARCH_FRAME_PTR(tst->arch); - *sp = ARCH_STACK_PTR(tst->arch); + *ip = INSTR_PTR(tst->arch); + *fp = FRAME_PTR(tst->arch); + *sp = STACK_PTR(tst->arch); *stack_highest_word = tst->stack_highest_word; /* Nasty little hack to deal with sysinfo syscalls - if libc is @@ -355,7 +355,7 @@ Addr VG_(get_EIP_from_ExeContext) ( ExeContext* e, UInt n ) Addr VG_(get_EIP) ( ThreadId tid ) { - return ARCH_INSTR_PTR(VG_(threads)[ tid ].arch); + return INSTR_PTR(VG_(threads)[ tid ].arch); } /*--------------------------------------------------------------------*/ diff --git a/coregrind/vg_main.c b/coregrind/vg_main.c index 091391b0ff..114ad1eb26 100644 --- a/coregrind/vg_main.c +++ b/coregrind/vg_main.c @@ -326,7 +326,7 @@ void VG_(unimplemented) ( Char* msg ) /* Get the simulated stack pointer */ Addr VG_(get_stack_pointer) ( ThreadId tid ) { - return ARCH_STACK_PTR( VG_(threads)[tid].arch ); + return STACK_PTR( VG_(threads)[tid].arch ); } /* Initialize the PID and PGRP of scheduler LWP; this is also called diff --git a/coregrind/vg_needs.c b/coregrind/vg_needs.c index 4ac6354e5d..c62c5b573e 100644 --- a/coregrind/vg_needs.c +++ b/coregrind/vg_needs.c @@ -102,10 +102,7 @@ void VG_(sanity_check_needs) ( void) VG_(tool_panic)("`die_mem_stack' should be defined\n"); } - if ( (VG_(defined_post_reg_write_syscall_return)() || - VG_(defined_post_reg_write_deliver_signal)() || - VG_(defined_post_reg_write_pthread_return)() || - VG_(defined_post_reg_write_clientreq_return)() || + if ( (VG_(defined_post_reg_write)() || VG_(defined_post_reg_write_clientcall_return)()) && ! VG_(needs).shadow_regs) { diff --git a/coregrind/vg_proxylwp.c b/coregrind/vg_proxylwp.c index dde25f70c6..ae3d1f363b 100644 --- a/coregrind/vg_proxylwp.c +++ b/coregrind/vg_proxylwp.c @@ -307,7 +307,7 @@ void VG_(proxy_handlesig)(const vki_siginfo_t *siginfo, Addr ip, Int sysnum) anywhere else, except that we can make some assertions about the proxy and machine state here. */ vg_assert(px->state == PXS_RunSyscall); - vg_assert(PLATFORM_SYSCALL_RET(px->tst->arch) == -VKI_ERESTARTSYS); + vg_assert(SYSCALL_RET(px->tst->arch) == -VKI_ERESTARTSYS); } else if (vga_sys_after <= ip && ip <= vga_sys_done) { /* We're after the syscall. Either it was interrupted by the signal, or the syscall completed normally. In either case @@ -316,7 +316,7 @@ void VG_(proxy_handlesig)(const vki_siginfo_t *siginfo, Addr ip, Int sysnum) vg_assert(px->state == PXS_RunSyscall || px->state == PXS_SysDone); px->state = PXS_SysDone; - PLATFORM_SYSCALL_RET(px->tst->arch) = sysnum; + SYSCALL_RET(px->tst->arch) = sysnum; } px_printf(" signalled in state %s\n", pxs_name(px->state)); @@ -433,7 +433,7 @@ static Int proxylwp(void *v) */ reply.u.syscallno = tst->syscallno; - PLATFORM_SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS; + SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS; px->state = PXS_IntReply; break; @@ -603,14 +603,14 @@ static Int proxylwp(void *v) */ px_printf("RunSyscall in SigACK: rejecting syscall %d with ERESTARTSYS\n", reply.u.syscallno); - PLATFORM_SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS; + SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS; } else { Int syscallno = tst->syscallno; px->state = PXS_RunSyscall; /* If we're interrupted before we get to the syscall itself, we want the syscall restarted. */ - PLATFORM_SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS; + SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS; /* set our process group ID to match parent */ if (VG_(getpgrp)() != VG_(main_pgrp)) @@ -1022,8 +1022,8 @@ static void sys_wait_results(Bool block, ThreadId tid, enum RequestType reqtype, if (VG_(clo_trace_syscalls)) VG_(printf)("sys_wait_results: got PX_RunSyscall for SYSCALL[%d,%d](%3d) --> %lld (%llx)\n", VG_(getpid)(), res.tid, tst->syscallno, - (Long)(Word)PLATFORM_SYSCALL_RET(tst->arch), - (ULong)PLATFORM_SYSCALL_RET(tst->arch)); + (Long)(Word)SYSCALL_RET(tst->arch), + (ULong)SYSCALL_RET(tst->arch)); if (tst->status != VgTs_WaitSys) VG_(printf)("tid %d in status %d\n", @@ -1201,8 +1201,8 @@ Int VG_(sys_issue)(int tid) req.request = PX_RunSyscall; - tst->syscallno = PLATFORM_SYSCALL_NUM(tst->arch); - PLATFORM_SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS; + tst->syscallno = SYSCALL_NUM(tst->arch); + SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS; res = VG_(write)(proxy->topx, &req, sizeof(req)); diff --git a/coregrind/vg_scheduler.c b/coregrind/vg_scheduler.c index 4179360028..ffb09d7bdc 100644 --- a/coregrind/vg_scheduler.c +++ b/coregrind/vg_scheduler.c @@ -148,7 +148,7 @@ ThreadId VG_(first_matching_thread_stack) for (tid = 1; tid < VG_N_THREADS; tid++) { if (VG_(threads)[tid].status == VgTs_Empty) continue; if (tid == tid_to_skip) continue; - if ( p ( ARCH_STACK_PTR(VG_(threads)[tid].arch), + if ( p ( STACK_PTR(VG_(threads)[tid].arch), VG_(threads)[tid].stack_highest_word, d ) ) return tid; } @@ -180,9 +180,9 @@ void VG_(pp_sched_status) ( void ) VG_(threads)[i].associated_mx, VG_(threads)[i].associated_cv ); VG_(pp_ExeContext)( - VG_(get_ExeContext2)( ARCH_INSTR_PTR(VG_(threads)[i].arch), - ARCH_FRAME_PTR(VG_(threads)[i].arch), - ARCH_STACK_PTR(VG_(threads)[i].arch), + VG_(get_ExeContext2)( INSTR_PTR(VG_(threads)[i].arch), + FRAME_PTR(VG_(threads)[i].arch), + STACK_PTR(VG_(threads)[i].arch), VG_(threads)[i].stack_highest_word) ); } @@ -443,12 +443,12 @@ void handle_signal_return ( ThreadId tid ) return; if (VG_(threads)[tid].status == VgTs_Sleeping - && PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_nanosleep) { + && SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_nanosleep) { /* We interrupted a nanosleep(). The right thing to do is to write the unused time to nanosleep's second param, but that's too much effort ... we just say that 1 nanosecond was not used, and return EINTR. */ - rem = (struct vki_timespec*)PLATFORM_SYSCALL_ARG2(VG_(threads)[tid].arch); + rem = (struct vki_timespec*)SYSCALL_ARG2(VG_(threads)[tid].arch); if (rem != NULL) { rem->tv_sec = 0; rem->tv_nsec = 1; @@ -502,7 +502,7 @@ void sched_do_syscall ( ThreadId tid ) vg_assert(VG_(is_valid_tid)(tid)); vg_assert(VG_(threads)[tid].status == VgTs_Runnable); - syscall_no = PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch); + syscall_no = SYSCALL_NUM(VG_(threads)[tid].arch); /* Special-case nanosleep because we can. But should we? @@ -512,7 +512,7 @@ void sched_do_syscall ( ThreadId tid ) if (0 && syscall_no == __NR_nanosleep) { UInt t_now, t_awaken; struct vki_timespec* req; - req = (struct vki_timespec*)PLATFORM_SYSCALL_ARG1(VG_(threads)[tid].arch); + req = (struct vki_timespec*)SYSCALL_ARG1(VG_(threads)[tid].arch); if (req->tv_sec < 0 || req->tv_nsec < 0 || req->tv_nsec >= 1000000000) { SET_SYSCALL_RETVAL(tid, -VKI_EINVAL); @@ -821,18 +821,18 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid ) if (VG_(bbs_done) > 31700000 + 0) { dispatch_ctr_SAVED = VG_(dispatch_ctr) = 2; VG_(translate)(&VG_(threads)[tid], - ARCH_INSTR_PTR(VG_(threads)[tid].arch), + INSTR_PTR(VG_(threads)[tid].arch), /*debugging*/True); } - vg_assert(ARCH_INSTR_PTR(VG_(threads)[tid].arch) != 0); + vg_assert(INSTR_PTR(VG_(threads)[tid].arch) != 0); # endif trc = run_thread_for_a_while ( tid ); # if 0 - if (0 == ARCH_INSTR_PTR(VG_(threads)[tid].arch)) { + if (0 == INSTR_PTR(VG_(threads)[tid].arch)) { VG_(printf)("tid = %d, dc = %llu\n", tid, VG_(bbs_done)); - vg_assert(0 != ARCH_INSTR_PTR(VG_(threads)[tid].arch)); + vg_assert(0 != INSTR_PTR(VG_(threads)[tid].arch)); } # endif @@ -840,7 +840,7 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid ) thread. */ if (trc == VG_TRC_INNER_FASTMISS) { - Addr ip = ARCH_INSTR_PTR(VG_(threads)[tid].arch); + Addr ip = INSTR_PTR(VG_(threads)[tid].arch); vg_assert(VG_(dispatch_ctr) > 1); @@ -868,7 +868,7 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid ) } if (trc == VG_TRC_EBP_JMP_CLIENTREQ) { - UWord* args = (UWord*)(ARCH_CLREQ_ARGS(VG_(threads)[tid].arch)); + UWord* args = (UWord*)(CLREQ_ARGS(VG_(threads)[tid].arch)); UWord reqno = args[0]; /* VG_(printf)("request 0x%x\n", reqno); */ @@ -899,7 +899,7 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid ) to exit. */ # if 0 { UInt* esp; Int i; - esp=(UInt*)ARCH_STACK_PTR(VG_(threads)[tid].arch); + esp=(UInt*)STACK_PTR(VG_(threads)[tid].arch); VG_(printf)("\nBEFORE\n"); for (i = 10; i >= -10; i--) VG_(printf)("%2d %p = 0x%x\n", i, &esp[i], esp[i]); @@ -917,24 +917,24 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid ) __libc_freeres does some invalid frees which crash the unprotected malloc/free system. */ - if (PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit - || PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit_group + if (SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit + || SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit_group ) { /* Remember the supplied argument. */ - *exitcode = PLATFORM_SYSCALL_ARG1(VG_(threads)[tid].arch); + *exitcode = SYSCALL_ARG1(VG_(threads)[tid].arch); // Inform tool about regs read by syscall VG_TRACK( pre_reg_read, Vg_CoreSysCall, tid, "(syscallno)", - R_SYSCALL_NUM, sizeof(UWord) ); + O_SYSCALL_NUM, sizeof(UWord) ); - if (PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit) + if (SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit) VG_TRACK( pre_reg_read, Vg_CoreSysCall, tid, - "exit(error_code)", R_SYSCALL_ARG1, sizeof(int) ); + "exit(error_code)", O_SYSCALL_ARG1, sizeof(int) ); - if (PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit_group) + if (SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit_group) VG_TRACK( pre_reg_read, Vg_CoreSysCall, tid, - "exit_group(error_code)", R_SYSCALL_ARG1, + "exit_group(error_code)", O_SYSCALL_ARG1, sizeof(int) ); /* Only run __libc_freeres if the tool says it's ok and @@ -950,7 +950,7 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid ) "Caught __NR_exit; running __libc_freeres()"); } VG_(nuke_all_threads_except) ( tid ); - ARCH_INSTR_PTR(VG_(threads)[tid].arch) = + INSTR_PTR(VG_(threads)[tid].arch) = __libc_freeres_wrapper; vg_assert(VG_(threads)[tid].status == VgTs_Runnable); goto stage1; /* party on, dudes (but not for much longer :) */ @@ -968,13 +968,13 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid ) } /* We've dealt with __NR_exit at this point. */ - vg_assert(PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) != __NR_exit && - PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) != __NR_exit_group); + vg_assert(SYSCALL_NUM(VG_(threads)[tid].arch) != __NR_exit && + SYSCALL_NUM(VG_(threads)[tid].arch) != __NR_exit_group); /* Trap syscalls to __NR_sched_yield and just have this thread yield instead. Not essential, just an optimisation. */ - if (PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_sched_yield) { + if (SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_sched_yield) { SET_SYSCALL_RETVAL(tid, 0); /* syscall returns with success */ goto stage1; /* find a new thread to run */ } @@ -983,7 +983,7 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid ) # if 0 { UInt* esp; Int i; - esp=(UInt*)ARCH_STACK_PTR(VG_(threads)[tid].arch); + esp=(UInt*)STACK_PTR(VG_(threads)[tid].arch); VG_(printf)("AFTER\n"); for (i = 10; i >= -10; i--) VG_(printf)("%2d %p = 0x%x\n", i, &esp[i], esp[i]); @@ -1166,7 +1166,7 @@ void make_thread_jump_to_cancelhdlr ( ThreadId tid ) VGA_(set_arg_and_bogus_ret)(tid, (UWord)PTHREAD_CANCELED, 0xBEADDEEF); /* .cancel_pend will hold &thread_exit_wrapper */ - ARCH_INSTR_PTR(VG_(threads)[tid].arch) = (UWord)VG_(threads)[tid].cancel_pend; + INSTR_PTR(VG_(threads)[tid].arch) = (UWord)VG_(threads)[tid].cancel_pend; VG_(proxy_abort_syscall)(tid); @@ -1304,7 +1304,8 @@ void maybe_rendezvous_joiners_and_joinees ( void ) *thread_return = VG_(threads)[jee].joinee_retval; /* Not really right, since it makes the thread's return value appear to be defined even if it isn't. */ - VG_TRACK( post_mem_write, (Addr)thread_return, sizeof(void*) ); + VG_TRACK( post_mem_write, Vg_CorePThread, jnr, + (Addr)thread_return, sizeof(void*) ); } /* Joinee is discarded */ @@ -1413,7 +1414,8 @@ void do__cleanup_pop ( ThreadId tid, CleanupEntry* cu ) VG_TRACK( pre_mem_write, Vg_CorePThread, tid, "cleanup pop", (Addr)cu, sizeof(CleanupEntry) ); *cu = VG_(threads)[tid].custack[sp]; - VG_TRACK( post_mem_write, (Addr)cu, sizeof(CleanupEntry) ); + VG_TRACK( post_mem_write, Vg_CorePThread, tid, + (Addr)cu, sizeof(CleanupEntry) ); VG_(threads)[tid].custack_used = sp; SET_PTHREQ_RETVAL(tid, 0); } @@ -1802,14 +1804,14 @@ void do__apply_in_new_thread ( ThreadId parent_tid, VG_TRACK ( die_mem_stack, VG_(threads)[tid].stack_base, VG_(threads)[tid].stack_size - VG_AR_CLIENT_STACKBASE_REDZONE_SZB); - VG_TRACK ( ban_mem_stack, ARCH_STACK_PTR(VG_(threads)[tid].arch), + VG_TRACK ( ban_mem_stack, STACK_PTR(VG_(threads)[tid].arch), VG_AR_CLIENT_STACKBASE_REDZONE_SZB ); VGA_(thread_initial_stack)(tid, (UWord)arg, (Addr)&do__apply_in_new_thread_bogusRA); /* this is where we start */ - ARCH_INSTR_PTR(VG_(threads)[tid].arch) = (UWord)fn; + INSTR_PTR(VG_(threads)[tid].arch) = (UWord)fn; if (VG_(clo_trace_sched)) { VG_(sprintf)(msg_buf, "new thread, created by %d", parent_tid ); @@ -2482,7 +2484,8 @@ void do_pthread_key_create ( ThreadId tid, VG_TRACK( pre_mem_write, Vg_CorePThread, tid, "pthread_key_create: key", (Addr)key, sizeof(pthread_key_t)); *key = i; - VG_TRACK( post_mem_write, (Addr)key, sizeof(pthread_key_t) ); + VG_TRACK( post_mem_write, Vg_CorePThread, tid, + (Addr)key, sizeof(pthread_key_t) ); SET_PTHREQ_RETVAL(tid, 0); } @@ -2598,7 +2601,8 @@ void do__get_key_destr_and_spec ( ThreadId tid, cu->data.function.arg = VG_(threads)[tid].specifics_ptr[key]; } - VG_TRACK( post_mem_write, (Addr)cu, sizeof(CleanupEntry) ); + VG_TRACK( post_mem_write, Vg_CorePThread, tid, + (Addr)cu, sizeof(CleanupEntry) ); SET_PTHREQ_RETVAL(tid, 0); } @@ -2639,7 +2643,8 @@ void do_pthread_sigmask ( ThreadId tid, VG_(do_pthread_sigmask_SCSS_upd) ( tid, vki_how, newmask, oldmask ); if (oldmask) - VG_TRACK( post_mem_write, (Addr)oldmask, sizeof(vki_sigset_t) ); + VG_TRACK( post_mem_write, Vg_CorePThread, tid, + (Addr)oldmask, sizeof(vki_sigset_t) ); /* Success. */ SET_PTHREQ_RETVAL(tid, 0); @@ -2780,7 +2785,8 @@ void do__get_fhstack_entry ( ThreadId tid, Int n, /*OUT*/ *fh = vg_fhstack[n]; SET_PTHREQ_RETVAL(tid, 0); - VG_TRACK( post_mem_write, (Addr)fh, sizeof(ForkHandlerEntry) ); + VG_TRACK( post_mem_write, Vg_CorePThread, tid, + (Addr)fh, sizeof(ForkHandlerEntry) ); } @@ -2812,17 +2818,52 @@ void do__get_stack_info ( ThreadId tid, ThreadId which, StackInfo* si ) } /* --------------------------------------------------------------------- - Specifying shadow register values + Shadow register manipulations ------------------------------------------------------------------ */ -void VG_(set_return_from_syscall_shadow) ( ThreadId tid, UInt ret_shadow ) +void VG_(set_shadow_regs_area) ( ThreadId tid, OffT offset, SizeT size, + const UChar* area ) { - VGA_(set_thread_shadow_archreg)(tid, R_SYSCALL_RET, ret_shadow); + ThreadState* tst; + + vg_assert(VG_(is_valid_tid)(tid)); + tst = & VG_(threads)[tid]; + + // Bounds check + vg_assert(0 <= offset && offset < sizeof(VexGuestArchState)); + vg_assert(offset + size <= sizeof(VexGuestArchState)); + + VG_(memcpy)( (void*)(((Addr)(&tst->arch.vex_shadow)) + offset), area, size); +} + +void VG_(get_shadow_regs_area) ( ThreadId tid, OffT offset, SizeT size, + UChar* area ) +{ + ThreadState* tst; + + vg_assert(VG_(is_valid_tid)(tid)); + tst = & VG_(threads)[tid]; + + // Bounds check + vg_assert(0 <= offset && offset < sizeof(VexGuestArchState)); + vg_assert(offset + size <= sizeof(VexGuestArchState)); + + VG_(memcpy)( area, (void*)(((Addr)&(tst->arch.vex_shadow)) + offset), size); +} + + +void VG_(set_return_from_syscall_shadow) ( ThreadId tid, UWord ret_shadow ) +{ + VG_(set_shadow_regs_area)(tid, O_SYSCALL_RET, sizeof(UWord), + (UChar*)&ret_shadow); } UInt VG_(get_exit_status_shadow) ( ThreadId tid ) { - return VGA_(get_thread_shadow_archreg)(tid, R_SYSCALL_ARG1); + UInt ret; + VG_(get_shadow_regs_area)(tid, O_SYSCALL_ARG1, sizeof(UInt), + (UChar*)&ret); + return ret; } void VG_(intercept_libc_freeres_wrapper)(Addr addr) @@ -3273,7 +3314,7 @@ void scheduler_sanity ( void ) if (VG_(threads)[i].status != VgTs_Empty) { Int stack_used = (Addr)VG_(threads)[i].stack_highest_word - - (Addr)ARCH_STACK_PTR(VG_(threads)[i].arch); + - (Addr)STACK_PTR(VG_(threads)[i].arch); Int stack_avail = VG_(threads)[i].stack_size - VG_AR_CLIENT_STACKBASE_REDZONE_SZB diff --git a/coregrind/vg_signals.c b/coregrind/vg_signals.c index 046ce2dfe1..044e3b0fd0 100644 --- a/coregrind/vg_signals.c +++ b/coregrind/vg_signals.c @@ -481,9 +481,9 @@ void VG_(do_sys_sigaltstack) ( ThreadId tid ) Addr m_SP; vg_assert(VG_(is_valid_tid)(tid)); - ss = (vki_stack_t*)PLATFORM_SYSCALL_ARG1(VG_(threads)[tid].arch); - oss = (vki_stack_t*)PLATFORM_SYSCALL_ARG2(VG_(threads)[tid].arch); - m_SP = ARCH_STACK_PTR(VG_(threads)[tid].arch); + ss = (vki_stack_t*)SYSCALL_ARG1(VG_(threads)[tid].arch); + oss = (vki_stack_t*)SYSCALL_ARG2(VG_(threads)[tid].arch); + m_SP = STACK_PTR(VG_(threads)[tid].arch); if (VG_(clo_trace_signals)) VG_(message)(Vg_DebugExtraMsg, @@ -498,7 +498,7 @@ void VG_(do_sys_sigaltstack) ( ThreadId tid ) } if (ss != NULL) { - if (on_sig_stack(tid, ARCH_STACK_PTR(VG_(threads)[tid].arch))) { + if (on_sig_stack(tid, STACK_PTR(VG_(threads)[tid].arch))) { SET_SYSCALL_RETVAL(tid, -VKI_EPERM); return; } @@ -534,9 +534,9 @@ void VG_(do_sys_sigaction) ( ThreadId tid ) vg_assert(is_correct_sigmask()); vg_assert(VG_(is_valid_tid)(tid)); - signo = PLATFORM_SYSCALL_ARG1(VG_(threads)[tid].arch); - new_act = (struct vki_sigaction*)PLATFORM_SYSCALL_ARG2(VG_(threads)[tid].arch); - old_act = (struct vki_sigaction*)PLATFORM_SYSCALL_ARG3(VG_(threads)[tid].arch); + signo = SYSCALL_ARG1(VG_(threads)[tid].arch); + new_act = (struct vki_sigaction*)SYSCALL_ARG2(VG_(threads)[tid].arch); + old_act = (struct vki_sigaction*)SYSCALL_ARG3(VG_(threads)[tid].arch); if (VG_(clo_trace_signals)) VG_(message)(Vg_DebugExtraMsg, @@ -839,7 +839,7 @@ void vg_push_signal_frame ( ThreadId tid, const vki_siginfo_t *siginfo ) && /* there is a defined and enabled alt stack, which we're not already using. Logic from get_sigframe in arch/i386/kernel/signal.c. */ - sas_ss_flags(tid, ARCH_STACK_PTR(tst->arch)) == 0 + sas_ss_flags(tid, STACK_PTR(tst->arch)) == 0 ) { esp_top_of_frame = (Addr)(tst->altstack.ss_sp) + tst->altstack.ss_size; @@ -852,7 +852,7 @@ void vg_push_signal_frame ( ThreadId tid, const vki_siginfo_t *siginfo ) VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/True ); } else { - esp_top_of_frame = ARCH_STACK_PTR(tst->arch); + esp_top_of_frame = STACK_PTR(tst->arch); /* Signal delivery to tools */ VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/False ); @@ -1503,8 +1503,8 @@ void VG_(deliver_signal) ( ThreadId tid, const vki_siginfo_t *info, Bool async ) if (tst->status == VgTs_WaitSys) { /* blocked in a syscall; we assume it should be interrupted */ - if (PLATFORM_SYSCALL_RET(tst->arch) == -VKI_ERESTARTSYS) - PLATFORM_SYSCALL_RET(tst->arch) = -VKI_EINTR; + if (SYSCALL_RET(tst->arch) == -VKI_ERESTARTSYS) + SYSCALL_RET(tst->arch) = -VKI_EINTR; } VG_(proxy_sigack)(tid, &tst->sig_mask); @@ -1729,7 +1729,7 @@ void vg_sync_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext if (info->si_signo == VKI_SIGSEGV) { ThreadId tid = VG_(get_current_tid)(); Addr fault = (Addr)info->_sifields._sigfault._addr; - Addr esp = ARCH_STACK_PTR(VG_(threads)[tid].arch); + Addr esp = STACK_PTR(VG_(threads)[tid].arch); Segment *seg; seg = VG_(find_segment)(fault); diff --git a/coregrind/vg_syscalls.c b/coregrind/vg_syscalls.c index 9d02cccd35..88cdd1329e 100644 --- a/coregrind/vg_syscalls.c +++ b/coregrind/vg_syscalls.c @@ -858,8 +858,7 @@ void buf_and_len_pre_check( ThreadId tid, Addr buf_p, Addr buflen_p, if (VG_(defined_pre_mem_write)()) { UInt buflen_in = deref_UInt( tid, buflen_p, buflen_s); if (buflen_in > 0) { - TL_(pre_mem_write) ( Vg_CoreSysCall, - tid, buf_s, buf_p, buflen_in ); + TL_(pre_mem_write) ( Vg_CoreSysCall, tid, buf_s, buf_p, buflen_in ); } } } @@ -871,7 +870,7 @@ void buf_and_len_post_check( ThreadId tid, Int res, if (!VG_(is_kerror)(res) && VG_(defined_post_mem_write)()) { UInt buflen_out = deref_UInt( tid, buflen_p, s); if (buflen_out > 0 && buf_p != (Addr)NULL) { - TL_(post_mem_write) ( buf_p, buflen_out ); + TL_(post_mem_write) ( Vg_CoreSysCall, tid, buf_p, buflen_out ); } } } @@ -1023,14 +1022,14 @@ Bool VG_(fd_allowed)(Int fd, const Char *syscallname, ThreadId tid, Bool soft) #define POST(x) \ void VGA_(gen_##x##_after) (ThreadId tid, ThreadState *tst) -#define SYSNO PLATFORM_SYSCALL_NUM(tst->arch) // in PRE(x) -#define res PLATFORM_SYSCALL_RET(tst->arch) // in POST(x) -#define arg1 PLATFORM_SYSCALL_ARG1(tst->arch) -#define arg2 PLATFORM_SYSCALL_ARG2(tst->arch) -#define arg3 PLATFORM_SYSCALL_ARG3(tst->arch) -#define arg4 PLATFORM_SYSCALL_ARG4(tst->arch) -#define arg5 PLATFORM_SYSCALL_ARG5(tst->arch) -#define arg6 PLATFORM_SYSCALL_ARG6(tst->arch) +#define SYSNO SYSCALL_NUM(tst->arch) // in PRE(x) +#define res SYSCALL_RET(tst->arch) // in POST(x) +#define arg1 SYSCALL_ARG1(tst->arch) +#define arg2 SYSCALL_ARG2(tst->arch) +#define arg3 SYSCALL_ARG3(tst->arch) +#define arg4 SYSCALL_ARG4(tst->arch) +#define arg5 SYSCALL_ARG5(tst->arch) +#define arg6 SYSCALL_ARG6(tst->arch) #define set_result(val) PLATFORM_SET_SYSCALL_RESULT(tst->arch, (val)) @@ -1415,7 +1414,7 @@ PRE(sys_getitimer, NBRunInLWP) POST(sys_getitimer) { if (arg2 != (Addr)NULL) { - VG_TRACK( post_mem_write,arg2, sizeof(struct vki_itimerval)); + POST_MEM_WRITE(arg2, sizeof(struct vki_itimerval)); } } @@ -1434,7 +1433,7 @@ PRE(sys_setitimer, NBRunInLWP) POST(sys_setitimer) { if (arg3 != (Addr)NULL) { - VG_TRACK( post_mem_write,arg3, sizeof(struct vki_itimerval)); + POST_MEM_WRITE(arg3, sizeof(struct vki_itimerval)); } } @@ -2275,7 +2274,7 @@ PRE(sys_getppid, 0) PRE_REG_READ0(long, "getppid"); } -static void common_post_getrlimit(UWord a1, UWord a2) +static void common_post_getrlimit(ThreadId tid, UWord a1, UWord a2) { POST_MEM_WRITE( a2, sizeof(struct vki_rlimit) ); @@ -2305,7 +2304,7 @@ PRE(sys_old_getrlimit, 0) POST(sys_old_getrlimit) { - common_post_getrlimit(arg1, arg2); + common_post_getrlimit(tid, arg1, arg2); } PRE(sys_getrlimit, 0) @@ -2318,7 +2317,7 @@ PRE(sys_getrlimit, 0) POST(sys_getrlimit) { - common_post_getrlimit(arg1, arg2); + common_post_getrlimit(tid, arg1, arg2); } PRE(sys_getrusage, 0) @@ -2332,7 +2331,7 @@ PRE(sys_getrusage, 0) POST(sys_getrusage) { if (res == 0) - VG_TRACK( post_mem_write, arg2, sizeof(struct vki_rusage) ); + POST_MEM_WRITE( arg2, sizeof(struct vki_rusage) ); } PRE(sys_gettimeofday, 0) @@ -3027,7 +3026,7 @@ PRE(sys_ioctl, MayBlock) PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", arg3, sizeof(struct ifconf)); KERNEL_DO_SYSCALL(tid,res); if (!VG_(is_kerror)(res) && res == 0) - VG_TRACK( post_mem_write,arg3, sizeof(struct ifconf)); + POST_MEM_WRITE(arg3, sizeof(struct ifconf)); */ PRE_MEM_READ( "ioctl(SIOCGIFCONF)", arg3, sizeof(struct vki_ifconf)); if ( arg3 ) { @@ -3645,28 +3644,28 @@ POST(sys_ioctl) case VKI_SG_SET_COMMAND_Q: break; case VKI_SG_IO: - VG_TRACK( post_mem_write,arg3, sizeof(vki_sg_io_hdr_t)); + POST_MEM_WRITE(arg3, sizeof(vki_sg_io_hdr_t)); break; case VKI_SG_GET_SCSI_ID: - VG_TRACK( post_mem_write,arg3, sizeof(vki_sg_scsi_id_t)); + POST_MEM_WRITE(arg3, sizeof(vki_sg_scsi_id_t)); break; case VKI_SG_SET_RESERVED_SIZE: break; case VKI_SG_SET_TIMEOUT: break; case VKI_SG_GET_RESERVED_SIZE: - VG_TRACK( post_mem_write,arg3, sizeof(int)); + POST_MEM_WRITE(arg3, sizeof(int)); break; case VKI_SG_GET_TIMEOUT: - VG_TRACK( post_mem_write,arg3, sizeof(int)); + POST_MEM_WRITE(arg3, sizeof(int)); break; case VKI_SG_GET_VERSION_NUM: break; case VKI_SG_EMULATED_HOST: - VG_TRACK( post_mem_write,arg3, sizeof(int)); + POST_MEM_WRITE(arg3, sizeof(int)); break; case VKI_SG_GET_SG_TABLESIZE: - VG_TRACK( post_mem_write,arg3, sizeof(int)); + POST_MEM_WRITE(arg3, sizeof(int)); break; case VKI_IIOCGETCPS: @@ -3678,61 +3677,57 @@ POST(sys_ioctl) /* These all use struct ifreq AFAIK */ case VKI_SIOCGIFINDEX: /* get iface index */ - VG_TRACK( post_mem_write, - (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_ifindex, - sizeof(((struct vki_ifreq *)arg3)->vki_ifr_ifindex) ); + POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_ifindex, + sizeof(((struct vki_ifreq *)arg3)->vki_ifr_ifindex) ); break; case VKI_SIOCGIFFLAGS: /* get flags */ - VG_TRACK( post_mem_write, - (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_flags, - sizeof(((struct vki_ifreq *)arg3)->vki_ifr_flags) ); + POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_flags, + sizeof(((struct vki_ifreq *)arg3)->vki_ifr_flags) ); break; case VKI_SIOCGIFHWADDR: /* Get hardware address */ - VG_TRACK( post_mem_write, - (Addr)&((struct vki_ifreq *)arg3)->ifr_hwaddr, - sizeof(((struct vki_ifreq *)arg3)->ifr_hwaddr) ); + POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)arg3)->ifr_hwaddr, + sizeof(((struct vki_ifreq *)arg3)->ifr_hwaddr) ); break; case VKI_SIOCGIFMTU: /* get MTU size */ - VG_TRACK( post_mem_write, - (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_mtu, - sizeof(((struct vki_ifreq *)arg3)->vki_ifr_mtu) ); + POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_mtu, + sizeof(((struct vki_ifreq *)arg3)->vki_ifr_mtu) ); break; case VKI_SIOCGIFADDR: /* get PA address */ case VKI_SIOCGIFDSTADDR: /* get remote PA address */ case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */ case VKI_SIOCGIFNETMASK: /* get network PA mask */ - VG_TRACK( post_mem_write, + POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)arg3)->ifr_addr, sizeof(((struct vki_ifreq *)arg3)->ifr_addr) ); break; case VKI_SIOCGIFMETRIC: /* get metric */ - VG_TRACK( post_mem_write, + POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_metric, sizeof(((struct vki_ifreq *)arg3)->vki_ifr_metric) ); break; case VKI_SIOCGIFMAP: /* Get device parameters */ - VG_TRACK( post_mem_write, + POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)arg3)->ifr_map, sizeof(((struct vki_ifreq *)arg3)->ifr_map) ); break; break; case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */ - VG_TRACK( post_mem_write, + POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)arg3)->ifr_qlen, sizeof(((struct vki_ifreq *)arg3)->ifr_qlen) ); break; case VKI_SIOCGIFNAME: /* get iface name */ - VG_TRACK( post_mem_write, + POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_name, sizeof(((struct vki_ifreq *)arg3)->vki_ifr_name) ); break; case VKI_SIOCGMIIPHY: /* get hardware entry */ - VG_TRACK( post_mem_write, + POST_MEM_WRITE( (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id, sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id) ); break; case VKI_SIOCGMIIREG: /* get hardware entry registers */ - VG_TRACK( post_mem_write, + POST_MEM_WRITE( (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->val_out, sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->val_out) ); break; @@ -3741,7 +3736,7 @@ POST(sys_ioctl) PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", arg3, sizeof(struct ifconf)); KERNEL_DO_SYSCALL(tid,res); if (!VG_(is_kerror)(res) && res == 0) - VG_TRACK( post_mem_write,arg3, sizeof(struct ifconf)); + POST_MEM_WRITE(arg3, sizeof(struct ifconf)); */ if (res == 0 && arg3 ) { struct vki_ifconf *ifc = (struct vki_ifconf *) arg3; @@ -3750,18 +3745,18 @@ POST(sys_ioctl) } break; case VKI_SIOCGSTAMP: - VG_TRACK( post_mem_write,arg3, sizeof(struct vki_timeval)); + POST_MEM_WRITE( arg3, sizeof(struct vki_timeval) ); break; /* SIOCOUTQ is an ioctl that, when called on a socket, returns the number of bytes currently in that socket's send buffer. It writes this value as an int to the memory location indicated by the third argument of ioctl(2). */ case VKI_SIOCOUTQ: - VG_TRACK( post_mem_write,arg3, sizeof(int)); + POST_MEM_WRITE(arg3, sizeof(int)); break; case VKI_SIOCGRARP: /* get RARP table entry */ case VKI_SIOCGARP: /* get ARP table entry */ - VG_TRACK( post_mem_write,arg3, sizeof(struct vki_arpreq)); + POST_MEM_WRITE(arg3, sizeof(struct vki_arpreq)); break; case VKI_SIOCSIFFLAGS: /* set flags */ @@ -3790,7 +3785,7 @@ POST(sys_ioctl) break; case VKI_SIOCGPGRP: - VG_TRACK( post_mem_write,arg3, sizeof(int)); + POST_MEM_WRITE(arg3, sizeof(int)); break; case VKI_SIOCSPGRP: break; @@ -3814,7 +3809,7 @@ POST(sys_ioctl) case VKI_SOUND_PCM_READ_BITS: case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */ case VKI_SOUND_PCM_READ_FILTER: - VG_TRACK( post_mem_write,arg3, sizeof(int)); + POST_MEM_WRITE(arg3, sizeof(int)); break; case VKI_SNDCTL_SEQ_CTRLRATE: case VKI_SNDCTL_DSP_SPEED: @@ -3834,7 +3829,7 @@ POST(sys_ioctl) break; case VKI_SNDCTL_DSP_GETOSPACE: case VKI_SNDCTL_DSP_GETISPACE: - VG_TRACK( post_mem_write,arg3, sizeof(vki_audio_buf_info)); + POST_MEM_WRITE(arg3, sizeof(vki_audio_buf_info)); break; case VKI_SNDCTL_DSP_SETTRIGGER: break; @@ -3857,38 +3852,38 @@ POST(sys_ioctl) break; case VKI_RTC_RD_TIME: case VKI_RTC_ALM_READ: - VG_TRACK( post_mem_write,arg3, sizeof(struct vki_rtc_time)); + POST_MEM_WRITE(arg3, sizeof(struct vki_rtc_time)); break; case VKI_RTC_ALM_SET: break; case VKI_RTC_IRQP_READ: - VG_TRACK( post_mem_write,arg3, sizeof(unsigned long)); + POST_MEM_WRITE(arg3, sizeof(unsigned long)); break; case VKI_BLKGETSIZE: - VG_TRACK( post_mem_write,arg3, sizeof(unsigned long)); + POST_MEM_WRITE(arg3, sizeof(unsigned long)); break; /* Hard disks */ case VKI_HDIO_GET_IDENTITY: /* 0x030d */ - VG_TRACK( post_mem_write,arg3, VKI_SIZEOF_STRUCT_HD_DRIVEID ); + POST_MEM_WRITE(arg3, VKI_SIZEOF_STRUCT_HD_DRIVEID ); break; /* CD ROM stuff (??) */ case VKI_CDROMSUBCHNL: - VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_subchnl)); + POST_MEM_WRITE(arg3, sizeof(struct vki_cdrom_subchnl)); break; case VKI_CDROMREADTOCHDR: - VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_tochdr)); + POST_MEM_WRITE(arg3, sizeof(struct vki_cdrom_tochdr)); break; case VKI_CDROMREADTOCENTRY: - VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_tochdr)); + POST_MEM_WRITE(arg3, sizeof(struct vki_cdrom_tochdr)); break; case VKI_CDROMMULTISESSION: - VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_multisession)); + POST_MEM_WRITE(arg3, sizeof(struct vki_cdrom_multisession)); break; case VKI_CDROMVOLREAD: - VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_volctrl)); + POST_MEM_WRITE(arg3, sizeof(struct vki_cdrom_volctrl)); break; case VKI_CDROMREADAUDIO: { @@ -3906,17 +3901,17 @@ POST(sys_ioctl) break; case VKI_FIGETBSZ: - VG_TRACK( post_mem_write,arg3, sizeof(unsigned long)); + POST_MEM_WRITE(arg3, sizeof(unsigned long)); break; case VKI_FIBMAP: - VG_TRACK( post_mem_write,arg3, sizeof(unsigned long)); + POST_MEM_WRITE(arg3, sizeof(unsigned long)); break; case VKI_FBIOGET_VSCREENINFO: //0x4600 - VG_TRACK( post_mem_write,arg3, sizeof(struct vki_fb_var_screeninfo)); + POST_MEM_WRITE(arg3, sizeof(struct vki_fb_var_screeninfo)); break; case VKI_FBIOGET_FSCREENINFO: //0x4602 - VG_TRACK( post_mem_write,arg3, sizeof(struct vki_fb_fix_screeninfo)); + POST_MEM_WRITE(arg3, sizeof(struct vki_fb_fix_screeninfo)); break; case VKI_PPCLAIM: @@ -4090,7 +4085,7 @@ POST(sys_ioctl) if (size > 0 && (dir & _VKI_IOC_READ) && res == 0 && arg3 != (Addr)NULL) - VG_TRACK( post_mem_write,arg3, size); + POST_MEM_WRITE(arg3, size); break; } } @@ -5282,7 +5277,7 @@ PRE(sys_sched_getaffinity, 0) POST(sys_sched_getaffinity) { - VG_TRACK(post_mem_write, arg3, arg2); + POST_MEM_WRITE(arg3, arg2); } PRE(sys_acct, 0) diff --git a/coregrind/x86-linux/core_platform.h b/coregrind/x86-linux/core_platform.h index 7810905a23..01ac0cd0d9 100644 --- a/coregrind/x86-linux/core_platform.h +++ b/coregrind/x86-linux/core_platform.h @@ -36,36 +36,27 @@ //#include "platform_arch.h" // platform-specific tool stuff /* --------------------------------------------------------------------- - Interesting registers + Dealing with registers ------------------------------------------------------------------ */ // Accessors for the ThreadArchState -#define PLATFORM_SYSCALL_NUM(regs) ((regs).vex.guest_EAX) -#define PLATFORM_SYSCALL_RET(regs) ((regs).vex.guest_EAX) -#define PLATFORM_SYSCALL_ARG1(regs) ((regs).vex.guest_EBX) -#define PLATFORM_SYSCALL_ARG2(regs) ((regs).vex.guest_ECX) -#define PLATFORM_SYSCALL_ARG3(regs) ((regs).vex.guest_EDX) -#define PLATFORM_SYSCALL_ARG4(regs) ((regs).vex.guest_ESI) -#define PLATFORM_SYSCALL_ARG5(regs) ((regs).vex.guest_EDI) -#define PLATFORM_SYSCALL_ARG6(regs) ((regs).vex.guest_EBP) - +#define PLATFORM_SYSCALL_NUM guest_EAX +#define PLATFORM_SYSCALL_ARG1 guest_EBX +#define PLATFORM_SYSCALL_ARG2 guest_ECX +#define PLATFORM_SYSCALL_ARG3 guest_EDX +#define PLATFORM_SYSCALL_ARG4 guest_ESI +#define PLATFORM_SYSCALL_ARG5 guest_EDI +#define PLATFORM_SYSCALL_ARG6 guest_EBP +#define PLATFORM_SYSCALL_RET guest_EAX + +// Setting a syscall result #define PLATFORM_SET_SYSCALL_RESULT(regs, val) \ ((regs).vex.guest_EAX = (val)) -// Interesting register numbers -#define R_SYSCALL_NUM R_EAX -#define R_SYSCALL_ARG1 R_EBX -#define R_SYSCALL_ARG2 R_ECX -#define R_SYSCALL_ARG3 R_EDX -#define R_SYSCALL_ARG4 R_ESI -#define R_SYSCALL_ARG5 R_EDI -#define R_SYSCALL_ARG6 R_EBP -#define R_SYSCALL_RET R_EAX - // Setting thread regs and shadow regs from within the core #define SET_SYSCALL_RETVAL(zztid, zzval) \ - SET_THREAD_REG(zztid, zzval, PLATFORM_SYSCALL_RET, R_SYSCALL_RET, \ - post_reg_write_syscall_return) + SET_THREAD_REG(zztid, zzval, SYSCALL_RET, post_reg_write, \ + Vg_CoreSysCall, zztid, O_SYSCALL_RET, sizeof(UWord)) /* --------------------------------------------------------------------- Exports of vg_ldt.c @@ -115,7 +106,7 @@ extern Addr VG_(do_useseg) ( UInt seg_selector, Addr virtual_addr ); } #define PLATFORM_GET_MMAP_ARGS(tst, a1, a2, a3, a4, a5, a6) do {\ - UInt *arg_block = (UInt*)PLATFORM_SYSCALL_ARG1(tst->arch); \ + UInt *arg_block = (UInt*)SYSCALL_ARG1(tst->arch); \ PRE_MEM_READ( "old_mmap(args)", arg1, 6*sizeof(UWord) ); \ a1 = arg_block[0]; \ a2 = arg_block[1]; \ diff --git a/coregrind/x86-linux/ldt.c b/coregrind/x86-linux/ldt.c index 86173d109f..a85b480a72 100644 --- a/coregrind/x86-linux/ldt.c +++ b/coregrind/x86-linux/ldt.c @@ -450,7 +450,7 @@ Int VG_(sys_set_thread_area) ( ThreadId tid, "set_thread_area(info->entry)", (Addr) & info->entry_number, sizeof(unsigned int) ); info->entry_number = idx + VKI_GDT_ENTRY_TLS_MIN; - VG_TRACK( post_mem_write, + VG_TRACK( post_mem_write, Vg_CoreSysCall, tid, (Addr) & info->entry_number, sizeof(unsigned int) ); return 0; diff --git a/coregrind/x86-linux/syscalls.c b/coregrind/x86-linux/syscalls.c index 70d5758490..97aede5211 100644 --- a/coregrind/x86-linux/syscalls.c +++ b/coregrind/x86-linux/syscalls.c @@ -181,14 +181,14 @@ void VGA_(restart_syscall)(ThreadArchState *arch) #define POST(x) \ static void x86_linux_##x##_after (ThreadId tid, ThreadState *tst) -#define SYSNO PLATFORM_SYSCALL_NUM(tst->arch) // in PRE(x) -#define res PLATFORM_SYSCALL_RET(tst->arch) // in POST(x) -#define arg1 PLATFORM_SYSCALL_ARG1(tst->arch) -#define arg2 PLATFORM_SYSCALL_ARG2(tst->arch) -#define arg3 PLATFORM_SYSCALL_ARG3(tst->arch) -#define arg4 PLATFORM_SYSCALL_ARG4(tst->arch) -#define arg5 PLATFORM_SYSCALL_ARG5(tst->arch) -#define arg6 PLATFORM_SYSCALL_ARG6(tst->arch) +#define SYSNO SYSCALL_NUM(tst->arch) // in PRE(x) +#define res SYSCALL_RET(tst->arch) // in POST(x) +#define arg1 SYSCALL_ARG1(tst->arch) +#define arg2 SYSCALL_ARG2(tst->arch) +#define arg3 SYSCALL_ARG3(tst->arch) +#define arg4 SYSCALL_ARG4(tst->arch) +#define arg5 SYSCALL_ARG5(tst->arch) +#define arg6 SYSCALL_ARG6(tst->arch) #define set_result(val) PLATFORM_SET_SYSCALL_RESULT(tst->arch, (val)) diff --git a/coregrind/x86/core_arch.h b/coregrind/x86/core_arch.h index 0d8747af0b..1b8f702719 100644 --- a/coregrind/x86/core_arch.h +++ b/coregrind/x86/core_arch.h @@ -41,21 +41,18 @@ Interesting registers ------------------------------------------------------------------ */ -// Accessors for the ThreadArchState -#define ARCH_INSTR_PTR(regs) ((regs).vex.guest_EIP) -#define ARCH_STACK_PTR(regs) ((regs).vex.guest_ESP) -#define ARCH_FRAME_PTR(regs) ((regs).vex.guest_EBP) +// Vex field names +#define ARCH_INSTR_PTR guest_EIP +#define ARCH_STACK_PTR guest_ESP +#define ARCH_FRAME_PTR guest_EBP -#define ARCH_CLREQ_ARGS(regs) ((regs).vex.guest_EAX) -#define ARCH_PTHREQ_RET(regs) ((regs).vex.guest_EDX) -#define ARCH_CLREQ_RET(regs) ((regs).vex.guest_EDX) +#define ARCH_CLREQ_ARGS guest_EAX +#define ARCH_CLREQ_RET guest_EDX +#define ARCH_PTHREQ_RET guest_EDX -// Accessors for the baseBlock -#define R_STACK_PTR R_ESP -#define R_FRAME_PTR R_EBP - -#define R_CLREQ_RET R_EDX -#define R_PTHREQ_RET R_EDX +// Register numbers, for vg_symtab2.c +#define R_STACK_PTR 4 +#define R_FRAME_PTR 5 // Stack frame layout and linkage #define FIRST_STACK_FRAME(ebp) (ebp) @@ -155,6 +152,7 @@ typedef } ThreadArchState; +typedef VexGuestX86State VexGuestArchState; /* --------------------------------------------------------------------- libpthread stuff diff --git a/coregrind/x86/signal.c b/coregrind/x86/signal.c index 59cf02b1d1..3eed1c195b 100644 --- a/coregrind/x86/signal.c +++ b/coregrind/x86/signal.c @@ -147,8 +147,8 @@ static void synth_ucontext(ThreadId tid, const vki_siginfo_t *si, } #define SET_SIGNAL_ESP(zztid, zzval) \ - SET_THREAD_REG(zztid, zzval, ARCH_STACK_PTR, R_STACK_PTR, \ - post_reg_write_deliver_signal) + SET_THREAD_REG(zztid, zzval, STACK_PTR, post_reg_write, \ + Vg_CoreSignal, zztid, O_STACK_PTR, sizeof(Addr)) void VGA_(push_signal_frame)(ThreadId tid, Addr esp_top_of_frame, const vki_siginfo_t *siginfo, @@ -181,7 +181,8 @@ void VGA_(push_signal_frame)(ThreadId tid, Addr esp_top_of_frame, frame->retaddr = (UInt)VG_(client_trampoline_code)+VG_(tramp_sigreturn_offset); frame->sigNo = sigNo; frame->sigNo_private = sigNo; - VG_TRACK( post_mem_write, (Addr)frame, offsetof(VgSigFrame, handlerArgs) ); + VG_TRACK( post_mem_write, Vg_CoreSignal, tid, + (Addr)frame, offsetof(VgSigFrame, handlerArgs) ); if (flags & VKI_SA_SIGINFO) { /* if the client asked for a siginfo delivery, then build the stack that way */ @@ -189,17 +190,20 @@ void VGA_(push_signal_frame)(ThreadId tid, Addr esp_top_of_frame, (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) ); frame->handlerArgs.sigInfo.psigInfo = (Addr)&frame->sigInfo; frame->handlerArgs.sigInfo.puContext = (Addr)&frame->uContext; - VG_TRACK( post_mem_write, (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) ); + VG_TRACK( post_mem_write, Vg_CoreSignal, tid, + (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) ); VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)", (Addr)&frame->sigInfo, sizeof(frame->sigInfo) ); VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t)); - VG_TRACK( post_mem_write, (Addr)&frame->sigInfo, sizeof(frame->sigInfo) ); + VG_TRACK( post_mem_write, Vg_CoreSignal, tid, + (Addr)&frame->sigInfo, sizeof(frame->sigInfo) ); VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)", (Addr)&frame->uContext, sizeof(frame->uContext) ); synth_ucontext(tid, siginfo, mask, &frame->uContext); - VG_TRACK( post_mem_write, (Addr)&frame->uContext, sizeof(frame->uContext) ); + VG_TRACK( post_mem_write, Vg_CoreSignal, tid, + (Addr)&frame->uContext, sizeof(frame->uContext) ); } else { struct vki_ucontext uc; @@ -211,8 +215,8 @@ void VGA_(push_signal_frame)(ThreadId tid, Addr esp_top_of_frame, (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigContext) ); VG_(memcpy)(&frame->handlerArgs.sigContext, &uc.uc_mcontext, sizeof(struct vki_sigcontext)); - VG_TRACK( post_mem_write, (Addr)&frame->handlerArgs, - sizeof(frame->handlerArgs.sigContext) ); + VG_TRACK( post_mem_write, Vg_CoreSignal, tid, + (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigContext) ); frame->handlerArgs.sigContext.oldmask = tst->sig_mask.sig[0]; } diff --git a/coregrind/x86/state.c b/coregrind/x86/state.c index 3f710a9973..5e97522c8f 100644 --- a/coregrind/x86/state.c +++ b/coregrind/x86/state.c @@ -79,7 +79,8 @@ void VGA_(init_thread1state) ( Addr client_eip, VGOFF_(m_eip) = offsetof(VexGuestX86State,guest_EIP)/4; if (VG_(needs).shadow_regs) { - VG_TRACK( post_regs_write_init ); + VG_TRACK( post_reg_write, Vg_CoreStartup, /*tid*/1, /*offset*/0, + sizeof(VexGuestArchState)); } /* I assume that if we have SSE2 we also have SSE */ @@ -96,57 +97,6 @@ void VGA_(init_thread1state) ( Addr client_eip, } -/*------------------------------------------------------------*/ -/*--- Register access stuff ---*/ -/*------------------------------------------------------------*/ - -void VGA_(set_thread_shadow_archreg) ( ThreadId tid, UInt archreg, UInt val ) -{ - ThreadState* tst; - - vg_assert(VG_(is_valid_tid)(tid)); - tst = & VG_(threads)[tid]; - if (0) - VG_(printf)("set_thread_shadow_archreg(%d, %d, 0x%x)\n", - tid, archreg, val); - switch (archreg) { - case R_EAX: tst->arch.vex_shadow.guest_EAX = val; break; - case R_ECX: tst->arch.vex_shadow.guest_ECX = val; break; - case R_EDX: tst->arch.vex_shadow.guest_EDX = val; break; - case R_EBX: tst->arch.vex_shadow.guest_EBX = val; break; - case R_ESP: tst->arch.vex_shadow.guest_ESP = val; break; - case R_EBP: tst->arch.vex_shadow.guest_EBP = val; break; - case R_ESI: tst->arch.vex_shadow.guest_ESI = val; break; - case R_EDI: tst->arch.vex_shadow.guest_EDI = val; break; - default: VG_(core_panic)( "set_thread_shadow_archreg"); - } -} - -UInt VGA_(get_thread_shadow_archreg) ( ThreadId tid, UInt archreg ) -{ - ThreadState* tst; - - vg_assert(VG_(is_valid_tid)(tid)); - tst = & VG_(threads)[tid]; - - if (0) - VG_(printf)("get_thread_shadow_archreg(%d, %d)\n", - tid, archreg); - - switch (archreg) { - case R_EAX: return tst->arch.vex_shadow.guest_EAX; - case R_ECX: return tst->arch.vex_shadow.guest_ECX; - case R_EDX: return tst->arch.vex_shadow.guest_EDX; - case R_EBX: return tst->arch.vex_shadow.guest_EBX; - case R_ESP: return tst->arch.vex_shadow.guest_ESP; - case R_EBP: return tst->arch.vex_shadow.guest_EBP; - case R_ESI: return tst->arch.vex_shadow.guest_ESI; - case R_EDI: return tst->arch.vex_shadow.guest_EDI; - default: VG_(core_panic)( "get_thread_shadow_archreg"); - } -} - - /*------------------------------------------------------------*/ /*--- Thread stuff ---*/ /*------------------------------------------------------------*/ @@ -187,8 +137,8 @@ void VGA_(set_arg_and_bogus_ret)( ThreadId tid, UWord arg, Addr ret ) /* Push the arg, and mark it as readable. */ SET_PTHREQ_ESP(tid, VG_(threads)[tid].arch.vex.guest_ESP - sizeof(UWord)); * (UInt*)(VG_(threads)[tid].arch.vex.guest_ESP) = arg; - VG_TRACK( post_mem_write, VG_(threads)[tid].arch.vex.guest_ESP, - sizeof(void*) ); + VG_TRACK( post_mem_write, Vg_CoreSignal, tid, + VG_(threads)[tid].arch.vex.guest_ESP, sizeof(void*) ); /* Don't mark the pushed return address as readable; any attempt to read this is an internal valgrind bug since thread_exit_wrapper() should not @@ -199,7 +149,7 @@ void VGA_(set_arg_and_bogus_ret)( ThreadId tid, UWord arg, Addr ret ) void VGA_(thread_initial_stack)(ThreadId tid, UWord arg, Addr ret) { - Addr esp = (Addr)ARCH_STACK_PTR(VG_(threads)[tid].arch); + Addr esp = (Addr)STACK_PTR(VG_(threads)[tid].arch); /* push two args */ esp -= 2 * sizeof(UWord); @@ -213,7 +163,7 @@ void VGA_(thread_initial_stack)(ThreadId tid, UWord arg, Addr ret) *(UWord*)(esp+sizeof(UWord)) = arg; *(UWord*)(esp) = ret; - VG_TRACK ( post_mem_write, esp, 2 * sizeof(UWord) ); + VG_TRACK ( post_mem_write, Vg_CoreSignal, tid, esp, 2 * sizeof(UWord) ); } @@ -221,6 +171,16 @@ void VGA_(thread_initial_stack)(ThreadId tid, UWord arg, Addr ret) /*--- Symtab stuff ---*/ /*------------------------------------------------------------*/ +/* This is the Intel register encoding -- integer regs. */ +#define R_EAX 0 +#define R_ECX 1 +#define R_EDX 2 +#define R_EBX 3 +#define R_ESP 4 +#define R_EBP 5 +#define R_ESI 6 +#define R_EDI 7 + UInt *VGA_(reg_addr_from_tst)(Int regno, ThreadArchState *arch) { switch (regno) { diff --git a/include/tool.h.base b/include/tool.h.base index 31b278eb32..b59eb7e3c2 100644 --- a/include/tool.h.base +++ b/include/tool.h.base @@ -566,28 +566,13 @@ extern void VG_(cpuid) ( UInt eax, /* ------------------------------------------------------------------ */ /* Accessing archregs and their shadows */ -extern UInt VGA_(get_archreg) ( UInt archreg ); -extern UInt VGA_(get_thread_archreg) ( ThreadId tid, UInt archreg ); - -extern UInt VGA_(get_shadow_archreg) ( UInt archreg ); -extern void VGA_(set_shadow_archreg) ( UInt archreg, UInt val ); - -extern UInt VGA_(get_thread_shadow_archreg) ( ThreadId tid, UInt archreg ); -extern void VGA_(set_thread_shadow_archreg) ( ThreadId tid, UInt archreg, - UInt val ); - -/* ToDo: FIX */ -/* This is the Intel register encoding -- integer regs. */ -#define R_EAX 0 -#define R_ECX 1 -#define R_EDX 2 -#define R_EBX 3 -#define R_ESP 4 -#define R_EBP 5 -#define R_ESI 6 -#define R_EDI 7 - +// For get/set, 'area' is where the asked-for shadow state will be copied +// into/from. +extern void VG_(get_shadow_regs_area) ( ThreadId tid, OffT guest_state_offset, + SizeT size, UChar* area ); +extern void VG_(set_shadow_regs_area) ( ThreadId tid, OffT guest_state_offset, + SizeT size, const UChar* area ); /*====================================================================*/ /*=== Execution contexts ===*/ @@ -957,7 +942,7 @@ extern void *VG_(SkipNode_Next) (const SkipList *l, void *data); syscall. Call it from TL_(post_syscall)() (not TL_(pre_syscall)()!) to override the default shadow register value. */ extern void VG_(set_return_from_syscall_shadow) ( ThreadId tid, - UInt ret_shadow ); + UWord ret_shadow ); /* This can be called from TL_(fini)() to find the shadow of the argument to exit(), ie. the shadow of the program's return value. */ @@ -1101,7 +1086,8 @@ extern float TL_(shadow_ratio); /* Part of the core from which this call was made. Useful for determining what kind of error message should be emitted. */ typedef - enum { Vg_CorePThread, Vg_CoreSignal, Vg_CoreSysCall, Vg_CoreTranslate } + enum { Vg_CoreStartup, Vg_CorePThread, Vg_CoreSignal, Vg_CoreSysCall, + Vg_CoreTranslate, Vg_CoreClientReq } CorePart; /* Useful to use in VG_(get_Xreg_usage)() */ diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c index 94667c8137..776814ae78 100644 --- a/memcheck/mc_main.c +++ b/memcheck/mc_main.c @@ -740,35 +740,36 @@ void mc_set_perms (Addr a, SizeT len, Bool rr, Bool ww, Bool xx) else mc_make_noaccess(a, len); } +static +void mc_post_mem_write(CorePart part, ThreadId tid, Addr a, SizeT len) +{ + mc_make_readable(a, len); +} /*------------------------------------------------------------*/ /*--- Register event handlers ---*/ /*------------------------------------------------------------*/ -static void mc_post_regs_write_init ( void ) -{ -#if 0 - UInt i; - for (i = FIRST_ARCH_REG; i <= LAST_ARCH_REG; i++) - VG_(set_shadow_archreg)( i, VGM_WORD_VALID ); - VG_(set_shadow_eflags)( VGM_EFLAGS_VALID ); -#endif -} - -static void mc_post_reg_write(ThreadId tid, UInt reg) +// When a reg is written, mark the corresponding shadow reg bytes as valid. +static void mc_post_reg_write(CorePart part, ThreadId tid, OffT offset, + SizeT size) { - VGA_(set_thread_shadow_archreg)( tid, reg, VGM_WORD_VALID ); + UChar area[size]; + VG_(memset)(area, VGM_BYTE_VALID, size); + VG_(set_shadow_regs_area)( tid, offset, size, area ); } -static void mc_post_reg_write_clientcall(ThreadId tid, UInt reg, Addr f ) +static void mc_post_reg_write_clientcall(ThreadId tid, OffT offset, SizeT size, + Addr f) { - VGA_(set_thread_shadow_archreg)( tid, reg, VGM_WORD_VALID ); + mc_post_reg_write(/*dummy*/0, tid, offset, size); } -static void mc_pre_reg_read(CorePart part, ThreadId tid, Char* s, UInt reg, +static void mc_pre_reg_read(CorePart part, ThreadId tid, Char* s, OffT offset, SizeT size) { UWord mask; + UWord sh_reg_contents; // XXX: the only one at the moment tl_assert(Vg_CoreSysCall == part); @@ -780,7 +781,8 @@ static void mc_pre_reg_read(CorePart part, ThreadId tid, Char* s, UInt reg, default: VG_(tool_panic)("Unhandled size in mc_pre_reg_read"); } - if (VGM_WORD_VALID != (mask & VGA_(get_thread_shadow_archreg)( tid, reg )) ) + VG_(get_shadow_regs_area)( tid, offset, size, (UChar*)&sh_reg_contents ); + if ( VGM_WORD_VALID != (mask & sh_reg_contents) ) MAC_(record_param_error) ( tid, 0, /*isReg*/True, /*isUnaddr*/False, s ); } @@ -1950,15 +1952,11 @@ void TL_(pre_clo_init)(void) VG_(init_pre_mem_read) ( & mc_check_is_readable ); VG_(init_pre_mem_read_asciiz) ( & mc_check_is_readable_asciiz ); VG_(init_pre_mem_write) ( & mc_check_is_writable ); - VG_(init_post_mem_write) ( & mc_make_readable ); + VG_(init_post_mem_write) ( & mc_post_mem_write ); VG_(init_pre_reg_read) ( & mc_pre_reg_read ); - VG_(init_post_regs_write_init) ( & mc_post_regs_write_init ); - VG_(init_post_reg_write_syscall_return) ( & mc_post_reg_write ); - VG_(init_post_reg_write_deliver_signal) ( & mc_post_reg_write ); - VG_(init_post_reg_write_pthread_return) ( & mc_post_reg_write ); - VG_(init_post_reg_write_clientreq_return) ( & mc_post_reg_write ); + VG_(init_post_reg_write) ( & mc_post_reg_write ); VG_(init_post_reg_write_clientcall_return) ( & mc_post_reg_write_clientcall ); VGP_(register_profile_event) ( VgpSetMem, "set-mem-perms" );