blob: 71fb7deb1a6668a34cb13e4d733a24f335648bc0 [file] [log] [blame]
/*--------------------------------------------------------------------*/
/*--- 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 ---*/
/*--------------------------------------------------------------------*/