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_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. */
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      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, Active* act );
312
313static void   handle_maybe_load_notifier( const HChar* soname,
314                                                HChar* symbol, Addr addr );
315
316static void   handle_require_text_symbols ( 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        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 HChar** alloc_symname_array ( HChar* pri_name, HChar** sec_names,
338                                     HChar** twoslots )
339{
340   /* Special-case the common case: only one name.  We expect the
341      caller to supply a stack-allocated 2-entry array for this. */
342   if (sec_names == NULL) {
343      twoslots[0] = pri_name;
344      twoslots[1] = NULL;
345      return twoslots;
346   }
347   /* Else must use dynamic allocation.  Figure out size .. */
348   Word    n_req = 1;
349   HChar** pp    = sec_names;
350   while (*pp) { n_req++; pp++; }
351   /* .. allocate and copy in. */
352   HChar** arr = dinfo_zalloc( "redir.asa.1", (n_req+1) * sizeof(HChar*) );
353   Word    i   = 0;
354   arr[i++] = pri_name;
355   pp = sec_names;
356   while (*pp) { arr[i++] = *pp; pp++; }
357   tl_assert(i == n_req);
358   tl_assert(arr[n_req] == NULL);
359   return arr;
360}
361
362
363/* Free the array allocated by alloc_symname_array, if any. */
364static void free_symname_array ( HChar** names, HChar** twoslots )
365{
366   if (names != twoslots)
367      dinfo_free(names);
368}
369
370static HChar const* advance_to_equal ( HChar const* c ) {
371   while (*c && *c != '=') {
372      ++c;
373   }
374   return c;
375}
376static HChar const* advance_to_comma ( HChar const* c ) {
377   while (*c && *c != ',') {
378      ++c;
379   }
380   return c;
381}
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
390void VG_(redir_notify_new_DebugInfo)( DebugInfo* newdi )
391{
392   Bool         ok, isWrap;
393   Int          i, nsyms, becTag, becPrio;
394   Spec*        specList;
395   Spec*        spec;
396   TopSpec*     ts;
397   TopSpec*     newts;
398   HChar*       sym_name_pri;
399   HChar**      sym_names_sec;
400   Addr         sym_addr, sym_toc;
401   HChar        demangled_sopatt[N_DEMANGLED];
402   HChar        demangled_fnpatt[N_DEMANGLED];
403   Bool         check_ppcTOCs = False;
404   Bool         isText;
405   const HChar* newdi_soname;
406
407#  if defined(VG_PLAT_USES_PPCTOC)
408   check_ppcTOCs = True;
409#  endif
410
411   vg_assert(newdi);
412   newdi_soname = VG_(DebugInfo_get_soname)(newdi);
413   vg_assert(newdi_soname != NULL);
414
415#ifdef ENABLE_INNER
416   {
417      /* When an outer Valgrind is executing an inner Valgrind, the
418         inner "sees" in its address space the mmap-ed vgpreload files
419         of the outer.  The inner must avoid interpreting the
420         redirections given in the outer vgpreload mmap-ed files.
421         Otherwise, some tool combinations badly fail.
422
423         Example: outer memcheck tool executing an inner none tool.
424
425         If inner none interprets the outer malloc redirection, the
426         inner will redirect malloc to a memcheck function it does not
427         have (as the redirection target is from the outer).  With
428         such a failed redirection, a call to malloc inside the inner
429         will then result in a "no-operation" (and so no memory will
430         be allocated).
431
432         When running as an inner, no redirection will be done
433         for a vgpreload file if this file is not located in the
434         inner VALGRIND_LIB directory.
435
436         Recognising a vgpreload file based on a filename pattern
437         is a kludge. An alternate solution would be to change
438         the _vgr prefix according to outer/inner/client.
439      */
440      const HChar* newdi_filename = VG_(DebugInfo_get_filename)(newdi);
441      const HChar* newdi_basename = VG_(basename) (newdi_filename);
442      if (VG_(strncmp) (newdi_basename, "vgpreload_", 10) == 0) {
443         /* This looks like a vgpreload file => check if this file
444            is from the inner VALGRIND_LIB.
445            We do this check using VG_(stat) + dev/inode comparison
446            as vg-in-place defines a VALGRIND_LIB with symlinks
447            pointing to files inside the valgrind build directories. */
448         struct vg_stat newdi_stat;
449         SysRes newdi_res;
450         HChar in_vglib_filename[VKI_PATH_MAX];
451         struct vg_stat in_vglib_stat;
452         SysRes in_vglib_res;
453
454         newdi_res = VG_(stat)(newdi_filename, &newdi_stat);
455
456         VG_(strncpy) (in_vglib_filename, VG_(libdir), VKI_PATH_MAX);
457         VG_(strncat) (in_vglib_filename, "/", VKI_PATH_MAX);
458         VG_(strncat) (in_vglib_filename, newdi_basename, VKI_PATH_MAX);
459         in_vglib_res = VG_(stat)(in_vglib_filename, &in_vglib_stat);
460
461         /* If we find newdi_basename in inner VALGRIND_LIB
462            but newdi_filename is not the same file, then we do
463            not execute the redirection. */
464         if (!sr_isError(in_vglib_res)
465             && !sr_isError(newdi_res)
466             && (newdi_stat.dev != in_vglib_stat.dev
467                 || newdi_stat.ino != in_vglib_stat.ino)) {
468            /* <inner VALGRIND_LIB>/newdi_basename is an existing file
469               and is different of newdi_filename.
470               So, we do not execute newdi_filename redirection. */
471            if ( VG_(clo_verbosity) > 1 ) {
472               VG_(message)( Vg_DebugMsg,
473                             "Skipping vgpreload redir in %s"
474                             " (not from VALGRIND_LIB_INNER)\n",
475                             newdi_filename);
476            }
477            return;
478         } else {
479            if ( VG_(clo_verbosity) > 1 ) {
480               VG_(message)( Vg_DebugMsg,
481                             "Executing vgpreload redir in %s"
482                             " (from VALGRIND_LIB_INNER)\n",
483                             newdi_filename);
484            }
485         }
486      }
487   }
488#endif
489
490
491   /* stay sane: we don't already have this. */
492   for (ts = topSpecs; ts; ts = ts->next)
493      vg_assert(ts->seginfo != newdi);
494
495   /* scan this DebugInfo's symbol table, pulling out and demangling
496      any specs found */
497
498   specList = NULL; /* the spec list we're building up */
499
500   nsyms = VG_(DebugInfo_syms_howmany)( newdi );
501   for (i = 0; i < nsyms; i++) {
502      VG_(DebugInfo_syms_getidx)( newdi, i, &sym_addr, &sym_toc,
503                                  NULL, &sym_name_pri, &sym_names_sec,
504                                  &isText, NULL );
505      /* Set up to conveniently iterate over all names for this symbol. */
506      HChar*  twoslots[2];
507      HChar** names_init = alloc_symname_array(sym_name_pri, sym_names_sec,
508                                               &twoslots[0]);
509      HChar** names;
510      for (names = names_init; *names; names++) {
511         ok = VG_(maybe_Z_demangle)( *names,
512                                     demangled_sopatt, N_DEMANGLED,
513                                     demangled_fnpatt, N_DEMANGLED,
514                                     &isWrap, &becTag, &becPrio );
515         /* ignore data symbols */
516         if (!isText)
517            continue;
518         if (!ok) {
519            /* It's not a full-scale redirect, but perhaps it is a load-notify
520               fn?  Let the load-notify department see it. */
521            handle_maybe_load_notifier( newdi_soname, *names, sym_addr );
522            continue;
523         }
524         if (check_ppcTOCs && sym_toc == 0) {
525            /* This platform uses toc pointers, but none could be found
526               for this symbol, so we can't safely redirect/wrap to it.
527               Just skip it; we'll make a second pass over the symbols in
528               the following loop, and complain at that point. */
529            continue;
530         }
531
532         if (0 == VG_(strncmp) (demangled_sopatt,
533                                VG_SO_SYN_PREFIX, VG_SO_SYN_PREFIX_LEN)) {
534            /* This is a redirection for handling lib so synonyms. If we
535               have a matching lib synonym, then replace the sopatt.
536               Otherwise, just ignore this redirection spec. */
537
538            if (!VG_(clo_soname_synonyms))
539               continue; // No synonyms => skip the redir.
540
541            /* Search for a matching synonym=newname*/
542            SizeT const sopatt_syn_len
543               = VG_(strlen)(demangled_sopatt+VG_SO_SYN_PREFIX_LEN);
544            HChar const* last = VG_(clo_soname_synonyms);
545
546            while (*last) {
547               HChar const* first = last;
548               last = advance_to_equal(first);
549
550               if ((last - first) == sopatt_syn_len
551                   && 0 == VG_(strncmp)(demangled_sopatt+VG_SO_SYN_PREFIX_LEN,
552                                        first,
553                                        sopatt_syn_len)) {
554                  // Found the demangle_sopatt synonym => replace it
555                  first = last + 1;
556                  last = advance_to_comma(first);
557                  VG_(strncpy)(demangled_sopatt, first, last - first);
558                  demangled_sopatt[last - first] = '\0';
559                  break;
560               }
561
562               last = advance_to_comma(last);
563               if (*last == ',')
564                  last++;
565            }
566
567            // If we have not replaced the sopatt, then skip the redir.
568            if (0 == VG_(strncmp) (demangled_sopatt,
569                                   VG_SO_SYN_PREFIX, VG_SO_SYN_PREFIX_LEN))
570               continue;
571         }
572
573         spec = dinfo_zalloc("redir.rnnD.1", sizeof(Spec));
574         vg_assert(spec);
575         spec->from_sopatt = dinfo_strdup("redir.rnnD.2", demangled_sopatt);
576         spec->from_fnpatt = dinfo_strdup("redir.rnnD.3", demangled_fnpatt);
577         vg_assert(spec->from_sopatt);
578         vg_assert(spec->from_fnpatt);
579         spec->to_addr = sym_addr;
580         spec->isWrap = isWrap;
581         spec->becTag = becTag;
582         spec->becPrio = becPrio;
583         /* check we're not adding manifestly stupid destinations */
584         vg_assert(is_plausible_guest_addr(sym_addr));
585         spec->next = specList;
586         spec->mark = False; /* not significant */
587         spec->done = False; /* not significant */
588         specList = spec;
589      }
590      free_symname_array(names_init, &twoslots[0]);
591   }
592
593   if (check_ppcTOCs) {
594      for (i = 0; i < nsyms; i++) {
595         VG_(DebugInfo_syms_getidx)( newdi, i, &sym_addr, &sym_toc,
596                                     NULL, &sym_name_pri, &sym_names_sec,
597                                     &isText, NULL );
598         HChar*  twoslots[2];
599         HChar** names_init = alloc_symname_array(sym_name_pri, sym_names_sec,
600                                                  &twoslots[0]);
601         HChar** names;
602         for (names = names_init; *names; names++) {
603            ok = isText
604                 && VG_(maybe_Z_demangle)(
605                       *names, demangled_sopatt, N_DEMANGLED,
606                       demangled_fnpatt, N_DEMANGLED, &isWrap, NULL, NULL );
607            if (!ok)
608               /* not a redirect.  Ignore. */
609               continue;
610            if (sym_toc != 0)
611               /* has a valid toc pointer.  Ignore. */
612               continue;
613
614            for (spec = specList; spec; spec = spec->next)
615               if (0 == VG_(strcmp)(spec->from_sopatt, demangled_sopatt)
616                   && 0 == VG_(strcmp)(spec->from_fnpatt, demangled_fnpatt))
617                  break;
618            if (spec)
619               /* a redirect to some other copy of that symbol, which
620                  does have a TOC value, already exists */
621               continue;
622
623            /* Complain */
624            VG_(message)(Vg_DebugMsg,
625                         "WARNING: no TOC ptr for redir/wrap to %s %s\n",
626                         demangled_sopatt, demangled_fnpatt);
627         }
628         free_symname_array(names_init, &twoslots[0]);
629      }
630   }
631
632   /* Ok.  Now specList holds the list of specs from the DebugInfo.
633      Build a new TopSpec, but don't add it to topSpecs yet. */
634   newts = dinfo_zalloc("redir.rnnD.4", sizeof(TopSpec));
635   vg_assert(newts);
636   newts->next    = NULL; /* not significant */
637   newts->seginfo = newdi;
638   newts->specs   = specList;
639   newts->mark    = False; /* not significant */
640
641   /* We now need to augment the active set with the following partial
642      cross product:
643
644      (1) actives formed by matching the new specs in specList against
645          all symbols currently listed in topSpecs
646
647      (2) actives formed by matching the new symbols in newdi against
648          all specs currently listed in topSpecs
649
650      (3) actives formed by matching the new symbols in newdi against
651          the new specs in specList
652
653      This is necessary in order to maintain the invariant that
654      Actives contains all bindings generated by matching ALL specs in
655      topSpecs against ALL symbols in topSpecs (that is, a cross
656      product of ALL known specs against ALL known symbols).
657   */
658   /* Case (1) */
659   for (ts = topSpecs; ts; ts = ts->next) {
660      if (ts->seginfo)
661         generate_and_add_actives( specList,    newts,
662                                   ts->seginfo, ts );
663   }
664
665   /* Case (2) */
666   for (ts = topSpecs; ts; ts = ts->next) {
667      generate_and_add_actives( ts->specs, ts,
668                                newdi,     newts );
669   }
670
671   /* Case (3) */
672   generate_and_add_actives( specList, newts,
673                             newdi,    newts );
674
675   /* Finally, add the new TopSpec. */
676   newts->next = topSpecs;
677   topSpecs = newts;
678
679   if (VG_(clo_trace_redir))
680      show_redir_state("after VG_(redir_notify_new_DebugInfo)");
681
682   /* Really finally (quite unrelated to all the above) check the
683      names in the module against any --require-text-symbol=
684      specifications we might have. */
685   handle_require_text_symbols(newdi);
686}
687
688#undef N_DEMANGLED
689
690/* Add a new target for an indirect function. Adds a new redirection
691   for the indirection function with address old_from that redirects
692   the ordinary function with address new_from to the target address
693   of the original redirection. */
694
695void VG_(redir_add_ifunc_target)( Addr old_from, Addr new_from )
696{
697    Active *old, new;
698
699    old = VG_(OSetGen_Lookup)(activeSet, &old_from);
700    vg_assert(old);
701    vg_assert(old->isIFunc);
702
703    new = *old;
704    new.from_addr = new_from;
705    new.isIFunc = False;
706    maybe_add_active (new);
707
708    if (VG_(clo_trace_redir)) {
709       VG_(message)( Vg_DebugMsg,
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
721static
722void generate_and_add_actives (
723        /* spec list and the owning TopSpec */
724        Spec*    specs,
725        TopSpec* parent_spec,
726	/* seginfo and the owning TopSpec */
727        DebugInfo* di,
728        TopSpec* parent_sym
729     )
730{
731   Spec*   sp;
732   Bool    anyMark, isText, isIFunc;
733   Active  act;
734   Int     nsyms, i;
735   Addr    sym_addr;
736   HChar*  sym_name_pri;
737   HChar** sym_names_sec;
738
739   /* First figure out which of the specs match the seginfo's soname.
740      Also clear the 'done' bits, so that after the main loop below
741      tell which of the Specs really did get done. */
742   anyMark = False;
743   for (sp = specs; sp; sp = sp->next) {
744      sp->done = False;
745      sp->mark = VG_(string_match)( sp->from_sopatt,
746                                    VG_(DebugInfo_get_soname)(di) );
747      anyMark = anyMark || sp->mark;
748   }
749
750   /* shortcut: if none of the sonames match, there will be no bindings. */
751   if (!anyMark)
752      return;
753
754   /* Iterate outermost over the symbols in the seginfo, in the hope
755      of trashing the caches less. */
756   nsyms = VG_(DebugInfo_syms_howmany)( di );
757   for (i = 0; i < nsyms; i++) {
758      VG_(DebugInfo_syms_getidx)( di, i, &sym_addr, NULL,
759                                  NULL, &sym_name_pri, &sym_names_sec,
760                                  &isText, &isIFunc );
761      HChar*  twoslots[2];
762      HChar** names_init = alloc_symname_array(sym_name_pri, sym_names_sec,
763                                               &twoslots[0]);
764      HChar** names;
765      for (names = names_init; *names; names++) {
766
767         /* ignore data symbols */
768         if (!isText)
769            continue;
770
771         for (sp = specs; sp; sp = sp->next) {
772            if (!sp->mark)
773               continue; /* soname doesn't match */
774            if (VG_(string_match)( sp->from_fnpatt, *names )) {
775               /* got a new binding.  Add to collection. */
776               act.from_addr   = sym_addr;
777               act.to_addr     = sp->to_addr;
778               act.parent_spec = parent_spec;
779               act.parent_sym  = parent_sym;
780               act.becTag      = sp->becTag;
781               act.becPrio     = sp->becPrio;
782               act.isWrap      = sp->isWrap;
783               act.isIFunc     = isIFunc;
784               sp->done = True;
785               maybe_add_active( act );
786            }
787         } /* for (sp = specs; sp; sp = sp->next) */
788
789      } /* iterating over names[] */
790      free_symname_array(names_init, &twoslots[0]);
791   } /* for (i = 0; i < nsyms; i++)  */
792
793   /* Now, finally, look for Specs which were marked to be done, but
794      didn't get matched.  If any such are mandatory we must abort the
795      system at this point. */
796   for (sp = specs; sp; sp = sp->next) {
797      if (!sp->mark)
798         continue;
799      if (sp->mark && (!sp->done) && sp->mandatory)
800         break;
801   }
802   if (sp) {
803      const HChar** strp;
804      const HChar* v = "valgrind:  ";
805      vg_assert(sp->mark);
806      vg_assert(!sp->done);
807      vg_assert(sp->mandatory);
808      VG_(printf)("\n");
809      VG_(printf)(
810      "%sFatal error at startup: a function redirection\n", v);
811      VG_(printf)(
812      "%swhich is mandatory for this platform-tool combination\n", v);
813      VG_(printf)(
814      "%scannot be set up.  Details of the redirection are:\n", v);
815      VG_(printf)(
816      "%s\n", v);
817      VG_(printf)(
818      "%sA must-be-redirected function\n", v);
819      VG_(printf)(
820      "%swhose name matches the pattern:      %s\n", v, sp->from_fnpatt);
821      VG_(printf)(
822      "%sin an object with soname matching:   %s\n", v, sp->from_sopatt);
823      VG_(printf)(
824      "%swas not found whilst processing\n", v);
825      VG_(printf)(
826      "%ssymbols from the object with soname: %s\n",
827      v, VG_(DebugInfo_get_soname)(di));
828      VG_(printf)(
829      "%s\n", v);
830
831      for (strp = sp->mandatory; *strp; strp++)
832         VG_(printf)(
833         "%s%s\n", v, *strp);
834
835      VG_(printf)(
836      "%s\n", v);
837      VG_(printf)(
838      "%sCannot continue -- exiting now.  Sorry.\n", v);
839      VG_(printf)("\n");
840      VG_(exit)(1);
841   }
842}
843
844
845/* Add an act (passed by value; is copied here) and deal with
846   conflicting bindings. */
847static void maybe_add_active ( Active act )
848{
849   const HChar*  what = NULL;
850   Active* old     = NULL;
851   Bool    add_act = False;
852
853   /* Complain and ignore manifestly bogus 'from' addresses.
854
855      Kludge: because this can get called befor the trampoline area (a
856      bunch of magic 'to' addresses) has its ownership changed from V
857      to C, we can't check the 'to' address similarly.  Sigh.
858
859      amd64-linux hack: the vsysinfo pages appear to have no
860      permissions
861         ffffffffff600000-ffffffffffe00000 ---p 00000000 00:00 0
862      so skip the check for them.  */
863   if (!is_plausible_guest_addr(act.from_addr)
864#      if defined(VGP_amd64_linux)
865       && act.from_addr != 0xFFFFFFFFFF600000ULL
866       && act.from_addr != 0xFFFFFFFFFF600400ULL
867       && act.from_addr != 0xFFFFFFFFFF600800ULL
868#      endif
869      ) {
870      what = "redirection from-address is in non-executable area";
871      goto bad;
872   }
873
874   old = VG_(OSetGen_Lookup)( activeSet, &act.from_addr );
875   if (old) {
876      /* Dodgy.  Conflicting binding. */
877      vg_assert(old->from_addr == act.from_addr);
878      if (old->to_addr != act.to_addr) {
879         /* We've got a conflicting binding -- that is, from_addr is
880            specified to redirect to two different destinations,
881            old->to_addr and act.to_addr.  If we can prove that they
882            are behaviourally equivalent then that's no problem.  So
883            we can look at the behavioural eclass tags for both
884            functions to see if that's so.  If they are equal, and
885            nonzero, then that's fine.  But if not, we can't show they
886            are equivalent, so we have to complain, and ignore the new
887            binding. */
888         vg_assert(old->becTag  >= 0 && old->becTag  <= 9999);
889         vg_assert(old->becPrio >= 0 && old->becPrio <= 9);
890         vg_assert(act.becTag   >= 0 && act.becTag   <= 9999);
891         vg_assert(act.becPrio  >= 0 && act.becPrio  <= 9);
892         if (old->becTag == 0)
893            vg_assert(old->becPrio == 0);
894         if (act.becTag == 0)
895            vg_assert(act.becPrio == 0);
896
897         if (old->becTag == 0 || act.becTag == 0 || old->becTag != act.becTag) {
898            /* We can't show that they are equivalent.  Complain and
899               ignore. */
900            what = "new redirection conflicts with existing -- ignoring it";
901            goto bad;
902         }
903         /* They have the same eclass tag.  Use the priorities to
904            resolve the ambiguity. */
905         if (act.becPrio <= old->becPrio) {
906            /* The new one doesn't have a higher priority, so just
907               ignore it. */
908            if (VG_(clo_verbosity) > 2) {
909               VG_(message)(Vg_UserMsg, "Ignoring %s redirection:\n",
910                            act.becPrio < old->becPrio ? "lower priority"
911                                                       : "duplicate");
912               show_active(             "    old: ", old);
913               show_active(             "    new: ", &act);
914            }
915         } else {
916            /* The tricky case.  The new one has a higher priority, so
917               we need to get the old one out of the OSet and install
918               this one in its place. */
919            if (VG_(clo_verbosity) > 1) {
920               VG_(message)(Vg_UserMsg,
921                           "Preferring higher priority redirection:\n");
922               show_active(             "    old: ", old);
923               show_active(             "    new: ", &act);
924            }
925            add_act = True;
926            void* oldNd = VG_(OSetGen_Remove)( activeSet, &act.from_addr );
927            vg_assert(oldNd == old);
928            VG_(OSetGen_FreeNode)( activeSet, old );
929            old = NULL;
930         }
931      } else {
932         /* This appears to be a duplicate of an existing binding.
933            Safe(ish) -- ignore. */
934         /* XXXXXXXXXXX COMPLAIN if new and old parents differ */
935      }
936
937   } else {
938      /* There's no previous binding for this from_addr, so we must
939         add 'act' to the active set. */
940      add_act = True;
941   }
942
943   /* So, finally, actually add it. */
944   if (add_act) {
945      Active* a = VG_(OSetGen_AllocNode)(activeSet, sizeof(Active));
946      vg_assert(a);
947      *a = act;
948      VG_(OSetGen_Insert)(activeSet, a);
949      /* Now that a new from->to redirection is in force, we need to
950         get rid of any translations intersecting 'from' in order that
951         they get redirected to 'to'.  So discard them.  Just for
952         paranoia (but, I believe, unnecessarily), discard 'to' as
953         well. */
954      VG_(discard_translations)( (Addr64)act.from_addr, 1,
955                                 "redir_new_DebugInfo(from_addr)");
956      VG_(discard_translations)( (Addr64)act.to_addr, 1,
957                                 "redir_new_DebugInfo(to_addr)");
958      if (VG_(clo_verbosity) > 2) {
959         VG_(message)(Vg_UserMsg, "Adding active redirection:\n");
960         show_active(             "    new: ", &act);
961      }
962   }
963   return;
964
965  bad:
966   vg_assert(what);
967   vg_assert(!add_act);
968   if (VG_(clo_verbosity) > 1) {
969      VG_(message)(Vg_UserMsg, "WARNING: %s\n", what);
970      if (old) {
971         show_active(             "    old: ", old);
972      }
973      show_active(             "    new: ", &act);
974   }
975}
976
977
978/* Notify m_redir of the deletion of a DebugInfo.  This is relatively
979   simple -- just get rid of all actives derived from it, and free up
980   the associated list elements. */
981
982void 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. */
1086Addr 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 */
1110static 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 */
1132static void add_hardwired_spec (const  HChar* sopatt, const HChar* fnpatt,
1133                                Addr   to_addr,
1134                                const HChar** mandatory )
1135{
1136   Spec* spec = dinfo_zalloc("redir.ahs.1", sizeof(Spec));
1137   vg_assert(spec);
1138
1139   if (topSpecs == NULL) {
1140      topSpecs = dinfo_zalloc("redir.ahs.2", sizeof(TopSpec));
1141      vg_assert(topSpecs);
1142      /* symtab_zalloc sets all fields to zero */
1143   }
1144
1145   vg_assert(topSpecs != NULL);
1146   vg_assert(topSpecs->next == NULL);
1147   vg_assert(topSpecs->seginfo == NULL);
1148   /* FIXED PARTS */
1149   spec->from_sopatt = (HChar *)sopatt;
1150   spec->from_fnpatt = (HChar *)fnpatt;
1151   spec->to_addr     = to_addr;
1152   spec->isWrap      = False;
1153   spec->mandatory   = mandatory;
1154   /* VARIABLE PARTS */
1155   spec->mark        = False; /* not significant */
1156   spec->done        = False; /* not significant */
1157
1158   spec->next = topSpecs->specs;
1159   topSpecs->specs = spec;
1160}
1161
1162
1163__attribute__((unused)) /* not used on all platforms */
1164static const HChar* complain_about_stripped_glibc_ldso[]
1165= { "Possible fixes: (1, short term): install glibc's debuginfo",
1166    "package on this machine.  (2, longer term): ask the packagers",
1167    "for your Linux distribution to please in future ship a non-",
1168    "stripped ld.so (or whatever the dynamic linker .so is called)",
1169    "that exports the above-named function using the standard",
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
1185void VG_(redir_initialise) ( void )
1186{
1187   // Assert that there are no DebugInfos so far
1188   vg_assert( VG_(next_DebugInfo)(NULL) == NULL );
1189
1190   // Initialise active mapping.
1191   activeSet = VG_(OSetGen_Create)(offsetof(Active, from_addr),
1192                                   NULL,     // Use fast comparison
1193                                   dinfo_zalloc,
1194                                   "redir.ri.1",
1195                                   dinfo_free);
1196
1197   // The rest of this function just adds initial Specs.
1198
1199#  if defined(VGP_x86_linux)
1200   /* If we're using memcheck, use this intercept right from the
1201      start, otherwise ld.so (glibc-2.3.5) makes a lot of noise. */
1202   if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
1203      const HChar** mandatory;
1204#     if defined(GLIBC_2_2) || defined(GLIBC_2_3) || defined(GLIBC_2_4) \
1205         || defined(GLIBC_2_5) || defined(GLIBC_2_6) || defined(GLIBC_2_7) \
1206         || defined(GLIBC_2_8) || defined(GLIBC_2_9) \
1207         || defined(GLIBC_2_10) || defined(GLIBC_2_11)
1208      mandatory = NULL;
1209#     else
1210      /* for glibc-2.12 and later, this is mandatory - can't sanely
1211         continue without it */
1212      mandatory = complain_about_stripped_glibc_ldso;
1213#     endif
1214      add_hardwired_spec(
1215         "ld-linux.so.2", "index",
1216         (Addr)&VG_(x86_linux_REDIR_FOR_index), mandatory);
1217      add_hardwired_spec(
1218         "ld-linux.so.2", "strlen",
1219         (Addr)&VG_(x86_linux_REDIR_FOR_strlen), mandatory);
1220   }
1221
1222#  elif defined(VGP_amd64_linux)
1223   /* Redirect vsyscalls to local versions */
1224   add_hardwired_active(
1225      0xFFFFFFFFFF600000ULL,
1226      (Addr)&VG_(amd64_linux_REDIR_FOR_vgettimeofday)
1227   );
1228   add_hardwired_active(
1229      0xFFFFFFFFFF600400ULL,
1230      (Addr)&VG_(amd64_linux_REDIR_FOR_vtime)
1231   );
1232   add_hardwired_active(
1233      0xFFFFFFFFFF600800ULL,
1234      (Addr)&VG_(amd64_linux_REDIR_FOR_vgetcpu)
1235   );
1236
1237   /* If we're using memcheck, use these intercepts right from
1238      the start, otherwise ld.so makes a lot of noise. */
1239   if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
1240
1241      add_hardwired_spec(
1242         "ld-linux-x86-64.so.2", "strlen",
1243         (Addr)&VG_(amd64_linux_REDIR_FOR_strlen),
1244#        if defined(GLIBC_2_2) || defined(GLIBC_2_3) || defined(GLIBC_2_4) \
1245            || defined(GLIBC_2_5) || defined(GLIBC_2_6) || defined(GLIBC_2_7) \
1246            || defined(GLIBC_2_8) || defined(GLIBC_2_9)
1247         NULL
1248#        else
1249         /* for glibc-2.10 and later, this is mandatory - can't sanely
1250            continue without it */
1251         complain_about_stripped_glibc_ldso
1252#        endif
1253      );
1254   }
1255
1256#  elif defined(VGP_ppc32_linux)
1257   /* If we're using memcheck, use these intercepts right from
1258      the start, otherwise ld.so makes a lot of noise. */
1259   if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
1260
1261      /* this is mandatory - can't sanely continue without it */
1262      add_hardwired_spec(
1263         "ld.so.1", "strlen",
1264         (Addr)&VG_(ppc32_linux_REDIR_FOR_strlen),
1265         complain_about_stripped_glibc_ldso
1266      );
1267      add_hardwired_spec(
1268         "ld.so.1", "strcmp",
1269         (Addr)&VG_(ppc32_linux_REDIR_FOR_strcmp),
1270         NULL /* not mandatory - so why bother at all? */
1271         /* glibc-2.6.1 (openSUSE 10.3, ppc32) seems fine without it */
1272      );
1273      add_hardwired_spec(
1274         "ld.so.1", "index",
1275         (Addr)&VG_(ppc32_linux_REDIR_FOR_strchr),
1276         NULL /* not mandatory - so why bother at all? */
1277         /* glibc-2.6.1 (openSUSE 10.3, ppc32) seems fine without it */
1278      );
1279   }
1280
1281#  elif defined(VGP_ppc64_linux)
1282   /* If we're using memcheck, use these intercepts right from
1283      the start, otherwise ld.so makes a lot of noise. */
1284   if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
1285
1286      /* this is mandatory - can't sanely continue without it */
1287      add_hardwired_spec(
1288         "ld64.so.1", "strlen",
1289         (Addr)VG_(fnptr_to_fnentry)( &VG_(ppc64_linux_REDIR_FOR_strlen) ),
1290         complain_about_stripped_glibc_ldso
1291      );
1292
1293      add_hardwired_spec(
1294         "ld64.so.1", "index",
1295         (Addr)VG_(fnptr_to_fnentry)( &VG_(ppc64_linux_REDIR_FOR_strchr) ),
1296         NULL /* not mandatory - so why bother at all? */
1297         /* glibc-2.5 (FC6, ppc64) seems fine without it */
1298      );
1299   }
1300
1301#  elif defined(VGP_arm_linux)
1302   /* If we're using memcheck, use these intercepts right from the
1303      start, otherwise ld.so makes a lot of noise.  In most ARM-linux
1304      distros, ld.so's soname is ld-linux.so.3, but Ubuntu 14.04 on
1305      Odroid uses ld-linux-armhf.so.3 for some reason. */
1306   if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
1307      /* strlen */
1308      add_hardwired_spec(
1309         "ld-linux.so.3", "strlen",
1310         (Addr)&VG_(arm_linux_REDIR_FOR_strlen),
1311         complain_about_stripped_glibc_ldso
1312      );
1313      add_hardwired_spec(
1314         "ld-linux-armhf.so.3", "strlen",
1315         (Addr)&VG_(arm_linux_REDIR_FOR_strlen),
1316         complain_about_stripped_glibc_ldso
1317      );
1318      /* memcpy */
1319      add_hardwired_spec(
1320         "ld-linux.so.3", "memcpy",
1321         (Addr)&VG_(arm_linux_REDIR_FOR_memcpy),
1322         complain_about_stripped_glibc_ldso
1323      );
1324      add_hardwired_spec(
1325         "ld-linux-armhf.so.3", "memcpy",
1326         (Addr)&VG_(arm_linux_REDIR_FOR_memcpy),
1327         complain_about_stripped_glibc_ldso
1328      );
1329   }
1330
1331#  elif defined(VGP_arm64_linux)
1332   /* If we're using memcheck, use these intercepts right from
1333      the start, otherwise ld.so makes a lot of noise. */
1334   if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
1335      add_hardwired_spec(
1336         "ld-linux-aarch64.so.1", "strlen",
1337         (Addr)&VG_(arm64_linux_REDIR_FOR_strlen),
1338         complain_about_stripped_glibc_ldso
1339      );
1340      add_hardwired_spec(
1341         "ld-linux-aarch64.so.1", "index",
1342         (Addr)&VG_(arm64_linux_REDIR_FOR_index),
1343         NULL
1344      );
1345      add_hardwired_spec(
1346         "ld-linux-aarch64.so.1", "strcmp",
1347         (Addr)&VG_(arm64_linux_REDIR_FOR_strcmp),
1348         NULL
1349      );
1350      //add_hardwired_spec(
1351      //   "ld-linux.so.3", "memcpy",
1352      //   (Addr)&VG_(arm_linux_REDIR_FOR_memcpy),
1353      //   complain_about_stripped_glibc_ldso
1354      //);
1355   }
1356
1357#  elif defined(VGP_x86_darwin)
1358   /* If we're using memcheck, use these intercepts right from
1359      the start, otherwise dyld makes a lot of noise. */
1360   if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
1361      add_hardwired_spec("dyld", "strcmp",
1362                         (Addr)&VG_(x86_darwin_REDIR_FOR_strcmp), NULL);
1363      add_hardwired_spec("dyld", "strlen",
1364                         (Addr)&VG_(x86_darwin_REDIR_FOR_strlen), NULL);
1365      add_hardwired_spec("dyld", "strcat",
1366                         (Addr)&VG_(x86_darwin_REDIR_FOR_strcat), NULL);
1367      add_hardwired_spec("dyld", "strcpy",
1368                         (Addr)&VG_(x86_darwin_REDIR_FOR_strcpy), NULL);
1369      add_hardwired_spec("dyld", "strlcat",
1370                         (Addr)&VG_(x86_darwin_REDIR_FOR_strlcat), NULL);
1371   }
1372
1373#  elif defined(VGP_amd64_darwin)
1374   /* If we're using memcheck, use these intercepts right from
1375      the start, otherwise dyld makes a lot of noise. */
1376   if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
1377      add_hardwired_spec("dyld", "strcmp",
1378                         (Addr)&VG_(amd64_darwin_REDIR_FOR_strcmp), NULL);
1379      add_hardwired_spec("dyld", "strlen",
1380                         (Addr)&VG_(amd64_darwin_REDIR_FOR_strlen), NULL);
1381      add_hardwired_spec("dyld", "strcat",
1382                         (Addr)&VG_(amd64_darwin_REDIR_FOR_strcat), NULL);
1383      add_hardwired_spec("dyld", "strcpy",
1384                         (Addr)&VG_(amd64_darwin_REDIR_FOR_strcpy), NULL);
1385      add_hardwired_spec("dyld", "strlcat",
1386                         (Addr)&VG_(amd64_darwin_REDIR_FOR_strlcat), NULL);
1387      // DDD: #warning fixme rdar://6166275
1388      add_hardwired_spec("dyld", "arc4random",
1389                         (Addr)&VG_(amd64_darwin_REDIR_FOR_arc4random), NULL);
1390   }
1391
1392#  elif defined(VGP_s390x_linux)
1393   /* nothing so far */
1394
1395#  elif defined(VGP_mips32_linux)
1396   if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
1397
1398      /* this is mandatory - can't sanely continue without it */
1399      add_hardwired_spec(
1400         "ld.so.3", "strlen",
1401         (Addr)&VG_(mips32_linux_REDIR_FOR_strlen),
1402         complain_about_stripped_glibc_ldso
1403      );
1404   }
1405
1406#  elif defined(VGP_mips64_linux)
1407   if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
1408
1409      /* this is mandatory - can't sanely continue without it */
1410      add_hardwired_spec(
1411         "ld.so.3", "strlen",
1412         (Addr)&VG_(mips64_linux_REDIR_FOR_strlen),
1413         complain_about_stripped_glibc_ldso
1414      );
1415   }
1416
1417#  else
1418#    error Unknown platform
1419#  endif
1420
1421   if (VG_(clo_trace_redir))
1422      show_redir_state("after VG_(redir_initialise)");
1423}
1424
1425
1426/*------------------------------------------------------------*/
1427/*--- MISC HELPERS                                         ---*/
1428/*------------------------------------------------------------*/
1429
1430static void* dinfo_zalloc(const HChar* ec, SizeT n) {
1431   void* p;
1432   vg_assert(n > 0);
1433   p = VG_(arena_malloc)(VG_AR_DINFO, ec, n);
1434   tl_assert(p);
1435   VG_(memset)(p, 0, n);
1436   return p;
1437}
1438
1439static void dinfo_free(void* p) {
1440   tl_assert(p);
1441   return VG_(arena_free)(VG_AR_DINFO, p);
1442}
1443
1444static HChar* dinfo_strdup(const HChar* ec, const HChar* str)
1445{
1446   return VG_(arena_strdup)(VG_AR_DINFO, ec, str);
1447}
1448
1449/* Really this should be merged with translations_allowable_from_seg
1450   in m_translate. */
1451static Bool is_plausible_guest_addr(Addr a)
1452{
1453   NSegment const* seg = VG_(am_find_nsegment)(a);
1454   return seg != NULL
1455          && (seg->kind == SkAnonC || seg->kind == SkFileC)
1456          && (seg->hasX || seg->hasR); /* crude x86-specific hack */
1457}
1458
1459
1460/*------------------------------------------------------------*/
1461/*--- NOTIFY-ON-LOAD FUNCTIONS                             ---*/
1462/*------------------------------------------------------------*/
1463
1464static
1465void handle_maybe_load_notifier( const HChar* soname,
1466                                       HChar* symbol, Addr addr )
1467{
1468#  if defined(VGP_x86_linux)
1469   /* x86-linux only: if we see _dl_sysinfo_int80, note its address.
1470      See comment on declaration of VG_(client__dl_sysinfo_int80) for
1471      the reason.  As far as I can tell, the relevant symbol is always
1472      in object with soname "ld-linux.so.2". */
1473   if (symbol && symbol[0] == '_'
1474              && 0 == VG_(strcmp)(symbol, "_dl_sysinfo_int80")
1475              && 0 == VG_(strcmp)(soname, "ld-linux.so.2")) {
1476      if (VG_(client__dl_sysinfo_int80) == 0)
1477         VG_(client__dl_sysinfo_int80) = addr;
1478   }
1479#  endif
1480
1481   /* Normal load-notifier handling after here.  First, ignore all
1482      symbols lacking the right prefix. */
1483   vg_assert(symbol); // assert rather than segfault if it is NULL
1484   if (0 != VG_(strncmp)(symbol, VG_NOTIFY_ON_LOAD_PREFIX,
1485                                 VG_NOTIFY_ON_LOAD_PREFIX_LEN))
1486      /* Doesn't have the right prefix */
1487      return;
1488
1489   if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(freeres))) == 0)
1490      VG_(client___libc_freeres_wrapper) = addr;
1491   else
1492   if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(ifunc_wrapper))) == 0)
1493      iFuncWrapper = addr;
1494   else
1495      vg_assert2(0, "unrecognised load notification function: %s", symbol);
1496}
1497
1498
1499/*------------------------------------------------------------*/
1500/*--- REQUIRE-TEXT-SYMBOL HANDLING                         ---*/
1501/*------------------------------------------------------------*/
1502
1503/* In short: check that the currently-being-loaded object has text
1504   symbols that satisfy any --require-text-symbol= specifications that
1505   apply to it, and abort the run with an error message if not.
1506*/
1507static void handle_require_text_symbols ( DebugInfo* di )
1508{
1509   /* First thing to do is figure out which, if any,
1510      --require-text-symbol specification strings apply to this
1511      object.  Most likely none do, since it is not expected to
1512      frequently be used.  Work through the list of specs and
1513      accumulate in fnpatts[] the fn patterns that pertain to this
1514      object. */
1515   HChar* fnpatts[VG_CLO_MAX_REQ_TSYMS];
1516   Int    fnpatts_used = 0;
1517   Int    i, j;
1518   const HChar* di_soname = VG_(DebugInfo_get_soname)(di);
1519   vg_assert(di_soname); // must be present
1520
1521   VG_(memset)(&fnpatts, 0, sizeof(fnpatts));
1522
1523   vg_assert(VG_(clo_n_req_tsyms) >= 0);
1524   vg_assert(VG_(clo_n_req_tsyms) <= VG_CLO_MAX_REQ_TSYMS);
1525   for (i = 0; i < VG_(clo_n_req_tsyms); i++) {
1526      const HChar* clo_spec = VG_(clo_req_tsyms)[i];
1527      vg_assert(clo_spec && VG_(strlen)(clo_spec) >= 4);
1528      // clone the spec, so we can stick a zero at the end of the sopatt
1529      HChar *spec = VG_(strdup)("m_redir.hrts.1", clo_spec);
1530      HChar sep = spec[0];
1531      HChar* sopatt = &spec[1];
1532      HChar* fnpatt = VG_(strchr)(sopatt, sep);
1533      // the initial check at clo processing in time in m_main
1534      // should ensure this.
1535      vg_assert(fnpatt && *fnpatt == sep);
1536      *fnpatt = 0;
1537      fnpatt++;
1538      if (VG_(string_match)(sopatt, di_soname))
1539         fnpatts[fnpatts_used++]
1540            = VG_(strdup)("m_redir.hrts.2", fnpatt);
1541      VG_(free)(spec);
1542   }
1543
1544   if (fnpatts_used == 0)
1545      return;  /* no applicable spec strings */
1546
1547   /* So finally, fnpatts[0 .. fnpatts_used - 1] contains the set of
1548      (patterns for) text symbol names that must be found in this
1549      object, in order to continue.  That is, we must find at least
1550      one text symbol name that matches each pattern, else we must
1551      abort the run. */
1552
1553   if (0) VG_(printf)("for %s\n", di_soname);
1554   for (i = 0; i < fnpatts_used; i++)
1555      if (0) VG_(printf)("   fnpatt: %s\n", fnpatts[i]);
1556
1557   /* For each spec, look through the syms to find one that matches.
1558      This isn't terribly efficient but it happens rarely, so no big
1559      deal. */
1560   for (i = 0; i < fnpatts_used; i++) {
1561      Bool   found  = False;
1562      HChar* fnpatt = fnpatts[i];
1563      Int    nsyms  = VG_(DebugInfo_syms_howmany)(di);
1564      for (j = 0; j < nsyms; j++) {
1565         Bool    isText        = False;
1566         HChar*  sym_name_pri  = NULL;
1567         HChar** sym_names_sec = NULL;
1568         VG_(DebugInfo_syms_getidx)( di, j, NULL, NULL,
1569                                     NULL, &sym_name_pri, &sym_names_sec,
1570                                     &isText, NULL );
1571         HChar*  twoslots[2];
1572         HChar** names_init = alloc_symname_array(sym_name_pri, sym_names_sec,
1573                                                  &twoslots[0]);
1574         HChar** names;
1575         for (names = names_init; *names; names++) {
1576            /* ignore data symbols */
1577            if (0) VG_(printf)("QQQ %s\n", *names);
1578            vg_assert(sym_name_pri);
1579            if (!isText)
1580               continue;
1581            if (VG_(string_match)(fnpatt, *names)) {
1582               found = True;
1583               break;
1584            }
1585         }
1586         free_symname_array(names_init, &twoslots[0]);
1587         if (found)
1588            break;
1589      }
1590
1591      if (!found) {
1592         const HChar* v = "valgrind:  ";
1593         VG_(printf)("\n");
1594         VG_(printf)(
1595         "%sFatal error at when loading library with soname\n", v);
1596         VG_(printf)(
1597         "%s   %s\n", v, di_soname);
1598         VG_(printf)(
1599         "%sCannot find any text symbol with a name "
1600         "that matches the pattern\n", v);
1601         VG_(printf)("%s   %s\n", v, fnpatt);
1602         VG_(printf)("%sas required by a --require-text-symbol= "
1603         "specification.\n", v);
1604         VG_(printf)("\n");
1605         VG_(printf)(
1606         "%sCannot continue -- exiting now.\n", v);
1607         VG_(printf)("\n");
1608         VG_(exit)(1);
1609      }
1610   }
1611
1612   /* All required specs were found.  Just free memory and return. */
1613   for (i = 0; i < fnpatts_used; i++)
1614      VG_(free)(fnpatts[i]);
1615}
1616
1617
1618/*------------------------------------------------------------*/
1619/*--- SANITY/DEBUG                                         ---*/
1620/*------------------------------------------------------------*/
1621
1622static void show_spec ( const HChar* left, Spec* spec )
1623{
1624   VG_(message)( Vg_DebugMsg,
1625                 "%s%25s %30s %s-> (%04d.%d) 0x%08llx\n",
1626                 left,
1627                 spec->from_sopatt, spec->from_fnpatt,
1628                 spec->isWrap ? "W" : "R",
1629                 spec->becTag, spec->becPrio,
1630                 (ULong)spec->to_addr );
1631}
1632
1633static void show_active ( const HChar* left, Active* act )
1634{
1635   Bool ok;
1636   HChar name1[64] = "";
1637   HChar name2[64] = "";
1638   name1[0] = name2[0] = 0;
1639   ok = VG_(get_fnname_w_offset)(act->from_addr, name1, 64);
1640   if (!ok) VG_(strcpy)(name1, "???");
1641   ok = VG_(get_fnname_w_offset)(act->to_addr, name2, 64);
1642   if (!ok) VG_(strcpy)(name2, "???");
1643
1644   VG_(message)(Vg_DebugMsg, "%s0x%08llx (%20s) %s-> (%04d.%d) 0x%08llx %s\n",
1645                             left,
1646                             (ULong)act->from_addr, name1,
1647                             act->isWrap ? "W" : "R",
1648                             act->becTag, act->becPrio,
1649                             (ULong)act->to_addr, name2 );
1650}
1651
1652static void show_redir_state ( const HChar* who )
1653{
1654   TopSpec* ts;
1655   Spec*    sp;
1656   Active*  act;
1657   VG_(message)(Vg_DebugMsg, "<<\n");
1658   VG_(message)(Vg_DebugMsg, "   ------ REDIR STATE %s ------\n", who);
1659   for (ts = topSpecs; ts; ts = ts->next) {
1660      if (ts->seginfo)
1661         VG_(message)(Vg_DebugMsg,
1662                      "   TOPSPECS of soname %s filename %s\n",
1663                      VG_(DebugInfo_get_soname)(ts->seginfo),
1664                      VG_(DebugInfo_get_filename)(ts->seginfo));
1665      else
1666         VG_(message)(Vg_DebugMsg,
1667                      "   TOPSPECS of soname (hardwired)\n");
1668
1669      for (sp = ts->specs; sp; sp = sp->next)
1670         show_spec("     ", sp);
1671   }
1672   VG_(message)(Vg_DebugMsg, "   ------ ACTIVE ------\n");
1673   VG_(OSetGen_ResetIter)( activeSet );
1674   while ( (act = VG_(OSetGen_Next)(activeSet)) ) {
1675      show_active("    ", act);
1676   }
1677
1678   VG_(message)(Vg_DebugMsg, ">>\n");
1679}
1680
1681/*--------------------------------------------------------------------*/
1682/*--- end                                                          ---*/
1683/*--------------------------------------------------------------------*/
1684