// 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)
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()
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
};
const UInt VGA_(syscall_table_size) =
sizeof(VGA_(syscall_table)) / sizeof(VGA_(syscall_table)[0]);
-#undef GENX_
-#undef GENXY
-
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
#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
//
// 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);
#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);
// 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)
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)
// 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)
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()
const UInt VGA_(syscall_table_size) =
sizeof(VGA_(syscall_table)) / sizeof(VGA_(syscall_table)[0]);
-#undef GENX_
-#undef GENXY
-
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/