From: Nicholas Nethercote Date: Fri, 10 Sep 2004 17:42:11 +0000 (+0000) Subject: Arch-abstraction: X-Git-Tag: svn/VALGRIND_3_0_0~1600 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=db64449073653847e203a6147b3f04d81e83fb8d;p=thirdparty%2Fvalgrind.git Arch-abstraction: - added x86-linux/core_platform.h - factored out getting/setting of system call arguments, put it in platform-specific part. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2685 --- diff --git a/coregrind/core.h b/coregrind/core.h index 018da8b7d5..deff8721f5 100644 --- a/coregrind/core.h +++ b/coregrind/core.h @@ -85,7 +85,9 @@ #include "core_asm.h" // asm stuff #include "tool.h" // tool stuff -#include "core_arch.h" // arch-specific stuff; eg. x86/arch.h +#include "core_arch.h" // arch-specific stuff, eg. x86/core_arch.h +#include "core_platform.h" // platform-specific stuff, + // eg. x86-linux/core_platform.h #include "valgrind.h" diff --git a/coregrind/vg_proxylwp.c b/coregrind/vg_proxylwp.c index 90fe9e73d5..8c57639c55 100644 --- a/coregrind/vg_proxylwp.c +++ b/coregrind/vg_proxylwp.c @@ -430,7 +430,7 @@ void VG_(proxy_handlesig)(const vki_ksiginfo_t *siginfo, anywhere else, except that we can make some assertions about the proxy and machine state here. */ vg_assert(px->state == PXS_RunSyscall); - vg_assert(px->tst->arch.m_eax == -VKI_ERESTARTSYS); + vg_assert(PLATFORM_SYSCALL_RET(px->tst->arch) == -VKI_ERESTARTSYS); } else if (sys_after <= eip && eip <= sys_done) { /* We're after the syscall. Either it was interrupted by the signal, or the syscall completed normally. In either case @@ -439,7 +439,7 @@ void VG_(proxy_handlesig)(const vki_ksiginfo_t *siginfo, vg_assert(px->state == PXS_RunSyscall || px->state == PXS_SysDone); px->state = PXS_SysDone; - px->tst->arch.m_eax = eax; + PLATFORM_SYSCALL_RET(px->tst->arch) = eax; } px_printf(" signalled in state %s\n", pxs_name(px->state)); @@ -556,7 +556,7 @@ static Int proxylwp(void *v) */ reply.u.syscallno = tst->syscallno; - tst->arch.m_eax = -VKI_ERESTARTSYS; + PLATFORM_SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS; px->state = PXS_IntReply; break; @@ -726,14 +726,14 @@ static Int proxylwp(void *v) */ px_printf("RunSyscall in SigACK: rejecting syscall %d with ERESTARTSYS\n", reply.u.syscallno); - tst->arch.m_eax = -VKI_ERESTARTSYS; + PLATFORM_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. */ - tst->arch.m_eax = -VKI_ERESTARTSYS; + PLATFORM_SYSCALL_RET(tst->arch) = -VKI_ERESTARTSYS; /* set our process group ID to match parent */ if (VG_(getpgrp)() != VG_(main_pgrp)) @@ -1142,7 +1142,8 @@ static void sys_wait_results(Bool block, ThreadId tid, enum RequestType reqtype, case PX_RunSyscall: if (VG_(clo_trace_syscalls)) VG_(message)(Vg_DebugMsg, "sys_wait_results: got PX_RunSyscall for TID %d: syscall %d result %d", - res.tid, tst->syscallno, tst->arch.m_eax); + res.tid, tst->syscallno, + PLATFORM_SYSCALL_RET(tst->arch)); if (tst->status != VgTs_WaitSys) VG_(printf)("tid %d in status %d\n", @@ -1301,8 +1302,8 @@ Int VG_(sys_issue)(int tid) req.request = PX_RunSyscall; - tst->syscallno = tst->arch.m_eax; - tst->arch.m_eax = -VKI_ERESTARTSYS; + tst->syscallno = PLATFORM_SYSCALL_NUM(tst->arch); + PLATFORM_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 71a979638d..021fe6075b 100644 --- a/coregrind/vg_scheduler.c +++ b/coregrind/vg_scheduler.c @@ -467,12 +467,12 @@ void handle_signal_return ( ThreadId tid ) return; if (VG_(threads)[tid].status == VgTs_Sleeping - && VG_(threads)[tid].arch.m_eax == __NR_nanosleep) { + && PLATFORM_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 *)VG_(threads)[tid].arch.m_ecx; /* arg2 */ + rem = (struct vki_timespec*)PLATFORM_SYSCALL_ARG2(VG_(threads)[tid].arch); if (rem != NULL) { rem->tv_sec = 0; rem->tv_nsec = 1; @@ -526,7 +526,7 @@ void sched_do_syscall ( ThreadId tid ) vg_assert(VG_(is_valid_tid)(tid)); vg_assert(VG_(threads)[tid].status == VgTs_Runnable); - syscall_no = VG_(threads)[tid].arch.m_eax; /* syscall number */ + syscall_no = PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch); /* Special-case nanosleep because we can. But should we? @@ -536,7 +536,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*)VG_(threads)[tid].arch.m_ebx; /* arg1 */ + req = (struct vki_timespec*)PLATFORM_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); @@ -924,12 +924,12 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid ) __libc_freeres does some invalid frees which crash the unprotected malloc/free system. */ - if (VG_(threads)[tid].arch.m_eax == __NR_exit - || VG_(threads)[tid].arch.m_eax == __NR_exit_group + if (PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit + || PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) == __NR_exit_group ) { /* If __NR_exit, remember the supplied argument. */ - *exitcode = VG_(threads)[tid].arch.m_ebx; /* syscall arg1 */ + *exitcode = PLATFORM_SYSCALL_ARG1(VG_(threads)[tid].arch); /* Only run __libc_freeres if the tool says it's ok and it hasn't been overridden with --run-libc-freeres=no @@ -962,13 +962,13 @@ VgSchedReturnCode do_scheduler ( Int* exitcode, ThreadId* last_run_tid ) } /* We've dealt with __NR_exit at this point. */ - vg_assert(VG_(threads)[tid].arch.m_eax != __NR_exit && - VG_(threads)[tid].arch.m_eax != __NR_exit_group); + vg_assert(PLATFORM_SYSCALL_NUM(VG_(threads)[tid].arch) != __NR_exit && + PLATFORM_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 (VG_(threads)[tid].arch.m_eax == __NR_sched_yield) { + if (PLATFORM_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 */ } diff --git a/coregrind/vg_signals.c b/coregrind/vg_signals.c index d47cfdd76b..e0df4ac715 100644 --- a/coregrind/vg_signals.c +++ b/coregrind/vg_signals.c @@ -489,8 +489,8 @@ void VG_(do__NR_sigaltstack) ( ThreadId tid ) Addr m_esp; vg_assert(VG_(is_valid_tid)(tid)); - ss = (vki_kstack_t*)(VG_(threads)[tid].arch.m_ebx); - oss = (vki_kstack_t*)(VG_(threads)[tid].arch.m_ecx); + ss = (vki_kstack_t*)(PLATFORM_SYSCALL_ARG1(VG_(threads)[tid].arch)); + oss = (vki_kstack_t*)(PLATFORM_SYSCALL_ARG2(VG_(threads)[tid].arch)); m_esp = VG_(threads)[tid].arch.m_esp; if (VG_(clo_trace_signals)) @@ -542,9 +542,9 @@ void VG_(do__NR_sigaction) ( ThreadId tid ) vg_assert(is_correct_sigmask()); vg_assert(VG_(is_valid_tid)(tid)); - signo = VG_(threads)[tid].arch.m_ebx; /* int sigNo */ - new_act = (vki_ksigaction*)(VG_(threads)[tid].arch.m_ecx); - old_act = (vki_ksigaction*)(VG_(threads)[tid].arch.m_edx); + signo = PLATFORM_SYSCALL_ARG1(VG_(threads)[tid].arch); + new_act = (vki_ksigaction*)PLATFORM_SYSCALL_ARG2(VG_(threads)[tid].arch); + old_act = (vki_ksigaction*)PLATFORM_SYSCALL_ARG3(VG_(threads)[tid].arch); if (VG_(clo_trace_signals)) VG_(message)(Vg_DebugExtraMsg, @@ -1867,8 +1867,8 @@ void VG_(deliver_signal) ( ThreadId tid, const vki_ksiginfo_t *info, Bool async if (tst->status == VgTs_WaitSys) { /* blocked in a syscall; we assume it should be interrupted */ - if (tst->arch.m_eax == -VKI_ERESTARTSYS) - tst->arch.m_eax = -VKI_EINTR; + if (PLATFORM_SYSCALL_RET(tst->arch) == -VKI_ERESTARTSYS) + PLATFORM_SYSCALL_RET(tst->arch) = -VKI_EINTR; } VG_(proxy_sigack)(tid, &tst->sig_mask); diff --git a/coregrind/vg_syscalls.c b/coregrind/vg_syscalls.c index 39591cebae..2934f40e45 100644 --- a/coregrind/vg_syscalls.c +++ b/coregrind/vg_syscalls.c @@ -1010,14 +1010,14 @@ static Bool fd_allowed(Int fd, const Char *syscall, ThreadId tid, Bool soft) #define POSTALIAS(new, old) \ POST(new) __attribute__((alias(STR(after_##old)))) -#define SYSNO (tst->arch.m_eax) /* in PRE(x) */ -#define res (tst->arch.m_eax) /* in POST(x) */ -#define arg1 (tst->arch.m_ebx) -#define arg2 (tst->arch.m_ecx) -#define arg3 (tst->arch.m_edx) -#define arg4 (tst->arch.m_esi) -#define arg5 (tst->arch.m_edi) -#define arg6 (tst->arch.m_ebp) +#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) PRE(exit_group) { diff --git a/coregrind/x86-linux/Makefile.am b/coregrind/x86-linux/Makefile.am index 15936733cc..31e8cc5a01 100644 --- a/coregrind/x86-linux/Makefile.am +++ b/coregrind/x86-linux/Makefile.am @@ -4,4 +4,5 @@ include $(top_srcdir)/Makefile.core-AM_CPPFLAGS.am AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -fomit-frame-pointer -g noinst_HEADERS = \ + core_platform.h \ vki_unistd.h diff --git a/coregrind/x86-linux/core_platform.h b/coregrind/x86-linux/core_platform.h new file mode 100644 index 0000000000..3dafc7805d --- /dev/null +++ b/coregrind/x86-linux/core_platform.h @@ -0,0 +1,63 @@ + +/*--------------------------------------------------------------------*/ +/*--- x86-Linux-specific stuff for the core. ---*/ +/*--- x86-linux/core_platform.h ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, an extensible x86 protected-mode + emulator for monitoring program execution on x86-Unixes. + + Copyright (C) 2000-2004 Nicholas Nethercote + njn25@cam.ac.uk + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#ifndef __X86_LINUX_CORE_PLATFORM_H +#define __X86_LINUX_CORE_PLATFORM_H + +//#include "core_platform_asm.h" // platform-specific asm stuff +//#include "platform_arch.h" // platform-specific tool stuff + +/* --------------------------------------------------------------------- + Interesting registers + ------------------------------------------------------------------ */ + +// Accessors for the arch_thread_t +#define PLATFORM_SYSCALL_NUM(regs) ((regs).m_eax) +#define PLATFORM_SYSCALL_RET(regs) ((regs).m_eax) +#define PLATFORM_SYSCALL_ARG1(regs) ((regs).m_ebx) +#define PLATFORM_SYSCALL_ARG2(regs) ((regs).m_ecx) +#define PLATFORM_SYSCALL_ARG3(regs) ((regs).m_edx) +#define PLATFORM_SYSCALL_ARG4(regs) ((regs).m_esi) +#define PLATFORM_SYSCALL_ARG5(regs) ((regs).m_edi) +#define PLATFORM_SYSCALL_ARG6(regs) ((regs).m_ebp) + +#define PLATFORM_PRE_SYSCALL_RESULT(regs, val) ((regs).m_eax = (val)) + +// Interesting register numbers +#define R_SYSCALL_NUM R_EAX +#define R_SYSCALL_ARG1 R_EBX +#define R_SYSCALL_RET R_EAX + +#endif // __X86_LINUX_CORE_PLATFORM_H + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/x86/core_arch.h b/coregrind/x86/core_arch.h index 55fae1945b..425ff5b5b4 100644 --- a/coregrind/x86/core_arch.h +++ b/coregrind/x86/core_arch.h @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------*/ -/*--- Arch-specific stuff for the core. x86/core_arch.h ---*/ +/*--- x86-specific stuff for the core. x86/core_arch.h ---*/ /*--------------------------------------------------------------------*/ /*