blob: 21f3c30ab85e942346a220365df0a47df98e0040 [file] [log] [blame]
njn16eeb4e2005-06-16 03:56:58 +00001
2/*--------------------------------------------------------------------*/
3/*--- Redirections, etc. pub_tool_redir.h ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
sewardje4b0bf02006-06-05 23:21:15 +000010 Copyright (C) 2000-2006 Julian Seward
njn16eeb4e2005-06-16 03:56:58 +000011 jseward@acm.org
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
njn4a164d02005-06-18 18:49:40 +000031#ifndef __PUB_TOOL_REDIR_H
32#define __PUB_TOOL_REDIR_H
njn16eeb4e2005-06-16 03:56:58 +000033
sewardj0ec07f32006-01-12 12:32:32 +000034/* The following macros facilitate function replacement and wrapping.
njn16eeb4e2005-06-16 03:56:58 +000035
sewardj0ec07f32006-01-12 12:32:32 +000036 Function wrapping and function replacement are similar but not
37 identical.
njn16eeb4e2005-06-16 03:56:58 +000038
sewardj0ec07f32006-01-12 12:32:32 +000039 A replacement for some function F simply diverts all calls to F
40 to the stated replacement. There is no way to get back to F itself
41 from the replacement.
42
43 A wrapper for a function F causes all calls to F to instead go to
44 the wrapper. However, from inside the wrapper, it is possible
45 (with some difficulty) to get to F itself.
46
47 You may notice that replacement is a special case of wrapping, in
48 which the call to the original is omitted. For implementation
49 reasons, though, it is important to use the following macros
50 correctly: in particular, if you want to write a replacement, make
51 sure you use the VG_REPLACE_FN_ macros and not the VG_WRAP_FN_
52 macros.
53
54 Replacement
55 ~~~~~~~~~~~
56 To write a replacement function, do this:
57
58 ret_type
59 VG_REPLACE_FUNCTION_ZU(zEncodedSoname,fnname) ( .. args .. )
njn16eeb4e2005-06-16 03:56:58 +000060 {
61 ... body ...
62 }
63
64 zEncodedSoname should be a Z-encoded soname (see below for Z-encoding
65 details) and fnname should be an unencoded fn name. The resulting name is
66
sewardj0ec07f32006-01-12 12:32:32 +000067 _vgrZU_zEncodedSoname_fnname
njn16eeb4e2005-06-16 03:56:58 +000068
sewardj0ec07f32006-01-12 12:32:32 +000069 The "_vgrZU_" is a prefix that gets discarded upon decoding.
70
71 It is also possible to write
72
73 ret_type
74 VG_REPLACE_FUNCTION_ZZ(zEncodedSoname,zEncodedFnname) ( .. args .. )
75 {
76 ... body ...
77 }
njn16eeb4e2005-06-16 03:56:58 +000078
sewardj0ec07f32006-01-12 12:32:32 +000079 which means precisely the same, but the function name is also
80 Z-encoded. This can sometimes be necessary. In this case the
81 resulting function name is
82
83 _vgrZZ_zEncodedSoname_zEncodedFnname
84
85 When it sees this either such name, the core's symbol-table reading
86 machinery and redirection machinery first Z-decode the soname and
87 if necessary the fnname. They are encoded so that they may include
88 arbitrary characters, and in particular they may contain '*', which
89 acts as a wildcard.
90
91 They then will conspire to cause calls to any function matching
92 'fnname' in any object whose soname matches 'soname' to actually be
93 routed to this function. This is used in Valgrind to define dozens
94 of replacements of malloc, free, etc.
njn16eeb4e2005-06-16 03:56:58 +000095
96 The soname must be a Z-encoded bit of text because sonames can
sewardj0ec07f32006-01-12 12:32:32 +000097 contain dots etc which are not valid symbol names. The function
98 name may or may not be Z-encoded: to include wildcards it has to be,
99 but Z-encoding C++ function names which are themselves already mangled
100 using Zs in some way is tedious and error prone, so the _ZU variant
101 allows them not to be Z-encoded.
njn16eeb4e2005-06-16 03:56:58 +0000102
sewardj0ec07f32006-01-12 12:32:32 +0000103 Note that the soname "NONE" is specially interpreted to match any
104 shared object which doesn't have a soname.
njn16eeb4e2005-06-16 03:56:58 +0000105
106 Note also that the replacement function should probably (must be?) in
107 client space, so it runs on the simulated CPU. So it must be in
njn7b4e5ba2005-08-25 22:53:57 +0000108 either vgpreload_<tool>.so or vgpreload_core.so. It also only works
109 with functions in shared objects, I think.
njn16eeb4e2005-06-16 03:56:58 +0000110
sewardj0ec07f32006-01-12 12:32:32 +0000111 It is important that the Z-encoded names contain no unencoded
112 underscores, since the intercept-handlers in m_redir.c detect the
113 end of the soname by looking for the first trailing underscore.
njn16eeb4e2005-06-16 03:56:58 +0000114
sewardj0ec07f32006-01-12 12:32:32 +0000115 Wrapping
116 ~~~~~~~~
117 This is identical to replacement, except that you should use the
118 macro names
njn16eeb4e2005-06-16 03:56:58 +0000119
sewardj0ec07f32006-01-12 12:32:32 +0000120 VG_WRAP_FUNCTION_ZU
121 VG_WRAP_FUNCTION_ZZ
122
123 instead.
124
125 Z-encoding
126 ~~~~~~~~~~
127 Z-encoding details: the scheme is like GHC's. It is just about
128 readable enough to make a preprocessor unnecessary. First the
129 "_vgrZU_" or "_vgrZZ_" prefix is added, and then the following
130 characters are transformed.
131
132 * --> Za (asterisk)
133 + --> Zp (plus)
134 : --> Zc (colon)
135 . --> Zd (dot)
136 _ --> Zu (underscore)
137 - --> Zh (hyphen)
138 (space) --> Zs (space)
sewardj6b9cc872006-10-17 01:39:30 +0000139 @ --> ZA (at)
sewardj0ec07f32006-01-12 12:32:32 +0000140 Z --> ZZ (Z)
sewardj6b9cc872006-10-17 01:39:30 +0000141 ( --> ZL (left)
142 ) --> ZR (right)
njn16eeb4e2005-06-16 03:56:58 +0000143
144 Everything else is left unchanged.
145*/
146
sewardj0ec07f32006-01-12 12:32:32 +0000147/* If you change these, the code in VG_(maybe_Z_demangle) needs to be
148 changed accordingly. NOTE: duplicates
149 I_{WRAP,REPLACE}_SONAME_FNNAME_Z{U,Z} in valgrind.h. */
150
sewardj6b9cc872006-10-17 01:39:30 +0000151/* Use an extra level of macroisation so as to ensure the soname/fnname
152 args are fully macro-expanded before pasting them together. */
153#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
sewardj0ec07f32006-01-12 12:32:32 +0000154
sewardj6b9cc872006-10-17 01:39:30 +0000155#define VG_REPLACE_FUNCTION_ZU(soname,fnname) VG_CONCAT4(_vgrZU_,soname,_,fnname)
156#define VG_REPLACE_FUNCTION_ZZ(soname,fnname) VG_CONCAT4(_vgrZZ_,soname,_,fnname)
157
158#define VG_WRAP_FUNCTION_ZU(soname,fnname) VG_CONCAT4(_vgwZU_,soname,_,fnname)
159#define VG_WRAP_FUNCTION_ZZ(soname,fnname) VG_CONCAT4(_vgwZZ_,soname,_,fnname)
160
njn16eeb4e2005-06-16 03:56:58 +0000161
njn4a164d02005-06-18 18:49:40 +0000162#endif // __PUB_TOOL_REDIR_H
njn16eeb4e2005-06-16 03:56:58 +0000163
164/*--------------------------------------------------------------------*/
165/*--- end ---*/
166/*--------------------------------------------------------------------*/