Bug 439685 compiler warning in callgrind/main.c
[valgrind.git] / include / pub_tool_redir.h
blobf88d3b571f92d4e64ee9a368a3e4b7e1f010e546
2 /*--------------------------------------------------------------------*/
3 /*--- Redirections, etc. pub_tool_redir.h ---*/
4 /*--------------------------------------------------------------------*/
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
10 Copyright (C) 2000-2017 Julian Seward
11 jseward@acm.org
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.
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.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
29 #ifndef __PUB_TOOL_REDIR_H
30 #define __PUB_TOOL_REDIR_H
32 #include "config.h" /* DARWIN_VERS */
33 #include "pub_tool_basics.h" // Bool and HChar
35 /* The following macros facilitate function replacement and wrapping.
37 Function wrapping and function replacement are similar but not
38 identical.
40 A replacement for some function F simply diverts all calls to F
41 to the stated replacement. There is no way to get back to F itself
42 from the replacement.
44 A wrapper for a function F causes all calls to F to instead go to
45 the wrapper. However, from inside the wrapper, it is possible
46 (with some difficulty) to get to F itself.
48 You may notice that replacement is a special case of wrapping, in
49 which the call to the original is omitted. For implementation
50 reasons, though, it is important to use the following macros
51 correctly: in particular, if you want to write a replacement, make
52 sure you use the VG_REPLACE_FN_ macros and not the VG_WRAP_FN_
53 macros.
55 Finally there is the concept of prioritised behavioural equivalence
56 tags. A tag is a 5-digit decimal number (00000 to 99999) encoded
57 in the name. The top 4 digits are the equivalence class number,
58 and the last digit is a priority.
60 When processing redirections at library load time, if the set of
61 available specifications yields more than one replacement or
62 wrapper function for a given address, the system will try to
63 resolve the situation by examining the tags on the
64 replacements/wrappers.
66 If two replacement/wrapper functions have the same tag and
67 priority, then the redirection machinery will assume they have
68 identical behaviour and can choose between them arbitrarily. If
69 they have the same tag but different priorities, then the one with
70 higher priority will be chosen. If neither case holds, then the
71 redirection is ambiguous and the system will ignore one of them
72 arbitrarily, but print a warning when running at -v or above.
74 The tag is mandatory and must comprise 5 decimal digits. The tag
75 00000 is special and means "does not have behaviour identical to any
76 other replacement/wrapper function". Hence if you wish to write a
77 wrap/replacement function that is not subject to the above
78 resolution rules, use 00000 for the tag. Tags 00001 through 00009
79 may not be used for any purpose.
82 Replacement
83 ~~~~~~~~~~~
84 To write a replacement function, do this:
86 ret_type
87 VG_REPLACE_FUNCTION_ZU(zEncodedSoname,fnname) ( .. args .. )
89 ... body ...
92 zEncodedSoname should be a Z-encoded soname (see below for
93 Z-encoding details) and fnname should be an unencoded fn name. A
94 default-safe equivalence tag of 00000 is assumed (see comments
95 above). The resulting name is
97 _vgr00000ZU_zEncodedSoname_fnname
99 The "_vgr00000ZU_" is a prefix that gets discarded upon decoding.
100 It identifies this function as a replacement and specifies its
101 equivalence tag.
103 It is also possible to write
105 ret_type
106 VG_REPLACE_FUNCTION_ZZ(zEncodedSoname,zEncodedFnname) ( .. args .. )
108 ... body ...
111 which means precisely the same, but the function name is also
112 Z-encoded. This can sometimes be necessary. In this case the
113 resulting function name is
115 _vgr00000ZZ_zEncodedSoname_zEncodedFnname
117 When it sees this either such name, the core's symbol-table reading
118 machinery and redirection machinery first Z-decode the soname and
119 if necessary the fnname. They are encoded so that they may include
120 arbitrary characters, and in particular they may contain '*', which
121 acts as a wildcard.
123 They then will conspire to cause calls to any function matching
124 'fnname' in any object whose soname matches 'soname' to actually be
125 routed to this function. This is used in Valgrind to define dozens
126 of replacements of malloc, free, etc.
128 The soname must be a Z-encoded bit of text because sonames can
129 contain dots etc which are not valid symbol names. The function
130 name may or may not be Z-encoded: to include wildcards it has to be,
131 but Z-encoding C++ function names which are themselves already mangled
132 using Zs in some way is tedious and error prone, so the _ZU variant
133 allows them not to be Z-encoded.
135 Note that the soname "NONE" is specially interpreted to match any
136 shared object which doesn't have a soname.
138 Note also that the replacement function should probably (must be?) in
139 client space, so it runs on the simulated CPU. So it must be in
140 either vgpreload_<tool>.so or vgpreload_core.so. It also only works
141 with functions in shared objects, I think.
143 It is important that the Z-encoded names contain no unencoded
144 underscores, since the intercept-handlers in m_redir.c detect the
145 end of the soname by looking for the first trailing underscore.
147 To write function names which explicitly state the equivalence class
148 tag, use
149 VG_REPLACE_FUNCTION_EZU(5-digit-tag,zEncodedSoname,fnname)
151 VG_REPLACE_FUNCTION_EZZ(5-digit-tag,zEncodedSoname,zEncodedFnname)
153 As per comments above, the tag must be a 5 digit decimal number,
154 padded with leading zeroes, in the range 00010 to 99999 inclusive.
157 Wrapping
158 ~~~~~~~~
159 This is identical to replacement, except that you should use the
160 macro names
162 VG_WRAP_FUNCTION_ZU
163 VG_WRAP_FUNCTION_ZZ
164 VG_WRAP_FUNCTION_EZU
165 VG_WRAP_FUNCTION_EZZ
167 instead.
169 Z-encoding
170 ~~~~~~~~~~
171 Z-encoding details: the scheme is like GHC's. It is just about
172 readable enough to make a preprocessor unnecessary. First the
173 "_vgrZU_" or "_vgrZZ_" prefix is added, and then the following
174 characters are transformed.
176 * --> Za (asterisk)
177 : --> Zc (colon)
178 . --> Zd (dot)
179 - --> Zh (hyphen)
180 + --> Zp (plus)
181 (space) --> Zs (space)
182 _ --> Zu (underscore)
183 @ --> ZA (at)
184 $ --> ZD (dollar)
185 ( --> ZL (left)
186 % --> ZP (percent)
187 ) --> ZR (right)
188 / --> ZS (slash)
189 Z --> ZZ (Z)
191 Everything else is left unchanged.
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. */
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
202 #define VG_CONCAT6(_aa,_bb,_cc,_dd,_ee,_ff) _aa##_bb##_cc##_dd##_ee##_ff
204 /* The 4 basic macros. */
205 #define VG_REPLACE_FUNCTION_EZU(_eclasstag,_soname,_fnname) \
206 VG_CONCAT6(_vgr,_eclasstag,ZU_,_soname,_,_fnname)
208 #define VG_REPLACE_FUNCTION_EZZ(_eclasstag,_soname,_fnname) \
209 VG_CONCAT6(_vgr,_eclasstag,ZZ_,_soname,_,_fnname)
211 #define VG_WRAP_FUNCTION_EZU(_eclasstag,_soname,_fnname) \
212 VG_CONCAT6(_vgw,_eclasstag,ZU_,_soname,_,_fnname)
214 #define VG_WRAP_FUNCTION_EZZ(_eclasstag,_soname,_fnname) \
215 VG_CONCAT6(_vgw,_eclasstag,ZZ_,_soname,_,_fnname)
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)
221 #define VG_REPLACE_FUNCTION_ZZ(_soname,_fnname) \
222 VG_CONCAT6(_vgr,00000,ZZ_,_soname,_,_fnname)
224 #define VG_WRAP_FUNCTION_ZU(_soname,_fnname) \
225 VG_CONCAT6(_vgw,00000,ZU_,_soname,_,_fnname)
227 #define VG_WRAP_FUNCTION_ZZ(_soname,_fnname) \
228 VG_CONCAT6(_vgw,00000,ZZ_,_soname,_,_fnname)
231 /* --------- Some handy Z-encoded names. --------- */
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.
242 /* --- Soname of the standard C library. --- */
244 #if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
245 # if defined(MUSL_LIBC)
246 # define VG_Z_LIBC_SONAME libcZdZa // libc.*
247 #else
248 # define VG_Z_LIBC_SONAME libcZdsoZa // libc.so*
249 #endif
250 #elif defined(VGO_darwin) && (DARWIN_VERS <= DARWIN_10_6)
251 # define VG_Z_LIBC_SONAME libSystemZdZaZddylib // libSystem.*.dylib
253 #elif defined(VGO_darwin) && (DARWIN_VERS == DARWIN_10_7 \
254 || DARWIN_VERS == DARWIN_10_8)
255 # define VG_Z_LIBC_SONAME libsystemZucZaZddylib // libsystem_c*.dylib
256 /* Note that the idea of a single name for the C library falls
257 apart on more recent Darwins (10.8 and later) since the
258 functionality (malloc, free, str*) is split between
259 libsystem_c.dylib, libsystem_malloc.dylib and
260 libsystem_platform.dylib. This makes VG_Z_LIBC_SONAME somewhat useless
261 at least inside vg_replace_strmem.c, and that hardwires some dylib
262 names directly, for OSX 10.9. */
264 #elif defined(VGO_darwin) && (DARWIN_VERS >= DARWIN_10_9)
265 # define VG_Z_LIBC_SONAME libsystemZumallocZddylib // libsystem_malloc.dylib
267 #else
268 # error "Unknown platform"
270 #endif
272 /* --- Sonames of the GNU C++ library. --- */
274 // Valid on all platforms(?)
275 #define VG_Z_LIBSTDCXX_SONAME libstdcZpZpZa // libstdc++*
277 /* --- Soname of the clang C++ library. --- */
279 #define VG_Z_LIBCXX_SONAME libcZpZpZa // libc++*
282 /* --- Soname of the pthreads library. --- */
284 #if defined(VGO_linux)
285 # define VG_Z_LIBPTHREAD_SONAME libpthreadZdsoZd0 // libpthread.so.0
286 #elif defined(VGO_freebsd)
287 # define VG_Z_LIBPTHREAD_SONAME libthrZdsoZa // libthr.so*
288 #elif defined(VGO_darwin)
289 # define VG_Z_LIBPTHREAD_SONAME libSystemZdZaZddylib // libSystem.*.dylib
290 #elif defined(VGO_solaris)
291 # define VG_Z_LIBPTHREAD_SONAME libpthreadZdsoZd1 // libpthread.so.1
292 #else
293 # error "Unknown platform"
294 #endif
296 /* --- Sonames for Linux ELF linkers, plus unencoded versions. --- */
298 #if defined(VGO_linux)
300 #define VG_Z_LD_LINUX_SO_3 ldZhlinuxZdsoZd3 // ld-linux.so.3
301 #define VG_U_LD_LINUX_SO_3 "ld-linux.so.3"
303 #define VG_Z_LD_LINUX_SO_2 ldZhlinuxZdsoZd2 // ld-linux.so.2
304 #define VG_U_LD_LINUX_SO_2 "ld-linux.so.2"
306 #define VG_Z_LD_LINUX_X86_64_SO_2 ldZhlinuxZhx86Zh64ZdsoZd2
307 // ld-linux-x86-64.so.2
308 #define VG_U_LD_LINUX_X86_64_SO_2 "ld-linux-x86-64.so.2"
310 #define VG_Z_LD64_SO_1 ld64ZdsoZd1 // ld64.so.1
311 #define VG_U_LD64_SO_1 "ld64.so.1"
312 #define VG_U_LD64_SO_2 "ld64.so.2" // PPC LE loader
314 #define VG_Z_LD_SO_1 ldZdsoZd1 // ld.so.1
315 #define VG_U_LD_SO_1 "ld.so.1"
317 #define VG_Z_LD_LINUX_AARCH64_SO_1 ldZhlinuxZhaarch64ZdsoZd1
318 #define VG_U_LD_LINUX_AARCH64_SO_1 "ld-linux-aarch64.so.1"
320 #define VG_U_LD_LINUX_ARMHF_SO_3 "ld-linux-armhf.so.3"
322 #define VG_U_LD_LINUX_MIPSN8_S0_1 "ld-linux-mipsn8.so.1"
324 #endif
326 /* --- Sonames for FreeBSD ELF linkers, plus unencoded versions. --- */
328 #if defined(VGO_freebsd)
330 #define VG_Z_LD_ELF_SO_1 ldZhelfZdsoZd1 // ld-elf.so.1
331 #define VG_U_LD_ELF_SO_1 "ld-elf.so.1"
333 #define VG_Z_LD_ELF32_SO_1 ldZhelf32ZdsoZd1 // ld-elf32.so.1
334 #define VG_U_LD_ELF32_SO_1 "ld-elf32.so.1"
336 #endif
338 /* --- Executable name for Darwin Mach-O linker. --- */
340 #if defined(VGO_darwin)
342 #define VG_Z_DYLD dyld // dyld
343 #define VG_U_DYLD "dyld"
345 #endif
347 /* --- Soname for Solaris run-time linker. --- */
348 // Note: run-time linker contains absolute pathname in the SONAME.
350 #if defined(VGO_solaris)
352 #if defined(VGP_x86_solaris)
353 # define VG_Z_LD_SO_1 ZSlibZSldZdsoZd1 // /lib/ld.so.1
354 # define VG_U_LD_SO_1 "/lib/ld.so.1"
355 #elif defined(VGP_amd64_solaris)
356 # define VG_Z_LD_SO_1 ZSlibZSamd64ZSldZdsoZd1 // /lib/amd64/ld.so.1
357 # define VG_U_LD_SO_1 "/lib/amd64/ld.so.1"
358 #else
359 # error "Unknown platform"
360 #endif
362 /* --- Soname for Solaris libumem allocation interposition. --- */
364 #define VG_Z_LIBUMEM_SO_1 libumemZdsoZd1 // libumem.so.1
365 #define VG_U_LIBUMEM_SO_1 "libumem.so.1"
367 #endif
369 // Prefix for synonym soname synonym handling
370 #define VG_SO_SYN(name) VgSoSyn##name
371 #define VG_SO_SYN_PREFIX "VgSoSyn"
372 #define VG_SO_SYN_PREFIX_LEN 7
374 // Special soname synonym place holder for the malloc symbols that can
375 // be replaced using --soname-synonyms. Otherwise will match all
376 // public symbols in any shared library/executable.
377 #define SO_SYN_MALLOC VG_SO_SYN(somalloc)
378 #define SO_SYN_MALLOC_NAME "VgSoSynsomalloc"
380 Bool VG_(is_soname_ld_so) (const HChar *soname);
382 // Some macros to help decide which libraries (libc or libpthread
383 // or some platform-specific variation of these) should be used
384 // for wrapping pthread/semaphore functions with DRD and Helgrind
385 // The possibilities are
386 // a) only in libpthread
387 // b) mabye in both libpthread and libc or
388 // c) only in libc
390 // Linux GNU libc is moving from a) to c)
391 // Fedora 33 has pthread functions in both libc and libpthread
392 // and at least glibc 2.32 (Fedora 34) has an implementation of all pthread
393 // functions in both libc and libpthread. Older glibc versions only have an
394 // implementation of the pthread functions in libpthread.
396 // Linux MUSL libc is c) it provides a single library that includes
397 // pthreads functions.
399 // Darwin is a)
401 // Solaris is c) libpthread is just a filter library on top of libc.
402 // Threading and synchronization functions in runtime linker are not
403 // intercepted.
405 // FreeBSD is b) pthread functions are lin libthr but semaphore
406 // functions are lin libc
408 #if defined(VGO_darwin) || defined(VGO_freebsd)
409 #define VG_WRAP_THREAD_FUNCTION_LIBPTHREAD_ONLY
410 #elif defined(VGO_solaris) || (defined(VGO_linux) && defined(MUSL_LIBC))
411 #define VG_WRAP_THREAD_FUNCTION_LIBC_ONLY
412 #elif defined(VGO_linux)
413 #define VG_WRAP_THREAD_FUNCTION_LIBC_AND_LIBPTHREAD
414 #else
415 # error "Unknown platform"
416 #endif
418 #endif // __PUB_TOOL_REDIR_H
420 /*--------------------------------------------------------------------*/
421 /*--- end ---*/
422 /*--------------------------------------------------------------------*/