blob: 69d0f3779bb753ab7293fa42ef90fe483174d258 [file] [log] [blame]
njnc0ae7052005-08-25 22:55:19 +00001
sewardjcbdddcf2005-03-10 23:23:45 +00002/*--------------------------------------------------------------------*/
njnc0ae7052005-08-25 22:55:19 +00003/*--- Function replacement and wrapping. m_redir.c ---*/
sewardjcbdddcf2005-03-10 23:23:45 +00004/*--------------------------------------------------------------------*/
5
6/*
njnc0ae7052005-08-25 22:55:19 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjcbdddcf2005-03-10 23:23:45 +00009
sewardj0f157dd2013-10-18 14:27:36 +000010 Copyright (C) 2000-2013 Julian Seward
sewardjcbdddcf2005-03-10 23:23:45 +000011 jseward@acm.org
sewardj0f157dd2013-10-18 14:27:36 +000012 Copyright (C) 2003-2013 Jeremy Fitzhardinge
sewardjcbdddcf2005-03-10 23:23:45 +000013 jeremy@goop.org
14
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of the
18 License, or (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 02111-1307, USA.
29
30 The GNU General Public License is contained in the file COPYING.
31*/
sewardjcbdddcf2005-03-10 23:23:45 +000032
njnc7561b92005-06-19 01:24:32 +000033#include "pub_core_basics.h"
sewardj45f4e7c2005-09-27 19:20:21 +000034#include "pub_core_debuglog.h"
njn88c51482005-06-25 20:49:33 +000035#include "pub_core_debuginfo.h"
njn97405b22005-06-02 03:39:33 +000036#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +000037#include "pub_core_libcassert.h"
njn36a20fa2005-06-03 03:08:39 +000038#include "pub_core_libcprint.h"
philippe277eaff2012-03-03 12:01:48 +000039#include "pub_core_vki.h"
40#include "pub_core_libcfile.h"
sewardjd7a02db2008-12-12 08:07:49 +000041#include "pub_core_seqmatch.h"
njnaf1d7df2005-06-11 01:31:52 +000042#include "pub_core_mallocfree.h"
njn20242342005-05-16 23:31:24 +000043#include "pub_core_options.h"
njn8a96ec52005-10-15 15:48:52 +000044#include "pub_core_oset.h"
njnd1af0032005-05-29 17:01:48 +000045#include "pub_core_redir.h"
njna7598f62005-06-18 03:27:58 +000046#include "pub_core_trampoline.h"
njn8bddf582005-05-13 23:40:55 +000047#include "pub_core_transtab.h"
sewardj461c69d2005-11-17 20:15:04 +000048#include "pub_core_tooliface.h" // VG_(needs).malloc_replacement
sewardj6b9cc872006-10-17 01:39:30 +000049#include "pub_core_machine.h" // VG_(fnptr_to_fnentry)
sewardj0ec07f32006-01-12 12:32:32 +000050#include "pub_core_aspacemgr.h" // VG_(am_find_nsegment)
sewardj14c7cc52007-02-25 15:08:24 +000051#include "pub_core_xarray.h"
sewardj0ec07f32006-01-12 12:32:32 +000052#include "pub_core_clientstate.h" // VG_(client___libc_freeres_wrapper)
53#include "pub_core_demangle.h" // VG_(maybe_Z_demangle)
philippe277eaff2012-03-03 12:01:48 +000054#include "pub_core_libcproc.h" // VG_(libdir)
sewardj461c69d2005-11-17 20:15:04 +000055
bart257b91b2009-12-31 13:31:11 +000056#include "config.h" /* GLIBC_2_* */
57
sewardj55f9d1a2005-04-25 11:11:44 +000058
sewardj0ec07f32006-01-12 12:32:32 +000059/* This module is a critical part of the redirection/intercept system.
60 It keeps track of the current intercept state, cleans up the
61 translation caches when that state changes, and finally, answers
62 queries about the whether an address is currently redirected or
63 not. It doesn't do any of the control-flow trickery needed to put
64 the redirections into practice. That is the job of m_translate,
65 which calls here to find out which translations need to be
66 redirected.
67
68 The interface is simple. VG_(redir_initialise) initialises and
69 loads some hardwired redirects which never disappear; this is
70 platform-specific.
71
72 The module is notified of redirection state changes by m_debuginfo.
sewardjf9ebc392010-05-09 22:30:43 +000073 That calls VG_(redir_notify_new_DebugInfo) when a new DebugInfo
74 (shared object symbol table, basically) appears. Appearance of new
75 symbols can cause new (active) redirections to appear for two
76 reasons: the symbols in the new table may match existing
77 redirection specifications (see comments below), and because the
78 symbols in the new table may themselves supply new redirect
79 specifications which match existing symbols (or ones in the new
80 table).
sewardj0ec07f32006-01-12 12:32:32 +000081
82 Redirect specifications are really symbols with "funny" prefixes
sewardj85cf9002011-08-16 09:54:00 +000083 (_vgrNNNNZU_ and _vgrNNNNZZ_). These names tell m_redir that the
sewardj0ec07f32006-01-12 12:32:32 +000084 associated code should replace the standard entry point for some
85 set of functions. The set of functions is specified by a (soname
86 pattern, function name pattern) pair which is encoded in the symbol
87 name following the prefix. The names use a Z-encoding scheme so
88 that they may contain punctuation characters and wildcards (*).
89 The encoding scheme is described in pub_tool_redir.h and is decoded
sewardj85cf9002011-08-16 09:54:00 +000090 by VG_(maybe_Z_demangle). The NNNN are behavioural equivalence
91 class tags, and are used to by code in this module to resolve
92 situations where one address appears to be redirected to more than
93 one replacement/wrapper. This is also described in
94 pub_tool_redir.h.
sewardj0ec07f32006-01-12 12:32:32 +000095
96 When a shared object is unloaded, this module learns of it via a
sewardjf9ebc392010-05-09 22:30:43 +000097 call to VG_(redir_notify_delete_DebugInfo). It then removes from
98 its tables all active redirections in any way associated with that
sewardj0ec07f32006-01-12 12:32:32 +000099 object, and tidies up the translation caches accordingly.
100
101 That takes care of tracking the redirection state. When a
102 translation is actually to be made, m_translate calls to
103 VG_(redir_do_lookup) in this module to find out if the
104 translation's address should be redirected.
105*/
106
sewardjcbdddcf2005-03-10 23:23:45 +0000107/*------------------------------------------------------------*/
sewardj0ec07f32006-01-12 12:32:32 +0000108/*--- Semantics ---*/
sewardjcbdddcf2005-03-10 23:23:45 +0000109/*------------------------------------------------------------*/
110
sewardj0ec07f32006-01-12 12:32:32 +0000111/* The redirector holds two pieces of state:
njnd9109c62005-06-26 04:49:25 +0000112
sewardj0ec07f32006-01-12 12:32:32 +0000113 Specs - a set of (soname pattern, fnname pattern) -> redir addr
114 Active - a set of orig addr -> (bool, redir addr)
sewardjcbdddcf2005-03-10 23:23:45 +0000115
sewardj0ec07f32006-01-12 12:32:32 +0000116 Active is the currently active set of bindings that the translator
117 consults. Specs is the current set of specifications as harvested
118 from reading symbol tables of the currently loaded objects.
sewardjcbdddcf2005-03-10 23:23:45 +0000119
sewardj0ec07f32006-01-12 12:32:32 +0000120 Active is a pure function of Specs and the current symbol table
121 state (maintained by m_debuginfo). Call the latter SyminfoState.
sewardjcbdddcf2005-03-10 23:23:45 +0000122
sewardj0ec07f32006-01-12 12:32:32 +0000123 Therefore whenever either Specs or SyminfoState changes, Active
124 must be recomputed. [Inefficient if done naively, but this is a
125 spec].
njn8a96ec52005-10-15 15:48:52 +0000126
sewardj0ec07f32006-01-12 12:32:32 +0000127 Active is computed as follows:
sewardjcbdddcf2005-03-10 23:23:45 +0000128
sewardj0ec07f32006-01-12 12:32:32 +0000129 Active = empty
130 for spec in Specs {
131 sopatt = spec.soname pattern
132 fnpatt = spec.fnname pattern
133 redir = spec.redir addr
134 for so matching sopatt in SyminfoState {
135 for fn matching fnpatt in fnnames_of(so) {
136 &fn -> redir is added to Active
137 }
138 }
tom748a1312005-04-02 15:53:01 +0000139 }
140
sewardj0ec07f32006-01-12 12:32:32 +0000141 [as an implementation detail, when a binding (orig -> redir) is
142 deleted from Active as a result of recomputing it, then all
143 translations intersecting redir must be deleted. However, this is
144 not part of the spec].
145
146 [Active also depends on where the aspacemgr has decided to put all
147 the pieces of code -- that affects the "orig addr" and "redir addr"
148 values.]
149
150 ---------------------
151
152 That completes the spec, apart from one difficult issue: duplicates.
153
154 Clearly we must impose the requirement that domain(Active) contains
155 no duplicates. The difficulty is how to constrain Specs enough to
156 avoid getting into that situation. It's easy to write specs which
157 could cause conflicting bindings in Active, eg:
158
159 (libpthread.so, pthread_mutex_lock) -> a1
160 (libpthread.so, pthread_*) -> a2
161
162 for a1 != a2. Or even hairier:
163
164 (libpthread.so, pthread_mutex_*) -> a1
165 (libpthread.so, pthread_*_lock) -> a2
166
167 I can't think of any sane way of detecting when an addition to
168 Specs would generate conflicts. However, considering we don't
169 actually want to have a system that allows this, I propose this:
170 all changes to Specs are acceptable. But, when recomputing Active
171 following the change, if the same orig is bound to more than one
172 redir, then the first binding for orig is retained, and all the
173 rest ignored.
174
175 ===========================================================
176 ===========================================================
177 Incremental implementation:
178
sewardjf9ebc392010-05-09 22:30:43 +0000179 When a new DebugInfo appears:
sewardj0ec07f32006-01-12 12:32:32 +0000180 - it may be the source of new specs
181 - it may be the source of new matches for existing specs
182 Therefore:
183
sewardjf9ebc392010-05-09 22:30:43 +0000184 - (new Specs x existing DebugInfos): scan all symbols in the new
185 DebugInfo to find new specs. Each of these needs to be compared
186 against all symbols in all the existing DebugInfos to generate
sewardj0ec07f32006-01-12 12:32:32 +0000187 new actives.
188
sewardjf9ebc392010-05-09 22:30:43 +0000189 - (existing Specs x new DebugInfo): scan all symbols in the
190 DebugInfo, trying to match them to any existing specs, also
191 generating new actives.
sewardj0ec07f32006-01-12 12:32:32 +0000192
sewardjf9ebc392010-05-09 22:30:43 +0000193 - (new Specs x new DebugInfo): scan all symbols in the new
194 DebugInfo, trying to match them against the new specs, to
195 generate new actives.
sewardj0ec07f32006-01-12 12:32:32 +0000196
197 - Finally, add new new specs to the current set of specs.
198
199 When adding a new active (s,d) to the Actives:
200 lookup s in Actives
201 if already bound to d, ignore
202 if already bound to something other than d, complain loudly and ignore
203 else add (s,d) to Actives
204 and discard (s,1) and (d,1) (maybe overly conservative)
205
sewardjf9ebc392010-05-09 22:30:43 +0000206 When a DebugInfo disappears:
sewardj0ec07f32006-01-12 12:32:32 +0000207 - delete all specs acquired from the seginfo
208 - delete all actives derived from the just-deleted specs
209 - if each active (s,d) deleted, discard (s,1) and (d,1)
210*/
211
212
213/*------------------------------------------------------------*/
214/*--- REDIRECTION SPECIFICATIONS ---*/
215/*------------------------------------------------------------*/
216
217/* A specification of a redirection we want to do. Note that because
218 both the "from" soname and function name may contain wildcards, the
sewardj5092a972007-11-16 18:45:40 +0000219 spec can match an arbitrary number of times.
220
221 16 Nov 2007: Comments re .mandatory field: The initial motivation
222 for this is making Memcheck work sanely on glibc-2.6.X ppc32-linux.
223 We really need to intercept 'strlen' in ld.so right from startup.
224 If ld.so does not have a visible 'strlen' symbol, Memcheck
225 generates an impossible number of errors resulting from highly
226 tuned strlen implementation in ld.so, and is completely unusable
227 -- the resulting undefinedness eventually seeps everywhere. */
sewardj0ec07f32006-01-12 12:32:32 +0000228typedef
229 struct _Spec {
230 struct _Spec* next; /* linked list */
sewardjdf24cf12007-11-16 18:32:40 +0000231 /* FIXED PARTS -- set when created and not changed */
sewardj0ec07f32006-01-12 12:32:32 +0000232 HChar* from_sopatt; /* from soname pattern */
233 HChar* from_fnpatt; /* from fnname pattern */
234 Addr to_addr; /* where redirecting to */
235 Bool isWrap; /* wrap or replacement? */
sewardj85cf9002011-08-16 09:54:00 +0000236 Int becTag; /* 0 through 9999. Behavioural equivalance class tag.
237 If two wrappers have the same (non-zero) tag, they
238 are promising that they behave identically. */
sewardj96044842011-08-18 13:09:55 +0000239 Int becPrio; /* 0 through 9. Behavioural equivalence class prio.
240 Used to choose between competing wrappers with
241 the same (non-zero) tag. */
sewardjf499c7d2009-08-10 19:39:02 +0000242 const HChar** mandatory; /* non-NULL ==> abort V and print the
243 strings if from_sopatt is loaded but
244 from_fnpatt cannot be found */
sewardjdf24cf12007-11-16 18:32:40 +0000245 /* VARIABLE PARTS -- used transiently whilst processing redirections */
246 Bool mark; /* set if spec requires further processing */
247 Bool done; /* set if spec was successfully matched */
sewardj0ec07f32006-01-12 12:32:32 +0000248 }
249 Spec;
250
sewardjf9ebc392010-05-09 22:30:43 +0000251/* Top-level data structure. It contains a pointer to a DebugInfo and
252 also a list of the specs harvested from that DebugInfo. Note that
sewardj0ec07f32006-01-12 12:32:32 +0000253 seginfo is allowed to be NULL, meaning that the specs are
254 pre-loaded ones at startup and are not associated with any
255 particular seginfo. */
256typedef
257 struct _TopSpec {
258 struct _TopSpec* next; /* linked list */
sewardjb8b79ad2008-03-03 01:35:41 +0000259 DebugInfo* seginfo; /* symbols etc */
260 Spec* specs; /* specs pulled out of seginfo */
261 Bool mark; /* transient temporary used during deletion */
sewardj0ec07f32006-01-12 12:32:32 +0000262 }
263 TopSpec;
264
265/* This is the top level list of redirections. m_debuginfo maintains
sewardjf9ebc392010-05-09 22:30:43 +0000266 a list of DebugInfos, and the idea here is to maintain a list with
sewardj0ec07f32006-01-12 12:32:32 +0000267 the same number of elements (in fact, with one more element, so as
268 to record abovementioned preloaded specifications.) */
269static TopSpec* topSpecs = NULL;
270
271
272/*------------------------------------------------------------*/
273/*--- CURRENTLY ACTIVE REDIRECTIONS ---*/
274/*------------------------------------------------------------*/
275
276/* Represents a currently active binding. If either parent_spec or
277 parent_sym is NULL, then this binding was hardwired at startup and
278 should not be deleted. Same is true if either parent's seginfo
279 field is NULL. */
280typedef
281 struct {
282 Addr from_addr; /* old addr -- MUST BE THE FIRST WORD! */
283 Addr to_addr; /* where redirecting to */
284 TopSpec* parent_spec; /* the TopSpec which supplied the Spec */
285 TopSpec* parent_sym; /* the TopSpec which supplied the symbol */
sewardj85cf9002011-08-16 09:54:00 +0000286 Int becTag; /* behavioural eclass tag for ::to_addr */
sewardj96044842011-08-18 13:09:55 +0000287 Int becPrio; /* and its priority */
sewardj0ec07f32006-01-12 12:32:32 +0000288 Bool isWrap; /* wrap or replacement? */
tomd2645142009-10-29 09:27:11 +0000289 Bool isIFunc; /* indirect function? */
sewardj0ec07f32006-01-12 12:32:32 +0000290 }
291 Active;
292
293/* The active set is a fast lookup table */
294static OSet* activeSet = NULL;
295
tomd2645142009-10-29 09:27:11 +0000296/* Wrapper routine for indirect functions */
297static Addr iFuncWrapper;
sewardj0ec07f32006-01-12 12:32:32 +0000298
299/*------------------------------------------------------------*/
300/*--- FWDses ---*/
301/*------------------------------------------------------------*/
302
303static void maybe_add_active ( Active /*by value; callee copies*/ );
304
florian54fe2022012-10-27 23:07:42 +0000305static void* dinfo_zalloc(const HChar* ec, SizeT);
sewardjb8b79ad2008-03-03 01:35:41 +0000306static void dinfo_free(void*);
florian54fe2022012-10-27 23:07:42 +0000307static HChar* dinfo_strdup(const HChar* ec, const HChar*);
sewardj0ec07f32006-01-12 12:32:32 +0000308static Bool is_plausible_guest_addr(Addr);
309
florian54fe2022012-10-27 23:07:42 +0000310static void show_redir_state ( const HChar* who );
311static void show_active ( const HChar* left, Active* act );
sewardj0ec07f32006-01-12 12:32:32 +0000312
florian19f91bb2012-11-10 22:29:54 +0000313static void handle_maybe_load_notifier( const HChar* soname,
sewardja672ea32006-04-29 18:03:14 +0000314 HChar* symbol, Addr addr );
sewardj0ec07f32006-01-12 12:32:32 +0000315
sewardjf9ebc392010-05-09 22:30:43 +0000316static void handle_require_text_symbols ( DebugInfo* );
sewardj0ec07f32006-01-12 12:32:32 +0000317
318/*------------------------------------------------------------*/
319/*--- NOTIFICATIONS ---*/
320/*------------------------------------------------------------*/
321
322static
323void generate_and_add_actives (
324 /* spec list and the owning TopSpec */
325 Spec* specs,
326 TopSpec* parent_spec,
sewardjb8b79ad2008-03-03 01:35:41 +0000327 /* debuginfo and the owning TopSpec */
328 DebugInfo* di,
sewardj0ec07f32006-01-12 12:32:32 +0000329 TopSpec* parent_sym
330 );
331
sewardj85cf9002011-08-16 09:54:00 +0000332
333/* Copy all the names from a given symbol into an AR_DINFO allocated,
334 NULL terminated array, for easy iteration. Caller must pass also
335 the address of a 2-entry array which can be used in the common case
336 to avoid dynamic allocation. */
florian19f91bb2012-11-10 22:29:54 +0000337static HChar** alloc_symname_array ( HChar* pri_name, HChar** sec_names,
338 HChar** twoslots )
sewardj85cf9002011-08-16 09:54:00 +0000339{
340 /* Special-case the common case: only one name. We expect the
341 caller to supply a stack-allocated 2-entry array for this. */
342 if (sec_names == NULL) {
343 twoslots[0] = pri_name;
344 twoslots[1] = NULL;
345 return twoslots;
346 }
347 /* Else must use dynamic allocation. Figure out size .. */
348 Word n_req = 1;
florian19f91bb2012-11-10 22:29:54 +0000349 HChar** pp = sec_names;
sewardj85cf9002011-08-16 09:54:00 +0000350 while (*pp) { n_req++; pp++; }
351 /* .. allocate and copy in. */
florian19f91bb2012-11-10 22:29:54 +0000352 HChar** arr = dinfo_zalloc( "redir.asa.1", (n_req+1) * sizeof(HChar*) );
sewardj85cf9002011-08-16 09:54:00 +0000353 Word i = 0;
354 arr[i++] = pri_name;
355 pp = sec_names;
356 while (*pp) { arr[i++] = *pp; pp++; }
357 tl_assert(i == n_req);
358 tl_assert(arr[n_req] == NULL);
359 return arr;
360}
361
362
363/* Free the array allocated by alloc_symname_array, if any. */
florian19f91bb2012-11-10 22:29:54 +0000364static void free_symname_array ( HChar** names, HChar** twoslots )
sewardj85cf9002011-08-16 09:54:00 +0000365{
366 if (names != twoslots)
367 dinfo_free(names);
368}
369
philippe1e470b52012-05-11 19:33:46 +0000370static HChar const* advance_to_equal ( HChar const* c ) {
371 while (*c && *c != '=') {
372 ++c;
373 }
374 return c;
375}
376static HChar const* advance_to_comma ( HChar const* c ) {
377 while (*c && *c != ',') {
378 ++c;
379 }
380 return c;
381}
sewardj85cf9002011-08-16 09:54:00 +0000382
sewardjb8b79ad2008-03-03 01:35:41 +0000383/* Notify m_redir of the arrival of a new DebugInfo. This is fairly
sewardj0ec07f32006-01-12 12:32:32 +0000384 complex, but the net effect is to (1) add a new entry to the
385 topspecs list, and (2) figure out what new binding are now active,
386 and, as a result, add them to the actives mapping. */
387
388#define N_DEMANGLED 256
389
sewardj85cf9002011-08-16 09:54:00 +0000390void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi )
sewardj0ec07f32006-01-12 12:32:32 +0000391{
sewardj6b9cc872006-10-17 01:39:30 +0000392 Bool ok, isWrap;
sewardj96044842011-08-18 13:09:55 +0000393 Int i, nsyms, becTag, becPrio;
sewardj6b9cc872006-10-17 01:39:30 +0000394 Spec* specList;
395 Spec* spec;
396 TopSpec* ts;
397 TopSpec* newts;
florian19f91bb2012-11-10 22:29:54 +0000398 HChar* sym_name_pri;
399 HChar** sym_names_sec;
sewardj6b9cc872006-10-17 01:39:30 +0000400 Addr sym_addr, sym_toc;
401 HChar demangled_sopatt[N_DEMANGLED];
402 HChar demangled_fnpatt[N_DEMANGLED];
403 Bool check_ppcTOCs = False;
sewardjb8b79ad2008-03-03 01:35:41 +0000404 Bool isText;
florian19f91bb2012-11-10 22:29:54 +0000405 const HChar* newdi_soname;
sewardja672ea32006-04-29 18:03:14 +0000406
sewardj6b9cc872006-10-17 01:39:30 +0000407# if defined(VG_PLAT_USES_PPCTOC)
408 check_ppcTOCs = True;
409# endif
410
sewardj85cf9002011-08-16 09:54:00 +0000411 vg_assert(newdi);
412 newdi_soname = VG_(DebugInfo_get_soname)(newdi);
413 vg_assert(newdi_soname != NULL);
sewardj0ec07f32006-01-12 12:32:32 +0000414
philippe277eaff2012-03-03 12:01:48 +0000415#ifdef ENABLE_INNER
416 {
417 /* When an outer Valgrind is executing an inner Valgrind, the
418 inner "sees" in its address space the mmap-ed vgpreload files
419 of the outer. The inner must avoid interpreting the
420 redirections given in the outer vgpreload mmap-ed files.
421 Otherwise, some tool combinations badly fail.
422
423 Example: outer memcheck tool executing an inner none tool.
424
425 If inner none interprets the outer malloc redirection, the
426 inner will redirect malloc to a memcheck function it does not
427 have (as the redirection target is from the outer). With
428 such a failed redirection, a call to malloc inside the inner
429 will then result in a "no-operation" (and so no memory will
430 be allocated).
431
432 When running as an inner, no redirection will be done
433 for a vgpreload file if this file is not located in the
434 inner VALGRIND_LIB directory.
435
436 Recognising a vgpreload file based on a filename pattern
437 is a kludge. An alternate solution would be to change
438 the _vgr prefix according to outer/inner/client.
439 */
florian19f91bb2012-11-10 22:29:54 +0000440 const HChar* newdi_filename = VG_(DebugInfo_get_filename)(newdi);
441 const HChar* newdi_basename = VG_(basename) (newdi_filename);
philippe277eaff2012-03-03 12:01:48 +0000442 if (VG_(strncmp) (newdi_basename, "vgpreload_", 10) == 0) {
443 /* This looks like a vgpreload file => check if this file
444 is from the inner VALGRIND_LIB.
445 We do this check using VG_(stat) + dev/inode comparison
446 as vg-in-place defines a VALGRIND_LIB with symlinks
447 pointing to files inside the valgrind build directories. */
448 struct vg_stat newdi_stat;
449 SysRes newdi_res;
florian54fe2022012-10-27 23:07:42 +0000450 HChar in_vglib_filename[VKI_PATH_MAX];
philippe277eaff2012-03-03 12:01:48 +0000451 struct vg_stat in_vglib_stat;
452 SysRes in_vglib_res;
453
454 newdi_res = VG_(stat)(newdi_filename, &newdi_stat);
455
456 VG_(strncpy) (in_vglib_filename, VG_(libdir), VKI_PATH_MAX);
457 VG_(strncat) (in_vglib_filename, "/", VKI_PATH_MAX);
458 VG_(strncat) (in_vglib_filename, newdi_basename, VKI_PATH_MAX);
459 in_vglib_res = VG_(stat)(in_vglib_filename, &in_vglib_stat);
460
461 /* If we find newdi_basename in inner VALGRIND_LIB
462 but newdi_filename is not the same file, then we do
463 not execute the redirection. */
464 if (!sr_isError(in_vglib_res)
465 && !sr_isError(newdi_res)
466 && (newdi_stat.dev != in_vglib_stat.dev
467 || newdi_stat.ino != in_vglib_stat.ino)) {
468 /* <inner VALGRIND_LIB>/newdi_basename is an existing file
469 and is different of newdi_filename.
470 So, we do not execute newdi_filename redirection. */
471 if ( VG_(clo_verbosity) > 1 ) {
472 VG_(message)( Vg_DebugMsg,
473 "Skipping vgpreload redir in %s"
474 " (not from VALGRIND_LIB_INNER)\n",
475 newdi_filename);
476 }
477 return;
478 } else {
479 if ( VG_(clo_verbosity) > 1 ) {
480 VG_(message)( Vg_DebugMsg,
481 "Executing vgpreload redir in %s"
482 " (from VALGRIND_LIB_INNER)\n",
483 newdi_filename);
484 }
485 }
486 }
487 }
488#endif
489
490
sewardj0ec07f32006-01-12 12:32:32 +0000491 /* stay sane: we don't already have this. */
492 for (ts = topSpecs; ts; ts = ts->next)
sewardj85cf9002011-08-16 09:54:00 +0000493 vg_assert(ts->seginfo != newdi);
sewardj0ec07f32006-01-12 12:32:32 +0000494
sewardjb8b79ad2008-03-03 01:35:41 +0000495 /* scan this DebugInfo's symbol table, pulling out and demangling
sewardj0ec07f32006-01-12 12:32:32 +0000496 any specs found */
497
498 specList = NULL; /* the spec list we're building up */
499
sewardj85cf9002011-08-16 09:54:00 +0000500 nsyms = VG_(DebugInfo_syms_howmany)( newdi );
sewardj0ec07f32006-01-12 12:32:32 +0000501 for (i = 0; i < nsyms; i++) {
sewardj85cf9002011-08-16 09:54:00 +0000502 VG_(DebugInfo_syms_getidx)( newdi, i, &sym_addr, &sym_toc,
503 NULL, &sym_name_pri, &sym_names_sec,
504 &isText, NULL );
505 /* Set up to conveniently iterate over all names for this symbol. */
florian19f91bb2012-11-10 22:29:54 +0000506 HChar* twoslots[2];
507 HChar** names_init = alloc_symname_array(sym_name_pri, sym_names_sec,
sewardj85cf9002011-08-16 09:54:00 +0000508 &twoslots[0]);
florian19f91bb2012-11-10 22:29:54 +0000509 HChar** names;
sewardj85cf9002011-08-16 09:54:00 +0000510 for (names = names_init; *names; names++) {
511 ok = VG_(maybe_Z_demangle)( *names,
512 demangled_sopatt, N_DEMANGLED,
513 demangled_fnpatt, N_DEMANGLED,
sewardj96044842011-08-18 13:09:55 +0000514 &isWrap, &becTag, &becPrio );
sewardj85cf9002011-08-16 09:54:00 +0000515 /* ignore data symbols */
516 if (!isText)
517 continue;
518 if (!ok) {
519 /* It's not a full-scale redirect, but perhaps it is a load-notify
520 fn? Let the load-notify department see it. */
521 handle_maybe_load_notifier( newdi_soname, *names, sym_addr );
522 continue;
523 }
524 if (check_ppcTOCs && sym_toc == 0) {
525 /* This platform uses toc pointers, but none could be found
526 for this symbol, so we can't safely redirect/wrap to it.
527 Just skip it; we'll make a second pass over the symbols in
528 the following loop, and complain at that point. */
529 continue;
530 }
philippe1e470b52012-05-11 19:33:46 +0000531
532 if (0 == VG_(strncmp) (demangled_sopatt,
533 VG_SO_SYN_PREFIX, VG_SO_SYN_PREFIX_LEN)) {
534 /* This is a redirection for handling lib so synonyms. If we
535 have a matching lib synonym, then replace the sopatt.
536 Otherwise, just ignore this redirection spec. */
537
538 if (!VG_(clo_soname_synonyms))
539 continue; // No synonyms => skip the redir.
540
541 /* Search for a matching synonym=newname*/
542 SizeT const sopatt_syn_len
543 = VG_(strlen)(demangled_sopatt+VG_SO_SYN_PREFIX_LEN);
544 HChar const* last = VG_(clo_soname_synonyms);
545
546 while (*last) {
547 HChar const* first = last;
548 last = advance_to_equal(first);
549
550 if ((last - first) == sopatt_syn_len
551 && 0 == VG_(strncmp)(demangled_sopatt+VG_SO_SYN_PREFIX_LEN,
552 first,
553 sopatt_syn_len)) {
554 // Found the demangle_sopatt synonym => replace it
555 first = last + 1;
556 last = advance_to_comma(first);
557 VG_(strncpy)(demangled_sopatt, first, last - first);
558 demangled_sopatt[last - first] = '\0';
559 break;
560 }
561
562 last = advance_to_comma(last);
563 if (*last == ',')
564 last++;
565 }
566
567 // If we have not replaced the sopatt, then skip the redir.
568 if (0 == VG_(strncmp) (demangled_sopatt,
569 VG_SO_SYN_PREFIX, VG_SO_SYN_PREFIX_LEN))
570 continue;
571 }
572
sewardj85cf9002011-08-16 09:54:00 +0000573 spec = dinfo_zalloc("redir.rnnD.1", sizeof(Spec));
574 vg_assert(spec);
575 spec->from_sopatt = dinfo_strdup("redir.rnnD.2", demangled_sopatt);
576 spec->from_fnpatt = dinfo_strdup("redir.rnnD.3", demangled_fnpatt);
577 vg_assert(spec->from_sopatt);
578 vg_assert(spec->from_fnpatt);
579 spec->to_addr = sym_addr;
580 spec->isWrap = isWrap;
581 spec->becTag = becTag;
sewardj96044842011-08-18 13:09:55 +0000582 spec->becPrio = becPrio;
sewardj85cf9002011-08-16 09:54:00 +0000583 /* check we're not adding manifestly stupid destinations */
584 vg_assert(is_plausible_guest_addr(sym_addr));
585 spec->next = specList;
586 spec->mark = False; /* not significant */
587 spec->done = False; /* not significant */
588 specList = spec;
sewardj0ec07f32006-01-12 12:32:32 +0000589 }
sewardj85cf9002011-08-16 09:54:00 +0000590 free_symname_array(names_init, &twoslots[0]);
sewardj0ec07f32006-01-12 12:32:32 +0000591 }
592
sewardj6b9cc872006-10-17 01:39:30 +0000593 if (check_ppcTOCs) {
594 for (i = 0; i < nsyms; i++) {
sewardj85cf9002011-08-16 09:54:00 +0000595 VG_(DebugInfo_syms_getidx)( newdi, i, &sym_addr, &sym_toc,
596 NULL, &sym_name_pri, &sym_names_sec,
sewardja5cace02011-08-15 09:42:34 +0000597 &isText, NULL );
florian19f91bb2012-11-10 22:29:54 +0000598 HChar* twoslots[2];
599 HChar** names_init = alloc_symname_array(sym_name_pri, sym_names_sec,
sewardj85cf9002011-08-16 09:54:00 +0000600 &twoslots[0]);
florian19f91bb2012-11-10 22:29:54 +0000601 HChar** names;
sewardj85cf9002011-08-16 09:54:00 +0000602 for (names = names_init; *names; names++) {
603 ok = isText
604 && VG_(maybe_Z_demangle)(
605 *names, demangled_sopatt, N_DEMANGLED,
sewardj96044842011-08-18 13:09:55 +0000606 demangled_fnpatt, N_DEMANGLED, &isWrap, NULL, NULL );
sewardj85cf9002011-08-16 09:54:00 +0000607 if (!ok)
608 /* not a redirect. Ignore. */
609 continue;
610 if (sym_toc != 0)
611 /* has a valid toc pointer. Ignore. */
612 continue;
sewardj6b9cc872006-10-17 01:39:30 +0000613
sewardj85cf9002011-08-16 09:54:00 +0000614 for (spec = specList; spec; spec = spec->next)
615 if (0 == VG_(strcmp)(spec->from_sopatt, demangled_sopatt)
616 && 0 == VG_(strcmp)(spec->from_fnpatt, demangled_fnpatt))
617 break;
618 if (spec)
619 /* a redirect to some other copy of that symbol, which
620 does have a TOC value, already exists */
621 continue;
sewardj6b9cc872006-10-17 01:39:30 +0000622
sewardj85cf9002011-08-16 09:54:00 +0000623 /* Complain */
624 VG_(message)(Vg_DebugMsg,
625 "WARNING: no TOC ptr for redir/wrap to %s %s\n",
626 demangled_sopatt, demangled_fnpatt);
627 }
628 free_symname_array(names_init, &twoslots[0]);
sewardj6b9cc872006-10-17 01:39:30 +0000629 }
630 }
631
sewardjf9ebc392010-05-09 22:30:43 +0000632 /* Ok. Now specList holds the list of specs from the DebugInfo.
sewardj0ec07f32006-01-12 12:32:32 +0000633 Build a new TopSpec, but don't add it to topSpecs yet. */
sewardj9c606bd2008-09-18 18:12:50 +0000634 newts = dinfo_zalloc("redir.rnnD.4", sizeof(TopSpec));
sewardj0ec07f32006-01-12 12:32:32 +0000635 vg_assert(newts);
636 newts->next = NULL; /* not significant */
sewardj85cf9002011-08-16 09:54:00 +0000637 newts->seginfo = newdi;
sewardj0ec07f32006-01-12 12:32:32 +0000638 newts->specs = specList;
639 newts->mark = False; /* not significant */
640
641 /* We now need to augment the active set with the following partial
642 cross product:
643
644 (1) actives formed by matching the new specs in specList against
645 all symbols currently listed in topSpecs
646
sewardj85cf9002011-08-16 09:54:00 +0000647 (2) actives formed by matching the new symbols in newdi against
sewardj0ec07f32006-01-12 12:32:32 +0000648 all specs currently listed in topSpecs
649
sewardj85cf9002011-08-16 09:54:00 +0000650 (3) actives formed by matching the new symbols in newdi against
sewardj0ec07f32006-01-12 12:32:32 +0000651 the new specs in specList
652
653 This is necessary in order to maintain the invariant that
654 Actives contains all bindings generated by matching ALL specs in
655 topSpecs against ALL symbols in topSpecs (that is, a cross
656 product of ALL known specs against ALL known symbols).
657 */
658 /* Case (1) */
659 for (ts = topSpecs; ts; ts = ts->next) {
660 if (ts->seginfo)
661 generate_and_add_actives( specList, newts,
662 ts->seginfo, ts );
663 }
sewardj6b9cc872006-10-17 01:39:30 +0000664
sewardj0ec07f32006-01-12 12:32:32 +0000665 /* Case (2) */
666 for (ts = topSpecs; ts; ts = ts->next) {
667 generate_and_add_actives( ts->specs, ts,
sewardj85cf9002011-08-16 09:54:00 +0000668 newdi, newts );
sewardj0ec07f32006-01-12 12:32:32 +0000669 }
670
671 /* Case (3) */
672 generate_and_add_actives( specList, newts,
sewardj85cf9002011-08-16 09:54:00 +0000673 newdi, newts );
sewardj0ec07f32006-01-12 12:32:32 +0000674
675 /* Finally, add the new TopSpec. */
676 newts->next = topSpecs;
677 topSpecs = newts;
678
679 if (VG_(clo_trace_redir))
sewardjb8b79ad2008-03-03 01:35:41 +0000680 show_redir_state("after VG_(redir_notify_new_DebugInfo)");
sewardjf9ebc392010-05-09 22:30:43 +0000681
682 /* Really finally (quite unrelated to all the above) check the
683 names in the module against any --require-text-symbol=
684 specifications we might have. */
sewardj85cf9002011-08-16 09:54:00 +0000685 handle_require_text_symbols(newdi);
sewardj0ec07f32006-01-12 12:32:32 +0000686}
687
688#undef N_DEMANGLED
689
tomd2645142009-10-29 09:27:11 +0000690/* Add a new target for an indirect function. Adds a new redirection
691 for the indirection function with address old_from that redirects
692 the ordinary function with address new_from to the target address
693 of the original redirection. */
694
695void VG_(redir_add_ifunc_target)( Addr old_from, Addr new_from )
696{
697 Active *old, new;
698
699 old = VG_(OSetGen_Lookup)(activeSet, &old_from);
700 vg_assert(old);
701 vg_assert(old->isIFunc);
702
703 new = *old;
704 new.from_addr = new_from;
705 new.isIFunc = False;
706 maybe_add_active (new);
707
708 if (VG_(clo_trace_redir)) {
709 VG_(message)( Vg_DebugMsg,
sewardj85cf9002011-08-16 09:54:00 +0000710 "Adding redirect for indirect function "
711 "0x%llx from 0x%llx -> 0x%llx\n",
tomd2645142009-10-29 09:27:11 +0000712 (ULong)old_from, (ULong)new_from, (ULong)new.to_addr );
713 }
714}
sewardj0ec07f32006-01-12 12:32:32 +0000715
716/* Do one element of the basic cross product: add to the active set,
717 all matches resulting from comparing all the given specs against
718 all the symbols in the given seginfo. If a conflicting binding
719 would thereby arise, don't add it, but do complain. */
720
721static
722void generate_and_add_actives (
723 /* spec list and the owning TopSpec */
724 Spec* specs,
725 TopSpec* parent_spec,
726 /* seginfo and the owning TopSpec */
sewardjb8b79ad2008-03-03 01:35:41 +0000727 DebugInfo* di,
sewardj0ec07f32006-01-12 12:32:32 +0000728 TopSpec* parent_sym
729 )
730{
sewardj85cf9002011-08-16 09:54:00 +0000731 Spec* sp;
732 Bool anyMark, isText, isIFunc;
733 Active act;
734 Int nsyms, i;
735 Addr sym_addr;
florian19f91bb2012-11-10 22:29:54 +0000736 HChar* sym_name_pri;
737 HChar** sym_names_sec;
sewardj0ec07f32006-01-12 12:32:32 +0000738
sewardjdf24cf12007-11-16 18:32:40 +0000739 /* First figure out which of the specs match the seginfo's soname.
740 Also clear the 'done' bits, so that after the main loop below
741 tell which of the Specs really did get done. */
sewardj0ec07f32006-01-12 12:32:32 +0000742 anyMark = False;
743 for (sp = specs; sp; sp = sp->next) {
sewardjdf24cf12007-11-16 18:32:40 +0000744 sp->done = False;
sewardj0ec07f32006-01-12 12:32:32 +0000745 sp->mark = VG_(string_match)( sp->from_sopatt,
sewardje3f1e592009-07-31 09:41:29 +0000746 VG_(DebugInfo_get_soname)(di) );
sewardj0ec07f32006-01-12 12:32:32 +0000747 anyMark = anyMark || sp->mark;
748 }
749
750 /* shortcut: if none of the sonames match, there will be no bindings. */
751 if (!anyMark)
752 return;
753
754 /* Iterate outermost over the symbols in the seginfo, in the hope
755 of trashing the caches less. */
sewardje3f1e592009-07-31 09:41:29 +0000756 nsyms = VG_(DebugInfo_syms_howmany)( di );
sewardj0ec07f32006-01-12 12:32:32 +0000757 for (i = 0; i < nsyms; i++) {
sewardj85cf9002011-08-16 09:54:00 +0000758 VG_(DebugInfo_syms_getidx)( di, i, &sym_addr, NULL,
759 NULL, &sym_name_pri, &sym_names_sec,
760 &isText, &isIFunc );
florian19f91bb2012-11-10 22:29:54 +0000761 HChar* twoslots[2];
762 HChar** names_init = alloc_symname_array(sym_name_pri, sym_names_sec,
sewardj85cf9002011-08-16 09:54:00 +0000763 &twoslots[0]);
florian19f91bb2012-11-10 22:29:54 +0000764 HChar** names;
sewardj85cf9002011-08-16 09:54:00 +0000765 for (names = names_init; *names; names++) {
sewardjb8b79ad2008-03-03 01:35:41 +0000766
sewardj85cf9002011-08-16 09:54:00 +0000767 /* ignore data symbols */
768 if (!isText)
769 continue;
sewardj6b9cc872006-10-17 01:39:30 +0000770
sewardj85cf9002011-08-16 09:54:00 +0000771 for (sp = specs; sp; sp = sp->next) {
772 if (!sp->mark)
773 continue; /* soname doesn't match */
774 if (VG_(string_match)( sp->from_fnpatt, *names )) {
775 /* got a new binding. Add to collection. */
776 act.from_addr = sym_addr;
777 act.to_addr = sp->to_addr;
778 act.parent_spec = parent_spec;
779 act.parent_sym = parent_sym;
780 act.becTag = sp->becTag;
sewardj96044842011-08-18 13:09:55 +0000781 act.becPrio = sp->becPrio;
sewardj85cf9002011-08-16 09:54:00 +0000782 act.isWrap = sp->isWrap;
783 act.isIFunc = isIFunc;
784 sp->done = True;
785 maybe_add_active( act );
786 }
787 } /* for (sp = specs; sp; sp = sp->next) */
788
789 } /* iterating over names[] */
790 free_symname_array(names_init, &twoslots[0]);
sewardjdf24cf12007-11-16 18:32:40 +0000791 } /* for (i = 0; i < nsyms; i++) */
792
793 /* Now, finally, look for Specs which were marked to be done, but
794 didn't get matched. If any such are mandatory we must abort the
795 system at this point. */
796 for (sp = specs; sp; sp = sp->next) {
797 if (!sp->mark)
798 continue;
799 if (sp->mark && (!sp->done) && sp->mandatory)
800 break;
801 }
802 if (sp) {
sewardjf499c7d2009-08-10 19:39:02 +0000803 const HChar** strp;
florian6bd9dc12012-11-23 16:17:43 +0000804 const HChar* v = "valgrind: ";
sewardjdf24cf12007-11-16 18:32:40 +0000805 vg_assert(sp->mark);
806 vg_assert(!sp->done);
807 vg_assert(sp->mandatory);
808 VG_(printf)("\n");
809 VG_(printf)(
810 "%sFatal error at startup: a function redirection\n", v);
811 VG_(printf)(
812 "%swhich is mandatory for this platform-tool combination\n", v);
813 VG_(printf)(
814 "%scannot be set up. Details of the redirection are:\n", v);
815 VG_(printf)(
816 "%s\n", v);
817 VG_(printf)(
818 "%sA must-be-redirected function\n", v);
819 VG_(printf)(
820 "%swhose name matches the pattern: %s\n", v, sp->from_fnpatt);
821 VG_(printf)(
822 "%sin an object with soname matching: %s\n", v, sp->from_sopatt);
823 VG_(printf)(
824 "%swas not found whilst processing\n", v);
825 VG_(printf)(
sewardje3f1e592009-07-31 09:41:29 +0000826 "%ssymbols from the object with soname: %s\n",
827 v, VG_(DebugInfo_get_soname)(di));
sewardjdf24cf12007-11-16 18:32:40 +0000828 VG_(printf)(
829 "%s\n", v);
sewardjb57e6932009-08-02 12:21:31 +0000830
831 for (strp = sp->mandatory; *strp; strp++)
832 VG_(printf)(
833 "%s%s\n", v, *strp);
834
sewardjdf24cf12007-11-16 18:32:40 +0000835 VG_(printf)(
836 "%s\n", v);
837 VG_(printf)(
838 "%sCannot continue -- exiting now. Sorry.\n", v);
839 VG_(printf)("\n");
840 VG_(exit)(1);
sewardj0ec07f32006-01-12 12:32:32 +0000841 }
842}
843
844
845/* Add an act (passed by value; is copied here) and deal with
846 conflicting bindings. */
847static void maybe_add_active ( Active act )
848{
florian6bd9dc12012-11-23 16:17:43 +0000849 const HChar* what = NULL;
sewardj96044842011-08-18 13:09:55 +0000850 Active* old = NULL;
851 Bool add_act = False;
sewardj0ec07f32006-01-12 12:32:32 +0000852
853 /* Complain and ignore manifestly bogus 'from' addresses.
854
855 Kludge: because this can get called befor the trampoline area (a
856 bunch of magic 'to' addresses) has its ownership changed from V
857 to C, we can't check the 'to' address similarly. Sigh.
858
859 amd64-linux hack: the vsysinfo pages appear to have no
860 permissions
861 ffffffffff600000-ffffffffffe00000 ---p 00000000 00:00 0
862 so skip the check for them. */
863 if (!is_plausible_guest_addr(act.from_addr)
864# if defined(VGP_amd64_linux)
865 && act.from_addr != 0xFFFFFFFFFF600000ULL
866 && act.from_addr != 0xFFFFFFFFFF600400ULL
tomd6ae9e62012-02-09 11:54:16 +0000867 && act.from_addr != 0xFFFFFFFFFF600800ULL
sewardj0ec07f32006-01-12 12:32:32 +0000868# endif
869 ) {
870 what = "redirection from-address is in non-executable area";
871 goto bad;
872 }
873
njne2a9ad32007-09-17 05:30:48 +0000874 old = VG_(OSetGen_Lookup)( activeSet, &act.from_addr );
sewardj0ec07f32006-01-12 12:32:32 +0000875 if (old) {
876 /* Dodgy. Conflicting binding. */
877 vg_assert(old->from_addr == act.from_addr);
878 if (old->to_addr != act.to_addr) {
sewardjbd2cff22011-08-16 21:45:28 +0000879 /* We've got a conflicting binding -- that is, from_addr is
880 specified to redirect to two different destinations,
881 old->to_addr and act.to_addr. If we can prove that they
882 are behaviourally equivalent then that's no problem. So
883 we can look at the behavioural eclass tags for both
884 functions to see if that's so. If they are equal, and
885 nonzero, then that's fine. But if not, we can't show they
886 are equivalent, so we have to complain, and ignore the new
887 binding. */
sewardj96044842011-08-18 13:09:55 +0000888 vg_assert(old->becTag >= 0 && old->becTag <= 9999);
889 vg_assert(old->becPrio >= 0 && old->becPrio <= 9);
890 vg_assert(act.becTag >= 0 && act.becTag <= 9999);
891 vg_assert(act.becPrio >= 0 && act.becPrio <= 9);
892 if (old->becTag == 0)
893 vg_assert(old->becPrio == 0);
894 if (act.becTag == 0)
895 vg_assert(act.becPrio == 0);
896
897 if (old->becTag == 0 || act.becTag == 0 || old->becTag != act.becTag) {
898 /* We can't show that they are equivalent. Complain and
899 ignore. */
900 what = "new redirection conflicts with existing -- ignoring it";
901 goto bad;
902 }
903 /* They have the same eclass tag. Use the priorities to
904 resolve the ambiguity. */
905 if (act.becPrio <= old->becPrio) {
906 /* The new one doesn't have a higher priority, so just
907 ignore it. */
sewardj14127d62011-08-17 21:23:21 +0000908 if (VG_(clo_verbosity) > 2) {
sewardj96044842011-08-18 13:09:55 +0000909 VG_(message)(Vg_UserMsg, "Ignoring %s redirection:\n",
910 act.becPrio < old->becPrio ? "lower priority"
911 : "duplicate");
sewardj14127d62011-08-17 21:23:21 +0000912 show_active( " old: ", old);
913 show_active( " new: ", &act);
914 }
sewardjbd2cff22011-08-16 21:45:28 +0000915 } else {
sewardj96044842011-08-18 13:09:55 +0000916 /* The tricky case. The new one has a higher priority, so
917 we need to get the old one out of the OSet and install
918 this one in its place. */
919 if (VG_(clo_verbosity) > 1) {
920 VG_(message)(Vg_UserMsg,
921 "Preferring higher priority redirection:\n");
922 show_active( " old: ", old);
923 show_active( " new: ", &act);
924 }
925 add_act = True;
926 void* oldNd = VG_(OSetGen_Remove)( activeSet, &act.from_addr );
927 vg_assert(oldNd == old);
928 VG_(OSetGen_FreeNode)( activeSet, old );
929 old = NULL;
sewardjbd2cff22011-08-16 21:45:28 +0000930 }
njnd9109c62005-06-26 04:49:25 +0000931 } else {
sewardj0ec07f32006-01-12 12:32:32 +0000932 /* This appears to be a duplicate of an existing binding.
933 Safe(ish) -- ignore. */
934 /* XXXXXXXXXXX COMPLAIN if new and old parents differ */
tom748a1312005-04-02 15:53:01 +0000935 }
sewardj96044842011-08-18 13:09:55 +0000936
njnd9109c62005-06-26 04:49:25 +0000937 } else {
sewardj96044842011-08-18 13:09:55 +0000938 /* There's no previous binding for this from_addr, so we must
939 add 'act' to the active set. */
940 add_act = True;
941 }
942
943 /* So, finally, actually add it. */
944 if (add_act) {
njne2a9ad32007-09-17 05:30:48 +0000945 Active* a = VG_(OSetGen_AllocNode)(activeSet, sizeof(Active));
sewardj0ec07f32006-01-12 12:32:32 +0000946 vg_assert(a);
947 *a = act;
njne2a9ad32007-09-17 05:30:48 +0000948 VG_(OSetGen_Insert)(activeSet, a);
sewardj0ec07f32006-01-12 12:32:32 +0000949 /* Now that a new from->to redirection is in force, we need to
950 get rid of any translations intersecting 'from' in order that
951 they get redirected to 'to'. So discard them. Just for
952 paranoia (but, I believe, unnecessarily), discard 'to' as
953 well. */
954 VG_(discard_translations)( (Addr64)act.from_addr, 1,
sewardjb8b79ad2008-03-03 01:35:41 +0000955 "redir_new_DebugInfo(from_addr)");
sewardj0ec07f32006-01-12 12:32:32 +0000956 VG_(discard_translations)( (Addr64)act.to_addr, 1,
sewardjb8b79ad2008-03-03 01:35:41 +0000957 "redir_new_DebugInfo(to_addr)");
sewardj14127d62011-08-17 21:23:21 +0000958 if (VG_(clo_verbosity) > 2) {
959 VG_(message)(Vg_UserMsg, "Adding active redirection:\n");
960 show_active( " new: ", &act);
961 }
sewardj0ec07f32006-01-12 12:32:32 +0000962 }
963 return;
964
965 bad:
966 vg_assert(what);
sewardj96044842011-08-18 13:09:55 +0000967 vg_assert(!add_act);
sewardj0ec07f32006-01-12 12:32:32 +0000968 if (VG_(clo_verbosity) > 1) {
sewardj738856f2009-07-15 14:48:32 +0000969 VG_(message)(Vg_UserMsg, "WARNING: %s\n", what);
sewardjbd2cff22011-08-16 21:45:28 +0000970 if (old) {
971 show_active( " old: ", old);
972 }
sewardj0ec07f32006-01-12 12:32:32 +0000973 show_active( " new: ", &act);
njnd9109c62005-06-26 04:49:25 +0000974 }
tom748a1312005-04-02 15:53:01 +0000975}
976
njnd9109c62005-06-26 04:49:25 +0000977
sewardjb8b79ad2008-03-03 01:35:41 +0000978/* Notify m_redir of the deletion of a DebugInfo. This is relatively
sewardj0ec07f32006-01-12 12:32:32 +0000979 simple -- just get rid of all actives derived from it, and free up
980 the associated list elements. */
981
sewardjb8b79ad2008-03-03 01:35:41 +0000982void VG_(redir_notify_delete_DebugInfo)( DebugInfo* delsi )
sewardj0ec07f32006-01-12 12:32:32 +0000983{
984 TopSpec* ts;
985 TopSpec* tsPrev;
986 Spec* sp;
987 Spec* sp_next;
988 OSet* tmpSet;
989 Active* act;
990 Bool delMe;
njne2a9ad32007-09-17 05:30:48 +0000991 Addr addr;
sewardj0ec07f32006-01-12 12:32:32 +0000992
993 vg_assert(delsi);
994
995 /* Search for it, and make tsPrev point to the previous entry, if
996 any. */
997 tsPrev = NULL;
998 ts = topSpecs;
999 while (True) {
1000 if (ts == NULL) break;
1001 if (ts->seginfo == delsi) break;
1002 tsPrev = ts;
1003 ts = ts->next;
1004 }
1005
sewardjb8b79ad2008-03-03 01:35:41 +00001006 vg_assert(ts); /* else we don't have the deleted DebugInfo */
sewardj0ec07f32006-01-12 12:32:32 +00001007 vg_assert(ts->seginfo == delsi);
1008
1009 /* Traverse the actives, copying the addresses of those we intend
1010 to delete into tmpSet. */
sewardj9c606bd2008-09-18 18:12:50 +00001011 tmpSet = VG_(OSetWord_Create)(dinfo_zalloc, "redir.rndD.1", dinfo_free);
sewardj0ec07f32006-01-12 12:32:32 +00001012
1013 ts->mark = True;
1014
njne2a9ad32007-09-17 05:30:48 +00001015 VG_(OSetGen_ResetIter)( activeSet );
1016 while ( (act = VG_(OSetGen_Next)(activeSet)) ) {
sewardj0ec07f32006-01-12 12:32:32 +00001017 delMe = act->parent_spec != NULL
1018 && act->parent_sym != NULL
1019 && act->parent_spec->seginfo != NULL
1020 && act->parent_sym->seginfo != NULL
1021 && (act->parent_spec->mark || act->parent_sym->mark);
1022
1023 /* While we're at it, a bit of paranoia: delete any actives
sewardje6647f42006-03-12 00:39:19 +00001024 which don't have both feet in valid client executable areas.
1025 But don't delete hardwired-at-startup ones; these are denoted
1026 by having parent_spec or parent_sym being NULL. */
1027 if ( (!delMe)
1028 && act->parent_spec != NULL
1029 && act->parent_sym != NULL ) {
1030 if (!is_plausible_guest_addr(act->from_addr))
1031 delMe = True;
1032 if (!is_plausible_guest_addr(act->to_addr))
1033 delMe = True;
sewardj0ec07f32006-01-12 12:32:32 +00001034 }
1035
1036 if (delMe) {
njne2a9ad32007-09-17 05:30:48 +00001037 VG_(OSetWord_Insert)( tmpSet, act->from_addr );
sewardj0ec07f32006-01-12 12:32:32 +00001038 /* While we have our hands on both the 'from' and 'to'
1039 of this Active, do paranoid stuff with tt/tc. */
1040 VG_(discard_translations)( (Addr64)act->from_addr, 1,
sewardjb8b79ad2008-03-03 01:35:41 +00001041 "redir_del_DebugInfo(from_addr)");
sewardj0ec07f32006-01-12 12:32:32 +00001042 VG_(discard_translations)( (Addr64)act->to_addr, 1,
sewardjb8b79ad2008-03-03 01:35:41 +00001043 "redir_del_DebugInfo(to_addr)");
sewardj0ec07f32006-01-12 12:32:32 +00001044 }
1045 }
1046
njne2a9ad32007-09-17 05:30:48 +00001047 /* Now traverse tmpSet, deleting corresponding elements in activeSet. */
1048 VG_(OSetWord_ResetIter)( tmpSet );
1049 while ( VG_(OSetWord_Next)(tmpSet, &addr) ) {
1050 act = VG_(OSetGen_Remove)( activeSet, &addr );
sewardj0ec07f32006-01-12 12:32:32 +00001051 vg_assert(act);
njne2a9ad32007-09-17 05:30:48 +00001052 VG_(OSetGen_FreeNode)( activeSet, act );
sewardj0ec07f32006-01-12 12:32:32 +00001053 }
1054
njne2a9ad32007-09-17 05:30:48 +00001055 VG_(OSetWord_Destroy)( tmpSet );
sewardj0ec07f32006-01-12 12:32:32 +00001056
1057 /* The Actives set is now cleaned up. Free up this TopSpec and
1058 everything hanging off it. */
1059 for (sp = ts->specs; sp; sp = sp_next) {
sewardjb8b79ad2008-03-03 01:35:41 +00001060 if (sp->from_sopatt) dinfo_free(sp->from_sopatt);
1061 if (sp->from_fnpatt) dinfo_free(sp->from_fnpatt);
sewardj0ec07f32006-01-12 12:32:32 +00001062 sp_next = sp->next;
sewardjb8b79ad2008-03-03 01:35:41 +00001063 dinfo_free(sp);
sewardj0ec07f32006-01-12 12:32:32 +00001064 }
1065
1066 if (tsPrev == NULL) {
1067 /* first in list */
1068 topSpecs = ts->next;
njnd9109c62005-06-26 04:49:25 +00001069 } else {
sewardj0ec07f32006-01-12 12:32:32 +00001070 tsPrev->next = ts->next;
sewardjcbdddcf2005-03-10 23:23:45 +00001071 }
sewardjb8b79ad2008-03-03 01:35:41 +00001072 dinfo_free(ts);
sewardjcbdddcf2005-03-10 23:23:45 +00001073
sewardj0ec07f32006-01-12 12:32:32 +00001074 if (VG_(clo_trace_redir))
sewardjb8b79ad2008-03-03 01:35:41 +00001075 show_redir_state("after VG_(redir_notify_delete_DebugInfo)");
sewardjcbdddcf2005-03-10 23:23:45 +00001076}
1077
sewardj0ec07f32006-01-12 12:32:32 +00001078
1079/*------------------------------------------------------------*/
1080/*--- QUERIES (really the whole point of this module) ---*/
1081/*------------------------------------------------------------*/
1082
1083/* This is the crucial redirection function. It answers the question:
1084 should this code address be redirected somewhere else? It's used
1085 just before translating a basic block. */
1086Addr VG_(redir_do_lookup) ( Addr orig, Bool* isWrap )
sewardjcbdddcf2005-03-10 23:23:45 +00001087{
njne2a9ad32007-09-17 05:30:48 +00001088 Active* r = VG_(OSetGen_Lookup)(activeSet, &orig);
sewardjcbdddcf2005-03-10 23:23:45 +00001089 if (r == NULL)
sewardj0ec07f32006-01-12 12:32:32 +00001090 return orig;
sewardjcbdddcf2005-03-10 23:23:45 +00001091
1092 vg_assert(r->to_addr != 0);
sewardj0ec07f32006-01-12 12:32:32 +00001093 if (isWrap)
tomd2645142009-10-29 09:27:11 +00001094 *isWrap = r->isWrap || r->isIFunc;
tom3b42e162009-11-16 09:06:09 +00001095 if (r->isIFunc) {
1096 vg_assert(iFuncWrapper);
tomd2645142009-10-29 09:27:11 +00001097 return iFuncWrapper;
tom3b42e162009-11-16 09:06:09 +00001098 }
sewardjcbdddcf2005-03-10 23:23:45 +00001099 return r->to_addr;
1100}
1101
sewardj0ec07f32006-01-12 12:32:32 +00001102
1103/*------------------------------------------------------------*/
1104/*--- INITIALISATION ---*/
1105/*------------------------------------------------------------*/
1106
1107/* Add a never-delete-me Active. */
1108
1109__attribute__((unused)) /* only used on amd64 */
1110static void add_hardwired_active ( Addr from, Addr to )
njn8a96ec52005-10-15 15:48:52 +00001111{
sewardj0ec07f32006-01-12 12:32:32 +00001112 Active act;
1113 act.from_addr = from;
1114 act.to_addr = to;
1115 act.parent_spec = NULL;
1116 act.parent_sym = NULL;
sewardj85cf9002011-08-16 09:54:00 +00001117 act.becTag = 0; /* "not equivalent to any other fn" */
sewardj96044842011-08-18 13:09:55 +00001118 act.becPrio = 0; /* mandatory when becTag == 0 */
sewardj0ec07f32006-01-12 12:32:32 +00001119 act.isWrap = False;
tomb6fd3652009-11-01 16:37:33 +00001120 act.isIFunc = False;
sewardj0ec07f32006-01-12 12:32:32 +00001121 maybe_add_active( act );
njn8a96ec52005-10-15 15:48:52 +00001122}
1123
sewardj0ec07f32006-01-12 12:32:32 +00001124
1125/* Add a never-delete-me Spec. This is a bit of a kludge. On the
1126 assumption that this is called only at startup, only handle the
1127 case where topSpecs is completely empty, or if it isn't, it has
1128 just one entry and that is the one with NULL seginfo -- that is the
1129 entry that holds these initial specs. */
1130
1131__attribute__((unused)) /* not used on all platforms */
florian6bd9dc12012-11-23 16:17:43 +00001132static void add_hardwired_spec (const HChar* sopatt, const HChar* fnpatt,
1133 Addr to_addr,
1134 const HChar** mandatory )
njn8a96ec52005-10-15 15:48:52 +00001135{
sewardj9c606bd2008-09-18 18:12:50 +00001136 Spec* spec = dinfo_zalloc("redir.ahs.1", sizeof(Spec));
sewardj0ec07f32006-01-12 12:32:32 +00001137 vg_assert(spec);
1138
1139 if (topSpecs == NULL) {
sewardj9c606bd2008-09-18 18:12:50 +00001140 topSpecs = dinfo_zalloc("redir.ahs.2", sizeof(TopSpec));
sewardj0ec07f32006-01-12 12:32:32 +00001141 vg_assert(topSpecs);
sewardjdf24cf12007-11-16 18:32:40 +00001142 /* symtab_zalloc sets all fields to zero */
sewardj0ec07f32006-01-12 12:32:32 +00001143 }
1144
1145 vg_assert(topSpecs != NULL);
1146 vg_assert(topSpecs->next == NULL);
1147 vg_assert(topSpecs->seginfo == NULL);
sewardjdf24cf12007-11-16 18:32:40 +00001148 /* FIXED PARTS */
florian6bd9dc12012-11-23 16:17:43 +00001149 spec->from_sopatt = (HChar *)sopatt;
1150 spec->from_fnpatt = (HChar *)fnpatt;
sewardj0ec07f32006-01-12 12:32:32 +00001151 spec->to_addr = to_addr;
1152 spec->isWrap = False;
sewardjdf24cf12007-11-16 18:32:40 +00001153 spec->mandatory = mandatory;
1154 /* VARIABLE PARTS */
sewardj0ec07f32006-01-12 12:32:32 +00001155 spec->mark = False; /* not significant */
sewardjdf24cf12007-11-16 18:32:40 +00001156 spec->done = False; /* not significant */
sewardj0ec07f32006-01-12 12:32:32 +00001157
1158 spec->next = topSpecs->specs;
1159 topSpecs->specs = spec;
njn8a96ec52005-10-15 15:48:52 +00001160}
1161
njn8a96ec52005-10-15 15:48:52 +00001162
sewardjb57e6932009-08-02 12:21:31 +00001163__attribute__((unused)) /* not used on all platforms */
1164static const HChar* complain_about_stripped_glibc_ldso[]
1165= { "Possible fixes: (1, short term): install glibc's debuginfo",
1166 "package on this machine. (2, longer term): ask the packagers",
1167 "for your Linux distribution to please in future ship a non-",
1168 "stripped ld.so (or whatever the dynamic linker .so is called)",
1169 "that exports the above-named function using the standard",
sewardjd85ee0c2011-02-11 16:47:03 +00001170 "calling conventions for this platform. The package you need",
1171 "to install for fix (1) is called",
1172 "",
1173 " On Debian, Ubuntu: libc6-dbg",
1174 " On SuSE, openSuSE, Fedora, RHEL: glibc-debuginfo",
sewardjb57e6932009-08-02 12:21:31 +00001175 NULL
1176 };
1177
1178
sewardj0ec07f32006-01-12 12:32:32 +00001179/* Initialise the redir system, and create the initial Spec list and
1180 for amd64-linux a couple of permanent active mappings. The initial
1181 Specs are not converted into Actives yet, on the (checked)
sewardjb8b79ad2008-03-03 01:35:41 +00001182 assumption that no DebugInfos have so far been created, and so when
sewardj0ec07f32006-01-12 12:32:32 +00001183 they are created, that will happen. */
1184
1185void VG_(redir_initialise) ( void )
1186{
sewardjb8b79ad2008-03-03 01:35:41 +00001187 // Assert that there are no DebugInfos so far
sewardje3f1e592009-07-31 09:41:29 +00001188 vg_assert( VG_(next_DebugInfo)(NULL) == NULL );
sewardj0ec07f32006-01-12 12:32:32 +00001189
1190 // Initialise active mapping.
njne2a9ad32007-09-17 05:30:48 +00001191 activeSet = VG_(OSetGen_Create)(offsetof(Active, from_addr),
1192 NULL, // Use fast comparison
sewardjb8b79ad2008-03-03 01:35:41 +00001193 dinfo_zalloc,
sewardj9c606bd2008-09-18 18:12:50 +00001194 "redir.ri.1",
sewardjb8b79ad2008-03-03 01:35:41 +00001195 dinfo_free);
sewardj0ec07f32006-01-12 12:32:32 +00001196
1197 // The rest of this function just adds initial Specs.
1198
1199# if defined(VGP_x86_linux)
sewardj6a443b22005-11-20 19:37:54 +00001200 /* If we're using memcheck, use this intercept right from the
1201 start, otherwise ld.so (glibc-2.3.5) makes a lot of noise. */
1202 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
sewardjd28cc962011-03-28 08:22:55 +00001203 const HChar** mandatory;
1204# if defined(GLIBC_2_2) || defined(GLIBC_2_3) || defined(GLIBC_2_4) \
1205 || defined(GLIBC_2_5) || defined(GLIBC_2_6) || defined(GLIBC_2_7) \
1206 || defined(GLIBC_2_8) || defined(GLIBC_2_9) \
1207 || defined(GLIBC_2_10) || defined(GLIBC_2_11)
1208 mandatory = NULL;
1209# else
1210 /* for glibc-2.12 and later, this is mandatory - can't sanely
1211 continue without it */
1212 mandatory = complain_about_stripped_glibc_ldso;
1213# endif
sewardj0ec07f32006-01-12 12:32:32 +00001214 add_hardwired_spec(
1215 "ld-linux.so.2", "index",
sewardjd28cc962011-03-28 08:22:55 +00001216 (Addr)&VG_(x86_linux_REDIR_FOR_index), mandatory);
1217 add_hardwired_spec(
1218 "ld-linux.so.2", "strlen",
1219 (Addr)&VG_(x86_linux_REDIR_FOR_strlen), mandatory);
sewardj6a443b22005-11-20 19:37:54 +00001220 }
sewardjb9bce632005-06-21 01:41:34 +00001221
sewardj0ec07f32006-01-12 12:32:32 +00001222# elif defined(VGP_amd64_linux)
njnd1af0032005-05-29 17:01:48 +00001223 /* Redirect vsyscalls to local versions */
sewardj0ec07f32006-01-12 12:32:32 +00001224 add_hardwired_active(
sewardjb9bce632005-06-21 01:41:34 +00001225 0xFFFFFFFFFF600000ULL,
tomd6ae9e62012-02-09 11:54:16 +00001226 (Addr)&VG_(amd64_linux_REDIR_FOR_vgettimeofday)
sewardjb9bce632005-06-21 01:41:34 +00001227 );
tomd6ae9e62012-02-09 11:54:16 +00001228 add_hardwired_active(
tomf5db3b62005-06-21 13:26:17 +00001229 0xFFFFFFFFFF600400ULL,
tomd6ae9e62012-02-09 11:54:16 +00001230 (Addr)&VG_(amd64_linux_REDIR_FOR_vtime)
1231 );
1232 add_hardwired_active(
1233 0xFFFFFFFFFF600800ULL,
1234 (Addr)&VG_(amd64_linux_REDIR_FOR_vgetcpu)
sewardjb9bce632005-06-21 01:41:34 +00001235 );
1236
sewardjb57e6932009-08-02 12:21:31 +00001237 /* If we're using memcheck, use these intercepts right from
1238 the start, otherwise ld.so makes a lot of noise. */
1239 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
bart2ebe4112008-06-01 16:33:37 +00001240
sewardjb57e6932009-08-02 12:21:31 +00001241 add_hardwired_spec(
1242 "ld-linux-x86-64.so.2", "strlen",
1243 (Addr)&VG_(amd64_linux_REDIR_FOR_strlen),
1244# if defined(GLIBC_2_2) || defined(GLIBC_2_3) || defined(GLIBC_2_4) \
1245 || defined(GLIBC_2_5) || defined(GLIBC_2_6) || defined(GLIBC_2_7) \
1246 || defined(GLIBC_2_8) || defined(GLIBC_2_9)
1247 NULL
1248# else
1249 /* for glibc-2.10 and later, this is mandatory - can't sanely
1250 continue without it */
1251 complain_about_stripped_glibc_ldso
1252# endif
1253 );
1254 }
1255
1256# elif defined(VGP_ppc32_linux)
sewardj96fcfc82005-11-18 21:12:52 +00001257 /* If we're using memcheck, use these intercepts right from
1258 the start, otherwise ld.so makes a lot of noise. */
1259 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
sewardj0fd30492007-11-16 19:39:49 +00001260
sewardj5092a972007-11-16 18:45:40 +00001261 /* this is mandatory - can't sanely continue without it */
sewardj0ec07f32006-01-12 12:32:32 +00001262 add_hardwired_spec(
1263 "ld.so.1", "strlen",
sewardjdf24cf12007-11-16 18:32:40 +00001264 (Addr)&VG_(ppc32_linux_REDIR_FOR_strlen),
sewardjb57e6932009-08-02 12:21:31 +00001265 complain_about_stripped_glibc_ldso
sewardj96fcfc82005-11-18 21:12:52 +00001266 );
sewardj0ec07f32006-01-12 12:32:32 +00001267 add_hardwired_spec(
sewardjd5a30a42006-02-09 10:29:43 +00001268 "ld.so.1", "strcmp",
sewardjdf24cf12007-11-16 18:32:40 +00001269 (Addr)&VG_(ppc32_linux_REDIR_FOR_strcmp),
sewardj5092a972007-11-16 18:45:40 +00001270 NULL /* not mandatory - so why bother at all? */
1271 /* glibc-2.6.1 (openSUSE 10.3, ppc32) seems fine without it */
sewardj96fcfc82005-11-18 21:12:52 +00001272 );
sewardjcd8c95a2006-08-25 11:48:38 +00001273 add_hardwired_spec(
1274 "ld.so.1", "index",
sewardjdf24cf12007-11-16 18:32:40 +00001275 (Addr)&VG_(ppc32_linux_REDIR_FOR_strchr),
sewardj5092a972007-11-16 18:45:40 +00001276 NULL /* not mandatory - so why bother at all? */
1277 /* glibc-2.6.1 (openSUSE 10.3, ppc32) seems fine without it */
sewardjcd8c95a2006-08-25 11:48:38 +00001278 );
bart2ebe4112008-06-01 16:33:37 +00001279 }
sewardjb9bce632005-06-21 01:41:34 +00001280
sewardj0ec07f32006-01-12 12:32:32 +00001281# elif defined(VGP_ppc64_linux)
sewardjf0915fc2006-01-05 14:07:04 +00001282 /* If we're using memcheck, use these intercepts right from
1283 the start, otherwise ld.so makes a lot of noise. */
1284 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
1285
sewardj0fd30492007-11-16 19:39:49 +00001286 /* this is mandatory - can't sanely continue without it */
sewardj1a85f4f2006-01-12 21:15:35 +00001287 add_hardwired_spec(
1288 "ld64.so.1", "strlen",
sewardjdf24cf12007-11-16 18:32:40 +00001289 (Addr)VG_(fnptr_to_fnentry)( &VG_(ppc64_linux_REDIR_FOR_strlen) ),
sewardjb57e6932009-08-02 12:21:31 +00001290 complain_about_stripped_glibc_ldso
sewardjdf24cf12007-11-16 18:32:40 +00001291 );
sewardjf0915fc2006-01-05 14:07:04 +00001292
sewardj1a85f4f2006-01-12 21:15:35 +00001293 add_hardwired_spec(
1294 "ld64.so.1", "index",
sewardjdf24cf12007-11-16 18:32:40 +00001295 (Addr)VG_(fnptr_to_fnentry)( &VG_(ppc64_linux_REDIR_FOR_strchr) ),
sewardj0fd30492007-11-16 19:39:49 +00001296 NULL /* not mandatory - so why bother at all? */
1297 /* glibc-2.5 (FC6, ppc64) seems fine without it */
sewardjdf24cf12007-11-16 18:32:40 +00001298 );
bart2ebe4112008-06-01 16:33:37 +00001299 }
sewardj2c48c7b2005-11-29 13:05:56 +00001300
sewardj59570ff2010-01-01 11:59:33 +00001301# elif defined(VGP_arm_linux)
1302 /* If we're using memcheck, use these intercepts right from
1303 the start, otherwise ld.so makes a lot of noise. */
1304 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
1305 add_hardwired_spec(
1306 "ld-linux.so.3", "strlen",
1307 (Addr)&VG_(arm_linux_REDIR_FOR_strlen),
sewardjd69cee82010-08-22 12:13:35 +00001308 complain_about_stripped_glibc_ldso
sewardj59570ff2010-01-01 11:59:33 +00001309 );
1310 //add_hardwired_spec(
1311 // "ld-linux.so.3", "index",
1312 // (Addr)&VG_(arm_linux_REDIR_FOR_index),
1313 // NULL
1314 //);
1315 add_hardwired_spec(
1316 "ld-linux.so.3", "memcpy",
1317 (Addr)&VG_(arm_linux_REDIR_FOR_memcpy),
sewardjd69cee82010-08-22 12:13:35 +00001318 complain_about_stripped_glibc_ldso
sewardj59570ff2010-01-01 11:59:33 +00001319 );
1320 }
sewardjf0c12502014-01-12 12:54:00 +00001321
1322# elif defined(VGP_arm64_linux)
1323 /* If we're using memcheck, use these intercepts right from
1324 the start, otherwise ld.so makes a lot of noise. */
1325 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
sewardj7aa66512014-03-09 09:44:32 +00001326 add_hardwired_spec(
1327 "ld-linux-aarch64.so.1", "strlen",
1328 (Addr)&VG_(arm64_linux_REDIR_FOR_strlen),
1329 complain_about_stripped_glibc_ldso
1330 );
1331 add_hardwired_spec(
1332 "ld-linux-aarch64.so.1", "index",
1333 (Addr)&VG_(arm64_linux_REDIR_FOR_index),
1334 NULL
1335 );
1336 add_hardwired_spec(
1337 "ld-linux-aarch64.so.1", "strcmp",
1338 (Addr)&VG_(arm64_linux_REDIR_FOR_strcmp),
1339 NULL
1340 );
1341 //add_hardwired_spec(
1342 // "ld-linux.so.3", "memcpy",
1343 // (Addr)&VG_(arm_linux_REDIR_FOR_memcpy),
1344 // complain_about_stripped_glibc_ldso
1345 //);
sewardjf0c12502014-01-12 12:54:00 +00001346 }
sewardj59570ff2010-01-01 11:59:33 +00001347
njnea2d6fd2010-07-01 00:20:20 +00001348# elif defined(VGP_x86_darwin)
njnf76d27a2009-05-28 01:53:07 +00001349 /* If we're using memcheck, use these intercepts right from
1350 the start, otherwise dyld makes a lot of noise. */
1351 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
1352 add_hardwired_spec("dyld", "strcmp",
njnea2d6fd2010-07-01 00:20:20 +00001353 (Addr)&VG_(x86_darwin_REDIR_FOR_strcmp), NULL);
njnf76d27a2009-05-28 01:53:07 +00001354 add_hardwired_spec("dyld", "strlen",
njnea2d6fd2010-07-01 00:20:20 +00001355 (Addr)&VG_(x86_darwin_REDIR_FOR_strlen), NULL);
njnf76d27a2009-05-28 01:53:07 +00001356 add_hardwired_spec("dyld", "strcat",
njnea2d6fd2010-07-01 00:20:20 +00001357 (Addr)&VG_(x86_darwin_REDIR_FOR_strcat), NULL);
njnf76d27a2009-05-28 01:53:07 +00001358 add_hardwired_spec("dyld", "strcpy",
njnea2d6fd2010-07-01 00:20:20 +00001359 (Addr)&VG_(x86_darwin_REDIR_FOR_strcpy), NULL);
njnf76d27a2009-05-28 01:53:07 +00001360 add_hardwired_spec("dyld", "strlcat",
njnea2d6fd2010-07-01 00:20:20 +00001361 (Addr)&VG_(x86_darwin_REDIR_FOR_strlcat), NULL);
1362 }
1363
1364# elif defined(VGP_amd64_darwin)
1365 /* If we're using memcheck, use these intercepts right from
1366 the start, otherwise dyld makes a lot of noise. */
1367 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
1368 add_hardwired_spec("dyld", "strcmp",
1369 (Addr)&VG_(amd64_darwin_REDIR_FOR_strcmp), NULL);
1370 add_hardwired_spec("dyld", "strlen",
1371 (Addr)&VG_(amd64_darwin_REDIR_FOR_strlen), NULL);
1372 add_hardwired_spec("dyld", "strcat",
1373 (Addr)&VG_(amd64_darwin_REDIR_FOR_strcat), NULL);
1374 add_hardwired_spec("dyld", "strcpy",
1375 (Addr)&VG_(amd64_darwin_REDIR_FOR_strcpy), NULL);
1376 add_hardwired_spec("dyld", "strlcat",
1377 (Addr)&VG_(amd64_darwin_REDIR_FOR_strlcat), NULL);
njnf76d27a2009-05-28 01:53:07 +00001378 // DDD: #warning fixme rdar://6166275
1379 add_hardwired_spec("dyld", "arc4random",
njnea2d6fd2010-07-01 00:20:20 +00001380 (Addr)&VG_(amd64_darwin_REDIR_FOR_arc4random), NULL);
njnf76d27a2009-05-28 01:53:07 +00001381 }
1382
sewardjb5b87402011-03-07 16:05:35 +00001383# elif defined(VGP_s390x_linux)
1384 /* nothing so far */
1385
sewardj5db15402012-06-07 09:13:21 +00001386# elif defined(VGP_mips32_linux)
1387 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
1388
1389 /* this is mandatory - can't sanely continue without it */
1390 add_hardwired_spec(
1391 "ld.so.3", "strlen",
1392 (Addr)&VG_(mips32_linux_REDIR_FOR_strlen),
1393 complain_about_stripped_glibc_ldso
1394 );
1395 }
1396
petarj4df0bfc2013-02-27 23:17:33 +00001397# elif defined(VGP_mips64_linux)
1398 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
1399
1400 /* this is mandatory - can't sanely continue without it */
1401 add_hardwired_spec(
1402 "ld.so.3", "strlen",
1403 (Addr)&VG_(mips64_linux_REDIR_FOR_strlen),
1404 complain_about_stripped_glibc_ldso
1405 );
1406 }
1407
sewardj0ec07f32006-01-12 12:32:32 +00001408# else
1409# error Unknown platform
1410# endif
1411
1412 if (VG_(clo_trace_redir))
1413 show_redir_state("after VG_(redir_initialise)");
njnd1af0032005-05-29 17:01:48 +00001414}
sewardjcbdddcf2005-03-10 23:23:45 +00001415
njn16eeb4e2005-06-16 03:56:58 +00001416
sewardj0ec07f32006-01-12 12:32:32 +00001417/*------------------------------------------------------------*/
1418/*--- MISC HELPERS ---*/
1419/*------------------------------------------------------------*/
1420
florian54fe2022012-10-27 23:07:42 +00001421static void* dinfo_zalloc(const HChar* ec, SizeT n) {
sewardjdf24cf12007-11-16 18:32:40 +00001422 void* p;
1423 vg_assert(n > 0);
sewardj9c606bd2008-09-18 18:12:50 +00001424 p = VG_(arena_malloc)(VG_AR_DINFO, ec, n);
sewardjdf24cf12007-11-16 18:32:40 +00001425 tl_assert(p);
1426 VG_(memset)(p, 0, n);
1427 return p;
njn16eeb4e2005-06-16 03:56:58 +00001428}
1429
sewardjb8b79ad2008-03-03 01:35:41 +00001430static void dinfo_free(void* p) {
sewardjdf24cf12007-11-16 18:32:40 +00001431 tl_assert(p);
sewardjb8b79ad2008-03-03 01:35:41 +00001432 return VG_(arena_free)(VG_AR_DINFO, p);
njn16eeb4e2005-06-16 03:56:58 +00001433}
1434
florian54fe2022012-10-27 23:07:42 +00001435static HChar* dinfo_strdup(const HChar* ec, const HChar* str)
njnbc6d84d2005-06-19 18:58:03 +00001436{
sewardj9c606bd2008-09-18 18:12:50 +00001437 return VG_(arena_strdup)(VG_AR_DINFO, ec, str);
njnbc6d84d2005-06-19 18:58:03 +00001438}
1439
sewardj0ec07f32006-01-12 12:32:32 +00001440/* Really this should be merged with translations_allowable_from_seg
1441 in m_translate. */
1442static Bool is_plausible_guest_addr(Addr a)
njn16eeb4e2005-06-16 03:56:58 +00001443{
sewardj6b9cc872006-10-17 01:39:30 +00001444 NSegment const* seg = VG_(am_find_nsegment)(a);
sewardj0ec07f32006-01-12 12:32:32 +00001445 return seg != NULL
1446 && (seg->kind == SkAnonC || seg->kind == SkFileC)
1447 && (seg->hasX || seg->hasR); /* crude x86-specific hack */
1448}
1449
sewardjf9ebc392010-05-09 22:30:43 +00001450
sewardj0ec07f32006-01-12 12:32:32 +00001451/*------------------------------------------------------------*/
1452/*--- NOTIFY-ON-LOAD FUNCTIONS ---*/
1453/*------------------------------------------------------------*/
1454
sewardja672ea32006-04-29 18:03:14 +00001455static
florian19f91bb2012-11-10 22:29:54 +00001456void handle_maybe_load_notifier( const HChar* soname,
sewardja672ea32006-04-29 18:03:14 +00001457 HChar* symbol, Addr addr )
sewardj0ec07f32006-01-12 12:32:32 +00001458{
sewardja672ea32006-04-29 18:03:14 +00001459# if defined(VGP_x86_linux)
1460 /* x86-linux only: if we see _dl_sysinfo_int80, note its address.
1461 See comment on declaration of VG_(client__dl_sysinfo_int80) for
1462 the reason. As far as I can tell, the relevant symbol is always
1463 in object with soname "ld-linux.so.2". */
1464 if (symbol && symbol[0] == '_'
1465 && 0 == VG_(strcmp)(symbol, "_dl_sysinfo_int80")
1466 && 0 == VG_(strcmp)(soname, "ld-linux.so.2")) {
1467 if (VG_(client__dl_sysinfo_int80) == 0)
1468 VG_(client__dl_sysinfo_int80) = addr;
1469 }
1470# endif
1471
1472 /* Normal load-notifier handling after here. First, ignore all
1473 symbols lacking the right prefix. */
sewardjdd9508c2011-05-04 09:03:41 +00001474 vg_assert(symbol); // assert rather than segfault if it is NULL
sewardj0ec07f32006-01-12 12:32:32 +00001475 if (0 != VG_(strncmp)(symbol, VG_NOTIFY_ON_LOAD_PREFIX,
1476 VG_NOTIFY_ON_LOAD_PREFIX_LEN))
1477 /* Doesn't have the right prefix */
1478 return;
1479
1480 if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(freeres))) == 0)
1481 VG_(client___libc_freeres_wrapper) = addr;
sewardj96044842011-08-18 13:09:55 +00001482 else
1483 if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(ifunc_wrapper))) == 0)
tomd2645142009-10-29 09:27:11 +00001484 iFuncWrapper = addr;
njn16eeb4e2005-06-16 03:56:58 +00001485 else
1486 vg_assert2(0, "unrecognised load notification function: %s", symbol);
1487}
1488
sewardj0ec07f32006-01-12 12:32:32 +00001489
1490/*------------------------------------------------------------*/
sewardjf9ebc392010-05-09 22:30:43 +00001491/*--- REQUIRE-TEXT-SYMBOL HANDLING ---*/
1492/*------------------------------------------------------------*/
1493
1494/* In short: check that the currently-being-loaded object has text
1495 symbols that satisfy any --require-text-symbol= specifications that
1496 apply to it, and abort the run with an error message if not.
1497*/
1498static void handle_require_text_symbols ( DebugInfo* di )
1499{
1500 /* First thing to do is figure out which, if any,
1501 --require-text-symbol specification strings apply to this
1502 object. Most likely none do, since it is not expected to
1503 frequently be used. Work through the list of specs and
1504 accumulate in fnpatts[] the fn patterns that pertain to this
1505 object. */
1506 HChar* fnpatts[VG_CLO_MAX_REQ_TSYMS];
1507 Int fnpatts_used = 0;
1508 Int i, j;
1509 const HChar* di_soname = VG_(DebugInfo_get_soname)(di);
1510 vg_assert(di_soname); // must be present
1511
1512 VG_(memset)(&fnpatts, 0, sizeof(fnpatts));
1513
1514 vg_assert(VG_(clo_n_req_tsyms) >= 0);
1515 vg_assert(VG_(clo_n_req_tsyms) <= VG_CLO_MAX_REQ_TSYMS);
1516 for (i = 0; i < VG_(clo_n_req_tsyms); i++) {
florian19f91bb2012-11-10 22:29:54 +00001517 const HChar* clo_spec = VG_(clo_req_tsyms)[i];
1518 vg_assert(clo_spec && VG_(strlen)(clo_spec) >= 4);
sewardjf9ebc392010-05-09 22:30:43 +00001519 // clone the spec, so we can stick a zero at the end of the sopatt
florian19f91bb2012-11-10 22:29:54 +00001520 HChar *spec = VG_(strdup)("m_redir.hrts.1", clo_spec);
sewardjf9ebc392010-05-09 22:30:43 +00001521 HChar sep = spec[0];
1522 HChar* sopatt = &spec[1];
1523 HChar* fnpatt = VG_(strchr)(sopatt, sep);
1524 // the initial check at clo processing in time in m_main
1525 // should ensure this.
1526 vg_assert(fnpatt && *fnpatt == sep);
1527 *fnpatt = 0;
1528 fnpatt++;
1529 if (VG_(string_match)(sopatt, di_soname))
1530 fnpatts[fnpatts_used++]
1531 = VG_(strdup)("m_redir.hrts.2", fnpatt);
1532 VG_(free)(spec);
1533 }
1534
1535 if (fnpatts_used == 0)
1536 return; /* no applicable spec strings */
1537
1538 /* So finally, fnpatts[0 .. fnpatts_used - 1] contains the set of
1539 (patterns for) text symbol names that must be found in this
1540 object, in order to continue. That is, we must find at least
1541 one text symbol name that matches each pattern, else we must
1542 abort the run. */
1543
1544 if (0) VG_(printf)("for %s\n", di_soname);
1545 for (i = 0; i < fnpatts_used; i++)
1546 if (0) VG_(printf)(" fnpatt: %s\n", fnpatts[i]);
1547
1548 /* For each spec, look through the syms to find one that matches.
1549 This isn't terribly efficient but it happens rarely, so no big
1550 deal. */
1551 for (i = 0; i < fnpatts_used; i++) {
sewardj85cf9002011-08-16 09:54:00 +00001552 Bool found = False;
sewardjf9ebc392010-05-09 22:30:43 +00001553 HChar* fnpatt = fnpatts[i];
sewardj85cf9002011-08-16 09:54:00 +00001554 Int nsyms = VG_(DebugInfo_syms_howmany)(di);
sewardjf9ebc392010-05-09 22:30:43 +00001555 for (j = 0; j < nsyms; j++) {
sewardj85cf9002011-08-16 09:54:00 +00001556 Bool isText = False;
florian19f91bb2012-11-10 22:29:54 +00001557 HChar* sym_name_pri = NULL;
1558 HChar** sym_names_sec = NULL;
sewardjf9ebc392010-05-09 22:30:43 +00001559 VG_(DebugInfo_syms_getidx)( di, j, NULL, NULL,
sewardj85cf9002011-08-16 09:54:00 +00001560 NULL, &sym_name_pri, &sym_names_sec,
sewardja5cace02011-08-15 09:42:34 +00001561 &isText, NULL );
florian19f91bb2012-11-10 22:29:54 +00001562 HChar* twoslots[2];
1563 HChar** names_init = alloc_symname_array(sym_name_pri, sym_names_sec,
sewardj85cf9002011-08-16 09:54:00 +00001564 &twoslots[0]);
florian19f91bb2012-11-10 22:29:54 +00001565 HChar** names;
sewardj85cf9002011-08-16 09:54:00 +00001566 for (names = names_init; *names; names++) {
1567 /* ignore data symbols */
1568 if (0) VG_(printf)("QQQ %s\n", *names);
1569 vg_assert(sym_name_pri);
1570 if (!isText)
1571 continue;
1572 if (VG_(string_match)(fnpatt, *names)) {
1573 found = True;
1574 break;
1575 }
sewardjf9ebc392010-05-09 22:30:43 +00001576 }
sewardj85cf9002011-08-16 09:54:00 +00001577 free_symname_array(names_init, &twoslots[0]);
1578 if (found)
1579 break;
sewardjf9ebc392010-05-09 22:30:43 +00001580 }
1581
1582 if (!found) {
florian6bd9dc12012-11-23 16:17:43 +00001583 const HChar* v = "valgrind: ";
sewardjf9ebc392010-05-09 22:30:43 +00001584 VG_(printf)("\n");
1585 VG_(printf)(
1586 "%sFatal error at when loading library with soname\n", v);
1587 VG_(printf)(
1588 "%s %s\n", v, di_soname);
1589 VG_(printf)(
1590 "%sCannot find any text symbol with a name "
1591 "that matches the pattern\n", v);
1592 VG_(printf)("%s %s\n", v, fnpatt);
1593 VG_(printf)("%sas required by a --require-text-symbol= "
1594 "specification.\n", v);
1595 VG_(printf)("\n");
1596 VG_(printf)(
1597 "%sCannot continue -- exiting now.\n", v);
1598 VG_(printf)("\n");
1599 VG_(exit)(1);
1600 }
1601 }
1602
1603 /* All required specs were found. Just free memory and return. */
1604 for (i = 0; i < fnpatts_used; i++)
1605 VG_(free)(fnpatts[i]);
1606}
1607
1608
1609/*------------------------------------------------------------*/
sewardj0ec07f32006-01-12 12:32:32 +00001610/*--- SANITY/DEBUG ---*/
1611/*------------------------------------------------------------*/
1612
florian54fe2022012-10-27 23:07:42 +00001613static void show_spec ( const HChar* left, Spec* spec )
njn16eeb4e2005-06-16 03:56:58 +00001614{
sewardj738856f2009-07-15 14:48:32 +00001615 VG_(message)( Vg_DebugMsg,
sewardj96044842011-08-18 13:09:55 +00001616 "%s%25s %30s %s-> (%04d.%d) 0x%08llx\n",
sewardj738856f2009-07-15 14:48:32 +00001617 left,
1618 spec->from_sopatt, spec->from_fnpatt,
1619 spec->isWrap ? "W" : "R",
sewardj96044842011-08-18 13:09:55 +00001620 spec->becTag, spec->becPrio,
sewardj738856f2009-07-15 14:48:32 +00001621 (ULong)spec->to_addr );
njn16eeb4e2005-06-16 03:56:58 +00001622}
1623
florian54fe2022012-10-27 23:07:42 +00001624static void show_active ( const HChar* left, Active* act )
njn16eeb4e2005-06-16 03:56:58 +00001625{
sewardj0ec07f32006-01-12 12:32:32 +00001626 Bool ok;
1627 HChar name1[64] = "";
1628 HChar name2[64] = "";
1629 name1[0] = name2[0] = 0;
1630 ok = VG_(get_fnname_w_offset)(act->from_addr, name1, 64);
1631 if (!ok) VG_(strcpy)(name1, "???");
1632 ok = VG_(get_fnname_w_offset)(act->to_addr, name2, 64);
1633 if (!ok) VG_(strcpy)(name2, "???");
1634
sewardj96044842011-08-18 13:09:55 +00001635 VG_(message)(Vg_DebugMsg, "%s0x%08llx (%20s) %s-> (%04d.%d) 0x%08llx %s\n",
sewardj0ec07f32006-01-12 12:32:32 +00001636 left,
1637 (ULong)act->from_addr, name1,
1638 act->isWrap ? "W" : "R",
sewardj96044842011-08-18 13:09:55 +00001639 act->becTag, act->becPrio,
1640 (ULong)act->to_addr, name2 );
njn16eeb4e2005-06-16 03:56:58 +00001641}
1642
florian54fe2022012-10-27 23:07:42 +00001643static void show_redir_state ( const HChar* who )
njn16eeb4e2005-06-16 03:56:58 +00001644{
sewardj0ec07f32006-01-12 12:32:32 +00001645 TopSpec* ts;
1646 Spec* sp;
1647 Active* act;
sewardj738856f2009-07-15 14:48:32 +00001648 VG_(message)(Vg_DebugMsg, "<<\n");
1649 VG_(message)(Vg_DebugMsg, " ------ REDIR STATE %s ------\n", who);
sewardj0ec07f32006-01-12 12:32:32 +00001650 for (ts = topSpecs; ts; ts = ts->next) {
philippe80beb242012-05-03 21:09:51 +00001651 if (ts->seginfo)
1652 VG_(message)(Vg_DebugMsg,
1653 " TOPSPECS of soname %s filename %s\n",
florian3e798632012-11-24 19:41:54 +00001654 VG_(DebugInfo_get_soname)(ts->seginfo),
1655 VG_(DebugInfo_get_filename)(ts->seginfo));
philippe80beb242012-05-03 21:09:51 +00001656 else
1657 VG_(message)(Vg_DebugMsg,
1658 " TOPSPECS of soname (hardwired)\n");
1659
sewardj0ec07f32006-01-12 12:32:32 +00001660 for (sp = ts->specs; sp; sp = sp->next)
1661 show_spec(" ", sp);
1662 }
sewardj738856f2009-07-15 14:48:32 +00001663 VG_(message)(Vg_DebugMsg, " ------ ACTIVE ------\n");
njne2a9ad32007-09-17 05:30:48 +00001664 VG_(OSetGen_ResetIter)( activeSet );
1665 while ( (act = VG_(OSetGen_Next)(activeSet)) ) {
sewardj0ec07f32006-01-12 12:32:32 +00001666 show_active(" ", act);
1667 }
1668
sewardj738856f2009-07-15 14:48:32 +00001669 VG_(message)(Vg_DebugMsg, ">>\n");
njn16eeb4e2005-06-16 03:56:58 +00001670}
1671
njnc0ae7052005-08-25 22:55:19 +00001672/*--------------------------------------------------------------------*/
1673/*--- end ---*/
1674/*--------------------------------------------------------------------*/