blob: 15894e3999ea1d8a931dba4a6a5674a917e82ee0 [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
sewardj9eecbbb2010-05-03 21:37:12 +000010 Copyright (C) 2000-2010 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
sewardj85cf9002011-08-16 09:54:00 +000054 Finally there is the concept of behavioural equivalence tags. A
55 tag is a 4-digit decimal number (0001 to 9999) encoded in the name.
56 If two replacement functions have the same tag then the redirect
57 mechanism will assume that they have identical behaviour. If, when
58 processing redirections at library load time, the set of available
59 specifications yields more than one replacement or wrapper function
60 for a given address, the system will try to resolve the situation
61 by examining the tags on the replacements/wrappers. In particular,
62 if all of them have the same tag, then they are all claiming to
63 behave identically, so any of them may be chosen to be the actual
64 redirection target. Of course if not all of them have the same tag
65 then the redirection is ambiguous and the system will have to stop.
66
67 The tag is mandatory and must comprise 4 decimal digits. The tag
68 0000 is special and means "does not have behaviour identical to any
69 other replacement/wrapper function". Hence if you wish to write a
70 wrap/replacement function that is not subject to the above
71 resolution rules, use 0000 for the tag.
72
73
sewardj0ec07f32006-01-12 12:32:32 +000074 Replacement
75 ~~~~~~~~~~~
76 To write a replacement function, do this:
77
78 ret_type
79 VG_REPLACE_FUNCTION_ZU(zEncodedSoname,fnname) ( .. args .. )
njn16eeb4e2005-06-16 03:56:58 +000080 {
81 ... body ...
82 }
83
sewardj85cf9002011-08-16 09:54:00 +000084 zEncodedSoname should be a Z-encoded soname (see below for
85 Z-encoding details) and fnname should be an unencoded fn name. A
86 default-safe equivalence tag of 0000 is assumed (see comments
87 above). The resulting name is
njn16eeb4e2005-06-16 03:56:58 +000088
sewardj85cf9002011-08-16 09:54:00 +000089 _vgr0000ZU_zEncodedSoname_fnname
njn16eeb4e2005-06-16 03:56:58 +000090
sewardj85cf9002011-08-16 09:54:00 +000091 The "_vgr0000ZU_" is a prefix that gets discarded upon decoding.
92 It identifies this function as a replacement and specifies its
93 equivalence tag.
sewardj0ec07f32006-01-12 12:32:32 +000094
95 It is also possible to write
96
97 ret_type
98 VG_REPLACE_FUNCTION_ZZ(zEncodedSoname,zEncodedFnname) ( .. args .. )
99 {
100 ... body ...
101 }
njn16eeb4e2005-06-16 03:56:58 +0000102
sewardj0ec07f32006-01-12 12:32:32 +0000103 which means precisely the same, but the function name is also
104 Z-encoded. This can sometimes be necessary. In this case the
105 resulting function name is
106
sewardj85cf9002011-08-16 09:54:00 +0000107 _vgr0000ZZ_zEncodedSoname_zEncodedFnname
sewardj0ec07f32006-01-12 12:32:32 +0000108
109 When it sees this either such name, the core's symbol-table reading
110 machinery and redirection machinery first Z-decode the soname and
111 if necessary the fnname. They are encoded so that they may include
112 arbitrary characters, and in particular they may contain '*', which
113 acts as a wildcard.
114
115 They then will conspire to cause calls to any function matching
116 'fnname' in any object whose soname matches 'soname' to actually be
117 routed to this function. This is used in Valgrind to define dozens
118 of replacements of malloc, free, etc.
njn16eeb4e2005-06-16 03:56:58 +0000119
120 The soname must be a Z-encoded bit of text because sonames can
sewardj0ec07f32006-01-12 12:32:32 +0000121 contain dots etc which are not valid symbol names. The function
122 name may or may not be Z-encoded: to include wildcards it has to be,
123 but Z-encoding C++ function names which are themselves already mangled
124 using Zs in some way is tedious and error prone, so the _ZU variant
125 allows them not to be Z-encoded.
njn16eeb4e2005-06-16 03:56:58 +0000126
sewardj0ec07f32006-01-12 12:32:32 +0000127 Note that the soname "NONE" is specially interpreted to match any
128 shared object which doesn't have a soname.
njn16eeb4e2005-06-16 03:56:58 +0000129
130 Note also that the replacement function should probably (must be?) in
131 client space, so it runs on the simulated CPU. So it must be in
njn7b4e5ba2005-08-25 22:53:57 +0000132 either vgpreload_<tool>.so or vgpreload_core.so. It also only works
133 with functions in shared objects, I think.
njn16eeb4e2005-06-16 03:56:58 +0000134
sewardj0ec07f32006-01-12 12:32:32 +0000135 It is important that the Z-encoded names contain no unencoded
136 underscores, since the intercept-handlers in m_redir.c detect the
137 end of the soname by looking for the first trailing underscore.
njn16eeb4e2005-06-16 03:56:58 +0000138
sewardj85cf9002011-08-16 09:54:00 +0000139 To write function names which explicitly state the equivalence class
140 tag, use
141 VG_REPLACE_FUNCTION_EZU(4-digit-tag,zEncodedSoname,fnname)
142 or
143 VG_REPLACE_FUNCTION_EZZ(4-digit-tag,zEncodedSoname,zEncodedFnname)
144
145 As per comments above, the tag must be a 4 digit decimal number,
146 padded with leading zeroes, in the range 0001 to 9999 inclusive.
147
148
sewardj0ec07f32006-01-12 12:32:32 +0000149 Wrapping
150 ~~~~~~~~
151 This is identical to replacement, except that you should use the
152 macro names
njn16eeb4e2005-06-16 03:56:58 +0000153
sewardj0ec07f32006-01-12 12:32:32 +0000154 VG_WRAP_FUNCTION_ZU
155 VG_WRAP_FUNCTION_ZZ
sewardj85cf9002011-08-16 09:54:00 +0000156 VG_WRAP_FUNCTION_EZU
157 VG_WRAP_FUNCTION_EZZ
sewardj0ec07f32006-01-12 12:32:32 +0000158
159 instead.
160
161 Z-encoding
162 ~~~~~~~~~~
163 Z-encoding details: the scheme is like GHC's. It is just about
164 readable enough to make a preprocessor unnecessary. First the
165 "_vgrZU_" or "_vgrZZ_" prefix is added, and then the following
166 characters are transformed.
167
168 * --> Za (asterisk)
sewardj0ec07f32006-01-12 12:32:32 +0000169 : --> Zc (colon)
170 . --> Zd (dot)
sewardj0ec07f32006-01-12 12:32:32 +0000171 - --> Zh (hyphen)
sewardj578b1712009-07-26 19:41:07 +0000172 + --> Zp (plus)
sewardj0ec07f32006-01-12 12:32:32 +0000173 (space) --> Zs (space)
sewardj578b1712009-07-26 19:41:07 +0000174 _ --> Zu (underscore)
sewardj6b9cc872006-10-17 01:39:30 +0000175 @ --> ZA (at)
sewardj578b1712009-07-26 19:41:07 +0000176 $ --> ZD (dollar)
sewardj6b9cc872006-10-17 01:39:30 +0000177 ( --> ZL (left)
178 ) --> ZR (right)
sewardj578b1712009-07-26 19:41:07 +0000179 Z --> ZZ (Z)
njn16eeb4e2005-06-16 03:56:58 +0000180
181 Everything else is left unchanged.
182*/
183
sewardj0ec07f32006-01-12 12:32:32 +0000184/* If you change these, the code in VG_(maybe_Z_demangle) needs to be
185 changed accordingly. NOTE: duplicates
186 I_{WRAP,REPLACE}_SONAME_FNNAME_Z{U,Z} in valgrind.h. */
187
sewardj6b9cc872006-10-17 01:39:30 +0000188/* Use an extra level of macroisation so as to ensure the soname/fnname
189 args are fully macro-expanded before pasting them together. */
190#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
sewardj0ec07f32006-01-12 12:32:32 +0000191
sewardj85cf9002011-08-16 09:54:00 +0000192#define VG_CONCAT6(_aa,_bb,_cc,_dd,_ee,_ff) _aa##_bb##_cc##_dd##_ee##_ff
sewardj6b9cc872006-10-17 01:39:30 +0000193
sewardj85cf9002011-08-16 09:54:00 +0000194/* The 4 basic macros. */
195#define VG_REPLACE_FUNCTION_EZU(_eclasstag,_soname,_fnname) \
196 VG_CONCAT6(_vgr,_eclasstag,ZU_,_soname,_,_fnname)
197
198#define VG_REPLACE_FUNCTION_EZZ(_eclasstag,_soname,_fnname) \
199 VG_CONCAT6(_vgr,_eclasstag,ZZ_,_soname,_,_fnname)
200
201#define VG_WRAP_FUNCTION_EZU(_eclasstag,_soname,_fnname) \
202 VG_CONCAT6(_vgw,_eclasstag,ZU_,_soname,_,_fnname)
203
204#define VG_WRAP_FUNCTION_EZZ(_eclasstag,_soname,_fnname) \
205 VG_CONCAT6(_vgw,_eclasstag,ZZ_,_soname,_,_fnname)
206
207/* Convenience macros defined in terms of the above 4. */
208#define VG_REPLACE_FUNCTION_ZU(_soname,_fnname) \
209 VG_CONCAT6(_vgr,0000,ZU_,_soname,_,_fnname)
210
211#define VG_REPLACE_FUNCTION_ZZ(_soname,_fnname) \
212 VG_CONCAT6(_vgr,0000,ZZ_,_soname,_,_fnname)
213
214#define VG_WRAP_FUNCTION_ZU(_soname,_fnname) \
215 VG_CONCAT6(_vgw,0000,ZU_,_soname,_,_fnname)
216
217#define VG_WRAP_FUNCTION_ZZ(_soname,_fnname) \
218 VG_CONCAT6(_vgw,0000,ZZ_,_soname,_,_fnname)
219
sewardj6b9cc872006-10-17 01:39:30 +0000220
njne6154662009-02-10 04:23:41 +0000221/* --------- Some handy Z-encoded names. --------- */
222
njnb4cfbc42009-05-04 04:20:02 +0000223// Nb: ALL THESE NAMES MUST BEGIN WITH "VG_Z_". Why? If we applied
224// conditional compilation inconsistently we could accidentally use an
225// undefined constant like VG_Z_LIBC_DOT_A, resulting in a bogus Z-encoded
226// name like "_vgrZU_VG_Z_LIBC_DOT_A_foo". This can't be detected at
227// compile-time, because both the constant's name and its value are
228// identifiers. However, by always using "VG_Z_" as a prefix, we can do a
229// run-time check and abort if any name has "VG_Z_" in it, because that
230// indicates that the constant has been used without being defined.
231
njne6154662009-02-10 04:23:41 +0000232/* --- Soname of the standard C library. --- */
233
234#if defined(VGO_linux)
235# define VG_Z_LIBC_SONAME libcZdsoZa // libc.so*
njnf76d27a2009-05-28 01:53:07 +0000236#elif defined(VGO_darwin)
237# define VG_Z_LIBC_SONAME libSystemZdZaZddylib // libSystem.*.dylib
njne6154662009-02-10 04:23:41 +0000238#else
239# error "Unknown platform"
240#endif
241
242/* --- Soname of the GNU C++ library. --- */
243
njnb4cfbc42009-05-04 04:20:02 +0000244// Valid on all platforms(?)
njne6154662009-02-10 04:23:41 +0000245#define VG_Z_LIBSTDCXX_SONAME libstdcZpZpZa // libstdc++*
246
njn5f5ef2a2009-05-11 08:01:09 +0000247/* --- Soname of the pthreads library. --- */
248
sewardj6e9de462011-06-28 07:25:29 +0000249#if defined(VGO_linux)
njn5f5ef2a2009-05-11 08:01:09 +0000250# define VG_Z_LIBPTHREAD_SONAME libpthreadZdsoZd0 // libpthread.so.0
njnf76d27a2009-05-28 01:53:07 +0000251#elif defined(VGO_darwin)
252# define VG_Z_LIBPTHREAD_SONAME libSystemZdZaZddylib // libSystem.*.dylib
njn5f5ef2a2009-05-11 08:01:09 +0000253#else
254# error "Unknown platform"
255#endif
256
sewardja0eee322009-07-31 08:46:35 +0000257/* --- Sonames for Linux ELF linkers, plus unencoded versions. --- */
njne6154662009-02-10 04:23:41 +0000258
njnb4cfbc42009-05-04 04:20:02 +0000259#if defined(VGO_linux)
sewardja0eee322009-07-31 08:46:35 +0000260
sewardj651cfa42010-01-11 13:02:19 +0000261#define VG_Z_LD_LINUX_SO_3 ldZhlinuxZdsoZd3 // ld-linux.so.3
262#define VG_U_LD_LINUX_SO_3 "ld-linux.so.3"
263
njne6154662009-02-10 04:23:41 +0000264#define VG_Z_LD_LINUX_SO_2 ldZhlinuxZdsoZd2 // ld-linux.so.2
sewardja0eee322009-07-31 08:46:35 +0000265#define VG_U_LD_LINUX_SO_2 "ld-linux.so.2"
266
njne6154662009-02-10 04:23:41 +0000267#define VG_Z_LD_LINUX_X86_64_SO_2 ldZhlinuxZhx86Zh64ZdsoZd2 // ld-linux-x86-64.so.2
sewardja0eee322009-07-31 08:46:35 +0000268#define VG_U_LD_LINUX_X86_64_SO_2 "ld-linux-x86-64.so.2"
269
njne6154662009-02-10 04:23:41 +0000270#define VG_Z_LD64_SO_1 ld64ZdsoZd1 // ld64.so.1
sewardja0eee322009-07-31 08:46:35 +0000271#define VG_U_LD64_SO_1 "ld64.so.1"
272
njne6154662009-02-10 04:23:41 +0000273#define VG_Z_LD_SO_1 ldZdsoZd1 // ld.so.1
sewardja0eee322009-07-31 08:46:35 +0000274#define VG_U_LD_SO_1 "ld.so.1"
275
njnb4cfbc42009-05-04 04:20:02 +0000276#endif
njn16eeb4e2005-06-16 03:56:58 +0000277
njnf76d27a2009-05-28 01:53:07 +0000278/* --- Executable name for Darwin Mach-O linker. --- */
279
280#if defined(VGO_darwin)
sewardja0eee322009-07-31 08:46:35 +0000281
njnf76d27a2009-05-28 01:53:07 +0000282#define VG_Z_DYLD dyld // dyld
sewardja0eee322009-07-31 08:46:35 +0000283#define VG_U_DYLD "dyld"
284
njnf76d27a2009-05-28 01:53:07 +0000285#endif
286
287
njn4a164d02005-06-18 18:49:40 +0000288#endif // __PUB_TOOL_REDIR_H
njn16eeb4e2005-06-16 03:56:58 +0000289
290/*--------------------------------------------------------------------*/
291/*--- end ---*/
292/*--------------------------------------------------------------------*/