From: Nicholas Nethercote Date: Sat, 27 Nov 2004 15:22:24 +0000 (+0000) Subject: Factored out some stuff duplicated across all archs, to do with syscall X-Git-Tag: svn/VALGRIND_3_0_0~1194 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f23dea17b28226045c1f4db0f4d3c0ae39e9dbab;p=thirdparty%2Fvalgrind.git Factored out some stuff duplicated across all archs, to do with syscall wrappers. The management apologises for the excessive use of macros, but it's hard to avoid and really does make the repetitive parts of the code (ie. the parts that are repeated for each arch) much more concise. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3124 --- diff --git a/coregrind/arm-linux/syscalls.c b/coregrind/arm-linux/syscalls.c index 235881cc89..e686e06913 100644 --- a/coregrind/arm-linux/syscalls.c +++ b/coregrind/arm-linux/syscalls.c @@ -80,11 +80,8 @@ void VGA_(restart_syscall)(ThreadArchState *arch) // Nb: See the comment above the generic PRE/POST wrappers in // coregrind/vg_syscalls.c for notes about how they work. -#define PRE(x,f) \ - static UInt arm_linux_##x##_flags = f; \ - static void arm_linux_##x##_before(ThreadId tid, ThreadState *tst) -#define POST(x) \ - static void arm_linux_##x##_after (ThreadId tid, ThreadState *tst) +#define PRE(name, f) PRE_TEMPLATE(static, arm_linux, name, f) +#define POST(name) POST_TEMPLATE(static, arm_linux, name) #define SYSNO PLATFORM_SYSCALL_NUM(tst->arch) // in PRE(x) #define res PLATFORM_SYSCALL_RET(tst->arch) // in POST(x) @@ -148,22 +145,9 @@ PRE(sys_clone, Special) The ARM/Linux syscall table ------------------------------------------------------------------ */ -#define GENX_(const, name) \ - [const] = { &VGA_(gen_##name##_flags), VGA_(gen_##name##_before), NULL } -#define GENXY(const, name) \ - [const] = { &VGA_(gen_##name##_flags), VGA_(gen_##name##_before), \ - VGA_(gen_##name##_after) } - -#define LINX_(const, name) \ - [const] = { &VGA_(linux_##name##_flags), VGA_(linux_##name##_before), NULL } -#define LINXY(const, name) \ - [const] = { &VGA_(linux_##name##_flags), VGA_(linux_##name##_before), \ - VGA_(linux_##name##_after) } -#define PLAX_(const, name) \ - [const] = { &arm_linux_##name##_flags, arm_linux_##name##_before, NULL } -#define PLAXY(const, name) \ - [const] = { &arm_linux_##name##_flags, arm_linux_##name##_before, \ - arm_linux_##name##_after } +// Macros for adding ARM/Linux-specific wrappers to the syscall table. +#define PLAX_(const, name) SYS_WRAPPER_ENTRY_X_(arm_linux, const, name) +#define PLAXY(const, name) SYS_WRAPPER_ENTRY_XY(arm_linux, const, name) // This table maps from __NR_xxx syscall numbers (from // linux/include/asm-arm/unistd.h) to the appropriate PRE/POST sys_foo() @@ -175,6 +159,8 @@ PRE(sys_clone, Special) const struct SyscallTableEntry VGA_(syscall_table)[] = { // (restart_syscall) // 0 + GENX_(__NR_exit, sys_exit), // 1 + LINX_(__NR_mount, sys_mount), // 21 PLAX_(__NR_syscall, sys_syscall), // 113 PLAX_(__NR_clone, sys_clone), // 120 }; @@ -182,9 +168,6 @@ const struct SyscallTableEntry VGA_(syscall_table)[] = { const UInt VGA_(syscall_table_size) = sizeof(VGA_(syscall_table)) / sizeof(VGA_(syscall_table)[0]); -#undef GENX_ -#undef GENXY - /*--------------------------------------------------------------------*/ /*--- end ---*/ /*--------------------------------------------------------------------*/ diff --git a/coregrind/core.h b/coregrind/core.h index 32eb3fd4be..c3201250ad 100644 --- a/coregrind/core.h +++ b/coregrind/core.h @@ -1388,13 +1388,30 @@ void VG_(record_fd_open)(Int tid, Int fd, char *pathname); #define NBRunInLWP (1 << 2) // non-blocking, but must run in LWP context #define PostOnFail (1 << 3) -// For each generic ("gen") wrapper, we declare the pre-wrapper, the -// post-wrapper (which is actually not always needed), and the associated -// flags. -#define GEN_SYSCALL_WRAPPER(x) \ - extern UInt VGA_(gen_##x##_flags); \ - extern void VGA_(gen_##x##_before)(ThreadId tid, ThreadState *tst); \ - extern void VGA_(gen_##x##_after) (ThreadId tid, ThreadState *tst) +// Templates for generating the PRE and POST macros. For ones that must be +// publically visible, use an empty 'qual', 'prefix' should start with +// "vgArch_", and there should be corresponding global declarations (like +// the GEN_SYSCALL_WRAPPER ones below). Otherwise, use "static" for 'qual', +// and "vgArch_" should not be in the 'prefix'. +#define PRE_TEMPLATE(qual, prefix, name, f) \ + qual UInt prefix##_##name##_flags = f; \ + qual void prefix##_##name##_before(ThreadId tid, ThreadState *tst) +#define POST_TEMPLATE(qual, prefix, name) \ + qual void prefix##_##name##_after (ThreadId tid, ThreadState *tst) + +// This macro is used to write other macros which making writing syscall +// tables easier. +#define SYS_WRAPPER_ENTRY_X_(prefix, const, name) \ + [const] = { &prefix##_##name##_flags, \ + prefix##_##name##_before, NULL } +#define SYS_WRAPPER_ENTRY_XY(prefix, const, name) \ + [const] = { &prefix##_##name##_flags, \ + prefix##_##name##_before, \ + prefix##_##name##_after } + +// Macros for adding generic wrappers to a syscall table. +#define GENX_(const, name) SYS_WRAPPER_ENTRY_X_(vgArch_gen, const, name) +#define GENXY(const, name) SYS_WRAPPER_ENTRY_XY(vgArch_gen, const, name) // Generic (platform-independent) syscall wrappers. These are generally // POSIX or something like that; those that are not POSIX are annotated @@ -1408,6 +1425,14 @@ void VG_(record_fd_open)(Int tid, Int fd, char *pathname); // // Nb 2: if porting to a new OS, you should really check all these generic // wrappers to make sure they match your OS, painful as it might be. +// +// For each generic ("gen") wrapper, we declare the pre-wrapper, the +// post-wrapper (which is actually not always needed), and the associated +// flags. +#define GEN_SYSCALL_WRAPPER(x) \ + extern UInt VGA_(gen_##x##_flags); \ + extern void VGA_(gen_##x##_before)(ThreadId tid, ThreadState *tst); \ + extern void VGA_(gen_##x##_after) (ThreadId tid, ThreadState *tst) GEN_SYSCALL_WRAPPER(sys_ni_syscall); // * P -- unimplemented GEN_SYSCALL_WRAPPER(sys_exit); diff --git a/coregrind/linux/core_os.h b/coregrind/linux/core_os.h index a25883cc1a..f60da62911 100644 --- a/coregrind/linux/core_os.h +++ b/coregrind/linux/core_os.h @@ -32,12 +32,17 @@ #ifndef __LINUX_CORE_OS_H #define __LINUX_CORE_OS_H +// Macros for adding Linux-specific, arch-independent wrappers to a syscall +// table. +#define LINX_(const, name) SYS_WRAPPER_ENTRY_X_(vgArch_linux, const, name) +#define LINXY(const, name) SYS_WRAPPER_ENTRY_XY(vgArch_linux, const, name) + +// The following syscall wrappers are Linux-specific, but arch-independent. #define LINUX_SYSCALL_WRAPPER(x) \ extern UInt VGA_(linux_##x##_flags); \ extern void VGA_(linux_##x##_before)(ThreadId tid, ThreadState *tst); \ extern void VGA_(linux_##x##_after) (ThreadId tid, ThreadState *tst) -// These syscalls are Linux-specific, but architecture-independent. LINUX_SYSCALL_WRAPPER(sys_mount); LINUX_SYSCALL_WRAPPER(sys_oldumount); LINUX_SYSCALL_WRAPPER(sys_umount); diff --git a/coregrind/linux/syscalls.c b/coregrind/linux/syscalls.c index e731c82be5..754d1fc5e2 100644 --- a/coregrind/linux/syscalls.c +++ b/coregrind/linux/syscalls.c @@ -37,11 +37,8 @@ // Nb: See the comment above the generic PRE/POST wrappers in // coregrind/vg_syscalls.c for notes about how they work. -#define PRE(x,f) \ - UInt VGA_(linux_##x##_flags) = f; \ - void VGA_(linux_##x##_before)(ThreadId tid, ThreadState *tst) -#define POST(x) \ - void VGA_(linux_##x##_after) (ThreadId tid, ThreadState *tst) +#define PRE(name, f) PRE_TEMPLATE( , vgArch_linux, name, f) +#define POST(name) POST_TEMPLATE( , vgArch_linux, name) #define SYSNO SYSCALL_NUM(tst->arch) // in PRE(x) #define res SYSCALL_RET(tst->arch) // in POST(x) diff --git a/coregrind/vg_syscalls.c b/coregrind/vg_syscalls.c index 01a5b5c0a5..e825d4eade 100644 --- a/coregrind/vg_syscalls.c +++ b/coregrind/vg_syscalls.c @@ -1011,16 +1011,8 @@ Bool VG_(fd_allowed)(Int fd, const Char *syscallname, ThreadId tid, Bool soft) XXX: some of these are arch-specific, and should be factored out. */ -#define Special (1 << 0) -#define MayBlock (1 << 1) -#define NBRunInLWP (1 << 2) // non-blocking, but must run in LWP context -#define PostOnFail (1 << 3) - -#define PRE(x,f) \ - UInt VGA_(gen_##x##_flags) = f; \ - void VGA_(gen_##x##_before)(ThreadId tid, ThreadState *tst) -#define POST(x) \ - void VGA_(gen_##x##_after) (ThreadId tid, ThreadState *tst) +#define PRE(name, f) PRE_TEMPLATE( , vgArch_gen, name, f) +#define POST(name) POST_TEMPLATE( , vgArch_gen, name) #define SYSNO SYSCALL_NUM(tst->arch) // in PRE(x) #define res SYSCALL_RET(tst->arch) // in POST(x) diff --git a/coregrind/x86-linux/syscalls.c b/coregrind/x86-linux/syscalls.c index 6d146d760a..e40ba8994e 100644 --- a/coregrind/x86-linux/syscalls.c +++ b/coregrind/x86-linux/syscalls.c @@ -114,11 +114,8 @@ void VGA_(restart_syscall)(ThreadArchState *arch) // Nb: See the comment above the generic PRE/POST wrappers in // coregrind/vg_syscalls.c for notes about how they work. -#define PRE(x,f) \ - static UInt x86_linux_##x##_flags = f; \ - static void x86_linux_##x##_before(ThreadId tid, ThreadState *tst) -#define POST(x) \ - static void x86_linux_##x##_after (ThreadId tid, ThreadState *tst) +#define PRE(name, f) PRE_TEMPLATE(static, x86_linux, name, f) +#define POST(name) POST_TEMPLATE(static, x86_linux, name) #define SYSNO SYSCALL_NUM(tst->arch) // in PRE(x) #define res SYSCALL_RET(tst->arch) // in POST(x) @@ -311,22 +308,9 @@ POST(sys_ptrace) The x86/Linux syscall table ------------------------------------------------------------------ */ -#define GENX_(const, name) \ - [const] = { &VGA_(gen_##name##_flags), VGA_(gen_##name##_before), NULL } -#define GENXY(const, name) \ - [const] = { &VGA_(gen_##name##_flags), VGA_(gen_##name##_before), \ - VGA_(gen_##name##_after) } - -#define LINX_(const, name) \ - [const] = { &VGA_(linux_##name##_flags), VGA_(linux_##name##_before), NULL } -#define LINXY(const, name) \ - [const] = { &VGA_(linux_##name##_flags), VGA_(linux_##name##_before), \ - VGA_(linux_##name##_after) } -#define PLAX_(const, name) \ - [const] = { &x86_linux_##name##_flags, x86_linux_##name##_before, NULL } -#define PLAXY(const, name) \ - [const] = { &x86_linux_##name##_flags, x86_linux_##name##_before, \ - x86_linux_##name##_after } +// Macros for adding x86/Linux-specific wrappers to the syscall table. +#define PLAX_(const, name) SYS_WRAPPER_ENTRY_X_(x86_linux, const, name) +#define PLAXY(const, name) SYS_WRAPPER_ENTRY_XY(x86_linux, const, name) // This table maps from __NR_xxx syscall numbers (from // linux/include/asm-i386/unistd.h) to the appropriate PRE/POST sys_foo() @@ -685,9 +669,6 @@ const struct SyscallTableEntry VGA_(syscall_table)[] = { const UInt VGA_(syscall_table_size) = sizeof(VGA_(syscall_table)) / sizeof(VGA_(syscall_table)[0]); -#undef GENX_ -#undef GENXY - /*--------------------------------------------------------------------*/ /*--- end ---*/ /*--------------------------------------------------------------------*/