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_2_* */ 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 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, Active* act ); 312 313 static void handle_maybe_load_notifier( const HChar* soname, 314 HChar* symbol, Addr addr ); 315 316 static void handle_require_text_symbols ( 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 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 HChar** alloc_symname_array ( HChar* pri_name, HChar** sec_names, 338 HChar** twoslots ) 339 { 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; 349 HChar** pp = sec_names; 350 while (*pp) { n_req++; pp++; } 351 /* .. allocate and copy in. */ 352 HChar** arr = dinfo_zalloc( "redir.asa.1", (n_req+1) * sizeof(HChar*) ); 353 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. */ 364 static void free_symname_array ( HChar** names, HChar** twoslots ) 365 { 366 if (names != twoslots) 367 dinfo_free(names); 368 } 369 370 static HChar const* advance_to_equal ( HChar const* c ) { 371 while (*c && *c != '=') { 372 ++c; 373 } 374 return c; 375 } 376 static HChar const* advance_to_comma ( HChar const* c ) { 377 while (*c && *c != ',') { 378 ++c; 379 } 380 return c; 381 } 382 383 /* Notify m_redir of the arrival of a new DebugInfo. This is fairly 384 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 390 void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi ) 391 { 392 Bool ok, isWrap; 393 Int i, nsyms, becTag, becPrio; 394 Spec* specList; 395 Spec* spec; 396 TopSpec* ts; 397 TopSpec* newts; 398 HChar* sym_name_pri; 399 HChar** sym_names_sec; 400 Addr sym_addr, sym_toc; 401 HChar demangled_sopatt[N_DEMANGLED]; 402 HChar demangled_fnpatt[N_DEMANGLED]; 403 Bool check_ppcTOCs = False; 404 Bool isText; 405 const HChar* newdi_soname; 406 407 # if defined(VG_PLAT_USES_PPCTOC) 408 check_ppcTOCs = True; 409 # endif 410 411 vg_assert(newdi); 412 newdi_soname = VG_(DebugInfo_get_soname)(newdi); 413 vg_assert(newdi_soname != NULL); 414 415 #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 */ 440 const HChar* newdi_filename = VG_(DebugInfo_get_filename)(newdi); 441 const HChar* newdi_basename = VG_(basename) (newdi_filename); 442 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; 450 HChar in_vglib_filename[VKI_PATH_MAX]; 451 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 491 /* stay sane: we don't already have this. */ 492 for (ts = topSpecs; ts; ts = ts->next) 493 vg_assert(ts->seginfo != newdi); 494 495 /* scan this DebugInfo's symbol table, pulling out and demangling 496 any specs found */ 497 498 specList = NULL; /* the spec list we're building up */ 499 500 nsyms = VG_(DebugInfo_syms_howmany)( newdi ); 501 for (i = 0; i < nsyms; i++) { 502 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. */ 506 HChar* twoslots[2]; 507 HChar** names_init = alloc_symname_array(sym_name_pri, sym_names_sec, 508 &twoslots[0]); 509 HChar** names; 510 for (names = names_init; *names; names++) { 511 ok = VG_(maybe_Z_demangle)( *names, 512 demangled_sopatt, N_DEMANGLED, 513 demangled_fnpatt, N_DEMANGLED, 514 &isWrap, &becTag, &becPrio ); 515 /* 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 } 531 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 573 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; 582 spec->becPrio = becPrio; 583 /* 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; 589 } 590 free_symname_array(names_init, &twoslots[0]); 591 } 592 593 if (check_ppcTOCs) { 594 for (i = 0; i < nsyms; i++) { 595 VG_(DebugInfo_syms_getidx)( newdi, i, &sym_addr, &sym_toc, 596 NULL, &sym_name_pri, &sym_names_sec, 597 &isText, NULL ); 598 HChar* twoslots[2]; 599 HChar** names_init = alloc_symname_array(sym_name_pri, sym_names_sec, 600 &twoslots[0]); 601 HChar** names; 602 for (names = names_init; *names; names++) { 603 ok = isText 604 && VG_(maybe_Z_demangle)( 605 *names, demangled_sopatt, N_DEMANGLED, 606 demangled_fnpatt, N_DEMANGLED, &isWrap, NULL, NULL ); 607 if (!ok) 608 /* not a redirect. Ignore. */ 609 continue; 610 if (sym_toc != 0) 611 /* has a valid toc pointer. Ignore. */ 612 continue; 613 614 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; 622 623 /* 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]); 629 } 630 } 631 632 /* Ok. Now specList holds the list of specs from the DebugInfo. 633 Build a new TopSpec, but don't add it to topSpecs yet. */ 634 newts = dinfo_zalloc("redir.rnnD.4", sizeof(TopSpec)); 635 vg_assert(newts); 636 newts->next = NULL; /* not significant */ 637 newts->seginfo = newdi; 638 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 647 (2) actives formed by matching the new symbols in newdi against 648 all specs currently listed in topSpecs 649 650 (3) actives formed by matching the new symbols in newdi against 651 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 } 664 665 /* Case (2) */ 666 for (ts = topSpecs; ts; ts = ts->next) { 667 generate_and_add_actives( ts->specs, ts, 668 newdi, newts ); 669 } 670 671 /* Case (3) */ 672 generate_and_add_actives( specList, newts, 673 newdi, newts ); 674 675 /* Finally, add the new TopSpec. */ 676 newts->next = topSpecs; 677 topSpecs = newts; 678 679 if (VG_(clo_trace_redir)) 680 show_redir_state("after VG_(redir_notify_new_DebugInfo)"); 681 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. */ 685 handle_require_text_symbols(newdi); 686 } 687 688 #undef N_DEMANGLED 689 690 /* 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 695 void 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, 710 "Adding redirect for indirect function " 711 "0x%llx from 0x%llx -> 0x%llx\n", 712 (ULong)old_from, (ULong)new_from, (ULong)new.to_addr ); 713 } 714 } 715 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 721 static 722 void generate_and_add_actives ( 723 /* spec list and the owning TopSpec */ 724 Spec* specs, 725 TopSpec* parent_spec, 726 /* seginfo and the owning TopSpec */ 727 DebugInfo* di, 728 TopSpec* parent_sym 729 ) 730 { 731 Spec* sp; 732 Bool anyMark, isText, isIFunc; 733 Active act; 734 Int nsyms, i; 735 Addr sym_addr; 736 HChar* sym_name_pri; 737 HChar** sym_names_sec; 738 739 /* 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. */ 742 anyMark = False; 743 for (sp = specs; sp; sp = sp->next) { 744 sp->done = False; 745 sp->mark = VG_(string_match)( sp->from_sopatt, 746 VG_(DebugInfo_get_soname)(di) ); 747 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. */ 756 nsyms = VG_(DebugInfo_syms_howmany)( di ); 757 for (i = 0; i < nsyms; i++) { 758 VG_(DebugInfo_syms_getidx)( di, i, &sym_addr, NULL, 759 NULL, &sym_name_pri, &sym_names_sec, 760 &isText, &isIFunc ); 761 HChar* twoslots[2]; 762 HChar** names_init = alloc_symname_array(sym_name_pri, sym_names_sec, 763 &twoslots[0]); 764 HChar** names; 765 for (names = names_init; *names; names++) { 766 767 /* ignore data symbols */ 768 if (!isText) 769 continue; 770 771 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; 781 act.becPrio = sp->becPrio; 782 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]); 791 } /* 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) { 803 const HChar** strp; 804 const HChar* v = "valgrind: "; 805 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)( 826 "%ssymbols from the object with soname: %s\n", 827 v, VG_(DebugInfo_get_soname)(di)); 828 VG_(printf)( 829 "%s\n", v); 830 831 for (strp = sp->mandatory; *strp; strp++) 832 VG_(printf)( 833 "%s%s\n", v, *strp); 834 835 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); 841 } 842 } 843 844 845 /* Add an act (passed by value; is copied here) and deal with 846 conflicting bindings. */ 847 static void maybe_add_active ( Active act ) 848 { 849 const HChar* what = NULL; 850 Active* old = NULL; 851 Bool add_act = False; 852 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 867 && act.from_addr != 0xFFFFFFFFFF600800ULL 868 # endif 869 ) { 870 what = "redirection from-address is in non-executable area"; 871 goto bad; 872 } 873 874 old = VG_(OSetGen_Lookup)( activeSet, &act.from_addr ); 875 if (old) { 876 /* Dodgy. Conflicting binding. */ 877 vg_assert(old->from_addr == act.from_addr); 878 if (old->to_addr != act.to_addr) { 879 /* 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. */ 888 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. */ 908 if (VG_(clo_verbosity) > 2) { 909 VG_(message)(Vg_UserMsg, "Ignoring %s redirection:\n", 910 act.becPrio < old->becPrio ? "lower priority" 911 : "duplicate"); 912 show_active( " old: ", old); 913 show_active( " new: ", &act); 914 } 915 } else { 916 /* 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; 930 } 931 } else { 932 /* This appears to be a duplicate of an existing binding. 933 Safe(ish) -- ignore. */ 934 /* XXXXXXXXXXX COMPLAIN if new and old parents differ */ 935 } 936 937 } else { 938 /* 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) { 945 Active* a = VG_(OSetGen_AllocNode)(activeSet, sizeof(Active)); 946 vg_assert(a); 947 *a = act; 948 VG_(OSetGen_Insert)(activeSet, a); 949 /* 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, 955 "redir_new_DebugInfo(from_addr)"); 956 VG_(discard_translations)( (Addr64)act.to_addr, 1, 957 "redir_new_DebugInfo(to_addr)"); 958 if (VG_(clo_verbosity) > 2) { 959 VG_(message)(Vg_UserMsg, "Adding active redirection:\n"); 960 show_active( " new: ", &act); 961 } 962 } 963 return; 964 965 bad: 966 vg_assert(what); 967 vg_assert(!add_act); 968 if (VG_(clo_verbosity) > 1) { 969 VG_(message)(Vg_UserMsg, "WARNING: %s\n", what); 970 if (old) { 971 show_active( " old: ", old); 972 } 973 show_active( " new: ", &act); 974 } 975 } 976 977 978 /* Notify m_redir of the deletion of a DebugInfo. This is relatively 979 simple -- just get rid of all actives derived from it, and free up 980 the associated list elements. */ 981 982 void VG_(redir_notify_delete_DebugInfo)( DebugInfo* delsi ) 983 { 984 TopSpec* ts; 985 TopSpec* tsPrev; 986 Spec* sp; 987 Spec* sp_next; 988 OSet* tmpSet; 989 Active* act; 990 Bool delMe; 991 Addr addr; 992 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 1006 vg_assert(ts); /* else we don't have the deleted DebugInfo */ 1007 vg_assert(ts->seginfo == delsi); 1008 1009 /* Traverse the actives, copying the addresses of those we intend 1010 to delete into tmpSet. */ 1011 tmpSet = VG_(OSetWord_Create)(dinfo_zalloc, "redir.rndD.1", dinfo_free); 1012 1013 ts->mark = True; 1014 1015 VG_(OSetGen_ResetIter)( activeSet ); 1016 while ( (act = VG_(OSetGen_Next)(activeSet)) ) { 1017 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 1024 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; 1034 } 1035 1036 if (delMe) { 1037 VG_(OSetWord_Insert)( tmpSet, act->from_addr ); 1038 /* 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, 1041 "redir_del_DebugInfo(from_addr)"); 1042 VG_(discard_translations)( (Addr64)act->to_addr, 1, 1043 "redir_del_DebugInfo(to_addr)"); 1044 } 1045 } 1046 1047 /* 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 ); 1051 vg_assert(act); 1052 VG_(OSetGen_FreeNode)( activeSet, act ); 1053 } 1054 1055 VG_(OSetWord_Destroy)( tmpSet ); 1056 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) { 1060 if (sp->from_sopatt) dinfo_free(sp->from_sopatt); 1061 if (sp->from_fnpatt) dinfo_free(sp->from_fnpatt); 1062 sp_next = sp->next; 1063 dinfo_free(sp); 1064 } 1065 1066 if (tsPrev == NULL) { 1067 /* first in list */ 1068 topSpecs = ts->next; 1069 } else { 1070 tsPrev->next = ts->next; 1071 } 1072 dinfo_free(ts); 1073 1074 if (VG_(clo_trace_redir)) 1075 show_redir_state("after VG_(redir_notify_delete_DebugInfo)"); 1076 } 1077 1078 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. */ 1086 Addr VG_(redir_do_lookup) ( Addr orig, Bool* isWrap ) 1087 { 1088 Active* r = VG_(OSetGen_Lookup)(activeSet, &orig); 1089 if (r == NULL) 1090 return orig; 1091 1092 vg_assert(r->to_addr != 0); 1093 if (isWrap) 1094 *isWrap = r->isWrap || r->isIFunc; 1095 if (r->isIFunc) { 1096 vg_assert(iFuncWrapper); 1097 return iFuncWrapper; 1098 } 1099 return r->to_addr; 1100 } 1101 1102 1103 /*------------------------------------------------------------*/ 1104 /*--- INITIALISATION ---*/ 1105 /*------------------------------------------------------------*/ 1106 1107 /* Add a never-delete-me Active. */ 1108 1109 __attribute__((unused)) /* only used on amd64 */ 1110 static void add_hardwired_active ( Addr from, Addr to ) 1111 { 1112 Active act; 1113 act.from_addr = from; 1114 act.to_addr = to; 1115 act.parent_spec = NULL; 1116 act.parent_sym = NULL; 1117 act.becTag = 0; /* "not equivalent to any other fn" */ 1118 act.becPrio = 0; /* mandatory when becTag == 0 */ 1119 act.isWrap = False; 1120 act.isIFunc = False; 1121 maybe_add_active( act ); 1122 } 1123 1124 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 */ 1132 static void add_hardwired_spec (const HChar* sopatt, const HChar* fnpatt, 1133 Addr to_addr, 1134 const HChar** mandatory ) 1135 { 1136 Spec* spec = dinfo_zalloc("redir.ahs.1", sizeof(Spec)); 1137 vg_assert(spec); 1138 1139 if (topSpecs == NULL) { 1140 topSpecs = dinfo_zalloc("redir.ahs.2", sizeof(TopSpec)); 1141 vg_assert(topSpecs); 1142 /* symtab_zalloc sets all fields to zero */ 1143 } 1144 1145 vg_assert(topSpecs != NULL); 1146 vg_assert(topSpecs->next == NULL); 1147 vg_assert(topSpecs->seginfo == NULL); 1148 /* FIXED PARTS */ 1149 spec->from_sopatt = (HChar *)sopatt; 1150 spec->from_fnpatt = (HChar *)fnpatt; 1151 spec->to_addr = to_addr; 1152 spec->isWrap = False; 1153 spec->mandatory = mandatory; 1154 /* VARIABLE PARTS */ 1155 spec->mark = False; /* not significant */ 1156 spec->done = False; /* not significant */ 1157 1158 spec->next = topSpecs->specs; 1159 topSpecs->specs = spec; 1160 } 1161 1162 1163 __attribute__((unused)) /* not used on all platforms */ 1164 static 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", 1170 "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", 1175 NULL 1176 }; 1177 1178 1179 /* 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) 1182 assumption that no DebugInfos have so far been created, and so when 1183 they are created, that will happen. */ 1184 1185 void VG_(redir_initialise) ( void ) 1186 { 1187 // Assert that there are no DebugInfos so far 1188 vg_assert( VG_(next_DebugInfo)(NULL) == NULL ); 1189 1190 // Initialise active mapping. 1191 activeSet = VG_(OSetGen_Create)(offsetof(Active, from_addr), 1192 NULL, // Use fast comparison 1193 dinfo_zalloc, 1194 "redir.ri.1", 1195 dinfo_free); 1196 1197 // The rest of this function just adds initial Specs. 1198 1199 # if defined(VGP_x86_linux) 1200 /* 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)) { 1203 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 1214 add_hardwired_spec( 1215 "ld-linux.so.2", "index", 1216 (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); 1220 } 1221 1222 # elif defined(VGP_amd64_linux) 1223 /* Redirect vsyscalls to local versions */ 1224 add_hardwired_active( 1225 0xFFFFFFFFFF600000ULL, 1226 (Addr)&VG_(amd64_linux_REDIR_FOR_vgettimeofday) 1227 ); 1228 add_hardwired_active( 1229 0xFFFFFFFFFF600400ULL, 1230 (Addr)&VG_(amd64_linux_REDIR_FOR_vtime) 1231 ); 1232 add_hardwired_active( 1233 0xFFFFFFFFFF600800ULL, 1234 (Addr)&VG_(amd64_linux_REDIR_FOR_vgetcpu) 1235 ); 1236 1237 /* 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)) { 1240 1241 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) 1257 /* 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)) { 1260 1261 /* this is mandatory - can't sanely continue without it */ 1262 add_hardwired_spec( 1263 "ld.so.1", "strlen", 1264 (Addr)&VG_(ppc32_linux_REDIR_FOR_strlen), 1265 complain_about_stripped_glibc_ldso 1266 ); 1267 add_hardwired_spec( 1268 "ld.so.1", "strcmp", 1269 (Addr)&VG_(ppc32_linux_REDIR_FOR_strcmp), 1270 NULL /* not mandatory - so why bother at all? */ 1271 /* glibc-2.6.1 (openSUSE 10.3, ppc32) seems fine without it */ 1272 ); 1273 add_hardwired_spec( 1274 "ld.so.1", "index", 1275 (Addr)&VG_(ppc32_linux_REDIR_FOR_strchr), 1276 NULL /* not mandatory - so why bother at all? */ 1277 /* glibc-2.6.1 (openSUSE 10.3, ppc32) seems fine without it */ 1278 ); 1279 } 1280 1281 # elif defined(VGP_ppc64_linux) 1282 /* 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 1286 /* this is mandatory - can't sanely continue without it */ 1287 add_hardwired_spec( 1288 "ld64.so.1", "strlen", 1289 (Addr)VG_(fnptr_to_fnentry)( &VG_(ppc64_linux_REDIR_FOR_strlen) ), 1290 complain_about_stripped_glibc_ldso 1291 ); 1292 1293 add_hardwired_spec( 1294 "ld64.so.1", "index", 1295 (Addr)VG_(fnptr_to_fnentry)( &VG_(ppc64_linux_REDIR_FOR_strchr) ), 1296 NULL /* not mandatory - so why bother at all? */ 1297 /* glibc-2.5 (FC6, ppc64) seems fine without it */ 1298 ); 1299 } 1300 1301 # elif defined(VGP_arm_linux) 1302 /* If we're using memcheck, use these intercepts right from the 1303 start, otherwise ld.so makes a lot of noise. In most ARM-linux 1304 distros, ld.so's soname is ld-linux.so.3, but Ubuntu 14.04 on 1305 Odroid uses ld-linux-armhf.so.3 for some reason. */ 1306 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1307 /* strlen */ 1308 add_hardwired_spec( 1309 "ld-linux.so.3", "strlen", 1310 (Addr)&VG_(arm_linux_REDIR_FOR_strlen), 1311 complain_about_stripped_glibc_ldso 1312 ); 1313 add_hardwired_spec( 1314 "ld-linux-armhf.so.3", "strlen", 1315 (Addr)&VG_(arm_linux_REDIR_FOR_strlen), 1316 complain_about_stripped_glibc_ldso 1317 ); 1318 /* memcpy */ 1319 add_hardwired_spec( 1320 "ld-linux.so.3", "memcpy", 1321 (Addr)&VG_(arm_linux_REDIR_FOR_memcpy), 1322 complain_about_stripped_glibc_ldso 1323 ); 1324 add_hardwired_spec( 1325 "ld-linux-armhf.so.3", "memcpy", 1326 (Addr)&VG_(arm_linux_REDIR_FOR_memcpy), 1327 complain_about_stripped_glibc_ldso 1328 ); 1329 } 1330 1331 # elif defined(VGP_arm64_linux) 1332 /* If we're using memcheck, use these intercepts right from 1333 the start, otherwise ld.so makes a lot of noise. */ 1334 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1335 add_hardwired_spec( 1336 "ld-linux-aarch64.so.1", "strlen", 1337 (Addr)&VG_(arm64_linux_REDIR_FOR_strlen), 1338 complain_about_stripped_glibc_ldso 1339 ); 1340 add_hardwired_spec( 1341 "ld-linux-aarch64.so.1", "index", 1342 (Addr)&VG_(arm64_linux_REDIR_FOR_index), 1343 NULL 1344 ); 1345 add_hardwired_spec( 1346 "ld-linux-aarch64.so.1", "strcmp", 1347 (Addr)&VG_(arm64_linux_REDIR_FOR_strcmp), 1348 NULL 1349 ); 1350 //add_hardwired_spec( 1351 // "ld-linux.so.3", "memcpy", 1352 // (Addr)&VG_(arm_linux_REDIR_FOR_memcpy), 1353 // complain_about_stripped_glibc_ldso 1354 //); 1355 } 1356 1357 # elif defined(VGP_x86_darwin) 1358 /* If we're using memcheck, use these intercepts right from 1359 the start, otherwise dyld makes a lot of noise. */ 1360 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1361 add_hardwired_spec("dyld", "strcmp", 1362 (Addr)&VG_(x86_darwin_REDIR_FOR_strcmp), NULL); 1363 add_hardwired_spec("dyld", "strlen", 1364 (Addr)&VG_(x86_darwin_REDIR_FOR_strlen), NULL); 1365 add_hardwired_spec("dyld", "strcat", 1366 (Addr)&VG_(x86_darwin_REDIR_FOR_strcat), NULL); 1367 add_hardwired_spec("dyld", "strcpy", 1368 (Addr)&VG_(x86_darwin_REDIR_FOR_strcpy), NULL); 1369 add_hardwired_spec("dyld", "strlcat", 1370 (Addr)&VG_(x86_darwin_REDIR_FOR_strlcat), NULL); 1371 } 1372 1373 # elif defined(VGP_amd64_darwin) 1374 /* If we're using memcheck, use these intercepts right from 1375 the start, otherwise dyld makes a lot of noise. */ 1376 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1377 add_hardwired_spec("dyld", "strcmp", 1378 (Addr)&VG_(amd64_darwin_REDIR_FOR_strcmp), NULL); 1379 add_hardwired_spec("dyld", "strlen", 1380 (Addr)&VG_(amd64_darwin_REDIR_FOR_strlen), NULL); 1381 add_hardwired_spec("dyld", "strcat", 1382 (Addr)&VG_(amd64_darwin_REDIR_FOR_strcat), NULL); 1383 add_hardwired_spec("dyld", "strcpy", 1384 (Addr)&VG_(amd64_darwin_REDIR_FOR_strcpy), NULL); 1385 add_hardwired_spec("dyld", "strlcat", 1386 (Addr)&VG_(amd64_darwin_REDIR_FOR_strlcat), NULL); 1387 // DDD: #warning fixme rdar://6166275 1388 add_hardwired_spec("dyld", "arc4random", 1389 (Addr)&VG_(amd64_darwin_REDIR_FOR_arc4random), NULL); 1390 } 1391 1392 # elif defined(VGP_s390x_linux) 1393 /* nothing so far */ 1394 1395 # elif defined(VGP_mips32_linux) 1396 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1397 1398 /* this is mandatory - can't sanely continue without it */ 1399 add_hardwired_spec( 1400 "ld.so.3", "strlen", 1401 (Addr)&VG_(mips32_linux_REDIR_FOR_strlen), 1402 complain_about_stripped_glibc_ldso 1403 ); 1404 } 1405 1406 # elif defined(VGP_mips64_linux) 1407 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { 1408 1409 /* this is mandatory - can't sanely continue without it */ 1410 add_hardwired_spec( 1411 "ld.so.3", "strlen", 1412 (Addr)&VG_(mips64_linux_REDIR_FOR_strlen), 1413 complain_about_stripped_glibc_ldso 1414 ); 1415 } 1416 1417 # else 1418 # error Unknown platform 1419 # endif 1420 1421 if (VG_(clo_trace_redir)) 1422 show_redir_state("after VG_(redir_initialise)"); 1423 } 1424 1425 1426 /*------------------------------------------------------------*/ 1427 /*--- MISC HELPERS ---*/ 1428 /*------------------------------------------------------------*/ 1429 1430 static void* dinfo_zalloc(const HChar* ec, SizeT n) { 1431 void* p; 1432 vg_assert(n > 0); 1433 p = VG_(arena_malloc)(VG_AR_DINFO, ec, n); 1434 tl_assert(p); 1435 VG_(memset)(p, 0, n); 1436 return p; 1437 } 1438 1439 static void dinfo_free(void* p) { 1440 tl_assert(p); 1441 return VG_(arena_free)(VG_AR_DINFO, p); 1442 } 1443 1444 static HChar* dinfo_strdup(const HChar* ec, const HChar* str) 1445 { 1446 return VG_(arena_strdup)(VG_AR_DINFO, ec, str); 1447 } 1448 1449 /* Really this should be merged with translations_allowable_from_seg 1450 in m_translate. */ 1451 static Bool is_plausible_guest_addr(Addr a) 1452 { 1453 NSegment const* seg = VG_(am_find_nsegment)(a); 1454 return seg != NULL 1455 && (seg->kind == SkAnonC || seg->kind == SkFileC) 1456 && (seg->hasX || seg->hasR); /* crude x86-specific hack */ 1457 } 1458 1459 1460 /*------------------------------------------------------------*/ 1461 /*--- NOTIFY-ON-LOAD FUNCTIONS ---*/ 1462 /*------------------------------------------------------------*/ 1463 1464 static 1465 void handle_maybe_load_notifier( const HChar* soname, 1466 HChar* symbol, Addr addr ) 1467 { 1468 # if defined(VGP_x86_linux) 1469 /* x86-linux only: if we see _dl_sysinfo_int80, note its address. 1470 See comment on declaration of VG_(client__dl_sysinfo_int80) for 1471 the reason. As far as I can tell, the relevant symbol is always 1472 in object with soname "ld-linux.so.2". */ 1473 if (symbol && symbol[0] == '_' 1474 && 0 == VG_(strcmp)(symbol, "_dl_sysinfo_int80") 1475 && 0 == VG_(strcmp)(soname, "ld-linux.so.2")) { 1476 if (VG_(client__dl_sysinfo_int80) == 0) 1477 VG_(client__dl_sysinfo_int80) = addr; 1478 } 1479 # endif 1480 1481 /* Normal load-notifier handling after here. First, ignore all 1482 symbols lacking the right prefix. */ 1483 vg_assert(symbol); // assert rather than segfault if it is NULL 1484 if (0 != VG_(strncmp)(symbol, VG_NOTIFY_ON_LOAD_PREFIX, 1485 VG_NOTIFY_ON_LOAD_PREFIX_LEN)) 1486 /* Doesn't have the right prefix */ 1487 return; 1488 1489 if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(freeres))) == 0) 1490 VG_(client___libc_freeres_wrapper) = addr; 1491 else 1492 if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(ifunc_wrapper))) == 0) 1493 iFuncWrapper = addr; 1494 else 1495 vg_assert2(0, "unrecognised load notification function: %s", symbol); 1496 } 1497 1498 1499 /*------------------------------------------------------------*/ 1500 /*--- REQUIRE-TEXT-SYMBOL HANDLING ---*/ 1501 /*------------------------------------------------------------*/ 1502 1503 /* In short: check that the currently-being-loaded object has text 1504 symbols that satisfy any --require-text-symbol= specifications that 1505 apply to it, and abort the run with an error message if not. 1506 */ 1507 static void handle_require_text_symbols ( DebugInfo* di ) 1508 { 1509 /* First thing to do is figure out which, if any, 1510 --require-text-symbol specification strings apply to this 1511 object. Most likely none do, since it is not expected to 1512 frequently be used. Work through the list of specs and 1513 accumulate in fnpatts[] the fn patterns that pertain to this 1514 object. */ 1515 HChar* fnpatts[VG_CLO_MAX_REQ_TSYMS]; 1516 Int fnpatts_used = 0; 1517 Int i, j; 1518 const HChar* di_soname = VG_(DebugInfo_get_soname)(di); 1519 vg_assert(di_soname); // must be present 1520 1521 VG_(memset)(&fnpatts, 0, sizeof(fnpatts)); 1522 1523 vg_assert(VG_(clo_n_req_tsyms) >= 0); 1524 vg_assert(VG_(clo_n_req_tsyms) <= VG_CLO_MAX_REQ_TSYMS); 1525 for (i = 0; i < VG_(clo_n_req_tsyms); i++) { 1526 const HChar* clo_spec = VG_(clo_req_tsyms)[i]; 1527 vg_assert(clo_spec && VG_(strlen)(clo_spec) >= 4); 1528 // clone the spec, so we can stick a zero at the end of the sopatt 1529 HChar *spec = VG_(strdup)("m_redir.hrts.1", clo_spec); 1530 HChar sep = spec[0]; 1531 HChar* sopatt = &spec[1]; 1532 HChar* fnpatt = VG_(strchr)(sopatt, sep); 1533 // the initial check at clo processing in time in m_main 1534 // should ensure this. 1535 vg_assert(fnpatt && *fnpatt == sep); 1536 *fnpatt = 0; 1537 fnpatt++; 1538 if (VG_(string_match)(sopatt, di_soname)) 1539 fnpatts[fnpatts_used++] 1540 = VG_(strdup)("m_redir.hrts.2", fnpatt); 1541 VG_(free)(spec); 1542 } 1543 1544 if (fnpatts_used == 0) 1545 return; /* no applicable spec strings */ 1546 1547 /* So finally, fnpatts[0 .. fnpatts_used - 1] contains the set of 1548 (patterns for) text symbol names that must be found in this 1549 object, in order to continue. That is, we must find at least 1550 one text symbol name that matches each pattern, else we must 1551 abort the run. */ 1552 1553 if (0) VG_(printf)("for %s\n", di_soname); 1554 for (i = 0; i < fnpatts_used; i++) 1555 if (0) VG_(printf)(" fnpatt: %s\n", fnpatts[i]); 1556 1557 /* For each spec, look through the syms to find one that matches. 1558 This isn't terribly efficient but it happens rarely, so no big 1559 deal. */ 1560 for (i = 0; i < fnpatts_used; i++) { 1561 Bool found = False; 1562 HChar* fnpatt = fnpatts[i]; 1563 Int nsyms = VG_(DebugInfo_syms_howmany)(di); 1564 for (j = 0; j < nsyms; j++) { 1565 Bool isText = False; 1566 HChar* sym_name_pri = NULL; 1567 HChar** sym_names_sec = NULL; 1568 VG_(DebugInfo_syms_getidx)( di, j, NULL, NULL, 1569 NULL, &sym_name_pri, &sym_names_sec, 1570 &isText, NULL ); 1571 HChar* twoslots[2]; 1572 HChar** names_init = alloc_symname_array(sym_name_pri, sym_names_sec, 1573 &twoslots[0]); 1574 HChar** names; 1575 for (names = names_init; *names; names++) { 1576 /* ignore data symbols */ 1577 if (0) VG_(printf)("QQQ %s\n", *names); 1578 vg_assert(sym_name_pri); 1579 if (!isText) 1580 continue; 1581 if (VG_(string_match)(fnpatt, *names)) { 1582 found = True; 1583 break; 1584 } 1585 } 1586 free_symname_array(names_init, &twoslots[0]); 1587 if (found) 1588 break; 1589 } 1590 1591 if (!found) { 1592 const HChar* v = "valgrind: "; 1593 VG_(printf)("\n"); 1594 VG_(printf)( 1595 "%sFatal error at when loading library with soname\n", v); 1596 VG_(printf)( 1597 "%s %s\n", v, di_soname); 1598 VG_(printf)( 1599 "%sCannot find any text symbol with a name " 1600 "that matches the pattern\n", v); 1601 VG_(printf)("%s %s\n", v, fnpatt); 1602 VG_(printf)("%sas required by a --require-text-symbol= " 1603 "specification.\n", v); 1604 VG_(printf)("\n"); 1605 VG_(printf)( 1606 "%sCannot continue -- exiting now.\n", v); 1607 VG_(printf)("\n"); 1608 VG_(exit)(1); 1609 } 1610 } 1611 1612 /* All required specs were found. Just free memory and return. */ 1613 for (i = 0; i < fnpatts_used; i++) 1614 VG_(free)(fnpatts[i]); 1615 } 1616 1617 1618 /*------------------------------------------------------------*/ 1619 /*--- SANITY/DEBUG ---*/ 1620 /*------------------------------------------------------------*/ 1621 1622 static void show_spec ( const HChar* left, Spec* spec ) 1623 { 1624 VG_(message)( Vg_DebugMsg, 1625 "%s%25s %30s %s-> (%04d.%d) 0x%08llx\n", 1626 left, 1627 spec->from_sopatt, spec->from_fnpatt, 1628 spec->isWrap ? "W" : "R", 1629 spec->becTag, spec->becPrio, 1630 (ULong)spec->to_addr ); 1631 } 1632 1633 static void show_active ( const HChar* left, Active* act ) 1634 { 1635 Bool ok; 1636 HChar name1[64] = ""; 1637 HChar name2[64] = ""; 1638 name1[0] = name2[0] = 0; 1639 ok = VG_(get_fnname_w_offset)(act->from_addr, name1, 64); 1640 if (!ok) VG_(strcpy)(name1, "???"); 1641 ok = VG_(get_fnname_w_offset)(act->to_addr, name2, 64); 1642 if (!ok) VG_(strcpy)(name2, "???"); 1643 1644 VG_(message)(Vg_DebugMsg, "%s0x%08llx (%20s) %s-> (%04d.%d) 0x%08llx %s\n", 1645 left, 1646 (ULong)act->from_addr, name1, 1647 act->isWrap ? "W" : "R", 1648 act->becTag, act->becPrio, 1649 (ULong)act->to_addr, name2 ); 1650 } 1651 1652 static void show_redir_state ( const HChar* who ) 1653 { 1654 TopSpec* ts; 1655 Spec* sp; 1656 Active* act; 1657 VG_(message)(Vg_DebugMsg, "<<\n"); 1658 VG_(message)(Vg_DebugMsg, " ------ REDIR STATE %s ------\n", who); 1659 for (ts = topSpecs; ts; ts = ts->next) { 1660 if (ts->seginfo) 1661 VG_(message)(Vg_DebugMsg, 1662 " TOPSPECS of soname %s filename %s\n", 1663 VG_(DebugInfo_get_soname)(ts->seginfo), 1664 VG_(DebugInfo_get_filename)(ts->seginfo)); 1665 else 1666 VG_(message)(Vg_DebugMsg, 1667 " TOPSPECS of soname (hardwired)\n"); 1668 1669 for (sp = ts->specs; sp; sp = sp->next) 1670 show_spec(" ", sp); 1671 } 1672 VG_(message)(Vg_DebugMsg, " ------ ACTIVE ------\n"); 1673 VG_(OSetGen_ResetIter)( activeSet ); 1674 while ( (act = VG_(OSetGen_Next)(activeSet)) ) { 1675 show_active(" ", act); 1676 } 1677 1678 VG_(message)(Vg_DebugMsg, ">>\n"); 1679 } 1680 1681 /*--------------------------------------------------------------------*/ 1682 /*--- end ---*/ 1683 /*--------------------------------------------------------------------*/ 1684