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-2015 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     /         -->  ZS    (slash)
190
191   Everything else is left unchanged.
192*/
193
194/* If you change these, the code in VG_(maybe_Z_demangle) needs to be
195   changed accordingly.  NOTE: duplicates
196   I_{WRAP,REPLACE}_SONAME_FNNAME_Z{U,Z} in valgrind.h. */
197
198/* Use an extra level of macroisation so as to ensure the soname/fnname
199   args are fully macro-expanded before pasting them together. */
200#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
201
202#define VG_CONCAT6(_aa,_bb,_cc,_dd,_ee,_ff) _aa##_bb##_cc##_dd##_ee##_ff
203
204/* The 4 basic macros. */
205#define VG_REPLACE_FUNCTION_EZU(_eclasstag,_soname,_fnname) \
206   VG_CONCAT6(_vgr,_eclasstag,ZU_,_soname,_,_fnname)
207
208#define VG_REPLACE_FUNCTION_EZZ(_eclasstag,_soname,_fnname) \
209   VG_CONCAT6(_vgr,_eclasstag,ZZ_,_soname,_,_fnname)
210
211#define VG_WRAP_FUNCTION_EZU(_eclasstag,_soname,_fnname) \
212   VG_CONCAT6(_vgw,_eclasstag,ZU_,_soname,_,_fnname)
213
214#define VG_WRAP_FUNCTION_EZZ(_eclasstag,_soname,_fnname) \
215   VG_CONCAT6(_vgw,_eclasstag,ZZ_,_soname,_,_fnname)
216
217/* Convenience macros defined in terms of the above 4. */
218#define VG_REPLACE_FUNCTION_ZU(_soname,_fnname) \
219   VG_CONCAT6(_vgr,00000,ZU_,_soname,_,_fnname)
220
221#define VG_REPLACE_FUNCTION_ZZ(_soname,_fnname) \
222   VG_CONCAT6(_vgr,00000,ZZ_,_soname,_,_fnname)
223
224#define VG_WRAP_FUNCTION_ZU(_soname,_fnname) \
225   VG_CONCAT6(_vgw,00000,ZU_,_soname,_,_fnname)
226
227#define VG_WRAP_FUNCTION_ZZ(_soname,_fnname) \
228   VG_CONCAT6(_vgw,00000,ZZ_,_soname,_,_fnname)
229
230
231/* --------- Some handy Z-encoded names. --------- */
232
233// Nb: ALL THESE NAMES MUST BEGIN WITH "VG_Z_".  Why?  If we applied
234// conditional compilation inconsistently we could accidentally use an
235// undefined constant like VG_Z_LIBC_DOT_A, resulting in a bogus Z-encoded
236// name like "_vgrZU_VG_Z_LIBC_DOT_A_foo".  This can't be detected at
237// compile-time, because both the constant's name and its value are
238// identifiers.  However, by always using "VG_Z_" as a prefix, we can do a
239// run-time check and abort if any name has "VG_Z_" in it, because that
240// indicates that the constant has been used without being defined.
241
242/* --- Soname of the standard C library. --- */
243
244#if defined(VGO_linux) || defined(VGO_solaris)
245#  define  VG_Z_LIBC_SONAME  libcZdsoZa              // libc.so*
246
247#elif defined(VGO_darwin) && (DARWIN_VERS <= DARWIN_10_6)
248#  define  VG_Z_LIBC_SONAME  libSystemZdZaZddylib    // libSystem.*.dylib
249
250#elif defined(VGO_darwin) && (DARWIN_VERS == DARWIN_10_7 \
251                              || DARWIN_VERS == DARWIN_10_8)
252#  define  VG_Z_LIBC_SONAME  libsystemZucZaZddylib   // libsystem_c*.dylib
253   /* Note that the idea of a single name for the C library falls
254      apart on more recent Darwins (10.8 and later) since the
255      functionality (malloc, free, str*) is split between
256      libsystem_c.dylib, libsystem_malloc.dylib and
257      libsystem_platform.dylib.  This makes VG_Z_LIBC_SONAME somewhat useless
258      at least inside vg_replace_strmem.c, and that hardwires some dylib
259      names directly, for OSX 10.9. */
260
261#elif defined(VGO_darwin) && (DARWIN_VERS >= DARWIN_10_9)
262#  define  VG_Z_LIBC_SONAME  libsystemZumallocZddylib  // libsystem_malloc.dylib
263
264#else
265#  error "Unknown platform"
266
267#endif
268
269/* --- Soname of the GNU C++ library. --- */
270
271// Valid on all platforms(?)
272#define  VG_Z_LIBSTDCXX_SONAME  libstdcZpZpZa           // libstdc++*
273
274/* --- Soname of the pthreads library. --- */
275
276#if defined(VGO_linux)
277#  define  VG_Z_LIBPTHREAD_SONAME  libpthreadZdsoZd0     // libpthread.so.0
278#elif defined(VGO_darwin)
279#  define  VG_Z_LIBPTHREAD_SONAME  libSystemZdZaZddylib  // libSystem.*.dylib
280#elif defined(VGO_solaris)
281#  define  VG_Z_LIBPTHREAD_SONAME  libpthreadZdsoZd1     // libpthread.so.1
282#else
283#  error "Unknown platform"
284#endif
285
286/* --- Sonames for Linux ELF linkers, plus unencoded versions. --- */
287
288#if defined(VGO_linux)
289
290#define  VG_Z_LD_LINUX_SO_3         ldZhlinuxZdsoZd3           // ld-linux.so.3
291#define  VG_U_LD_LINUX_SO_3         "ld-linux.so.3"
292
293#define  VG_Z_LD_LINUX_SO_2         ldZhlinuxZdsoZd2           // ld-linux.so.2
294#define  VG_U_LD_LINUX_SO_2         "ld-linux.so.2"
295
296#define  VG_Z_LD_LINUX_X86_64_SO_2  ldZhlinuxZhx86Zh64ZdsoZd2
297                                                        // ld-linux-x86-64.so.2
298#define  VG_U_LD_LINUX_X86_64_SO_2  "ld-linux-x86-64.so.2"
299
300#define  VG_Z_LD64_SO_1             ld64ZdsoZd1                // ld64.so.1
301#define  VG_U_LD64_SO_1             "ld64.so.1"
302#define  VG_U_LD64_SO_2             "ld64.so.2"                // PPC LE loader
303
304#define  VG_Z_LD_SO_1               ldZdsoZd1                  // ld.so.1
305#define  VG_U_LD_SO_1               "ld.so.1"
306
307#define  VG_U_LD_LINUX_AARCH64_SO_1 "ld-linux-aarch64.so.1"
308#define  VG_U_LD_LINUX_ARMHF_SO_3   "ld-linux-armhf.so.3"
309
310#endif
311
312/* --- Executable name for Darwin Mach-O linker. --- */
313
314#if defined(VGO_darwin)
315
316#define  VG_Z_DYLD               dyld                       // dyld
317#define  VG_U_DYLD               "dyld"
318
319#endif
320
321/* --- Soname for Solaris run-time linker. --- */
322// Note: run-time linker contains absolute pathname in the SONAME.
323
324#if defined(VGO_solaris)
325
326#if defined(VGP_x86_solaris)
327#  define  VG_Z_LD_SO_1           ZSlibZSldZdsoZd1         // /lib/ld.so.1
328#  define  VG_U_LD_SO_1           "/lib/ld.so.1"
329#elif defined(VGP_amd64_solaris)
330#  define  VG_Z_LD_SO_1           ZSlibZSamd64ZSldZdsoZd1  // /lib/amd64/ld.so.1
331#  define  VG_U_LD_SO_1           "/lib/amd64/ld.so.1"
332#else
333#  error "Unknown platform"
334#endif
335
336/* --- Soname for Solaris libumem allocation interposition. --- */
337
338#define  VG_Z_LIBUMEM_SO_1          libumemZdsoZd1             // libumem.so.1
339#define  VG_U_LIBUMEM_SO_1          "libumem.so.1"
340
341#endif
342
343// Prefix for synonym soname synonym handling
344#define VG_SO_SYN(name)       VgSoSyn##name
345#define VG_SO_SYN_PREFIX     "VgSoSyn"
346#define VG_SO_SYN_PREFIX_LEN 7
347
348#endif   // __PUB_TOOL_REDIR_H
349
350/*--------------------------------------------------------------------*/
351/*--- end                                                          ---*/
352/*--------------------------------------------------------------------*/
353