| |
| /*--------------------------------------------------------------------*/ |
| /*--- 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 "vg_include.h" |
| #include <unistd.h> |
| #include <signal.h> |
| |
| 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 ---*/ |
| /*--------------------------------------------------------------------*/ |
| |