Merge in function wrapping support from the FNWRAP branch. That

branch hereby becomes inactive.  This currently breaks everything
except x86; fixes for amd64/ppc32 to follow.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5520
This commit is contained in:
Julian Seward
2006-01-12 12:32:32 +00:00
parent 5777709dc1
commit f9a9e03c7a
56 changed files with 3492 additions and 1348 deletions

View File

@@ -102,13 +102,29 @@ typedef struct _SegInfo SegInfo;
is present or not. */
extern SegInfo* VG_(find_seginfo) ( Addr a );
extern const SegInfo* VG_(next_seginfo) ( const SegInfo *si );
/* Fish bits out of SegInfos. */
extern Addr VG_(seginfo_start) ( const SegInfo *si );
extern SizeT VG_(seginfo_size) ( const SegInfo *si );
extern const UChar* VG_(seginfo_soname) ( const SegInfo *si );
extern const UChar* VG_(seginfo_filename) ( const SegInfo *si );
extern ULong VG_(seginfo_sym_offset)( const SegInfo *si );
/* Function for traversing the seginfo list. When called with NULL it
returns the first element; otherwise it returns the given element's
successor. */
extern const SegInfo* VG_(next_seginfo) ( const SegInfo *si );
/* Functions for traversing all the symbols in a SegInfo. _howmany
tells how many there are. _getidx retrieves the n'th, for n in 0
.. _howmany-1. You may not modify the function name thereby
acquired; if you want to do so, first strdup it. */
extern Int VG_(seginfo_syms_howmany) ( const SegInfo *si );
extern void VG_(seginfo_syms_getidx) ( const SegInfo *si,
Int idx,
/*OUT*/Addr* addr,
/*OUT*/UInt* size,
/*OUT*/HChar** name );
typedef
enum {
Vg_SectUnknown,

View File

@@ -34,13 +34,13 @@
#if defined(VGA_x86)
# define VG_MIN_INSTR_SZB 1 // min length of native instruction
# define VG_MAX_INSTR_SZB 16 // max length of native instruction
# define VG_CLREQ_SZB 18 // length of a client request, may
# define VG_CLREQ_SZB 14 // length of a client request, may
// be larger than VG_MAX_INSTR_SZB
# define VG_STACK_REDZONE_SZB 0 // number of addressable bytes below %RSP
#elif defined(VGA_amd64)
# define VG_MIN_INSTR_SZB 1
# define VG_MAX_INSTR_SZB 16
# define VG_CLREQ_SZB 18
# define VG_CLREQ_SZB 19
# define VG_STACK_REDZONE_SZB 128
#elif defined(VGA_ppc32)
# define VG_MIN_INSTR_SZB 4

View File

@@ -31,12 +31,32 @@
#ifndef __PUB_TOOL_REDIR_H
#define __PUB_TOOL_REDIR_H
/* The following macros facilitate function replacement, which is one form
of code replacement.
/* The following macros facilitate function replacement and wrapping.
The general idea is: you can write a function like this:
Function wrapping and function replacement are similar but not
identical.
ret_type VG_REPLACE_FUNCTION(zEncodedSoname, fnname) ( ... args ... )
A replacement for some function F simply diverts all calls to F
to the stated replacement. There is no way to get back to F itself
from the replacement.
A wrapper for a function F causes all calls to F to instead go to
the wrapper. However, from inside the wrapper, it is possible
(with some difficulty) to get to F itself.
You may notice that replacement is a special case of wrapping, in
which the call to the original is omitted. For implementation
reasons, though, it is important to use the following macros
correctly: in particular, if you want to write a replacement, make
sure you use the VG_REPLACE_FN_ macros and not the VG_WRAP_FN_
macros.
Replacement
~~~~~~~~~~~
To write a replacement function, do this:
ret_type
VG_REPLACE_FUNCTION_ZU(zEncodedSoname,fnname) ( .. args .. )
{
... body ...
}
@@ -44,52 +64,93 @@
zEncodedSoname should be a Z-encoded soname (see below for Z-encoding
details) and fnname should be an unencoded fn name. The resulting name is
_vgi_zEncodedSoname_fnname
_vgrZU_zEncodedSoname_fnname
The "_vgi_" is a prefix that gets discarded upon decoding.
The "_vgrZU_" is a prefix that gets discarded upon decoding.
It is also possible to write
ret_type
VG_REPLACE_FUNCTION_ZZ(zEncodedSoname,zEncodedFnname) ( .. args .. )
{
... body ...
}
When it sees this name, the core's symbol-table reading machinery
and redirection machinery will conspire to cause calls to the function
'fnname' in object with soname 'zEncodedSoname' to actually be routed to
the function written here. We use this below to define dozens of
replacements of malloc, free, etc.
which means precisely the same, but the function name is also
Z-encoded. This can sometimes be necessary. In this case the
resulting function name is
_vgrZZ_zEncodedSoname_zEncodedFnname
When it sees this either such name, the core's symbol-table reading
machinery and redirection machinery first Z-decode the soname and
if necessary the fnname. They are encoded so that they may include
arbitrary characters, and in particular they may contain '*', which
acts as a wildcard.
They then will conspire to cause calls to any function matching
'fnname' in any object whose soname matches 'soname' to actually be
routed to this function. This is used in Valgrind to define dozens
of replacements of malloc, free, etc.
The soname must be a Z-encoded bit of text because sonames can
contain dots etc which are not valid symbol names. But don't Z-encode
the function name, since it will already be a valid symbol name, and the
Z-encoding might screw up the C++ demangling.
contain dots etc which are not valid symbol names. The function
name may or may not be Z-encoded: to include wildcards it has to be,
but Z-encoding C++ function names which are themselves already mangled
using Zs in some way is tedious and error prone, so the _ZU variant
allows them not to be Z-encoded.
Note that the soname can contain '*' as a wildcard meaning "match
anything".
Note that the soname "NONE" is specially interpreted to match any
shared object which doesn't have a soname.
Note also that the replacement function should probably (must be?) in
client space, so it runs on the simulated CPU. So it must be in
either vgpreload_<tool>.so or vgpreload_core.so. It also only works
with functions in shared objects, I think.
It is important that the Z-encoded soname contains no unencoded
underscores, since the intercept-handlers in vg_symtab2.c detect
the end of the soname by looking for the first trailing underscore.
It is important that the Z-encoded names contain no unencoded
underscores, since the intercept-handlers in m_redir.c detect the
end of the soname by looking for the first trailing underscore.
Z-encoding details: the scheme is like GHC's. It is just about
readable enough to make a preprocessor unnecessary. First the "_vgi_"
prefix is added, and then the following characters are transformed.
Wrapping
~~~~~~~~
This is identical to replacement, except that you should use the
macro names
* --> Za ('a' for "asterisk")
+ --> Zp
: --> Zc
. --> Zd
_ --> Zu
- --> Zh ('h' for "hyphen")
(space) --> Zs
Z --> ZZ
VG_WRAP_FUNCTION_ZU
VG_WRAP_FUNCTION_ZZ
instead.
Z-encoding
~~~~~~~~~~
Z-encoding details: the scheme is like GHC's. It is just about
readable enough to make a preprocessor unnecessary. First the
"_vgrZU_" or "_vgrZZ_" prefix is added, and then the following
characters are transformed.
* --> Za (asterisk)
+ --> Zp (plus)
: --> Zc (colon)
. --> Zd (dot)
_ --> Zu (underscore)
- --> Zh (hyphen)
(space) --> Zs (space)
@ -> ZA (at)
Z --> ZZ (Z)
Everything else is left unchanged.
*/
#define VG_REPLACE_FUNCTION(soname, fnname) _vgi_##soname##_##fnname
#define VG_REPLACE_FUNCTION_PREFIX "_vgi_"
#define VG_REPLACE_FUNCTION_PREFIX_LEN 5
/* If you change these, the code in VG_(maybe_Z_demangle) needs to be
changed accordingly. NOTE: duplicates
I_{WRAP,REPLACE}_SONAME_FNNAME_Z{U,Z} in valgrind.h. */
#define VG_REPLACE_FUNCTION_ZU(soname,fnname) _vgrZU_##soname##_##fnname
#define VG_REPLACE_FUNCTION_ZZ(soname,fnname) _vgrZZ_##soname##_##fnname
#define VG_WRAP_FUNCTION_ZU(soname,fnname) _vgwZU_##soname##_##fnname
#define VG_WRAP_FUNCTION_ZZ(soname,fnname) _vgwZZ_##soname##_##fnname
#endif // __PUB_TOOL_REDIR_H

File diff suppressed because it is too large Load Diff