1 
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 
10    Copyright (C) 2000-2013 Julian Seward
11       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 
31 #ifndef __PUB_TOOL_REDIR_H
32 #define __PUB_TOOL_REDIR_H
33 
34 #include "config.h"           /* DARWIN_VERS */
35 
36 /* The following macros facilitate function replacement and wrapping.
37 
38    Function wrapping and function replacement are similar but not
39    identical.
40 
41    A replacement for some function F simply diverts all calls to F
42    to the stated replacement.  There is no way to get back to F itself
43    from the replacement.
44 
45    A wrapper for a function F causes all calls to F to instead go to
46    the wrapper.  However, from inside the wrapper, it is possible
47    (with some difficulty) to get to F itself.
48 
49    You may notice that replacement is a special case of wrapping, in
50    which the call to the original is omitted.  For implementation
51    reasons, though, it is important to use the following macros
52    correctly: in particular, if you want to write a replacement, make
53    sure you use the VG_REPLACE_FN_ macros and not the VG_WRAP_FN_
54    macros.
55 
56    Finally there is the concept of prioritised behavioural equivalence
57    tags.  A tag is a 5-digit decimal number (00000 to 99999) encoded
58    in the name.  The top 4 digits are the equivalence class number,
59    and the last digit is a priority.
60 
61    When processing redirections at library load time, if the set of
62    available specifications yields more than one replacement or
63    wrapper function for a given address, the system will try to
64    resolve the situation by examining the tags on the
65    replacements/wrappers.
66 
67    If two replacement/wrapper functions have the same tag and
68    priority, then the redirection machinery will assume they have
69    identical behaviour and can choose between them arbitrarily.  If
70    they have the same tag but different priorities, then the one with
71    higher priority will be chosen.  If neither case holds, then the
72    redirection is ambiguous and the system will ignore one of them
73    arbitrarily, but print a warning when running at -v or above.
74 
75    The tag is mandatory and must comprise 5 decimal digits.  The tag
76    00000 is special and means "does not have behaviour identical to any
77    other replacement/wrapper function".  Hence if you wish to write a
78    wrap/replacement function that is not subject to the above
79    resolution rules, use 00000 for the tag.  Tags 00001 through 00009
80    may not be used for any purpose.
81 
82 
83    Replacement
84    ~~~~~~~~~~~
85    To write a replacement function, do this:
86 
87       ret_type
88       VG_REPLACE_FUNCTION_ZU(zEncodedSoname,fnname) ( .. args .. )
89       {
90          ... body ...
91       }
92 
93    zEncodedSoname should be a Z-encoded soname (see below for
94    Z-encoding details) and fnname should be an unencoded fn name.  A
95    default-safe equivalence tag of 00000 is assumed (see comments
96    above).  The resulting name is
97 
98       _vgr00000ZU_zEncodedSoname_fnname
99 
100    The "_vgr00000ZU_" is a prefix that gets discarded upon decoding.
101    It identifies this function as a replacement and specifies its
102    equivalence tag.
103 
104    It is also possible to write
105 
106       ret_type
107       VG_REPLACE_FUNCTION_ZZ(zEncodedSoname,zEncodedFnname) ( .. args .. )
108       {
109          ... body ...
110       }
111 
112    which means precisely the same, but the function name is also
113    Z-encoded.  This can sometimes be necessary.  In this case the
114    resulting function name is
115 
116       _vgr00000ZZ_zEncodedSoname_zEncodedFnname
117 
118    When it sees this either such name, the core's symbol-table reading
119    machinery and redirection machinery first Z-decode the soname and
120    if necessary the fnname.  They are encoded so that they may include
121    arbitrary characters, and in particular they may contain '*', which
122    acts as a wildcard.
123 
124    They then will conspire to cause calls to any function matching
125    'fnname' in any object whose soname matches 'soname' to actually be
126    routed to this function.  This is used in Valgrind to define dozens
127    of replacements of malloc, free, etc.
128 
129    The soname must be a Z-encoded bit of text because sonames can
130    contain dots etc which are not valid symbol names.  The function
131    name may or may not be Z-encoded: to include wildcards it has to be,
132    but Z-encoding C++ function names which are themselves already mangled
133    using Zs in some way is tedious and error prone, so the _ZU variant
134    allows them not to be Z-encoded.
135 
136    Note that the soname "NONE" is specially interpreted to match any
137    shared object which doesn't have a soname.
138 
139    Note also that the replacement function should probably (must be?) in
140    client space, so it runs on the simulated CPU.  So it must be in
141    either vgpreload_<tool>.so or vgpreload_core.so.  It also only works
142    with functions in shared objects, I think.
143 
144    It is important that the Z-encoded names contain no unencoded
145    underscores, since the intercept-handlers in m_redir.c detect the
146    end of the soname by looking for the first trailing underscore.
147 
148    To write function names which explicitly state the equivalence class
149    tag, use
150      VG_REPLACE_FUNCTION_EZU(5-digit-tag,zEncodedSoname,fnname)
151    or
152      VG_REPLACE_FUNCTION_EZZ(5-digit-tag,zEncodedSoname,zEncodedFnname)
153 
154    As per comments above, the tag must be a 5 digit decimal number,
155    padded with leading zeroes, in the range 00010 to 99999 inclusive.
156 
157 
158    Wrapping
159    ~~~~~~~~
160    This is identical to replacement, except that you should use the
161    macro names
162 
163       VG_WRAP_FUNCTION_ZU
164       VG_WRAP_FUNCTION_ZZ
165       VG_WRAP_FUNCTION_EZU
166       VG_WRAP_FUNCTION_EZZ
167 
168    instead.
169 
170    Z-encoding
171    ~~~~~~~~~~
172    Z-encoding details: the scheme is like GHC's.  It is just about
173    readable enough to make a preprocessor unnecessary.  First the
174    "_vgrZU_" or "_vgrZZ_" prefix is added, and then the following
175    characters are transformed.
176 
177      *         -->  Za    (asterisk)
178      :         -->  Zc    (colon)
179      .         -->  Zd    (dot)
180      -         -->  Zh    (hyphen)
181      +         -->  Zp    (plus)
182      (space)   -->  Zs    (space)
183      _         -->  Zu    (underscore)
184      @         -->  ZA    (at)
185      $         -->  ZD    (dollar)
186      (         -->  ZL    (left)
187      )         -->  ZR    (right)
188      Z         -->  ZZ    (Z)
189 
190    Everything else is left unchanged.
191 */
192 
193 /* If you change these, the code in VG_(maybe_Z_demangle) needs to be
194    changed accordingly.  NOTE: duplicates
195    I_{WRAP,REPLACE}_SONAME_FNNAME_Z{U,Z} in valgrind.h. */
196 
197 /* Use an extra level of macroisation so as to ensure the soname/fnname
198    args are fully macro-expanded before pasting them together. */
199 #define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
200 
201 #define VG_CONCAT6(_aa,_bb,_cc,_dd,_ee,_ff) _aa##_bb##_cc##_dd##_ee##_ff
202 
203 /* The 4 basic macros. */
204 #define VG_REPLACE_FUNCTION_EZU(_eclasstag,_soname,_fnname) \
205    VG_CONCAT6(_vgr,_eclasstag,ZU_,_soname,_,_fnname)
206 
207 #define VG_REPLACE_FUNCTION_EZZ(_eclasstag,_soname,_fnname) \
208    VG_CONCAT6(_vgr,_eclasstag,ZZ_,_soname,_,_fnname)
209 
210 #define VG_WRAP_FUNCTION_EZU(_eclasstag,_soname,_fnname) \
211    VG_CONCAT6(_vgw,_eclasstag,ZU_,_soname,_,_fnname)
212 
213 #define VG_WRAP_FUNCTION_EZZ(_eclasstag,_soname,_fnname) \
214    VG_CONCAT6(_vgw,_eclasstag,ZZ_,_soname,_,_fnname)
215 
216 /* Convenience macros defined in terms of the above 4. */
217 #define VG_REPLACE_FUNCTION_ZU(_soname,_fnname) \
218    VG_CONCAT6(_vgr,00000,ZU_,_soname,_,_fnname)
219 
220 #define VG_REPLACE_FUNCTION_ZZ(_soname,_fnname) \
221    VG_CONCAT6(_vgr,00000,ZZ_,_soname,_,_fnname)
222 
223 #define VG_WRAP_FUNCTION_ZU(_soname,_fnname) \
224    VG_CONCAT6(_vgw,00000,ZU_,_soname,_,_fnname)
225 
226 #define VG_WRAP_FUNCTION_ZZ(_soname,_fnname) \
227    VG_CONCAT6(_vgw,00000,ZZ_,_soname,_,_fnname)
228 
229 
230 /* --------- Some handy Z-encoded names. --------- */
231 
232 // Nb: ALL THESE NAMES MUST BEGIN WITH "VG_Z_".  Why?  If we applied
233 // conditional compilation inconsistently we could accidentally use an
234 // undefined constant like VG_Z_LIBC_DOT_A, resulting in a bogus Z-encoded
235 // name like "_vgrZU_VG_Z_LIBC_DOT_A_foo".  This can't be detected at
236 // compile-time, because both the constant's name and its value are
237 // identifiers.  However, by always using "VG_Z_" as a prefix, we can do a
238 // run-time check and abort if any name has "VG_Z_" in it, because that
239 // indicates that the constant has been used without being defined.
240 
241 /* --- Soname of the standard C library. --- */
242 
243 #if defined(VGO_linux)
244 #  define  VG_Z_LIBC_SONAME  libcZdsoZa              // libc.so*
245 
246 #elif defined(VGO_darwin) && (DARWIN_VERS <= DARWIN_10_6)
247 #  define  VG_Z_LIBC_SONAME  libSystemZdZaZddylib    // libSystem.*.dylib
248 
249 #elif defined(VGO_darwin) && (DARWIN_VERS == DARWIN_10_7 \
250                               || DARWIN_VERS == DARWIN_10_8)
251 #  define  VG_Z_LIBC_SONAME  libsystemZucZaZddylib   // libsystem_c*.dylib
252    /* Note that the idea of a single name for the C library falls
253       apart on more recent Darwins (10.8 and later) since the
254       functionality (malloc, free, str*) is split between
255       libsystem_c.dylib, libsystem_malloc.dylib and
256       libsystem_platform.dylib.  This makes VG_Z_LIBC_SONAME somewhat useless
257       at least inside vg_replace_strmem.c, and that hardwires some dylib
258       names directly, for OSX 10.9. */
259 
260 #elif defined(VGO_darwin) && (DARWIN_VERS >= DARWIN_10_9)
261 #  define  VG_Z_LIBC_SONAME  libsystemZumallocZddylib  // libsystem_malloc.dylib
262 
263 #else
264 #  error "Unknown platform"
265 
266 #endif
267 
268 /* --- Soname of the GNU C++ library. --- */
269 
270 // Valid on all platforms(?)
271 #define  VG_Z_LIBSTDCXX_SONAME  libstdcZpZpZa           // libstdc++*
272 
273 /* --- Soname of the pthreads library. --- */
274 
275 #if defined(VGO_linux)
276 #  define  VG_Z_LIBPTHREAD_SONAME  libpthreadZdsoZd0     // libpthread.so.0
277 #elif defined(VGO_darwin)
278 #  define  VG_Z_LIBPTHREAD_SONAME  libSystemZdZaZddylib  // libSystem.*.dylib
279 #else
280 #  error "Unknown platform"
281 #endif
282 
283 /* --- Sonames for Linux ELF linkers, plus unencoded versions. --- */
284 
285 #if defined(VGO_linux)
286 
287 #define  VG_Z_LD_LINUX_SO_3         ldZhlinuxZdsoZd3           // ld-linux.so.3
288 #define  VG_U_LD_LINUX_SO_3         "ld-linux.so.3"
289 
290 #define  VG_Z_LD_LINUX_SO_2         ldZhlinuxZdsoZd2           // ld-linux.so.2
291 #define  VG_U_LD_LINUX_SO_2         "ld-linux.so.2"
292 
293 #define  VG_Z_LD_LINUX_X86_64_SO_2  ldZhlinuxZhx86Zh64ZdsoZd2
294                                                         // ld-linux-x86-64.so.2
295 #define  VG_U_LD_LINUX_X86_64_SO_2  "ld-linux-x86-64.so.2"
296 
297 #define  VG_Z_LD64_SO_1             ld64ZdsoZd1                // ld64.so.1
298 #define  VG_U_LD64_SO_1             "ld64.so.1"
299 #define  VG_U_LD64_SO_2             "ld64.so.2"                // PPC LE loader
300 
301 #define  VG_Z_LD_SO_1               ldZdsoZd1                  // ld.so.1
302 #define  VG_U_LD_SO_1               "ld.so.1"
303 
304 #define  VG_U_LD_LINUX_AARCH64_SO_1 "ld-linux-aarch64.so.1"
305 #define  VG_U_LD_LINUX_ARMHF_SO_3   "ld-linux-armhf.so.3"
306 
307 #endif
308 
309 /* --- Executable name for Darwin Mach-O linker. --- */
310 
311 #if defined(VGO_darwin)
312 
313 #define  VG_Z_DYLD               dyld                       // dyld
314 #define  VG_U_DYLD               "dyld"
315 
316 #endif
317 
318 
319 // Prefix for synonym soname synonym handling
320 #define VG_SO_SYN(name)       VgSoSyn##name
321 #define VG_SO_SYN_PREFIX     "VgSoSyn"
322 #define VG_SO_SYN_PREFIX_LEN 7
323 
324 #endif   // __PUB_TOOL_REDIR_H
325 
326 /*--------------------------------------------------------------------*/
327 /*--- end                                                          ---*/
328 /*--------------------------------------------------------------------*/
329