mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-12 06:11:37 +00:00
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:
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
1042
include/valgrind.h
1042
include/valgrind.h
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user