Home | History | Annotate | Download | only in coregrind
      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-2012 Julian Seward
     11       jseward (at) acm.org
     12    Copyright (C) 2003-2012 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(HChar* ec, SizeT);
    306 static void   dinfo_free(void*);
    307 static HChar* dinfo_strdup(HChar* ec, HChar*);
    308 static Bool   is_plausible_guest_addr(Addr);
    309 
    310 static void   show_redir_state ( HChar* who );
    311 static void   show_active ( HChar* left, Active* act );
    312 
    313 static void   handle_maybe_load_notifier( const UChar* 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 UChar** alloc_symname_array ( UChar* pri_name, UChar** sec_names,
    338                                      UChar** 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    UChar** pp    = sec_names;
    350    while (*pp) { n_req++; pp++; }
    351    /* .. allocate and copy in. */
    352    UChar** arr = dinfo_zalloc( "redir.asa.1", (n_req+1) * sizeof(UChar*) );
    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 ( UChar** names, UChar** 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    UChar*       sym_name_pri;
    399    UChar**      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 UChar* 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 UChar* newdi_filename = VG_(DebugInfo_get_filename)(newdi);
    441       const UChar* 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          Char 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       UChar*  twoslots[2];
    507       UChar** names_init = alloc_symname_array(sym_name_pri, sym_names_sec,
    508                                                &twoslots[0]);
    509       UChar** 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          UChar*  twoslots[2];
    599          UChar** names_init = alloc_symname_array(sym_name_pri, sym_names_sec,
    600                                                   &twoslots[0]);
    601          UChar** 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    UChar*  sym_name_pri;
    737    UChar** 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       UChar*  twoslots[2];
    762       UChar** names_init = alloc_symname_array(sym_name_pri, sym_names_sec,
    763                                                &twoslots[0]);
    764       UChar** 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       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    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 ( HChar* sopatt, 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 = sopatt;
   1150    spec->from_fnpatt = 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
   1303       the start, otherwise ld.so makes a lot of noise. */
   1304    if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
   1305       add_hardwired_spec(
   1306          "ld-linux.so.3", "strlen",
   1307          (Addr)&VG_(arm_linux_REDIR_FOR_strlen),
   1308          complain_about_stripped_glibc_ldso
   1309       );
   1310       //add_hardwired_spec(
   1311       //   "ld-linux.so.3", "index",
   1312       //   (Addr)&VG_(arm_linux_REDIR_FOR_index),
   1313       //   NULL
   1314       //);
   1315       add_hardwired_spec(
   1316          "ld-linux.so.3", "memcpy",
   1317          (Addr)&VG_(arm_linux_REDIR_FOR_memcpy),
   1318          complain_about_stripped_glibc_ldso
   1319       );
   1320    }
   1321    /* nothing so far */
   1322 
   1323 #  elif defined(VGP_x86_darwin)
   1324    /* If we're using memcheck, use these intercepts right from
   1325       the start, otherwise dyld makes a lot of noise. */
   1326    if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
   1327       add_hardwired_spec("dyld", "strcmp",
   1328                          (Addr)&VG_(x86_darwin_REDIR_FOR_strcmp), NULL);
   1329       add_hardwired_spec("dyld", "strlen",
   1330                          (Addr)&VG_(x86_darwin_REDIR_FOR_strlen), NULL);
   1331       add_hardwired_spec("dyld", "strcat",
   1332                          (Addr)&VG_(x86_darwin_REDIR_FOR_strcat), NULL);
   1333       add_hardwired_spec("dyld", "strcpy",
   1334                          (Addr)&VG_(x86_darwin_REDIR_FOR_strcpy), NULL);
   1335       add_hardwired_spec("dyld", "strlcat",
   1336                          (Addr)&VG_(x86_darwin_REDIR_FOR_strlcat), NULL);
   1337    }
   1338 
   1339 #  elif defined(VGP_amd64_darwin)
   1340    /* If we're using memcheck, use these intercepts right from
   1341       the start, otherwise dyld makes a lot of noise. */
   1342    if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
   1343       add_hardwired_spec("dyld", "strcmp",
   1344                          (Addr)&VG_(amd64_darwin_REDIR_FOR_strcmp), NULL);
   1345       add_hardwired_spec("dyld", "strlen",
   1346                          (Addr)&VG_(amd64_darwin_REDIR_FOR_strlen), NULL);
   1347       add_hardwired_spec("dyld", "strcat",
   1348                          (Addr)&VG_(amd64_darwin_REDIR_FOR_strcat), NULL);
   1349       add_hardwired_spec("dyld", "strcpy",
   1350                          (Addr)&VG_(amd64_darwin_REDIR_FOR_strcpy), NULL);
   1351       add_hardwired_spec("dyld", "strlcat",
   1352                          (Addr)&VG_(amd64_darwin_REDIR_FOR_strlcat), NULL);
   1353       // DDD: #warning fixme rdar://6166275
   1354       add_hardwired_spec("dyld", "arc4random",
   1355                          (Addr)&VG_(amd64_darwin_REDIR_FOR_arc4random), NULL);
   1356    }
   1357 
   1358 #  elif defined(VGP_s390x_linux)
   1359    /* nothing so far */
   1360 
   1361 #  elif defined(VGP_mips32_linux)
   1362    if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
   1363 
   1364       /* this is mandatory - can't sanely continue without it */
   1365       add_hardwired_spec(
   1366          "ld.so.3", "strlen",
   1367          (Addr)&VG_(mips32_linux_REDIR_FOR_strlen),
   1368          complain_about_stripped_glibc_ldso
   1369       );
   1370    }
   1371 
   1372 #  else
   1373 #    error Unknown platform
   1374 #  endif
   1375 
   1376    if (VG_(clo_trace_redir))
   1377       show_redir_state("after VG_(redir_initialise)");
   1378 }
   1379 
   1380 
   1381 /*------------------------------------------------------------*/
   1382 /*--- MISC HELPERS                                         ---*/
   1383 /*------------------------------------------------------------*/
   1384 
   1385 static void* dinfo_zalloc(HChar* ec, SizeT n) {
   1386    void* p;
   1387    vg_assert(n > 0);
   1388    p = VG_(arena_malloc)(VG_AR_DINFO, ec, n);
   1389    tl_assert(p);
   1390    VG_(memset)(p, 0, n);
   1391    return p;
   1392 }
   1393 
   1394 static void dinfo_free(void* p) {
   1395    tl_assert(p);
   1396    return VG_(arena_free)(VG_AR_DINFO, p);
   1397 }
   1398 
   1399 static HChar* dinfo_strdup(HChar* ec, HChar* str)
   1400 {
   1401    return VG_(arena_strdup)(VG_AR_DINFO, ec, str);
   1402 }
   1403 
   1404 /* Really this should be merged with translations_allowable_from_seg
   1405    in m_translate. */
   1406 static Bool is_plausible_guest_addr(Addr a)
   1407 {
   1408    NSegment const* seg = VG_(am_find_nsegment)(a);
   1409    return seg != NULL
   1410           && (seg->kind == SkAnonC || seg->kind == SkFileC)
   1411           && (seg->hasX || seg->hasR); /* crude x86-specific hack */
   1412 }
   1413 
   1414 
   1415 /*------------------------------------------------------------*/
   1416 /*--- NOTIFY-ON-LOAD FUNCTIONS                             ---*/
   1417 /*------------------------------------------------------------*/
   1418 
   1419 static
   1420 void handle_maybe_load_notifier( const UChar* soname,
   1421                                        HChar* symbol, Addr addr )
   1422 {
   1423 #  if defined(VGP_x86_linux)
   1424    /* x86-linux only: if we see _dl_sysinfo_int80, note its address.
   1425       See comment on declaration of VG_(client__dl_sysinfo_int80) for
   1426       the reason.  As far as I can tell, the relevant symbol is always
   1427       in object with soname "ld-linux.so.2". */
   1428    if (symbol && symbol[0] == '_'
   1429               && 0 == VG_(strcmp)(symbol, "_dl_sysinfo_int80")
   1430               && 0 == VG_(strcmp)(soname, "ld-linux.so.2")) {
   1431       if (VG_(client__dl_sysinfo_int80) == 0)
   1432          VG_(client__dl_sysinfo_int80) = addr;
   1433    }
   1434 #  endif
   1435 
   1436    /* Normal load-notifier handling after here.  First, ignore all
   1437       symbols lacking the right prefix. */
   1438    vg_assert(symbol); // assert rather than segfault if it is NULL
   1439    if (0 != VG_(strncmp)(symbol, VG_NOTIFY_ON_LOAD_PREFIX,
   1440                                  VG_NOTIFY_ON_LOAD_PREFIX_LEN))
   1441       /* Doesn't have the right prefix */
   1442       return;
   1443 
   1444    if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(freeres))) == 0)
   1445       VG_(client___libc_freeres_wrapper) = addr;
   1446    else
   1447    if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(ifunc_wrapper))) == 0)
   1448       iFuncWrapper = addr;
   1449    else
   1450       vg_assert2(0, "unrecognised load notification function: %s", symbol);
   1451 }
   1452 
   1453 
   1454 /*------------------------------------------------------------*/
   1455 /*--- REQUIRE-TEXT-SYMBOL HANDLING                         ---*/
   1456 /*------------------------------------------------------------*/
   1457 
   1458 /* In short: check that the currently-being-loaded object has text
   1459    symbols that satisfy any --require-text-symbol= specifications that
   1460    apply to it, and abort the run with an error message if not.
   1461 */
   1462 static void handle_require_text_symbols ( DebugInfo* di )
   1463 {
   1464    /* First thing to do is figure out which, if any,
   1465       --require-text-symbol specification strings apply to this
   1466       object.  Most likely none do, since it is not expected to
   1467       frequently be used.  Work through the list of specs and
   1468       accumulate in fnpatts[] the fn patterns that pertain to this
   1469       object. */
   1470    HChar* fnpatts[VG_CLO_MAX_REQ_TSYMS];
   1471    Int    fnpatts_used = 0;
   1472    Int    i, j;
   1473    const HChar* di_soname = VG_(DebugInfo_get_soname)(di);
   1474    vg_assert(di_soname); // must be present
   1475 
   1476    VG_(memset)(&fnpatts, 0, sizeof(fnpatts));
   1477 
   1478    vg_assert(VG_(clo_n_req_tsyms) >= 0);
   1479    vg_assert(VG_(clo_n_req_tsyms) <= VG_CLO_MAX_REQ_TSYMS);
   1480    for (i = 0; i < VG_(clo_n_req_tsyms); i++) {
   1481       HChar* spec = VG_(clo_req_tsyms)[i];
   1482       vg_assert(spec && VG_(strlen)(spec) >= 4);
   1483       // clone the spec, so we can stick a zero at the end of the sopatt
   1484       spec = VG_(strdup)("m_redir.hrts.1", spec);
   1485       HChar sep = spec[0];
   1486       HChar* sopatt = &spec[1];
   1487       HChar* fnpatt = VG_(strchr)(sopatt, sep);
   1488       // the initial check at clo processing in time in m_main
   1489       // should ensure this.
   1490       vg_assert(fnpatt && *fnpatt == sep);
   1491       *fnpatt = 0;
   1492       fnpatt++;
   1493       if (VG_(string_match)(sopatt, di_soname))
   1494          fnpatts[fnpatts_used++]
   1495             = VG_(strdup)("m_redir.hrts.2", fnpatt);
   1496       VG_(free)(spec);
   1497    }
   1498 
   1499    if (fnpatts_used == 0)
   1500       return;  /* no applicable spec strings */
   1501 
   1502    /* So finally, fnpatts[0 .. fnpatts_used - 1] contains the set of
   1503       (patterns for) text symbol names that must be found in this
   1504       object, in order to continue.  That is, we must find at least
   1505       one text symbol name that matches each pattern, else we must
   1506       abort the run. */
   1507 
   1508    if (0) VG_(printf)("for %s\n", di_soname);
   1509    for (i = 0; i < fnpatts_used; i++)
   1510       if (0) VG_(printf)("   fnpatt: %s\n", fnpatts[i]);
   1511 
   1512    /* For each spec, look through the syms to find one that matches.
   1513       This isn't terribly efficient but it happens rarely, so no big
   1514       deal. */
   1515    for (i = 0; i < fnpatts_used; i++) {
   1516       Bool   found  = False;
   1517       HChar* fnpatt = fnpatts[i];
   1518       Int    nsyms  = VG_(DebugInfo_syms_howmany)(di);
   1519       for (j = 0; j < nsyms; j++) {
   1520          Bool    isText        = False;
   1521          UChar*  sym_name_pri  = NULL;
   1522          UChar** sym_names_sec = NULL;
   1523          VG_(DebugInfo_syms_getidx)( di, j, NULL, NULL,
   1524                                      NULL, &sym_name_pri, &sym_names_sec,
   1525                                      &isText, NULL );
   1526          UChar*  twoslots[2];
   1527          UChar** names_init = alloc_symname_array(sym_name_pri, sym_names_sec,
   1528                                                   &twoslots[0]);
   1529          UChar** names;
   1530          for (names = names_init; *names; names++) {
   1531             /* ignore data symbols */
   1532             if (0) VG_(printf)("QQQ %s\n", *names);
   1533             vg_assert(sym_name_pri);
   1534             if (!isText)
   1535                continue;
   1536             if (VG_(string_match)(fnpatt, *names)) {
   1537                found = True;
   1538                break;
   1539             }
   1540          }
   1541          free_symname_array(names_init, &twoslots[0]);
   1542          if (found)
   1543             break;
   1544       }
   1545 
   1546       if (!found) {
   1547          HChar* v = "valgrind:  ";
   1548          VG_(printf)("\n");
   1549          VG_(printf)(
   1550          "%sFatal error at when loading library with soname\n", v);
   1551          VG_(printf)(
   1552          "%s   %s\n", v, di_soname);
   1553          VG_(printf)(
   1554          "%sCannot find any text symbol with a name "
   1555          "that matches the pattern\n", v);
   1556          VG_(printf)("%s   %s\n", v, fnpatt);
   1557          VG_(printf)("%sas required by a --require-text-symbol= "
   1558          "specification.\n", v);
   1559          VG_(printf)("\n");
   1560          VG_(printf)(
   1561          "%sCannot continue -- exiting now.\n", v);
   1562          VG_(printf)("\n");
   1563          VG_(exit)(1);
   1564       }
   1565    }
   1566 
   1567    /* All required specs were found.  Just free memory and return. */
   1568    for (i = 0; i < fnpatts_used; i++)
   1569       VG_(free)(fnpatts[i]);
   1570 }
   1571 
   1572 
   1573 /*------------------------------------------------------------*/
   1574 /*--- SANITY/DEBUG                                         ---*/
   1575 /*------------------------------------------------------------*/
   1576 
   1577 static void show_spec ( HChar* left, Spec* spec )
   1578 {
   1579    VG_(message)( Vg_DebugMsg,
   1580                  "%s%25s %30s %s-> (%04d.%d) 0x%08llx\n",
   1581                  left,
   1582                  spec->from_sopatt, spec->from_fnpatt,
   1583                  spec->isWrap ? "W" : "R",
   1584                  spec->becTag, spec->becPrio,
   1585                  (ULong)spec->to_addr );
   1586 }
   1587 
   1588 static void show_active ( HChar* left, Active* act )
   1589 {
   1590    Bool ok;
   1591    HChar name1[64] = "";
   1592    HChar name2[64] = "";
   1593    name1[0] = name2[0] = 0;
   1594    ok = VG_(get_fnname_w_offset)(act->from_addr, name1, 64);
   1595    if (!ok) VG_(strcpy)(name1, "???");
   1596    ok = VG_(get_fnname_w_offset)(act->to_addr, name2, 64);
   1597    if (!ok) VG_(strcpy)(name2, "???");
   1598 
   1599    VG_(message)(Vg_DebugMsg, "%s0x%08llx (%20s) %s-> (%04d.%d) 0x%08llx %s\n",
   1600                              left,
   1601                              (ULong)act->from_addr, name1,
   1602                              act->isWrap ? "W" : "R",
   1603                              act->becTag, act->becPrio,
   1604                              (ULong)act->to_addr, name2 );
   1605 }
   1606 
   1607 static void show_redir_state ( HChar* who )
   1608 {
   1609    TopSpec* ts;
   1610    Spec*    sp;
   1611    Active*  act;
   1612    VG_(message)(Vg_DebugMsg, "<<\n");
   1613    VG_(message)(Vg_DebugMsg, "   ------ REDIR STATE %s ------\n", who);
   1614    for (ts = topSpecs; ts; ts = ts->next) {
   1615       if (ts->seginfo)
   1616          VG_(message)(Vg_DebugMsg,
   1617                       "   TOPSPECS of soname %s filename %s\n",
   1618                       (HChar*)VG_(DebugInfo_get_soname)(ts->seginfo),
   1619                       (HChar*)VG_(DebugInfo_get_filename)(ts->seginfo));
   1620       else
   1621          VG_(message)(Vg_DebugMsg,
   1622                       "   TOPSPECS of soname (hardwired)\n");
   1623 
   1624       for (sp = ts->specs; sp; sp = sp->next)
   1625          show_spec("     ", sp);
   1626    }
   1627    VG_(message)(Vg_DebugMsg, "   ------ ACTIVE ------\n");
   1628    VG_(OSetGen_ResetIter)( activeSet );
   1629    while ( (act = VG_(OSetGen_Next)(activeSet)) ) {
   1630       show_active("    ", act);
   1631    }
   1632 
   1633    VG_(message)(Vg_DebugMsg, ">>\n");
   1634 }
   1635 
   1636 /*--------------------------------------------------------------------*/
   1637 /*--- end                                                          ---*/
   1638 /*--------------------------------------------------------------------*/
   1639