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