1 2 /*--------------------------------------------------------------------*/ 3 /*--- Function replacement and wrapping. m_redir.c ---*/ 4 /*--------------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2000-2013 Julian Seward 11 jseward (at) acm.org 12 Copyright (C) 2003-2013 Jeremy Fitzhardinge 13 jeremy (at) 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 */ 32 33 #include "pub_core_basics.h" 34 #include "pub_core_debuglog.h" 35 #include "pub_core_debuginfo.h" 36 #include "pub_core_libcbase.h" 37 #include "pub_core_libcassert.h" 38 #include "pub_core_libcprint.h" 39 #include "pub_core_vki.h" 40 #include "pub_core_libcfile.h" 41 #include "pub_core_seqmatch.h" 42 #include "pub_core_mallocfree.h" 43 #include "pub_core_options.h" 44 #include "pub_core_oset.h" 45 #include "pub_core_redir.h" 46 #include "pub_core_trampoline.h" 47 #include "pub_core_transtab.h" 48 #include "pub_core_tooliface.h" // VG_(needs).malloc_replacement 49 #include "pub_core_machine.h" // VG_(fnptr_to_fnentry) 50 #include "pub_core_aspacemgr.h" // VG_(am_find_nsegment) 51 #include "pub_core_xarray.h" 52 #include "pub_core_clientstate.h" // VG_(client___libc_freeres_wrapper) 53 #include "pub_core_demangle.h" // VG_(maybe_Z_demangle) 54 #include "pub_core_libcproc.h" // VG_(libdir) 55 56 #include "config.h" /* GLIBC_MANDATORY_*_REDIRECT */ 57 58 59 /* 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. 73 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). 81 82 Redirect specifications are really symbols with "funny" prefixes 83 (_vgrNNNNZU_ and _vgrNNNNZZ_). These names tell m_redir that the 84 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 90 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. 95 96 When a shared object is unloaded, this module learns of it via a 97 call to VG_(redir_notify_delete_DebugInfo). It then removes from 98 its tables all active redirections in any way associated with that 99 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 107 /*------------------------------------------------------------*/ 108 /*--- Semantics ---*/ 109 /*------------------------------------------------------------*/ 110 111 /* The redirector holds two pieces of state: 112 113 Specs - a set of (soname pattern, fnname pattern) -> redir addr 114 Active - a set of orig addr -> (bool, redir addr) 115 116 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. 119 120 Active is a pure function of Specs and the current symbol table 121 state (maintained by m_debuginfo). Call the latter SyminfoState. 122 123 Therefore whenever either Specs or SyminfoState changes, Active 124 must be recomputed. [Inefficient if done naively, but this is a 125 spec]. 126 127 Active is computed as follows: 128 129 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 } 139 } 140 141 [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 179 When a new DebugInfo appears: 180 - it may be the source of new specs 181 - it may be the source of new matches for existing specs 182 Therefore: 183 184 - (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 187 new actives. 188 189 - (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. 192 193 - (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. 196 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 206 When a DebugInfo disappears: 207 - 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 219 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. */ 228 typedef 229 struct _Spec { 230 struct _Spec* next; /* linked list */ 231 /* FIXED PARTS -- set when created and not changed */ 232 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? */ 236 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. */ 239 Int becPrio; /* 0 through 9. Behavioural equivalence class prio. 240 Used to choose between competing wrappers with 241 the same (non-zero) tag. */ 242 const HChar** mandatory; /* non-NULL ==> abort V and print the 243 strings if from_sopatt is loaded but 244 from_fnpatt cannot be found */ 245 /* 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 */ 248 } 249 Spec; 250 251 /* 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 253 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. */ 256 typedef 257 struct _TopSpec { 258 struct _TopSpec* next; /* linked list */ 259 const DebugInfo* seginfo; /* symbols etc */ 260 Spec* specs; /* specs pulled out of seginfo */ 261 Bool mark; /* transient temporary used during deletion */ 262 } 263 TopSpec; 264 265 /* This is the top level list of redirections. m_debuginfo maintains 266 a list of DebugInfos, and the idea here is to maintain a list with 267 the same number of elements (in fact, with one more element, so as 268 to record abovementioned preloaded specifications.) */ 269 static 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. */ 280 typedef 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 */ 286 Int becTag; /* behavioural eclass tag for ::to_addr */ 287 Int becPrio; /* and its priority */ 288 Bool isWrap; /* wrap or replacement? */ 289 Bool isIFunc; /* indirect function? */ 290 } 291 Active; 292 293 /* The active set is a fast lookup table */ 294 static OSet* activeSet = NULL; 295 296 /* Wrapper routine for indirect functions */ 297 static Addr iFuncWrapper; 298 299 /*------------------------------------------------------------*/ 300 /*--- FWDses ---*/ 301 /*------------------------------------------------------------*/ 302 303 static void maybe_add_active ( Active /*by value; callee copies*/ ); 304 305 static void* dinfo_zalloc(const HChar* ec, SizeT); 306 static void dinfo_free(void*); 307 static HChar* dinfo_strdup(const HChar* ec, const HChar*); 308 static Bool is_plausible_guest_addr(Addr); 309 310 static void show_redir_state ( const HChar* who ); 311 static void show_active ( const HChar* left, const Active* act ); 312 313 static void handle_maybe_load_notifier( const HChar* soname, 314 const HChar* symbol, Addr addr ); 315 316 static void handle_require_text_symbols ( const DebugInfo* ); 317 318 /*------------------------------------------------------------*/ 319 /*--- NOTIFICATIONS ---*/ 320 /*------------------------------------------------------------*/ 321 322 static 323 void generate_and_add_actives ( 324 /* spec list and the owning TopSpec */ 325 Spec* specs, 326 TopSpec* parent_spec, 327 /* debuginfo and the owning TopSpec */ 328 const DebugInfo* di, 329 TopSpec* parent_sym 330 ); 331 332 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. */ 337 static const HChar** alloc_symname_array ( const HChar* pri_name, 338 const HChar** sec_names, 339 const HChar** twoslots ) 340 { 341 /* Special-case the common case: only one name. We expect the 342 caller to supply a stack-allocated 2-entry array for this. */ 343 if (sec_names == NULL) { 344 twoslots[0] = pri_name; 345 twoslots[1] = NULL; 346 return twoslots; 347 } 348 /* Else must use dynamic allocation. Figure out size .. */ 349 Word n_req = 1; 350 const HChar** pp = sec_names; 351 while (*pp) { n_req++; pp++; } 352 /* .. allocate and copy in. */ 353 const HChar** arr = dinfo_zalloc("redir.asa.1", (n_req+1) * sizeof(HChar*)); 354 Word i = 0; 355 arr[i++] = pri_name; 356 pp = sec_names; 357 while (*pp) { arr[i++] = *pp; pp++; } 358 vg_assert(i == n_req); 359 vg_assert(arr[n_req] == NULL); 360 return arr; 361 } 362 363 364 /* Free the array allocated by alloc_symname_array, if any. */ 365 static void free_symname_array ( const HChar** names, const HChar** twoslots ) 366 { 367 if (names != twoslots) 368 dinfo_free(names); 369 } 370 371 static HChar const* advance_to_equal ( HChar const* c ) { 372 while (*c && *c != '=') { 373 ++c; 374 } 375 return c; 376 } 377 static HChar const* advance_to_comma ( HChar const* c ) { 378 while (*c && *c != ',') { 379 ++c; 380 } 381 return c; 382 } 383 384 /* Notify m_redir of the arrival of a new DebugInfo. This is fairly 385 complex, but the net effect is to (1) add a new entry to the 386 topspecs list, and (2) figure out what new binding are now active, 387 and, as a result, add them to the actives mapping. */ 388 389 void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) 390 { 391 Bool ok, isWrap; 392 Int i, nsyms, becTag, becPrio; 393 Spec* specList; 394 Spec* spec; 395 TopSpec* ts; 396 TopSpec* newts; 397 const HChar* sym_name_pri; 398 const HChar** sym_names_sec; 399 SymAVMAs sym_avmas; 400 const HChar* demangled_sopatt; 401 const HChar* demangled_fnpatt; 402 Bool check_ppcTOCs = False; 403 Bool isText; 404 const HChar* newdi_soname; 405 Bool dehacktivate_pthread_stack_cache_var_search = False; 406 const HChar* const pthread_soname = "libpthread.so.0"; 407 const HChar* const pthread_stack_cache_actsize_varname 408 = "stack_cache_actsize"; 409 410 # if defined(VG_PLAT_USES_PPCTOC) 411 check_ppcTOCs = True; 412 # endif 413 414 vg_assert(newdi); 415 newdi_soname = VG_(DebugInfo_get_soname)(newdi); 416 vg_assert(newdi_soname != NULL); 417 418 #ifdef ENABLE_INNER 419 { 420 /* When an outer Valgrind is executing an inner Valgrind, the 421 inner "sees" in its address space the mmap-ed vgpreload files 422 of the outer. The inner must avoid interpreting the 423 redirections given in the outer vgpreload mmap-ed files. 424 Otherwise, some tool combinations badly fail. 425 426 Example: outer memcheck tool executing an inner none tool. 427 428 If inner none interprets the outer malloc redirection, the 429 inner will redirect malloc to a memcheck function it does not 430 have (as the redirection target is from the outer). With 431 such a failed redirection, a call to malloc inside the inner 432 will then result in a "no-operation" (and so no memory will 433 be allocated). 434 435 When running as an inner, no redirection will be done 436 for a vgpreload file if this file is not located in the 437 inner VALGRIND_LIB directory. 438 439 Recognising a vgpreload file based on a filename pattern 440 is a kludge. An alternate solution would be to change 441 the _vgr prefix according to outer/inner/client. 442 */ 443 const HChar* newdi_filename = VG_(DebugInfo_get_filename)(newdi); 444 const HChar* newdi_basename = VG_(basename) (newdi_filename); 445 if (VG_(strncmp) (newdi_basename, "vgpreload_", 10) == 0) { 446 /* This looks like a vgpreload file => check if this file 447 is from the inner VALGRIND_LIB. 448 We do this check using VG_(stat) + dev/inode comparison 449 as vg-in-place defines a VALGRIND_LIB with symlinks 450 pointing to files inside the valgrind build directories. */ 451 struct vg_stat newdi_stat; 452 SysRes newdi_res; 453 struct vg_stat in_vglib_stat; 454 SysRes in_vglib_res; 455 456 newdi_res = VG_(stat)(newdi_filename, &newdi_stat); 457 458 HChar in_vglib_filename[VG_(strlen)(VG_(libdir)) + 1 + 459 VG_(strlen)(newdi_basename) + 1]; 460 VG_(sprintf)(in_vglib_filename, "%s/%s", VG_(libdir), newdi_basename); 461 462 in_vglib_res = VG_(stat)(in_vglib_filename, &in_vglib_stat); 463 464 /* If we find newdi_basename in inner VALGRIND_LIB 465 but newdi_filename is not the same file, then we do 466 not execute the redirection. */ 467 if (!sr_isError(in_vglib_res) 468 && !sr_isError(newdi_res) 469 && (newdi_stat.dev != in_vglib_stat.dev 470 || newdi_stat.ino != in_vglib_stat.ino)) { 471 /* <inner VALGRIND_LIB>/newdi_basename is an existing file 472 and is different of newdi_filename. 473 So, we do not execute newdi_filename redirection. */ 474 if ( VG_(clo_verbosity) > 1 ) { 475 VG_(message)( Vg_DebugMsg, 476 "Skipping vgpreload redir in %s" 477 " (not from VALGRIND_LIB_INNER)\n", 478 newdi_filename); 479 } 480 return; 481 } else { 482 if ( VG_(clo_verbosity) > 1 ) { 483 VG_(message)( Vg_DebugMsg, 484 "Executing vgpreload redir in %s" 485 " (from VALGRIND_LIB_INNER)\n", 486 newdi_filename); 487 } 488 } 489 } 490 } 491 #endif 492 493 494 /* stay sane: we don't already have this. */ 495 for (ts = topSpecs; ts; ts = ts->next) 496 vg_assert(ts->seginfo != newdi); 497 498 /* scan this DebugInfo's symbol table, pulling out and demangling 499 any specs found */ 500 501 specList = NULL; /* the spec list we're building up */ 502 503 dehacktivate_pthread_stack_cache_var_search = 504 SimHintiS(SimHint_no_nptl_pthread_stackcache, VG_(clo_sim_hints)) 505 && 0 == VG_(strcmp)(newdi_soname, pthread_soname); 506 507 nsyms = VG_(DebugInfo_syms_howmany)( newdi ); 508 for (i = 0; i < nsyms; i++) { 509 VG_(DebugInfo_syms_getidx)( newdi, i, &sym_avmas, 510 NULL, &sym_name_pri, &sym_names_sec, 511 &isText, NULL ); 512 /* Set up to conveniently iterate over all names for this symbol. */ 513 const HChar* twoslots[2]; 514 const HChar** names_init = 515 alloc_symname_array(sym_name_pri, sym_names_sec, &twoslots[0]); 516 const HChar** names; 517 for (names = names_init; *names; names++) { 518 ok = VG_(maybe_Z_demangle)( *names, 519 &demangled_sopatt, 520 &demangled_fnpatt, 521 &isWrap, &becTag, &becPrio ); 522 /* ignore data symbols */ 523 if (!isText) { 524 /* But search for dehacktivate stack cache var if needed. */ 525 if (dehacktivate_pthread_stack_cache_var_search 526 && 0 == VG_(strcmp)(*names, 527 pthread_stack_cache_actsize_varname)) { 528 if ( VG_(clo_verbosity) > 1 ) { 529 VG_(message)( Vg_DebugMsg, 530 "deactivate nptl pthread stackcache via kludge:" 531 " found symbol %s at addr %p\n", 532 *names, (void*) sym_avmas.main); 533 } 534 VG_(client__stack_cache_actsize__addr) = (SizeT*) sym_avmas.main; 535 dehacktivate_pthread_stack_cache_var_search = False; 536 } 537 continue; 538 } 539 if (!ok) { 540 /* It's not a full-scale redirect, but perhaps it is a load-notify 541 fn? Let the load-notify department see it. */ 542 handle_maybe_load_notifier( newdi_soname, *names, sym_avmas.main ); 543 continue; 544 } 545 if (check_ppcTOCs && GET_TOCPTR_AVMA(sym_avmas) == 0) { 546 /* This platform uses toc pointers, but none could be found 547 for this symbol, so we can't safely redirect/wrap to it. 548 Just skip it; we'll make a second pass over the symbols in 549 the following loop, and complain at that point. */ 550 continue; 551 } 552 553 HChar *replaced_sopatt = NULL; 554 if (0 == VG_(strncmp) (demangled_sopatt, 555 VG_SO_SYN_PREFIX, VG_SO_SYN_PREFIX_LEN)) { 556 /* This is a redirection for handling lib so synonyms. If we 557 have a matching lib synonym, then replace the sopatt. 558 Otherwise, just ignore this redirection spec. */ 559 560 if (!VG_(clo_soname_synonyms)) 561 continue; // No synonyms => skip the redir. 562 563 /* Search for a matching synonym=newname*/ 564 SizeT const sopatt_syn_len 565 = VG_(strlen)(demangled_sopatt+VG_SO_SYN_PREFIX_LEN); 566 HChar const* last = VG_(clo_soname_synonyms); 567 568 while (*last) { 569 HChar const* first = last; 570 last = advance_to_equal(first); 571 572 if ((last - first) == sopatt_syn_len 573 && 0 == VG_(strncmp)(demangled_sopatt+VG_SO_SYN_PREFIX_LEN, 574 first, 575 sopatt_syn_len)) { 576 // Found the demangle_sopatt synonym => replace it 577 first = last + 1; 578 last = advance_to_comma(first); 579 replaced_sopatt = dinfo_zalloc("redir.rnnD.5", 580 last - first + 1); 581 VG_(strncpy)(replaced_sopatt, first, last - first); 582 replaced_sopatt[last - first] = '\0'; 583 demangled_sopatt = replaced_sopatt; 584 break; 585 } 586 587 last = advance_to_comma(last); 588 if (*last == ',') 589 last++; 590 } 591 592 // If we have not replaced the sopatt, then skip the redir. 593 if (replaced_sopatt == NULL) 594 continue; 595 } 596 597 spec = dinfo_zalloc("redir.rnnD.1", sizeof(Spec)); 598 spec->from_sopatt = dinfo_strdup("redir.rnnD.2", demangled_sopatt); 599 spec->from_fnpatt = dinfo_strdup("redir.rnnD.3", demangled_fnpatt); 600 spec->to_addr = sym_avmas.main; 601 spec->isWrap = isWrap; 602 spec->becTag = becTag; 603 spec->becPrio = becPrio; 604 /* check we're not adding manifestly stupid destinations */ 605 vg_assert(is_plausible_guest_addr(sym_avmas.main)); 606 spec->next = specList; 607 spec->mark = False; /* not significant */ 608 spec->done = False; /* not significant */ 609 specList = spec; 610 } 611 free_symname_array(names_init, &twoslots[0]); 612 } 613 if (dehacktivate_pthread_stack_cache_var_search) { 614 VG_(message)(Vg_DebugMsg, 615 "WARNING: could not find symbol for var %s in %s\n", 616 pthread_stack_cache_actsize_varname, pthread_soname); 617 VG_(message)(Vg_DebugMsg, 618 "=> pthread stack cache cannot be disabled!\n"); 619 } 620 621 if (check_ppcTOCs) { 622 for (i = 0; i < nsyms; i++) { 623 VG_(DebugInfo_syms_getidx)( newdi, i, &sym_avmas, 624 NULL, &sym_name_pri, &sym_names_sec, 625 &isText, NULL ); 626 const HChar* twoslots[2]; 627 const HChar** names_init = 628 alloc_symname_array(sym_name_pri, sym_names_sec, &twoslots[0]); 629 const HChar** names; 630 for (names = names_init; *names; names++) { 631 ok = isText 632 && VG_(maybe_Z_demangle)( 633 *names, &demangled_sopatt, 634 &demangled_fnpatt, &isWrap, NULL, NULL ); 635 if (!ok) 636 /* not a redirect. Ignore. */ 637 continue; 638 if (GET_TOCPTR_AVMA(sym_avmas) != 0) 639 /* has a valid toc pointer. Ignore. */ 640 continue; 641 642 for (spec = specList; spec; spec = spec->next) 643 if (0 == VG_(strcmp)(spec->from_sopatt, demangled_sopatt) 644 && 0 == VG_(strcmp)(spec->from_fnpatt, demangled_fnpatt)) 645 break; 646 if (spec) 647 /* a redirect to some other copy of that symbol, which 648 does have a TOC value, already exists */ 649 continue; 650 651 /* Complain */ 652 VG_(message)(Vg_DebugMsg, 653 "WARNING: no TOC ptr for redir/wrap to %s %s\n", 654 demangled_sopatt, demangled_fnpatt); 655 } 656 free_symname_array(names_init, &twoslots[0]); 657 } 658 } 659 660 /* Ok. Now specList holds the list of specs from the DebugInfo. 661 Build a new TopSpec, but don't add it to topSpecs yet. */ 662 newts = dinfo_zalloc("redir.rnnD.4", sizeof(TopSpec)); 663 newts->next = NULL; /* not significant */ 664 newts->seginfo = newdi; 665 newts->specs = specList; 666 newts->mark = False; /* not significant */ 667 668 /* We now need to augment the active set with the following partial 669 cross product: 670 671 (1) actives formed by matching the new specs in specList against 672 all symbols currently listed in topSpecs 673 674 (2) actives formed by matching the new symbols in newdi against 675 all specs currently listed in topSpecs 676 677 (3) actives formed by matching the new symbols in newdi against 678 the new specs in specList 679 680 This is necessary in order to maintain the invariant that 681 Actives contains all bindings generated by matching ALL specs in 682 topSpecs against ALL symbols in topSpecs (that is, a cross 683 product of ALL known specs against ALL known symbols). 684 */ 685 /* Case (1) */ 686 for (ts = topSpecs; ts; ts = ts->next) { 687 if (ts->seginfo) 688 generate_and_add_actives( specList, newts, 689 ts->seginfo, ts ); 690 } 691 692 /* Case (2) */ 693 for (ts = topSpecs; ts; ts = ts->next) { 694 generate_and_add_actives( ts->specs, ts, 695 newdi, newts ); 696 } 697 698 /* Case (3) */ 699 generate_and_add_actives( specList, newts, 700 newdi, newts ); 701 702 /* Finally, add the new TopSpec. */ 703 newts->next = topSpecs; 704 topSpecs = newts; 705 706 if (VG_(clo_trace_redir)) 707 show_redir_state("after VG_(redir_notify_new_DebugInfo)"); 708 709 /* Really finally (quite unrelated to all the above) check the 710 names in the module against any --require-text-symbol= 711 specifications we might have. */ 712 handle_require_text_symbols(newdi); 713 } 714 715 /* Add a new target for an indirect function. Adds a new redirection 716 for the indirection function with address old_from that redirects 717 the ordinary function with address new_from to the target address 718 of the original redirection. */ 719 720 void VG_(redir_add_ifunc_target)( Addr old_from, Addr new_from ) 721 { 722 Active *old, new; 723 724 old = VG_(OSetGen_Lookup)(activeSet, &old_from); 725 vg_assert(old); 726 vg_assert(old->isIFunc); 727 728 new = *old; 729 new.from_addr = new_from; 730 new.isIFunc = False; 731 maybe_add_active (new); 732 733 if (VG_(clo_trace_redir)) { 734 VG_(message)( Vg_DebugMsg, 735 "Adding redirect for indirect function " 736 "0x%lx from 0x%lx -> 0x%lx\n", 737 old_from, new_from, new.to_addr ); 738 } 739 } 740 741 /* Do one element of the basic cross product: add to the active set, 742 all matches resulting from comparing all the given specs against 743 all the symbols in the given seginfo. If a conflicting binding 744 would thereby arise, don't add it, but do complain. */ 745 746 static 747 void generate_and_add_actives ( 748 /* spec list and the owning TopSpec */ 749 Spec* specs, 750 TopSpec* parent_spec, 751 /* seginfo and the owning TopSpec */ 752 const DebugInfo* di, 753 TopSpec* parent_sym 754 ) 755 { 756 Spec* sp; 757 Bool anyMark, isText, isIFunc; 758 Active act; 759 Int nsyms, i; 760 SymAVMAs sym_avmas; 761 const HChar* sym_name_pri; 762 const HChar** sym_names_sec; 763 764 /* First figure out which of the specs match the seginfo's soname. 765 Also clear the 'done' bits, so that after the main loop below 766 tell which of the Specs really did get done. */ 767 anyMark = False; 768 for (sp = specs; sp; sp = sp->next) { 769 sp->done = False; 770 sp->mark = VG_(string_match)( sp->from_sopatt, 771 VG_(DebugInfo_get_soname)(di) ); 772 anyMark = anyMark || sp->mark; 773 } 774 775 /* shortcut: if none of the sonames match, there will be no bindings. */ 776 if (!anyMark) 777 return; 778 779 /* Iterate outermost over the symbols in the seginfo, in the hope 780 of trashing the caches less. */ 781 nsyms = VG_(DebugInfo_syms_howmany)( di ); 782 for (i = 0; i < nsyms; i++) { 783 VG_(DebugInfo_syms_getidx)( di, i, &sym_avmas, 784 NULL, &sym_name_pri, &sym_names_sec, 785 &isText, &isIFunc ); 786 const HChar* twoslots[2]; 787 const HChar** names_init = 788 alloc_symname_array(sym_name_pri, sym_names_sec, &twoslots[0]); 789 const HChar** names; 790 for (names = names_init; *names; names++) { 791 792 /* ignore data symbols */ 793 if (!isText) 794 continue; 795 796 for (sp = specs; sp; sp = sp->next) { 797 if (!sp->mark) 798 continue; /* soname doesn't match */ 799 if (VG_(string_match)( sp->from_fnpatt, *names )) { 800 /* got a new binding. Add to collection. */ 801 act.from_addr = sym_avmas.main; 802 act.to_addr = sp->to_addr; 803 act.parent_spec = parent_spec; 804 act.parent_sym = parent_sym; 805 act.becTag = sp->becTag; 806 act.becPrio = sp->becPrio; 807 act.isWrap = sp->isWrap; 808 act.isIFunc = isIFunc; 809 sp->done = True; 810 maybe_add_active( act ); 811 812 /* If the function being wrapped has a local entry point 813 * redirect it to the global entry point. The redirection 814 * must save and setup r2 then setup r12 for the new function. 815 * On return, r2 must be restored. Local entry points used 816 * in PPC64 Little Endian. 817 */ 818 if (GET_LOCAL_EP_AVMA(sym_avmas) != 0) { 819 act.from_addr = GET_LOCAL_EP_AVMA(sym_avmas); 820 maybe_add_active( act ); 821 } 822 823 } 824 } /* for (sp = specs; sp; sp = sp->next) */ 825 826 } /* iterating over names[] */ 827 free_symname_array(names_init, &twoslots[0]); 828 } /* for (i = 0; i < nsyms; i++) */ 829 830 /* Now, finally, look for Specs which were marked to be done, but 831 didn't get matched. If any such are mandatory we must abort the 832 system at this point. */ 833 for (sp = specs; sp; sp = sp->next) { 834 if (!sp->mark) 835 continue; 836 if (sp->mark && (!sp->done) && sp->mandatory) 837 break; 838 } 839 if (sp) { 840 const HChar** strp; 841 const HChar* v = "valgrind: "; 842 vg_assert(sp->mark); 843 vg_assert(!sp->done); 844 vg_assert(sp->mandatory); 845 VG_(printf)("\n"); 846 VG_(printf)( 847 "%sFatal error at startup: a function redirection\n", v); 848 VG_(printf)( 849 "%swhich is mandatory for this platform-tool combination\n", v); 850 VG_(printf)( 851 "%scannot be set up. Details of the redirection are:\n", v); 852 VG_(printf)( 853 "%s\n", v); 854 VG_(printf)( 855 "%sA must-be-redirected function\n", v); 856 VG_(printf)( 857 "%swhose name matches the pattern: %s\n", v, sp->from_fnpatt); 858 VG_(printf)( 859 "%sin an object with soname matching: %s\n", v, sp->from_sopatt); 860 VG_(printf)( 861 "%swas not found whilst processing\n", v); 862 VG_(printf)( 863 "%ssymbols from the object with soname: %s\n", 864 v, VG_(DebugInfo_get_soname)(di)); 865 VG_(printf)( 866 "%s\n", v); 867 868 for (strp = sp->mandatory; *strp; strp++) 869 VG_(printf)( 870 "%s%s\n", v, *strp); 871 872 VG_(printf)( 873 "%s\n", v); 874 VG_(printf)( 875 "%sCannot continue -- exiting now. Sorry.\n", v); 876 VG_(printf)("\n"); 877 VG_(exit)(1); 878 } 879 } 880 881 882 /* Add an act (passed by value; is copied here) and deal with 883 conflicting bindings. */ 884 static void maybe_add_active ( Active act ) 885 { 886 const HChar* what = NULL; 887 Active* old = NULL; 888 Bool add_act = False; 889 890 /* Complain and ignore manifestly bogus 'from' addresses. 891 892 Kludge: because this can get called befor the trampoline area (a 893 bunch of magic 'to' addresses) has its ownership changed from V 894 to C, we can't check the 'to' address similarly. Sigh. 895 896 amd64-linux hack: the vsysinfo pages appear to have no 897 permissions 898 ffffffffff600000-ffffffffffe00000 ---p 00000000 00:00 0 899 so skip the check for them. */ 900 if (!is_plausible_guest_addr(act.from_addr) 901 # if defined(VGP_amd64_linux) 902 && act.from_addr != 0xFFFFFFFFFF600000ULL 903 && act.from_addr != 0xFFFFFFFFFF600400ULL 904 && act.from_addr != 0xFFFFFFFFFF600800ULL 905 # endif 906 ) { 907 what = "redirection from-address is in non-executable area"; 908 goto bad; 909 } 910 911 old = VG_(OSetGen_Lookup)( activeSet, &act.from_addr ); 912 if (old) { 913 /* Dodgy. Conflicting binding. */ 914 vg_assert(old->from_addr == act.from_addr); 915 if (old->to_addr != act.to_addr) { 916 /* We've got a conflicting binding -- that is, from_addr is 917 specified to redirect to two different destinations, 918 old->to_addr and act.to_addr. If we can prove that they 919 are behaviourally equivalent then that's no problem. So 920 we can look at the behavioural eclass tags for both 921 functions to see if that's so. If they are equal, and 922 nonzero, then that's fine. But if not, we can't show they 923 are equivalent, so we have to complain, and ignore the new 924 binding. */ 925 vg_assert(old->becTag >= 0 && old->becTag <= 9999); 926 vg_assert(old->becPrio >= 0 && old->becPrio <= 9); 927 vg_assert(act.becTag >= 0 && act.becTag <= 9999); 928 vg_assert(act.becPrio >= 0 && act.becPrio <= 9); 929 if (old->becTag == 0) 930 vg_assert(old->becPrio == 0); 931 if (act.becTag == 0) 932 vg_assert(act.becPrio == 0); 933 934 if (old->becTag == 0 || act.becTag == 0 || old->becTag != act.becTag) { 935 /* We can't show that they are equivalent. Complain and 936 ignore. */ 937 what = "new redirection conflicts with existing -- ignoring it"; 938 goto bad; 939 } 940 /* They have the same eclass tag. Use the priorities to 941 resolve the ambiguity. */ 942 if (act.becPrio <= old->becPrio) { 943 /* The new one doesn't have a higher priority, so just 944 ignore it. */ 945 if (VG_(clo_verbosity) > 2) { 946 VG_(message)(Vg_UserMsg, "Ignoring %s redirection:\n", 947 act.becPrio < old->becPrio ? "lower priority" 948 : "duplicate"); 949 show_active( " old: ", old); 950 show_active( " new: ", &act); 951 } 952 } else { 953 /* The tricky case. The new one has a higher priority, so 954 we need to get the old one out of the OSet and install 955 this one in its place. */ 956 if (VG_(clo_verbosity) > 1) { 957 VG_(message)(Vg_UserMsg, 958 "Preferring higher priority redirection:\n"); 959 show_active( " old: ", old); 960 show_active( " new: ", &act); 961 } 962 add_act = True; 963 void* oldNd = VG_(OSetGen_Remove)( activeSet, &act.from_addr ); 964 vg_assert(oldNd == old); 965 VG_(OSetGen_FreeNode)( activeSet, old ); 966 old = NULL; 967 } 968 } else { 969 /* This appears to be a duplicate of an existing binding. 970 Safe(ish) -- ignore. */ 971 /* XXXXXXXXXXX COMPLAIN if new and old parents differ */ 972 } 973 974 } else { 975 /* There's no previous binding for this from_addr, so we must 976 add 'act' to the active set. */ 977 add_act = True; 978 } 979 980 /* So, finally, actually add it. */ 981 if (add_act) { 982 Active* a = VG_(OSetGen_AllocNode)(activeSet, sizeof(Active)); 983 vg_assert(a); 984 *a = act; 985 VG_(OSetGen_Insert)(activeSet, a); 986 /* Now that a new from->to redirection is in force, we need to 987 get rid of any translations intersecting 'from' in order that 988 they get redirected to 'to'. So discard them. Just for 989 paranoia (but, I believe, unnecessarily), discard 'to' as 990 well. */ 991 VG_(discard_translations)( act.from_addr, 1, 992 "redir_new_DebugInfo(from_addr)"); 993 VG_(discard_translations)( act.to_addr, 1, 994 "redir_new_DebugInfo(to_addr)"); 995 if (VG_(clo_verbosity) > 2) { 996 VG_(message)(Vg_UserMsg, "Adding active redirection:\n"); 997 show_active( " new: ", &act); 998 } 999 } 1000 return; 1001 1002 bad: 1003 vg_assert(what); 1004 vg_assert(!add_act); 1005 if (VG_(clo_verbosity) > 1) { 1006 VG_(message)(Vg_UserMsg, "WARNING: %s\n", what); 1007 if (old) { 1008 show_active( " old: ", old); 1009 } 1010 show_active( " new: ", &act); 1011 } 1012 } 1013 1014 1015 /* Notify m_redir of the deletion of a DebugInfo. This is relatively 1016 simple -- just get rid of all actives derived from it, and free up 1017 the associated list elements. */ 1018 1019 void VG_(redir_notify_delete_DebugInfo)( const DebugInfo* delsi ) 1020 { 1021 TopSpec* ts; 1022 TopSpec* tsPrev; 1023 Spec* sp; 1024 Spec* sp_next; 1025 OSet* tmpSet; 1026 Active* act; 1027 Bool delMe; 1028 Addr addr; 1029 1030 vg_assert(delsi); 1031 1032 /* Search for it, and make tsPrev point to the previous entry, if 1033 any. */ 1034 tsPrev = NULL; 1035 ts = topSpecs; 1036 while (True) { 1037 if (ts == NULL) break; 1038 if (ts->seginfo == delsi) break; 1039 tsPrev = ts; 1040 ts = ts->next; 1041 } 1042 1043 vg_assert(ts); /* else we don't have the deleted DebugInfo */ 1044 vg_assert(ts->seginfo == delsi); 1045 1046 /* Traverse the actives, copying the addresses of those we intend 1047 to delete into tmpSet. */ 1048 tmpSet = VG_(OSetWord_Create)(dinfo_zalloc, "redir.rndD.1", dinfo_free); 1049 1050 ts->mark = True; 1051 1052 VG_(OSetGen_ResetIter)( activeSet ); 1053 while ( (act = VG_(OSetGen_Next)(activeSet)) ) { 1054 delMe = act->parent_spec != NULL 1055 && act->parent_sym != NULL 1056 && act->parent_spec->seginfo != NULL 1057 && act->parent_sym->seginfo != NULL 1058 && (act->parent_spec->mark || act->parent_sym->mark); 1059 1060 /* While we're at it, a bit of paranoia: delete any actives 1061 which don't have both feet in valid client executable areas. 1062 But don't delete hardwired-at-startup ones; these are denoted 1063 by having parent_spec or parent_sym being NULL. */ 1064 if ( (!delMe) 1065 && act->parent_spec != NULL 1066 && act->parent_sym != NULL ) { 1067 if (!is_plausible_guest_addr(act->from_addr)) 1068 delMe = True; 1069 if (!is_plausible_guest_addr(act->to_addr)) 1070 delMe = True; 1071 } 1072 1073 if (delMe) { 1074 VG_(OSetWord_Insert)( tmpSet, act->from_addr ); 1075 /* While we have our hands on both the 'from' and 'to' 1076 of this Active, do paranoid stuff with tt/tc. */ 1077 VG_(discard_translations)( act->from_addr, 1, 1078 "redir_del_DebugInfo(from_addr)"); 1079 VG_(discard_translations)( act->to_addr, 1, 1080 "redir_del_DebugInfo(to_addr)"); 1081 } 1082 } 1083 1084 /* Now traverse tmpSet, deleting corresponding elements in activeSet. */ 1085 VG_(OSetWord_ResetIter)( tmpSet ); 1086 while ( VG_(OSetWord_Next)(tmpSet, &addr) ) { 1087 act = VG_(OSetGen_Remove)( activeSet, &addr ); 1088 vg_assert(act); 1089 VG_(OSetGen_FreeNode)( activeSet, act ); 1090 } 1091 1092 VG_(OSetWord_Destroy)( tmpSet ); 1093 1094 /* The Actives set is now cleaned up. Free up this TopSpec and 1095 everything hanging off it. */ 1096 for (sp = ts->specs; sp; sp = sp_next) { 1097 if (sp->from_sopatt) dinfo_free(sp->from_sopatt); 1098 if (sp->from_fnpatt) dinfo_free(sp->from_fnpatt); 1099 sp_next = sp->next; 1100 dinfo_free(sp); 1101 } 1102 1103 if (tsPrev == NULL) { 1104 /* first in list */ 1105 topSpecs = ts->next; 1106 } else { 1107 tsPrev->next = ts->next; 1108 } 1109 dinfo_free(ts); 1110 1111 if (VG_(clo_trace_redir)) 1112 show_redir_state("after VG_(redir_notify_delete_DebugInfo)"); 1113 } 1114 1115 1116 /*------------------------------------------------------------*/ 1117 /*--- QUERIES (really the whole point of this module) ---*/ 1118 /*------------------------------------------------------------*/ 1119 1120 /* This is the crucial redirection function. It answers the question: 1121 should this code address be redirected somewhere else? It's used 1122 just before translating a basic block. */ 1123 Addr VG_(redir_do_lookup) ( Addr orig, Bool* isWrap ) 1124 { 1125 Active* r = VG_(OSetGen_Lookup)(activeSet, &orig); 1126 if (r == NULL) 1127 return orig; 1128 1129 vg_assert(r->to_addr != 0); 1130 if (isWrap) 1131 *isWrap = r->isWrap || r->isIFunc; 1132 if (r->isIFunc) { 1133 vg_assert(iFuncWrapper); 1134 return iFuncWrapper; 1135 } 1136 return r->to_addr; 1137 } 1138 1139 1140 /*------------------------------------------------------------*/ 1141 /*--- INITIALISATION ---*/ 1142 /*------------------------------------------------------------*/ 1143 1144 /* Add a never-delete-me Active. */ 1145 1146 __attribute__((unused)) /* only used on amd64 */ 1147 static void add_hardwired_active ( Addr from, Addr to ) 1148 { 1149 Active act; 1150 act.from_addr = from; 1151 act.to_addr = to; 1152 act.parent_spec = NULL; 1153 act.parent_sym = NULL; 1154 act.becTag = 0; /* "not equivalent to any other fn" */ 1155 act.becPrio = 0; /* mandatory when becTag == 0 */ 1156 act.isWrap = False; 1157 act.isIFunc = False; 1158 maybe_add_active( act ); 1159 } 1160 1161 1162 /* Add a never-delete-me Spec. This is a bit of a kludge. On the 1163 assumption that this is called only at startup, only handle the 1164 case where topSpecs is completely empty, or if it isn't, it has 1165 just one entry and that is the one with NULL seginfo -- that is the 1166 entry that holds these initial specs. */ 1167 1168 __attribute__((unused)) /* not used on all platforms */ 1169 static void add_hardwired_spec (const HChar* sopatt, const HChar* fnpatt, 1170 Addr to_addr, 1171 const HChar** mandatory ) 1172 { 1173 Spec* spec = dinfo_zalloc("redir.ahs.1", sizeof(Spec)); 1174 1175 if (topSpecs == NULL) { 1176 topSpecs = dinfo_zalloc("redir.ahs.2", sizeof(TopSpec)); 1177 /* symtab_zalloc sets all fields to zero */ 1178 } 1179 1180 vg_assert(topSpecs != NULL); 1181 vg_assert(topSpecs->next == NULL); 1182 vg_assert(topSpecs->seginfo == NULL); 1183 /* FIXED PARTS */ 1184 /* Note, that these CONST_CAST will not cause a problem, in the sense 1185 that VG_(redir_notify_delete_DebugInfo) will delete them. The reason 1186 is that the TopSpec here has seginfo == NULL and such a TopSpec will 1187 never be freed. See the asserts at the beginning of said function. */ 1188 spec->from_sopatt = CONST_CAST(HChar *,sopatt); 1189 spec->from_fnpatt = CONST_CAST(HChar *,fnpatt); 1190 spec->to_addr = to_addr; 1191 spec->isWrap = False; 1192 spec->mandatory = mandatory; 1193 /* VARIABLE PARTS */ 1194 spec->mark = False; /* not significant */ 1195 spec->done = False; /* not significant */ 1196 1197 spec->next = topSpecs->specs; 1198 topSpecs->specs = spec; 1199 } 1200 1201 1202 __attribute__((unused)) /* not used on all platforms */ 1203 static const HChar* complain_about_stripped_glibc_ldso[] 1204 = { "Possible fixes: (1, short term): install glibc's debuginfo", 1205 "package on this machine. (2, longer term): ask the packagers", 1206 "for your Linux distribution to please in future ship a non-", 1207 "stripped ld.so (or whatever the dynamic linker .so is called)", 1208 "that exports the above-named function using the standard", 1209 "calling conventions for this platform. The package you need", 1210 "to install for fix (1) is called", 1211 "", 1212 " On Debian, Ubuntu: libc6-dbg", 1213 " On SuSE, openSuSE, Fedora, RHEL: glibc-debuginfo", 1214 NULL 1215 }; 1216 1217 1218 /* Initialise the redir system, and create the initial Spec list and 1219 for amd64-linux a couple of permanent active mappings. The initial 1220 Specs are not converted into Actives yet, on the (checked) 1221 assumption that no DebugInfos have so far been created, and so when 1222 they are created, that will happen. */ 1223 1224 void VG_(redir_initialise) ( void ) 1225 { 1226 // Assert that there are no DebugInfos so far 1227 vg_assert( VG_(next_DebugInfo)(NULL) == NULL ); 1228 1229 // Initialise active mapping. 1230 activeSet = VG_(OSetGen_Create)(offsetof(Active, from_addr), 1231 NULL, // Use fast comparison 1232 dinfo_zalloc, 1233 "redir.ri.1", 1234 dinfo_free); 1235 1236 // The rest of this function just adds initial Specs. 1237 1238 # if defined(VGP_x86_linux) 1239 /* If we're using memcheck, use this intercept right from the 1240 start, otherwise ld.so (glibc-2.3.5) makes a lot of noise. */ 1241 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1242 const HChar** mandatory; 1243 # ifndef GLIBC_MANDATORY_INDEX_AND_STRLEN_REDIRECT 1244 mandatory = NULL; 1245 # else 1246 /* for glibc-2.12 and later, this is mandatory - can't sanely 1247 continue without it */ 1248 mandatory = complain_about_stripped_glibc_ldso; 1249 # endif 1250 add_hardwired_spec( 1251 "ld-linux.so.2", "index", 1252 (Addr)&VG_(x86_linux_REDIR_FOR_index), mandatory); 1253 add_hardwired_spec( 1254 "ld-linux.so.2", "strlen", 1255 (Addr)&VG_(x86_linux_REDIR_FOR_strlen), mandatory); 1256 } 1257 1258 # elif defined(VGP_amd64_linux) 1259 /* Redirect vsyscalls to local versions */ 1260 add_hardwired_active( 1261 0xFFFFFFFFFF600000ULL, 1262 (Addr)&VG_(amd64_linux_REDIR_FOR_vgettimeofday) 1263 ); 1264 add_hardwired_active( 1265 0xFFFFFFFFFF600400ULL, 1266 (Addr)&VG_(amd64_linux_REDIR_FOR_vtime) 1267 ); 1268 add_hardwired_active( 1269 0xFFFFFFFFFF600800ULL, 1270 (Addr)&VG_(amd64_linux_REDIR_FOR_vgetcpu) 1271 ); 1272 1273 /* If we're using memcheck, use these intercepts right from 1274 the start, otherwise ld.so makes a lot of noise. */ 1275 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1276 1277 add_hardwired_spec( 1278 "ld-linux-x86-64.so.2", "strlen", 1279 (Addr)&VG_(amd64_linux_REDIR_FOR_strlen), 1280 # ifndef GLIBC_MANDATORY_STRLEN_REDIRECT 1281 NULL 1282 # else 1283 /* for glibc-2.10 and later, this is mandatory - can't sanely 1284 continue without it */ 1285 complain_about_stripped_glibc_ldso 1286 # endif 1287 ); 1288 } 1289 1290 # elif defined(VGP_ppc32_linux) 1291 /* If we're using memcheck, use these intercepts right from 1292 the start, otherwise ld.so makes a lot of noise. */ 1293 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1294 1295 /* this is mandatory - can't sanely continue without it */ 1296 add_hardwired_spec( 1297 "ld.so.1", "strlen", 1298 (Addr)&VG_(ppc32_linux_REDIR_FOR_strlen), 1299 complain_about_stripped_glibc_ldso 1300 ); 1301 add_hardwired_spec( 1302 "ld.so.1", "strcmp", 1303 (Addr)&VG_(ppc32_linux_REDIR_FOR_strcmp), 1304 NULL /* not mandatory - so why bother at all? */ 1305 /* glibc-2.6.1 (openSUSE 10.3, ppc32) seems fine without it */ 1306 ); 1307 add_hardwired_spec( 1308 "ld.so.1", "index", 1309 (Addr)&VG_(ppc32_linux_REDIR_FOR_strchr), 1310 NULL /* not mandatory - so why bother at all? */ 1311 /* glibc-2.6.1 (openSUSE 10.3, ppc32) seems fine without it */ 1312 ); 1313 } 1314 1315 # elif defined(VGP_ppc64be_linux) 1316 /* If we're using memcheck, use these intercepts right from 1317 the start, otherwise ld.so makes a lot of noise. */ 1318 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1319 1320 /* this is mandatory - can't sanely continue without it */ 1321 add_hardwired_spec( 1322 "ld64.so.1", "strlen", 1323 (Addr)VG_(fnptr_to_fnentry)( &VG_(ppc64_linux_REDIR_FOR_strlen) ), 1324 complain_about_stripped_glibc_ldso 1325 ); 1326 1327 add_hardwired_spec( 1328 "ld64.so.1", "index", 1329 (Addr)VG_(fnptr_to_fnentry)( &VG_(ppc64_linux_REDIR_FOR_strchr) ), 1330 NULL /* not mandatory - so why bother at all? */ 1331 /* glibc-2.5 (FC6, ppc64) seems fine without it */ 1332 ); 1333 } 1334 1335 # elif defined(VGP_ppc64le_linux) 1336 /* If we're using memcheck, use these intercepts right from 1337 * the start, otherwise ld.so makes a lot of noise. 1338 */ 1339 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1340 1341 /* this is mandatory - can't sanely continue without it */ 1342 add_hardwired_spec( 1343 "ld64.so.2", "strlen", 1344 (Addr)&VG_(ppc64_linux_REDIR_FOR_strlen), 1345 complain_about_stripped_glibc_ldso 1346 ); 1347 1348 add_hardwired_spec( 1349 "ld64.so.2", "index", 1350 (Addr)&VG_(ppc64_linux_REDIR_FOR_strchr), 1351 NULL /* not mandatory - so why bother at all? */ 1352 /* glibc-2.5 (FC6, ppc64) seems fine without it */ 1353 ); 1354 } 1355 1356 # elif defined(VGP_arm_linux) 1357 /* If we're using memcheck, use these intercepts right from the 1358 start, otherwise ld.so makes a lot of noise. In most ARM-linux 1359 distros, ld.so's soname is ld-linux.so.3, but Ubuntu 14.04 on 1360 Odroid uses ld-linux-armhf.so.3 for some reason. */ 1361 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1362 /* strlen */ 1363 add_hardwired_spec( 1364 "ld-linux.so.3", "strlen", 1365 (Addr)&VG_(arm_linux_REDIR_FOR_strlen), 1366 complain_about_stripped_glibc_ldso 1367 ); 1368 add_hardwired_spec( 1369 "ld-linux-armhf.so.3", "strlen", 1370 (Addr)&VG_(arm_linux_REDIR_FOR_strlen), 1371 complain_about_stripped_glibc_ldso 1372 ); 1373 /* memcpy */ 1374 add_hardwired_spec( 1375 "ld-linux.so.3", "memcpy", 1376 (Addr)&VG_(arm_linux_REDIR_FOR_memcpy), 1377 complain_about_stripped_glibc_ldso 1378 ); 1379 add_hardwired_spec( 1380 "ld-linux-armhf.so.3", "memcpy", 1381 (Addr)&VG_(arm_linux_REDIR_FOR_memcpy), 1382 complain_about_stripped_glibc_ldso 1383 ); 1384 /* strcmp */ 1385 add_hardwired_spec( 1386 "ld-linux.so.3", "strcmp", 1387 (Addr)&VG_(arm_linux_REDIR_FOR_strcmp), 1388 complain_about_stripped_glibc_ldso 1389 ); 1390 add_hardwired_spec( 1391 "ld-linux-armhf.so.3", "strcmp", 1392 (Addr)&VG_(arm_linux_REDIR_FOR_strcmp), 1393 complain_about_stripped_glibc_ldso 1394 ); 1395 } 1396 1397 # elif defined(VGP_arm64_linux) 1398 /* If we're using memcheck, use these intercepts right from 1399 the start, otherwise ld.so makes a lot of noise. */ 1400 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1401 add_hardwired_spec( 1402 "ld-linux-aarch64.so.1", "strlen", 1403 (Addr)&VG_(arm64_linux_REDIR_FOR_strlen), 1404 complain_about_stripped_glibc_ldso 1405 ); 1406 add_hardwired_spec( 1407 "ld-linux-aarch64.so.1", "index", 1408 (Addr)&VG_(arm64_linux_REDIR_FOR_index), 1409 NULL 1410 ); 1411 add_hardwired_spec( 1412 "ld-linux-aarch64.so.1", "strcmp", 1413 (Addr)&VG_(arm64_linux_REDIR_FOR_strcmp), 1414 NULL 1415 ); 1416 # if defined(VGPV_arm64_linux_android) 1417 add_hardwired_spec( 1418 "NONE", "__dl_strlen", // in /system/bin/linker64 1419 (Addr)&VG_(arm64_linux_REDIR_FOR_strlen), 1420 NULL 1421 ); 1422 # endif 1423 } 1424 1425 # elif defined(VGP_x86_darwin) 1426 /* If we're using memcheck, use these intercepts right from 1427 the start, otherwise dyld makes a lot of noise. */ 1428 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1429 add_hardwired_spec("dyld", "strcmp", 1430 (Addr)&VG_(x86_darwin_REDIR_FOR_strcmp), NULL); 1431 add_hardwired_spec("dyld", "strlen", 1432 (Addr)&VG_(x86_darwin_REDIR_FOR_strlen), NULL); 1433 add_hardwired_spec("dyld", "strcat", 1434 (Addr)&VG_(x86_darwin_REDIR_FOR_strcat), NULL); 1435 add_hardwired_spec("dyld", "strcpy", 1436 (Addr)&VG_(x86_darwin_REDIR_FOR_strcpy), NULL); 1437 add_hardwired_spec("dyld", "strlcat", 1438 (Addr)&VG_(x86_darwin_REDIR_FOR_strlcat), NULL); 1439 } 1440 1441 # elif defined(VGP_amd64_darwin) 1442 /* If we're using memcheck, use these intercepts right from 1443 the start, otherwise dyld makes a lot of noise. */ 1444 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1445 add_hardwired_spec("dyld", "strcmp", 1446 (Addr)&VG_(amd64_darwin_REDIR_FOR_strcmp), NULL); 1447 add_hardwired_spec("dyld", "strlen", 1448 (Addr)&VG_(amd64_darwin_REDIR_FOR_strlen), NULL); 1449 add_hardwired_spec("dyld", "strcat", 1450 (Addr)&VG_(amd64_darwin_REDIR_FOR_strcat), NULL); 1451 add_hardwired_spec("dyld", "strcpy", 1452 (Addr)&VG_(amd64_darwin_REDIR_FOR_strcpy), NULL); 1453 add_hardwired_spec("dyld", "strlcat", 1454 (Addr)&VG_(amd64_darwin_REDIR_FOR_strlcat), NULL); 1455 // DDD: #warning fixme rdar://6166275 1456 add_hardwired_spec("dyld", "arc4random", 1457 (Addr)&VG_(amd64_darwin_REDIR_FOR_arc4random), NULL); 1458 # if DARWIN_VERS == DARWIN_10_9 1459 add_hardwired_spec("dyld", "strchr", 1460 (Addr)&VG_(amd64_darwin_REDIR_FOR_strchr), NULL); 1461 # endif 1462 } 1463 1464 # elif defined(VGP_s390x_linux) 1465 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1466 // added in rsponse to BZ 327943 1467 add_hardwired_spec("ld64.so.1", "index", 1468 (Addr)&VG_(s390x_linux_REDIR_FOR_index), 1469 complain_about_stripped_glibc_ldso); 1470 } 1471 1472 # elif defined(VGP_mips32_linux) 1473 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1474 1475 /* this is mandatory - can't sanely continue without it */ 1476 add_hardwired_spec( 1477 "ld.so.3", "strlen", 1478 (Addr)&VG_(mips32_linux_REDIR_FOR_strlen), 1479 complain_about_stripped_glibc_ldso 1480 ); 1481 } 1482 1483 # elif defined(VGP_mips64_linux) 1484 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1485 1486 /* this is mandatory - can't sanely continue without it */ 1487 add_hardwired_spec( 1488 "ld.so.3", "strlen", 1489 (Addr)&VG_(mips64_linux_REDIR_FOR_strlen), 1490 complain_about_stripped_glibc_ldso 1491 ); 1492 } 1493 1494 # elif defined(VGP_tilegx_linux) 1495 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1496 1497 add_hardwired_spec( 1498 "ld.so.1", "strlen", 1499 (Addr)&VG_(tilegx_linux_REDIR_FOR_strlen), NULL 1500 ); 1501 } 1502 1503 # else 1504 # error Unknown platform 1505 # endif 1506 1507 if (VG_(clo_trace_redir)) 1508 show_redir_state("after VG_(redir_initialise)"); 1509 } 1510 1511 1512 /*------------------------------------------------------------*/ 1513 /*--- MISC HELPERS ---*/ 1514 /*------------------------------------------------------------*/ 1515 1516 static void* dinfo_zalloc(const HChar* ec, SizeT n) { 1517 void* p; 1518 vg_assert(n > 0); 1519 p = VG_(arena_malloc)(VG_AR_DINFO, ec, n); 1520 VG_(memset)(p, 0, n); 1521 return p; 1522 } 1523 1524 static void dinfo_free(void* p) { 1525 vg_assert(p); 1526 return VG_(arena_free)(VG_AR_DINFO, p); 1527 } 1528 1529 static HChar* dinfo_strdup(const HChar* ec, const HChar* str) 1530 { 1531 return VG_(arena_strdup)(VG_AR_DINFO, ec, str); 1532 } 1533 1534 /* Really this should be merged with translations_allowable_from_seg 1535 in m_translate. */ 1536 static Bool is_plausible_guest_addr(Addr a) 1537 { 1538 NSegment const* seg = VG_(am_find_nsegment)(a); 1539 return seg != NULL 1540 && (seg->kind == SkAnonC || seg->kind == SkFileC || 1541 seg->kind == SkShmC) 1542 && (seg->hasX || seg->hasR); /* crude x86-specific hack */ 1543 } 1544 1545 1546 /*------------------------------------------------------------*/ 1547 /*--- NOTIFY-ON-LOAD FUNCTIONS ---*/ 1548 /*------------------------------------------------------------*/ 1549 1550 static 1551 void handle_maybe_load_notifier( const HChar* soname, 1552 const HChar* symbol, Addr addr ) 1553 { 1554 # if defined(VGP_x86_linux) 1555 /* x86-linux only: if we see _dl_sysinfo_int80, note its address. 1556 See comment on declaration of VG_(client__dl_sysinfo_int80) for 1557 the reason. As far as I can tell, the relevant symbol is always 1558 in object with soname "ld-linux.so.2". */ 1559 if (symbol && symbol[0] == '_' 1560 && 0 == VG_(strcmp)(symbol, "_dl_sysinfo_int80") 1561 && 0 == VG_(strcmp)(soname, "ld-linux.so.2")) { 1562 if (VG_(client__dl_sysinfo_int80) == 0) 1563 VG_(client__dl_sysinfo_int80) = addr; 1564 } 1565 # endif 1566 1567 /* Normal load-notifier handling after here. First, ignore all 1568 symbols lacking the right prefix. */ 1569 vg_assert(symbol); // assert rather than segfault if it is NULL 1570 if (0 != VG_(strncmp)(symbol, VG_NOTIFY_ON_LOAD_PREFIX, 1571 VG_NOTIFY_ON_LOAD_PREFIX_LEN)) 1572 /* Doesn't have the right prefix */ 1573 return; 1574 1575 if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(freeres))) == 0) 1576 VG_(client___libc_freeres_wrapper) = addr; 1577 else 1578 if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(ifunc_wrapper))) == 0) 1579 iFuncWrapper = addr; 1580 else 1581 vg_assert2(0, "unrecognised load notification function: %s", symbol); 1582 } 1583 1584 1585 /*------------------------------------------------------------*/ 1586 /*--- REQUIRE-TEXT-SYMBOL HANDLING ---*/ 1587 /*------------------------------------------------------------*/ 1588 1589 /* In short: check that the currently-being-loaded object has text 1590 symbols that satisfy any --require-text-symbol= specifications that 1591 apply to it, and abort the run with an error message if not. 1592 */ 1593 static void handle_require_text_symbols ( const DebugInfo* di ) 1594 { 1595 /* First thing to do is figure out which, if any, 1596 --require-text-symbol specification strings apply to this 1597 object. Most likely none do, since it is not expected to 1598 frequently be used. Work through the list of specs and 1599 accumulate in fnpatts[] the fn patterns that pertain to this 1600 object. */ 1601 XArray *fnpatts = VG_(newXA)( VG_(malloc), "m_redir.hrts.5", 1602 VG_(free), sizeof(HChar*) ); 1603 1604 Int i, j; 1605 const HChar* di_soname = VG_(DebugInfo_get_soname)(di); 1606 vg_assert(di_soname); // must be present 1607 1608 for (i = 0; i < VG_(sizeXA)(VG_(clo_req_tsyms)); i++) { 1609 const HChar* clo_spec = *(HChar**) VG_(indexXA)(VG_(clo_req_tsyms), i); 1610 vg_assert(clo_spec && VG_(strlen)(clo_spec) >= 4); 1611 // clone the spec, so we can stick a zero at the end of the sopatt 1612 HChar *spec = VG_(strdup)("m_redir.hrts.1", clo_spec); 1613 HChar sep = spec[0]; 1614 HChar* sopatt = &spec[1]; 1615 HChar* fnpatt = VG_(strchr)(sopatt, sep); 1616 // the initial check at clo processing in time in m_main 1617 // should ensure this. 1618 vg_assert(fnpatt && *fnpatt == sep); 1619 *fnpatt = 0; 1620 fnpatt++; 1621 if (VG_(string_match)(sopatt, di_soname)) { 1622 HChar *pattern = VG_(strdup)("m_redir.hrts.2", fnpatt); 1623 VG_(addToXA)(fnpatts, &pattern); 1624 } 1625 VG_(free)(spec); 1626 } 1627 1628 if (VG_(sizeXA)(fnpatts) == 0) { 1629 VG_(deleteXA)(fnpatts); 1630 return; /* no applicable spec strings */ 1631 } 1632 1633 /* So finally, fnpatts contains the set of 1634 (patterns for) text symbol names that must be found in this 1635 object, in order to continue. That is, we must find at least 1636 one text symbol name that matches each pattern, else we must 1637 abort the run. */ 1638 1639 if (0) VG_(printf)("for %s\n", di_soname); 1640 for (i = 0; i < VG_(sizeXA)(fnpatts); i++) 1641 if (0) VG_(printf)(" fnpatt: %s\n", 1642 *(HChar**) VG_(indexXA)(fnpatts, i)); 1643 1644 /* For each spec, look through the syms to find one that matches. 1645 This isn't terribly efficient but it happens rarely, so no big 1646 deal. */ 1647 for (i = 0; i < VG_(sizeXA)(fnpatts); i++) { 1648 Bool found = False; 1649 const HChar* fnpatt = *(HChar**) VG_(indexXA)(fnpatts, i); 1650 Int nsyms = VG_(DebugInfo_syms_howmany)(di); 1651 for (j = 0; j < nsyms; j++) { 1652 Bool isText = False; 1653 const HChar* sym_name_pri = NULL; 1654 const HChar** sym_names_sec = NULL; 1655 VG_(DebugInfo_syms_getidx)( di, j, NULL, 1656 NULL, &sym_name_pri, &sym_names_sec, 1657 &isText, NULL ); 1658 const HChar* twoslots[2]; 1659 const HChar** names_init = 1660 alloc_symname_array(sym_name_pri, sym_names_sec, &twoslots[0]); 1661 const HChar** names; 1662 for (names = names_init; *names; names++) { 1663 /* ignore data symbols */ 1664 if (0) VG_(printf)("QQQ %s\n", *names); 1665 vg_assert(sym_name_pri); 1666 if (!isText) 1667 continue; 1668 if (VG_(string_match)(fnpatt, *names)) { 1669 found = True; 1670 break; 1671 } 1672 } 1673 free_symname_array(names_init, &twoslots[0]); 1674 if (found) 1675 break; 1676 } 1677 1678 if (!found) { 1679 const HChar* v = "valgrind: "; 1680 VG_(printf)("\n"); 1681 VG_(printf)( 1682 "%sFatal error at when loading library with soname\n", v); 1683 VG_(printf)( 1684 "%s %s\n", v, di_soname); 1685 VG_(printf)( 1686 "%sCannot find any text symbol with a name " 1687 "that matches the pattern\n", v); 1688 VG_(printf)("%s %s\n", v, fnpatt); 1689 VG_(printf)("%sas required by a --require-text-symbol= " 1690 "specification.\n", v); 1691 VG_(printf)("\n"); 1692 VG_(printf)( 1693 "%sCannot continue -- exiting now.\n", v); 1694 VG_(printf)("\n"); 1695 VG_(exit)(1); 1696 } 1697 } 1698 1699 /* All required specs were found. Just free memory and return. */ 1700 VG_(deleteXA)(fnpatts); 1701 } 1702 1703 1704 /*------------------------------------------------------------*/ 1705 /*--- SANITY/DEBUG ---*/ 1706 /*------------------------------------------------------------*/ 1707 1708 static void show_spec ( const HChar* left, const Spec* spec ) 1709 { 1710 VG_(message)( Vg_DebugMsg, 1711 "%s%-25s %-30s %s-> (%04d.%d) 0x%08lx\n", 1712 left, 1713 spec->from_sopatt, spec->from_fnpatt, 1714 spec->isWrap ? "W" : "R", 1715 spec->becTag, spec->becPrio, 1716 spec->to_addr ); 1717 } 1718 1719 static void show_active ( const HChar* left, const Active* act ) 1720 { 1721 Bool ok; 1722 const HChar *buf; 1723 1724 ok = VG_(get_fnname_w_offset)(act->from_addr, &buf); 1725 if (!ok) buf = "???"; 1726 // Stash away name1 1727 HChar name1[VG_(strlen)(buf) + 1]; 1728 VG_(strcpy)(name1, buf); 1729 1730 const HChar *name2; 1731 ok = VG_(get_fnname_w_offset)(act->to_addr, &name2); 1732 if (!ok) name2 = "???"; 1733 1734 VG_(message)(Vg_DebugMsg, "%s0x%08lx (%-20s) %s-> (%04d.%d) 0x%08lx %s\n", 1735 left, 1736 act->from_addr, name1, 1737 act->isWrap ? "W" : "R", 1738 act->becTag, act->becPrio, 1739 act->to_addr, name2 ); 1740 } 1741 1742 static void show_redir_state ( const HChar* who ) 1743 { 1744 TopSpec* ts; 1745 Spec* sp; 1746 Active* act; 1747 VG_(message)(Vg_DebugMsg, "<<\n"); 1748 VG_(message)(Vg_DebugMsg, " ------ REDIR STATE %s ------\n", who); 1749 for (ts = topSpecs; ts; ts = ts->next) { 1750 if (ts->seginfo) 1751 VG_(message)(Vg_DebugMsg, 1752 " TOPSPECS of soname %s filename %s\n", 1753 VG_(DebugInfo_get_soname)(ts->seginfo), 1754 VG_(DebugInfo_get_filename)(ts->seginfo)); 1755 else 1756 VG_(message)(Vg_DebugMsg, 1757 " TOPSPECS of soname (hardwired)\n"); 1758 1759 for (sp = ts->specs; sp; sp = sp->next) 1760 show_spec(" ", sp); 1761 } 1762 VG_(message)(Vg_DebugMsg, " ------ ACTIVE ------\n"); 1763 VG_(OSetGen_ResetIter)( activeSet ); 1764 while ( (act = VG_(OSetGen_Next)(activeSet)) ) { 1765 show_active(" ", act); 1766 } 1767 1768 VG_(message)(Vg_DebugMsg, ">>\n"); 1769 } 1770 1771 /*--------------------------------------------------------------------*/ 1772 /*--- end ---*/ 1773 /*--------------------------------------------------------------------*/ 1774