From: Julian Seward Date: Thu, 6 Oct 2005 03:19:49 +0000 (+0000) Subject: The m_syswrap subsystem is Valgrind's model of how the kernel behaves X-Git-Tag: svn/VALGRIND_3_1_0~357 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=287d92271f32dc638871dda1161093a6d712bbf8;p=thirdparty%2Fvalgrind.git The m_syswrap subsystem is Valgrind's model of how the kernel behaves with respect to syscalls. It is detailed and comprehensive but does not offer a way to deal with minor deviations in behaviour from the vanilla kernel sources, either due to running a hacked kernel or running a vanilla kernel with a custom kernel module loaded. This commit adds a flexible way to handle such cases without polluting the vanilla handler syswrap-*.c files or their supporting vki_*.h header files. For each OS, a syswrap-OS-variants.c file is added, containing wrappers for variants of OS. A new command line flag --kernel-variants= carries a comma separated list of variant names that apply to the current run. There are no other changes. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@4873 --- diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am index 25ff527c05..c03213697e 100644 --- a/coregrind/Makefile.am +++ b/coregrind/Makefile.am @@ -86,6 +86,7 @@ noinst_HEADERS = \ m_syswrap/priv_types_n_macros.h \ m_syswrap/priv_syswrap-generic.h \ m_syswrap/priv_syswrap-linux.h \ + m_syswrap/priv_syswrap-linux-variants.h \ m_syswrap/priv_syswrap-main.h BUILT_SOURCES = @@ -150,6 +151,7 @@ libcoregrind_a_SOURCES = \ m_syswrap/syscall-@VG_PLATFORM@.S \ m_syswrap/syswrap-generic.c \ m_syswrap/syswrap-@VG_OS@.c \ + m_syswrap/syswrap-@VG_OS@-variants.c \ m_syswrap/syswrap-@VG_PLATFORM@.c \ m_syswrap/syswrap-main.c diff --git a/coregrind/m_main.c b/coregrind/m_main.c index 66beba3278..e71b27a6a4 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -1099,6 +1099,8 @@ static Bool process_cmd_line_options( UInt* client_auxv, const char* toolname ) else if (VG_CLO_STREQ(arg, "--smc-check=all")) VG_(clo_smc_check) = Vg_SmcAll; + else VG_STR_CLO (arg, "--kernel-variant", VG_(clo_kernel_variant)) + else VG_BNUM_CLO(arg, "--vex-iropt-verbosity", VG_(clo_vex_control).iropt_verbosity, 0, 10) else VG_BNUM_CLO(arg, "--vex-iropt-level", diff --git a/coregrind/m_options.c b/coregrind/m_options.c index ac917b1b0a..21a723727d 100644 --- a/coregrind/m_options.c +++ b/coregrind/m_options.c @@ -77,6 +77,7 @@ Bool VG_(clo_show_emwarns) = False; Int VG_(clo_max_stackframe) = 2000000; Bool VG_(clo_wait_for_gdb) = False; VgSmc VG_(clo_smc_check) = Vg_SmcStack; +HChar* VG_(clo_kernel_variant) = NULL; /*--------------------------------------------------------------------*/ diff --git a/coregrind/m_syswrap/priv_syswrap-linux-variants.h b/coregrind/m_syswrap/priv_syswrap-linux-variants.h new file mode 100644 index 0000000000..2c93031f8b --- /dev/null +++ b/coregrind/m_syswrap/priv_syswrap-linux-variants.h @@ -0,0 +1,59 @@ + +/*--------------------------------------------------------------------*/ +/*--- Linux-variant specific syscalls stuff. ---*/ +/*--- priv_syswrap-linux.h ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2000-2005 Julian Seward + jseward@acm.org + + 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 __PRIV_SYSWRAP_LINUX_VARIANTS_H +#define __PRIV_SYSWRAP_LINUX_VARIANTS_H + +/* requires #include "priv_types_n_macros.h" */ + + +/* --------------------------------------------------------------- + BProc wrappers + ------------------------------------------------------------ */ + +#define TId ThreadId +#define UW UWord +#define SR SysRes + +/* Return 0 means hand to kernel, non-0 means fail w/ that value. */ +extern Int ML_(linux_variant_PRE_sys_bproc)( UW, UW, UW, UW, UW, UW ); + +extern void ML_(linux_variant_POST_sys_bproc)( UW, UW, UW, UW, UW, UW ); + +#undef TId +#undef UW +#undef SR + +#endif // __PRIV_SYSWRAP_LINUX_VARIANTS_H + +/*--------------------------------------------------------------------*/ +/*--- end priv_syswrap-linux-variants.h ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/m_syswrap/syswrap-linux-variants.c b/coregrind/m_syswrap/syswrap-linux-variants.c new file mode 100644 index 0000000000..8dc8a634d5 --- /dev/null +++ b/coregrind/m_syswrap/syswrap-linux-variants.c @@ -0,0 +1,91 @@ + +/*--------------------------------------------------------------------*/ +/*--- Handlers for syscalls on minor variants of Linux kernels. ---*/ +/*--- syswrap-linux-variants.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2000-2005 Julian Seward + jseward@acm.org + + 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. +*/ + +/* The files syswrap-generic.c, syswrap-linux.c, syswrap-x86-linux.c, + syswrap-amd64-linux.c and syswrap-ppc32-linux.c, and associated + vki*.h header files, constitute Valgrind's model of how a vanilla + Linux kernel behaves with respect to syscalls. + + On a few occasions, it is useful to run with a kernel that has some + (minor) extensions to the vanilla model, either due to running on a + hacked kernel, or using a vanilla kernel which has incorporated a + custom kernel module. Rather than clutter the standard model, all + such variant handlers are placed in here. + + Unlike the C files for the standard model, this file should also + contain all constants/types needed for said wrappers. The vki*.h + headers should not be polluted with non-vanilla info. */ + + +#include "pub_core_basics.h" +#include "pub_core_threadstate.h" +#include "pub_core_aspacemgr.h" +#include "pub_core_debuginfo.h" // VG_(di_notify_*) +#include "pub_core_transtab.h" // VG_(discard_translations) +#include "pub_core_debuglog.h" +#include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" +#include "pub_core_libcfile.h" +#include "pub_core_libcprint.h" +#include "pub_core_libcproc.h" +#include "pub_core_mallocfree.h" +#include "pub_core_tooliface.h" +#include "pub_core_options.h" +#include "pub_core_scheduler.h" +#include "pub_core_signals.h" +#include "pub_core_syscall.h" + +#include "priv_types_n_macros.h" +#include "priv_syswrap-linux-variants.h" + + +/* --------------------------------------------------------------- + BProc wrappers + ------------------------------------------------------------ */ + +/* Return 0 means hand to kernel, non-0 means fail w/ that value. */ +Int ML_(linux_variant_PRE_sys_bproc)( UWord arg1, UWord arg2, + UWord arg3, UWord arg4, + UWord arg5, UWord arg6 ) +{ + return 0; +} + +void ML_(linux_variant_POST_sys_bproc)( UWord arg1, UWord arg2, + UWord arg3, UWord arg4, + UWord arg5, UWord arg6 ) +{ +} + + +/*--------------------------------------------------------------------*/ +/*--- end syswrap-linux-variants.c ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index adb7d33e1c..0ce3db1fd2 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -55,6 +55,7 @@ #include "priv_types_n_macros.h" #include "priv_syswrap-generic.h" /* for decls of generic wrappers */ #include "priv_syswrap-linux.h" /* for decls of linux-ish wrappers */ +#include "priv_syswrap-linux-variants.h" /* decls of linux variant wrappers */ #include "priv_syswrap-main.h" #include "vki_unistd.h" /* for the __NR_* constants */ @@ -976,6 +977,7 @@ DECL_TEMPLATE(x86_linux, sys_get_thread_area); DECL_TEMPLATE(x86_linux, sys_ptrace); DECL_TEMPLATE(x86_linux, sys_sigaction); DECL_TEMPLATE(x86_linux, old_select); +DECL_TEMPLATE(x86_linux, sys_syscall223); PRE(old_select) { @@ -1876,6 +1878,41 @@ POST(sys_sigaction) POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction)); } + +/* --------------------------------------------------------------- + PRE/POST wrappers for x86/Linux-variant specific syscalls + ------------------------------------------------------------ */ + +PRE(sys_syscall223) +{ + Int err; + + /* 223 is used by sys_bproc. If we're not on a declared bproc + variant, fail in the usual way. */ + + if (!VG_(strstr)(VG_(clo_kernel_variant), "bproc")) { + PRINT("non-existent syscall! (syscall 223)"); + PRE_REG_READ0(long, "ni_syscall(223)"); + SET_STATUS_Failure( VKI_ENOSYS ); + return; + } + + err = ML_(linux_variant_PRE_sys_bproc)( ARG1, ARG2, ARG3, + ARG4, ARG5, ARG6 ); + if (err) { + SET_STATUS_Failure( err ); + return; + } + /* Let it go through. */ + *flags |= SfMayBlock; /* who knows? play safe. */ +} + +POST(sys_syscall223) +{ + ML_(linux_variant_POST_sys_bproc)( ARG1, ARG2, ARG3, + ARG4, ARG5, ARG6 ); +} + #undef PRE #undef POST @@ -2168,7 +2205,7 @@ const SyscallTableEntry ML_(syscall_table)[] = { GENXY(__NR_getdents64, sys_getdents64), // 220 GENXY(__NR_fcntl64, sys_fcntl64), // 221 GENX_(222, sys_ni_syscall), // 222 - GENX_(223, sys_ni_syscall), // 223 + PLAXY(223, sys_syscall223), // 223 // sys_bproc? LINX_(__NR_gettid, sys_gettid), // 224 //zz // (__NR_readahead, sys_readahead), // 225 */(Linux?) diff --git a/coregrind/pub_core_options.h b/coregrind/pub_core_options.h index a2e87fe430..67d8807259 100644 --- a/coregrind/pub_core_options.h +++ b/coregrind/pub_core_options.h @@ -163,8 +163,13 @@ typedef } VgSmc; +/* Describe extent to which self-modifying-code should be + auto-detected. */ extern VgSmc VG_(clo_smc_check); +/* String containing comma-separated names of minor kernel variants, + so they can be properly handled by m_syswrap. */ +extern HChar* VG_(clo_kernel_variant); #endif // __PUB_CORE_OPTIONS_H