/*--------------------------------------------------------------------*/ /*--- Intercepts for various libc functions we want to capture ---*/ /*--- (mostly for threading purposes). vg_intercept.c ---*/ /*--------------------------------------------------------------------*/ /* This file is part of Valgrind, an extensible x86 protected-mode emulator for monitoring program execution on x86-Unixes. Copyright (C) 2000-2004 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. */ /* --------------------------------------------------------------------- ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU. It is intended for various reasons as drop-in replacements for libc functions. These functions are not called directly - they're the targets of code redirection. They're named weirdly so that the intercept code can find them when the shared object is initially loaded. ------------------------------------------------------------------ */ /* The gory details: Symbols in this file are mangled by a preprocessor to produce a special symbol name. All symbols that need this handling should be passed to a special VG_INTERCEPT macro. This macro takes two arguments: a library name and a function name. These specify the function and the library that contains it that we need to intercept. For example: int VG_INTERCEPT(soname:libc.so.6, raise)(int sig) { ... } This example says that the "raise" function in the shared object libc.so.6 should be intercepted and redirected to the following piece of code. Internally, what's happening here is that this intercept gets turned into a special magic symbol name, with the ':' and '.' parts replaced by escapes, and a special prefix stuck on front. When we slurp in an object file, we scan the symbol table for the magic prefixes, demangle any symbols found and set up the intercepts that way. This is the safest way to do this, because we're not relying on intercepts being set up by code that may be called after other code that need the intercepts has had a chance to run. */ #include "valgrind.h" #include "core.h" #include #include int VG_INTERCEPT(soname:libc.so.6, raise)(int sig) { return kill(getpid(), sig); } int VG_INTERCEPT(soname:libc.so.6, __libc_raise)(int) __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, raise)), visibility("protected"))); int VG_INTERCEPT(soname:libc.so.6, __GI_raise)(int) __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, raise)), visibility("protected"))); int VG_INTERCEPT(soname:libc.so.6, __raise)(int) __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, raise)), visibility("protected"))); /* Don't alias, so there's no chance that "gsignal" will appear in a message instead of "raise" */ int VG_INTERCEPT(soname:libc.so.6, gsignal)(int sig) { return VG_INTERCEPT(soname:libc.so.6, raise)(sig); } int VG_INTERCEPT(soname:libc.so.6, __libc_gsignal)(int) __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, gsignal)), visibility("protected"))); int VG_INTERCEPT(soname:libc.so.6, __GI_gsignal)(int) __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, gsignal)), visibility("protected"))); int VG_INTERCEPT(soname:libc.so.6, __gsignal)(int) __attribute__((alias(VG_INTERCEPT_ALIAS(soname:libc.so.6, gsignal)), visibility("protected"))); /* --------------------------------------------------------------------- Hook for running __libc_freeres once the program exits. ------------------------------------------------------------------ */ void VG_WRAPPER(freeres)( void ) { int res; #ifndef __UCLIBC__ extern void __libc_freeres(void); __libc_freeres(); #endif VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, VG_USERREQ__LIBC_FREERES_DONE, 0, 0, 0, 0); /*NOTREACHED*/ *(int *)0 = 'x'; } /*--------------------------------------------------------------------*/ /*--- end vg_intercept.c ---*/ /*--------------------------------------------------------------------*/