f096bf
commit 13693666bd9fc7be37a907302e5d3d4f4b2c9358
f096bf
Author: mjw <mjw@a5019735-40e9-0310-863c-91ae7b9d1cf9>
f096bf
Date:   Sun Nov 15 16:50:43 2015 +0000
f096bf
f096bf
    BZ#355188 valgrind should intercept all malloc related global functions.
f096bf
    
f096bf
    This implements the interception of all globally public allocation
f096bf
    functions by default. It works by adding a flag to the spec to say the
f096bf
    interception only applies to global functions. Which is set for the
f096bf
    somalloc spec. The librarypath to match is set to "*" unless the user
f096bf
    overrides it. Then each DiSym keeps track of whether the symbol is local
f096bf
    or global. For a spec which has isGlobal set only isGlobal symbols will
f096bf
    match.
f096bf
    
f096bf
    Note that because of padding to keep the addresses in DiSym aligned the
f096bf
    addition of the extra bool isGlobal doesn't actually grow the struct.
f096bf
    The comments explain how the struct could be made more compact on 32bit
f096bf
    systems, but this isn't as easy on 64bit systems. So I didn't try to do
f096bf
    that in this patch.
f096bf
    
f096bf
    For ELF symbols keeping track of which are global is trivial. For pdb I
f096bf
    had to guess and made only the "Public" symbols global. I don't know
f096bf
    how/if macho keeps track of global symbols or not. For now I just mark
f096bf
    all of them local (which just means things work as previously on platforms
f096bf
    that use machos, no non-system symbols are matches by default for somalloc
f096bf
    unless the user explicitly tells which library name to match).
f096bf
    
f096bf
    Included are two testcases for shared libraries (wrapmalloc) and staticly
f096bf
    linked (wrapmallocstatic) malloc/free overrides that depend on the new
f096bf
    default. One existing testcase (new_override) was adjusted to explicitly
f096bf
    not use the new somalloc default because it depends on a user defined
f096bf
    new implementation that has side-effects and should explicitly not be
f096bf
    intercepted.
f096bf
    
f096bf
    git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15726 a5019735-40e9-0310-863c-91ae7b9d1cf9
f096bf
f096bf
diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c
f096bf
index 6f11cd2..4dc1129 100644
f096bf
--- a/coregrind/m_debuginfo/debuginfo.c
f096bf
+++ b/coregrind/m_debuginfo/debuginfo.c
f096bf
@@ -4306,7 +4306,8 @@ void VG_(DebugInfo_syms_getidx) ( const DebugInfo *si,
f096bf
                                   /*OUT*/const HChar**   pri_name,
f096bf
                                   /*OUT*/const HChar***  sec_names,
f096bf
                                   /*OUT*/Bool*     isText,
f096bf
-                                  /*OUT*/Bool*     isIFunc )
f096bf
+                                  /*OUT*/Bool*     isIFunc,
f096bf
+                                  /*OUT*/Bool*     isGlobal )
f096bf
 {
f096bf
    vg_assert(idx >= 0 && idx < si->symtab_used);
f096bf
    if (avmas)     *avmas     = si->symtab[idx].avmas;
f096bf
@@ -4315,6 +4316,7 @@ void VG_(DebugInfo_syms_getidx) ( const DebugInfo *si,
f096bf
    if (sec_names) *sec_names = si->symtab[idx].sec_names;
f096bf
    if (isText)    *isText    = si->symtab[idx].isText;
f096bf
    if (isIFunc)   *isIFunc   = si->symtab[idx].isIFunc;
f096bf
+   if (isGlobal)  *isGlobal  = si->symtab[idx].isGlobal;
f096bf
 }
f096bf
 
f096bf
 
f096bf
diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h
f096bf
index aa1d9f9..a43720a 100644
f096bf
--- a/coregrind/m_debuginfo/priv_storage.h
f096bf
+++ b/coregrind/m_debuginfo/priv_storage.h
f096bf
@@ -75,14 +75,18 @@ typedef
f096bf
                             the macros defined in pub_core_debuginfo.h */
f096bf
       const HChar*  pri_name;  /* primary name, never NULL */
f096bf
       const HChar** sec_names; /* NULL, or a NULL term'd array of other names */
f096bf
-      // XXX: this could be shrunk (on 32-bit platforms) by using 30
f096bf
-      // bits for the size and 1 bit each for isText and isIFunc.  If you
f096bf
-      // do this, make sure that all assignments to the latter two use
f096bf
-      // 0 or 1 (or True or False), and that a positive number larger
f096bf
-      // than 1 is never used to represent True.
f096bf
+      // XXX: DiSym could be shrunk (on 32-bit platforms to exactly 16
f096bf
+      // bytes, on 64-bit platforms the first 3 pointers already add
f096bf
+      // up to 24 bytes, so size plus bits will extend to 32 bytes
f096bf
+      // anyway) by using 29 bits for the size and 1 bit each for
f096bf
+      // isText, isIFunc and isGlobal.  If you do this, make sure that
f096bf
+      // all assignments to the latter two use 0 or 1 (or True or
f096bf
+      // False), and that a positive number larger than 1 is never
f096bf
+      // used to represent True.
f096bf
       UInt    size;    /* size in bytes */
f096bf
       Bool    isText;
f096bf
       Bool    isIFunc; /* symbol is an indirect function? */
f096bf
+      Bool    isGlobal; /* Is this symbol globally visible? */
f096bf
    }
f096bf
    DiSym;
f096bf
 
f096bf
diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c
f096bf
index 0861725..3820965 100644
f096bf
--- a/coregrind/m_debuginfo/readelf.c
f096bf
+++ b/coregrind/m_debuginfo/readelf.c
f096bf
@@ -241,7 +241,8 @@ Bool get_elf_symbol_info (
f096bf
         Bool*   from_opd_out,   /* ppc64be-linux only: did we deref an
f096bf
                                   .opd entry? */
f096bf
         Bool*   is_text_out,    /* is this a text symbol? */
f096bf
-        Bool*   is_ifunc        /* is this a  STT_GNU_IFUNC function ?*/
f096bf
+        Bool*   is_ifunc_out,   /* is this a STT_GNU_IFUNC function ?*/
f096bf
+        Bool*   is_global_out   /* is this a global symbol ?*/
f096bf
      )
f096bf
 {
f096bf
    Bool plausible;
f096bf
@@ -259,7 +260,8 @@ Bool get_elf_symbol_info (
f096bf
    SET_TOCPTR_AVMA(*sym_avmas_out, 0);   /* default to unknown/inapplicable */
f096bf
    SET_LOCAL_EP_AVMA(*sym_avmas_out, 0); /* default to unknown/inapplicable */
f096bf
    *from_opd_out      = False;
f096bf
-   *is_ifunc          = False;
f096bf
+   *is_ifunc_out      = False;
f096bf
+   *is_global_out     = False;
f096bf
 
f096bf
    /* Get the symbol size, but restrict it to fit in a signed 32 bit
f096bf
       int.  Also, deal with the stupid case of negative size by making
f096bf
@@ -373,10 +375,14 @@ Bool get_elf_symbol_info (
f096bf
    /* Check for indirect functions. */
f096bf
    if (*is_text_out
f096bf
        && ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC) {
f096bf
-       *is_ifunc = True;
f096bf
+      *is_ifunc_out = True;
f096bf
    }
f096bf
 #  endif
f096bf
 
f096bf
+   if (ELFXX_ST_BIND(sym->st_info) == STB_GLOBAL) {
f096bf
+      *is_global_out = True;
f096bf
+   }
f096bf
+
f096bf
 #  if defined(VGP_ppc64be_linux)
f096bf
    /* Allow STT_NOTYPE in the very special case where we're running on
f096bf
       ppc64be-linux and the symbol is one which the .opd-chasing hack
f096bf
@@ -777,6 +783,7 @@ void read_elf_symtab__normal(
f096bf
       SymAVMAs sym_avmas_really;
f096bf
       Int    sym_size = 0;
f096bf
       Bool   from_opd = False, is_text = False, is_ifunc = False;
f096bf
+      Bool   is_global = False;
f096bf
       DiOffT sym_name_really = DiOffT_INVALID;
f096bf
       sym_avmas_really.main = 0;
f096bf
       SET_TOCPTR_AVMA(sym_avmas_really, 0);
f096bf
@@ -787,7 +794,7 @@ void read_elf_symtab__normal(
f096bf
                               &sym_name_really, 
f096bf
                               &sym_avmas_really,
f096bf
                               &sym_size,
f096bf
-                              &from_opd, &is_text, &is_ifunc)) {
f096bf
+                              &from_opd, &is_text, &is_ifunc, &is_global)) {
f096bf
 
f096bf
          DiSym  disym;
f096bf
          VG_(memset)(&disym, 0, sizeof(disym));
f096bf
@@ -799,6 +806,7 @@ void read_elf_symtab__normal(
f096bf
          disym.size      = sym_size;
f096bf
          disym.isText    = is_text;
f096bf
          disym.isIFunc   = is_ifunc;
f096bf
+         disym.isGlobal  = is_global;
f096bf
          if (cstr) { ML_(dinfo_free)(cstr); cstr = NULL; }
f096bf
          vg_assert(disym.pri_name);
f096bf
          vg_assert(GET_TOCPTR_AVMA(disym.avmas) == 0);
f096bf
@@ -847,6 +855,7 @@ typedef
f096bf
       Bool       from_opd;
f096bf
       Bool       is_text;
f096bf
       Bool       is_ifunc;
f096bf
+      Bool       is_global;
f096bf
    }
f096bf
    TempSym;
f096bf
 
f096bf
@@ -911,6 +920,7 @@ void read_elf_symtab__ppc64be_linux(
f096bf
       SymAVMAs sym_avmas_really;
f096bf
       Int    sym_size = 0;
f096bf
       Bool   from_opd = False, is_text = False, is_ifunc = False;
f096bf
+      Bool   is_global = False;
f096bf
       DiOffT sym_name_really = DiOffT_INVALID;
f096bf
       DiSym  disym;
f096bf
       VG_(memset)(&disym, 0, sizeof(disym));
f096bf
@@ -923,7 +933,7 @@ void read_elf_symtab__ppc64be_linux(
f096bf
                               &sym_name_really, 
f096bf
                               &sym_avmas_really,
f096bf
                               &sym_size,
f096bf
-                              &from_opd, &is_text, &is_ifunc)) {
f096bf
+                              &from_opd, &is_text, &is_ifunc, &is_global)) {
f096bf
 
f096bf
          /* Check if we've seen this (name,addr) key before. */
f096bf
          key.addr = sym_avmas_really.main;
f096bf
@@ -996,6 +1006,7 @@ void read_elf_symtab__ppc64be_linux(
f096bf
             elem->from_opd = from_opd;
f096bf
             elem->is_text  = is_text;
f096bf
             elem->is_ifunc = is_ifunc;
f096bf
+            elem->is_global = is_global;
f096bf
             VG_(OSetGen_Insert)(oset, elem);
f096bf
             if (di->trace_symtab) {
f096bf
                HChar* str = ML_(img_strdup)(escn_strtab->img, "di.respl.2",
f096bf
@@ -1034,14 +1045,17 @@ void read_elf_symtab__ppc64be_linux(
f096bf
       disym.size      = elem->size;
f096bf
       disym.isText    = elem->is_text;
f096bf
       disym.isIFunc   = elem->is_ifunc;
f096bf
+      disym.isGlobal  = elem->is_global;
f096bf
       if (cstr) { ML_(dinfo_free)(cstr); cstr = NULL; }
f096bf
       vg_assert(disym.pri_name != NULL);
f096bf
 
f096bf
       ML_(addSym) ( di, &disym );
f096bf
       if (di->trace_symtab) {
f096bf
-         VG_(printf)("    rec(%c) [%4ld]:          "
f096bf
+         VG_(printf)("    rec(%c%c%c) [%4ld]:          "
f096bf
                      "   val %#010lx, toc %#010lx, sz %4d  %s\n",
f096bf
                      disym.isText ? 't' : 'd',
f096bf
+                     disym.isIFunc ? 'i' : '-',
f096bf
+                     disym.isGlobal ? 'g' : 'l',
f096bf
                      i,
f096bf
                      disym.avmas.main,
f096bf
                      GET_TOCPTR_AVMA(disym.avmas),
f096bf
diff --git a/coregrind/m_debuginfo/readmacho.c b/coregrind/m_debuginfo/readmacho.c
f096bf
index 98ab048..3d406a4 100644
f096bf
--- a/coregrind/m_debuginfo/readmacho.c
f096bf
+++ b/coregrind/m_debuginfo/readmacho.c
f096bf
@@ -365,6 +365,7 @@ void read_symtab( /*OUT*/XArray* /* DiSym */ syms,
f096bf
                          di->text_avma+di->text_size - sym_addr;
f096bf
       disym.isText     = True;
f096bf
       disym.isIFunc    = False;
f096bf
+      disym.isGlobal   = False;
f096bf
       // Lots of user function names get prepended with an underscore.  Eg. the
f096bf
       // function 'f' becomes the symbol '_f'.  And the "below main"
f096bf
       // function is called "start".  So we skip the leading underscore, and
f096bf
diff --git a/coregrind/m_debuginfo/readpdb.c b/coregrind/m_debuginfo/readpdb.c
f096bf
index 8b63e95..1ebf863 100644
f096bf
--- a/coregrind/m_debuginfo/readpdb.c
f096bf
+++ b/coregrind/m_debuginfo/readpdb.c
f096bf
@@ -1272,6 +1272,7 @@ static ULong DEBUG_SnarfCodeView(
f096bf
                              // FIXME: .namelen is sizeof(.data) including .name[]
f096bf
             vsym.isText    = (sym->generic.id == S_PUB_V1);
f096bf
             vsym.isIFunc   = False;
f096bf
+            vsym.isGlobal  = True;
f096bf
             ML_(addSym)( di, &vsym );
f096bf
             n_syms_read++;
f096bf
          }
f096bf
@@ -1299,6 +1300,7 @@ static ULong DEBUG_SnarfCodeView(
f096bf
             vsym.isText    = !!(IMAGE_SCN_CNT_CODE 
f096bf
                                 & sectp[sym->data_v2.segment-1].Characteristics);
f096bf
             vsym.isIFunc   = False;
f096bf
+            vsym.isGlobal  = True;
f096bf
             ML_(addSym)( di, &vsym );
f096bf
             n_syms_read++;
f096bf
          }
f096bf
@@ -1332,6 +1334,7 @@ static ULong DEBUG_SnarfCodeView(
f096bf
             vsym.isText    = !!(IMAGE_SCN_CNT_CODE
f096bf
                                 & sectp[sym->data_v2.segment-1].Characteristics);
f096bf
             vsym.isIFunc   = False;
f096bf
+            vsym.isGlobal  = True;
f096bf
             ML_(addSym)( di, &vsym );
f096bf
             n_syms_read++;
f096bf
          }
f096bf
@@ -1365,6 +1368,7 @@ static ULong DEBUG_SnarfCodeView(
f096bf
          vsym.size      = sym->proc_v1.proc_len;
f096bf
          vsym.isText    = True;
f096bf
          vsym.isIFunc   = False;
f096bf
+         vsym.isGlobal  = sym->generic.id == S_GPROC_V1;
f096bf
          if (debug)
f096bf
             VG_(umsg)("  Adding function %s addr=%#lx length=%u\n",
f096bf
                       symname, vsym.avmas.main, vsym.size );
f096bf
@@ -1386,6 +1390,7 @@ static ULong DEBUG_SnarfCodeView(
f096bf
          vsym.size      = sym->proc_v2.proc_len;
f096bf
          vsym.isText    = True;
f096bf
          vsym.isIFunc   = False;
f096bf
+         vsym.isGlobal  = sym->generic.id == S_GPROC_V2;
f096bf
          if (debug)
f096bf
             VG_(umsg)("  Adding function %s addr=%#lx length=%u\n",
f096bf
                       symname, vsym.avmas.main, vsym.size );
f096bf
@@ -1408,6 +1413,7 @@ static ULong DEBUG_SnarfCodeView(
f096bf
             vsym.size      = sym->proc_v3.proc_len;
f096bf
             vsym.isText    = 1;
f096bf
             vsym.isIFunc   = False;
f096bf
+            vsym.isGlobal  = sym->generic.id == S_GPROC_V3;
f096bf
             ML_(addSym)( di, &vsym );
f096bf
             n_syms_read++;
f096bf
          }
f096bf
diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c
f096bf
index 45bc135..7b2e26a 100644
f096bf
--- a/coregrind/m_debuginfo/storage.c
f096bf
+++ b/coregrind/m_debuginfo/storage.c
f096bf
@@ -98,10 +98,11 @@ void ML_(ppSym) ( Int idx, const DiSym* sym )
f096bf
    vg_assert(sym->pri_name);
f096bf
    if (sec_names)
f096bf
       vg_assert(sec_names);
f096bf
-   VG_(printf)( "%5d:  %c%c %#8lx .. %#8lx (%u)      %s%s",
f096bf
+   VG_(printf)( "%5d:  %c%c%c %#8lx .. %#8lx (%u)      %s%s",
f096bf
                 idx,
f096bf
                 sym->isText ? 'T' : '-',
f096bf
                 sym->isIFunc ? 'I' : '-',
f096bf
+                sym->isGlobal ? 'G' : '-',
f096bf
                 sym->avmas.main, 
f096bf
                 sym->avmas.main + sym->size - 1, sym->size,
f096bf
                 sym->pri_name, sec_names ? " " : "" );
f096bf
@@ -1646,7 +1647,7 @@ static void canonicaliseSymtab ( struct _DebugInfo* di )
f096bf
    Word  i, j, n_truncated;
f096bf
    Addr  sta1, sta2, end1, end2, toc1, toc2;
f096bf
    const HChar *pri1, *pri2, **sec1, **sec2;
f096bf
-   Bool  ist1, ist2, isf1, isf2;
f096bf
+   Bool  ist1, ist2, isf1, isf2, isg1, isg2;
f096bf
 
f096bf
 #  define SWAP(ty,aa,bb) \
f096bf
       do { ty tt = (aa); (aa) = (bb); (bb) = tt; } while (0)
f096bf
@@ -1693,6 +1694,8 @@ static void canonicaliseSymtab ( struct _DebugInfo* di )
f096bf
             }
f096bf
             /* mark w as an IFunc if either w or r are */
f096bf
             di->symtab[w].isIFunc = di->symtab[w].isIFunc || di->symtab[r].isIFunc;
f096bf
+            /* likewise for global symbols */
f096bf
+            di->symtab[w].isGlobal = di->symtab[w].isGlobal || di->symtab[r].isGlobal;
f096bf
             /* and use ::pri_names to indicate this slot is no longer in use */
f096bf
             di->symtab[r].pri_name = NULL;
f096bf
             if (di->symtab[r].sec_names) {
f096bf
@@ -1796,6 +1799,7 @@ static void canonicaliseSymtab ( struct _DebugInfo* di )
f096bf
       sec1 = di->symtab[i].sec_names;
f096bf
       ist1 = di->symtab[i].isText;
f096bf
       isf1 = di->symtab[i].isIFunc;
f096bf
+      isg1 = di->symtab[i].isGlobal;
f096bf
 
f096bf
       sta2 = di->symtab[i+1].avmas.main;
f096bf
       end2 = sta2 + di->symtab[i+1].size - 1;
f096bf
@@ -1805,6 +1809,7 @@ static void canonicaliseSymtab ( struct _DebugInfo* di )
f096bf
       sec2 = di->symtab[i+1].sec_names;
f096bf
       ist2 = di->symtab[i+1].isText;
f096bf
       isf2 = di->symtab[i+1].isIFunc;
f096bf
+      isg2 = di->symtab[i+1].isGlobal;
f096bf
 
f096bf
       if (sta1 < sta2) {
f096bf
          end1 = sta2 - 1;
f096bf
@@ -1814,7 +1819,7 @@ static void canonicaliseSymtab ( struct _DebugInfo* di )
f096bf
             sta1 = end2 + 1;
f096bf
             SWAP(Addr,sta1,sta2); SWAP(Addr,end1,end2); SWAP(Addr,toc1,toc2);
f096bf
             SWAP(const HChar*,pri1,pri2); SWAP(const HChar**,sec1,sec2);
f096bf
-            SWAP(Bool,ist1,ist2); SWAP(Bool,isf1,isf2);
f096bf
+            SWAP(Bool,ist1,ist2); SWAP(Bool,isf1,isf2); SWAP(Bool, isg1, isg2);
f096bf
          } else 
f096bf
          if (end1 < end2) {
f096bf
             sta2 = end1 + 1;
f096bf
@@ -1831,6 +1836,7 @@ static void canonicaliseSymtab ( struct _DebugInfo* di )
f096bf
       di->symtab[i].sec_names = sec1;
f096bf
       di->symtab[i].isText    = ist1;
f096bf
       di->symtab[i].isIFunc   = isf1;
f096bf
+      di->symtab[i].isGlobal  = isg1;
f096bf
 
f096bf
       di->symtab[i+1].avmas.main = sta2;
f096bf
       di->symtab[i+1].size       = end2 - sta2 + 1;
f096bf
@@ -1840,6 +1846,7 @@ static void canonicaliseSymtab ( struct _DebugInfo* di )
f096bf
       di->symtab[i+1].sec_names = sec2;
f096bf
       di->symtab[i+1].isText    = ist2;
f096bf
       di->symtab[i+1].isIFunc   = isf2;
f096bf
+      di->symtab[i+1].isGlobal  = isg2;
f096bf
 
f096bf
       vg_assert(sta1 <= sta2);
f096bf
       vg_assert(di->symtab[i].size > 0);
f096bf
diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c
f096bf
index 7e4df8d..3d3f70a 100644
f096bf
--- a/coregrind/m_redir.c
f096bf
+++ b/coregrind/m_redir.c
f096bf
@@ -233,6 +233,7 @@ typedef
f096bf
       HChar* from_fnpatt;  /* from fnname pattern  */
f096bf
       Addr   to_addr;      /* where redirecting to */
f096bf
       Bool   isWrap;       /* wrap or replacement? */
f096bf
+      Bool   isGlobal;     /* must the symbol to replace be global? */
f096bf
       Int    becTag; /* 0 through 9999.  Behavioural equivalance class tag.
f096bf
                         If two wrappers have the same (non-zero) tag, they
f096bf
                         are promising that they behave identically. */
f096bf
@@ -388,7 +389,7 @@ static HChar const* advance_to_comma ( HChar const* c ) {
f096bf
 
f096bf
 void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi )
f096bf
 {
f096bf
-   Bool         ok, isWrap;
f096bf
+   Bool         ok, isWrap, isGlobal;
f096bf
    Int          i, nsyms, becTag, becPrio;
f096bf
    Spec*        specList;
f096bf
    Spec*        spec;
f096bf
@@ -518,13 +519,14 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi )
f096bf
    for (i = 0; i < nsyms; i++) {
f096bf
       VG_(DebugInfo_syms_getidx)( newdi, i, &sym_avmas,
f096bf
                                   NULL, &sym_name_pri, &sym_names_sec,
f096bf
-                                  &isText, NULL );
f096bf
+                                  &isText, NULL, NULL );
f096bf
       /* Set up to conveniently iterate over all names for this symbol. */
f096bf
       const HChar*  twoslots[2];
f096bf
       const HChar** names_init =
f096bf
          alloc_symname_array(sym_name_pri, sym_names_sec, &twoslots[0]);
f096bf
       const HChar** names;
f096bf
       for (names = names_init; *names; names++) {
f096bf
+         isGlobal = False;
f096bf
          ok = VG_(maybe_Z_demangle)( *names,
f096bf
                                      &demangled_sopatt,
f096bf
                                      &demangled_fnpatt,
f096bf
@@ -579,15 +581,12 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi )
f096bf
                have a matching lib synonym, then replace the sopatt.
f096bf
                Otherwise, just ignore this redirection spec. */
f096bf
 
f096bf
-            if (!VG_(clo_soname_synonyms))
f096bf
-               continue; // No synonyms => skip the redir.
f096bf
-
f096bf
             /* Search for a matching synonym=newname*/
f096bf
             SizeT const sopatt_syn_len 
f096bf
                = VG_(strlen)(demangled_sopatt+VG_SO_SYN_PREFIX_LEN);
f096bf
             HChar const* last = VG_(clo_soname_synonyms);
f096bf
             
f096bf
-            while (*last) {
f096bf
+            while (last != NULL && *last) {
f096bf
                HChar const* first = last;
f096bf
                last = advance_to_equal(first);
f096bf
                
f096bf
@@ -611,6 +610,17 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi )
f096bf
                   last++;
f096bf
             }
f096bf
             
f096bf
+	    // If the user didn't set it then somalloc is special. We
f096bf
+	    // want to match public/global symbols that match the
f096bf
+	    // fnpatt everywhere.
f096bf
+	    if (replaced_sopatt == NULL
f096bf
+		&& VG_(strcmp) ( demangled_sopatt, SO_SYN_MALLOC_NAME ) == 0)
f096bf
+	      {
f096bf
+		replaced_sopatt = VG_(strdup)("m_redir.rnnD.1", "*");
f096bf
+		demangled_sopatt = replaced_sopatt;
f096bf
+		isGlobal = True;
f096bf
+	      }
f096bf
+
f096bf
             // If we have not replaced the sopatt, then skip the redir.
f096bf
             if (replaced_sopatt == NULL)
f096bf
                continue;
f096bf
@@ -621,6 +631,7 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi )
f096bf
          spec->from_fnpatt = dinfo_strdup("redir.rnnD.3", demangled_fnpatt);
f096bf
          spec->to_addr = sym_avmas.main;
f096bf
          spec->isWrap = isWrap;
f096bf
+         spec->isGlobal = isGlobal;
f096bf
          spec->becTag = becTag;
f096bf
          spec->becPrio = becPrio;
f096bf
          /* check we're not adding manifestly stupid destinations */
f096bf
@@ -653,7 +664,7 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi )
f096bf
       for (i = 0; i < nsyms; i++) {
f096bf
          VG_(DebugInfo_syms_getidx)( newdi, i, &sym_avmas,
f096bf
                                      NULL, &sym_name_pri, &sym_names_sec,
f096bf
-                                     &isText, NULL );
f096bf
+                                     &isText, NULL, NULL );
f096bf
          const HChar*  twoslots[2];
f096bf
          const HChar** names_init =
f096bf
             alloc_symname_array(sym_name_pri, sym_names_sec, &twoslots[0]);
f096bf
@@ -785,7 +796,7 @@ void generate_and_add_actives (
f096bf
      )
f096bf
 {
f096bf
    Spec*   sp;
f096bf
-   Bool    anyMark, isText, isIFunc;
f096bf
+   Bool    anyMark, isText, isIFunc, isGlobal;
f096bf
    Active  act;
f096bf
    Int     nsyms, i;
f096bf
    SymAVMAs  sym_avmas;
f096bf
@@ -813,7 +824,7 @@ void generate_and_add_actives (
f096bf
    for (i = 0; i < nsyms; i++) {
f096bf
       VG_(DebugInfo_syms_getidx)( di, i, &sym_avmas,
f096bf
                                   NULL, &sym_name_pri, &sym_names_sec,
f096bf
-                                  &isText, &isIFunc );
f096bf
+                                  &isText, &isIFunc, &isGlobal );
f096bf
       const HChar*  twoslots[2];
f096bf
       const HChar** names_init =
f096bf
          alloc_symname_array(sym_name_pri, sym_names_sec, &twoslots[0]);
f096bf
@@ -827,7 +838,8 @@ void generate_and_add_actives (
f096bf
          for (sp = specs; sp; sp = sp->next) {
f096bf
             if (!sp->mark)
f096bf
                continue; /* soname doesn't match */
f096bf
-            if (VG_(string_match)( sp->from_fnpatt, *names )) {
f096bf
+            if (VG_(string_match)( sp->from_fnpatt, *names )
f096bf
+		&& (sp->isGlobal == False || isGlobal == True)) {
f096bf
                /* got a new binding.  Add to collection. */
f096bf
                act.from_addr   = sym_avmas.main;
f096bf
                act.to_addr     = sp->to_addr;
f096bf
@@ -1220,6 +1232,7 @@ static void add_hardwired_spec (const  HChar* sopatt, const HChar* fnpatt,
f096bf
    spec->from_fnpatt = CONST_CAST(HChar *,fnpatt);
f096bf
    spec->to_addr     = to_addr;
f096bf
    spec->isWrap      = False;
f096bf
+   spec->isGlobal    = False;
f096bf
    spec->mandatory   = mandatory;
f096bf
    /* VARIABLE PARTS */
f096bf
    spec->mark        = False; /* not significant */
f096bf
@@ -1719,7 +1732,7 @@ static void handle_require_text_symbols ( const DebugInfo* di )
f096bf
          const HChar** sym_names_sec = NULL;
f096bf
          VG_(DebugInfo_syms_getidx)( di, j, NULL,
f096bf
                                      NULL, &sym_name_pri, &sym_names_sec,
f096bf
-                                     &isText, NULL );
f096bf
+                                     &isText, NULL, NULL );
f096bf
          const HChar*  twoslots[2];
f096bf
          const HChar** names_init =
f096bf
             alloc_symname_array(sym_name_pri, sym_names_sec, &twoslots[0]);
f096bf
@@ -1773,10 +1786,11 @@ static void handle_require_text_symbols ( const DebugInfo* di )
f096bf
 static void show_spec ( const HChar* left, const Spec* spec )
f096bf
 {
f096bf
    VG_(message)( Vg_DebugMsg, 
f096bf
-                 "%s%-25s %-30s %s-> (%04d.%d) 0x%08lx\n",
f096bf
+                 "%s%-25s %-30s %s%s-> (%04d.%d) 0x%08lx\n",
f096bf
                  left,
f096bf
                  spec->from_sopatt, spec->from_fnpatt,
f096bf
                  spec->isWrap ? "W" : "R",
f096bf
+                 spec->isGlobal ? "G" : "L",
f096bf
                  spec->becTag, spec->becPrio,
f096bf
                  spec->to_addr );
f096bf
 }
f096bf
diff --git a/coregrind/m_replacemalloc/vg_replace_malloc.c b/coregrind/m_replacemalloc/vg_replace_malloc.c
f096bf
index ccac130..3c79c8a 100644
f096bf
--- a/coregrind/m_replacemalloc/vg_replace_malloc.c
f096bf
+++ b/coregrind/m_replacemalloc/vg_replace_malloc.c
f096bf
@@ -291,7 +291,6 @@ static void init(void);
f096bf
 // For some lines, we will also define a replacement function
f096bf
 // whose only purpose is to be a soname synonym place holder
f096bf
 // that can be replaced using --soname-synonyms.
f096bf
-#define SO_SYN_MALLOC VG_SO_SYN(somalloc)
f096bf
 
f096bf
 // malloc
f096bf
 #if defined(VGO_linux)
f096bf
diff --git a/coregrind/pub_core_debuginfo.h b/coregrind/pub_core_debuginfo.h
f096bf
index b698f2c..8f26f25 100644
f096bf
--- a/coregrind/pub_core_debuginfo.h
f096bf
+++ b/coregrind/pub_core_debuginfo.h
f096bf
@@ -216,7 +216,8 @@ void VG_(DebugInfo_syms_getidx)  ( const DebugInfo *di,
f096bf
                                    /*OUT*/const HChar**   pri_name,
f096bf
                                    /*OUT*/const HChar***  sec_names,
f096bf
                                    /*OUT*/Bool*     isText,
f096bf
-                                   /*OUT*/Bool*     isIFunc );
f096bf
+                                   /*OUT*/Bool*     isIFunc,
f096bf
+                                   /*OUT*/Bool*     isGlobal );
f096bf
 /* ppc64-linux only: find the TOC pointer (R2 value) that should be in
f096bf
    force at the entry point address of the function containing
f096bf
    guest_code_addr.  Returns 0 if not known. */
f096bf
diff --git a/docs/xml/manual-core.xml b/docs/xml/manual-core.xml
f096bf
index edda8a1..c80aab0 100644
f096bf
--- a/docs/xml/manual-core.xml
f096bf
+++ b/docs/xml/manual-core.xml
f096bf
@@ -2315,18 +2315,26 @@ need to use them.</para>
f096bf
       <option></option>
f096bf
     </term>
f096bf
     <listitem>
f096bf
-      <para>When a shared library is loaded, Valgrind checks for 
f096bf
-      functions in the library that must be replaced or wrapped.
f096bf
-      For example, Memcheck replaces all malloc related
f096bf
-      functions (malloc, free, calloc, ...) with its own versions.
f096bf
-      Such replacements are done by default only in shared libraries whose
f096bf
-      soname matches a predefined soname pattern (e.g.
f096bf
-      <varname>libc.so*</varname> on linux).
f096bf
-      By default, no replacement is done for a statically linked
f096bf
-      library or for alternative libraries such as tcmalloc.
f096bf
+      <para>When a shared library is loaded, Valgrind checks for
f096bf
+      functions in the library that must be replaced or wrapped.  For
f096bf
+      example, Memcheck replaces some string and memory functions
f096bf
+      (strchr, strlen, strcpy, memchr, memcpy, memmove, etc.) with its
f096bf
+      own versions.  Such replacements are normally done only in shared
f096bf
+      libraries whose soname matches a predefined soname pattern (e.g.
f096bf
+      <varname>libc.so*</varname> on linux).  By default, no
f096bf
+      replacement is done for a statically linked library or for
f096bf
+      alternative libraries, except for the allocation functions
f096bf
+      (malloc, free, calloc, memalign, realloc, operator new, operator
f096bf
+      delete, etc.) Such allocation functions are intercepted by
f096bf
+      default in any shared library or in the executable if they are
f096bf
+      exported as global symbols. This means that if a replacement
f096bf
+      allocation library such as tcmalloc is found, its functions are
f096bf
+      also intercepted by default.
f096bf
+
f096bf
       In some cases, the replacements allow
f096bf
       <option>--soname-synonyms</option> to specify one additional
f096bf
-      synonym pattern, giving flexibility in the replacement. </para>
f096bf
+      synonym pattern, giving flexibility in the replacement.  Or to
f096bf
+      prevent interception of all public allocation symbols.</para>
f096bf
 
f096bf
       <para>Currently, this flexibility is only allowed for the
f096bf
       malloc related functions, using the
f096bf
@@ -2339,27 +2347,31 @@ need to use them.</para>
f096bf
         <listitem>
f096bf
 
f096bf
           <para>Alternate malloc library: to replace the malloc
f096bf
-          related functions in an alternate library with
f096bf
-          soname <varname>mymalloclib.so</varname>, give the
f096bf
+          related functions in a specific alternate library with
f096bf
+          soname <varname>mymalloclib.so</varname> (and not in any
f096bf
+          others), give the
f096bf
           option <option>--soname-synonyms=somalloc=mymalloclib.so</option>.
f096bf
           A pattern can be used to match multiple libraries sonames.
f096bf
           For
f096bf
           example, <option>--soname-synonyms=somalloc=*tcmalloc*</option>
f096bf
-          will match the soname of all variants of the tcmalloc library
f096bf
-          (native, debug, profiled, ... tcmalloc variants). </para>
f096bf
+          will match the soname of all variants of the tcmalloc
f096bf
+          library (native, debug, profiled, ... tcmalloc
f096bf
+          variants). </para>
f096bf
           <para>Note: the soname of a elf shared library can be
f096bf
           retrieved using the readelf utility. </para>
f096bf
 
f096bf
         </listitem>
f096bf
 
f096bf
         <listitem>
f096bf
-          <para>Replacements in a statically linked library are done by
f096bf
-          using the <varname>NONE</varname> pattern. For example, if
f096bf
-          you link with <varname>libtcmalloc.a</varname>, memcheck 
f096bf
-          will properly work when you give the
f096bf
-          option <option>--soname-synonyms=somalloc=NONE</option>.  Note
f096bf
-          that a NONE pattern will match the main executable and any
f096bf
-          shared library having no soname. </para>
f096bf
+          <para>Replacements in a statically linked library are done
f096bf
+          by using the <varname>NONE</varname> pattern. For example,
f096bf
+          if you link with <varname>libtcmalloc.a</varname>, and only
f096bf
+          want to intercept the malloc related functions in the
f096bf
+          executable (and standard libraries) themselves, but not any
f096bf
+          other shared libraries, you can give the
f096bf
+          option <option>--soname-synonyms=somalloc=NONE</option>.
f096bf
+          Note that a NONE pattern will match the main executable and
f096bf
+          any shared library having no soname. </para>
f096bf
         </listitem>
f096bf
 
f096bf
         <listitem>
f096bf
@@ -2369,6 +2381,17 @@ need to use them.</para>
f096bf
           </para>
f096bf
         </listitem>
f096bf
 
f096bf
+	<listitem>
f096bf
+	  <para>To only intercept allocation symbols in the default
f096bf
+	  system libraries, but not in any other shared library or the
f096bf
+	  executable defining public malloc or operator new related
f096bf
+	  functions use a non-existing library name
f096bf
+	  like <option>--soname-synonyms=somalloc=nouserintercepts</option>
f096bf
+	  (where <varname>nouserintercepts</varname> can be any
f096bf
+	  non-existing library name).
f096bf
+	  </para>
f096bf
+	</listitem>
f096bf
+
f096bf
       </itemizedlist>
f096bf
    </listitem>
f096bf
   </varlistentry>
f096bf
diff --git a/include/pub_tool_redir.h b/include/pub_tool_redir.h
f096bf
index bac00d7..21d186b 100644
f096bf
--- a/include/pub_tool_redir.h
f096bf
+++ b/include/pub_tool_redir.h
f096bf
@@ -345,6 +345,12 @@
f096bf
 #define VG_SO_SYN_PREFIX     "VgSoSyn"
f096bf
 #define VG_SO_SYN_PREFIX_LEN 7
f096bf
 
f096bf
+// Special soname synonym place holder for the malloc symbols that can
f096bf
+// be replaced using --soname-synonyms.  Otherwise will match all
f096bf
+// public symbols in any shared library/executable.
f096bf
+#define SO_SYN_MALLOC VG_SO_SYN(somalloc)
f096bf
+#define SO_SYN_MALLOC_NAME "VgSoSynsomalloc"
f096bf
+
f096bf
 #endif   // __PUB_TOOL_REDIR_H
f096bf
 
f096bf
 /*--------------------------------------------------------------------*/
f096bf
diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am
f096bf
index 68d9ca1..0f34127 100644
f096bf
--- a/memcheck/tests/Makefile.am
f096bf
+++ b/memcheck/tests/Makefile.am
f096bf
@@ -291,6 +291,9 @@ EXTRA_DIST = \
f096bf
 	wrap7.vgtest wrap7.stdout.exp wrap7.stderr.exp \
f096bf
 	wrap8.vgtest wrap8.stdout.exp wrap8.stderr.exp \
f096bf
 	wrap8.stdout.exp-ppc64 wrap8.stderr.exp-ppc64 \
f096bf
+	wrapmalloc.vgtest wrapmalloc.stdout.exp wrapmalloc.stderr.exp \
f096bf
+	wrapmallocstatic.vgtest wrapmallocstatic.stdout.exp \
f096bf
+	wrapmallocstatic.stderr.exp \
f096bf
 	writev1.stderr.exp writev1.stderr.exp-solaris writev1.vgtest \
f096bf
 	xml1.stderr.exp xml1.stdout.exp xml1.vgtest xml1.stderr.exp-s390x-mvc \
f096bf
 	threadname.vgtest threadname.stderr.exp \
f096bf
@@ -375,6 +378,7 @@ check_PROGRAMS = \
f096bf
 	wcs \
f096bf
 	xml1 \
f096bf
 	wrap1 wrap2 wrap3 wrap4 wrap5 wrap6 wrap7 wrap7so.so wrap8 \
f096bf
+	wrapmalloc wrapmallocso.so wrapmallocstatic \
f096bf
 	writev1
f096bf
 
f096bf
 if !SOLARIS_SUN_STUDIO_AS
f096bf
@@ -570,4 +574,26 @@ else
f096bf
 				-Wl,-soname -Wl,wrap7so.so
f096bf
 endif
f096bf
 
f096bf
+# Build shared object for wrapmalloc
f096bf
+wrapmalloc_SOURCES           = wrapmalloc.c
f096bf
+wrapmalloc_DEPENDENCIES      = wrapmallocso.so
f096bf
+if VGCONF_OS_IS_DARWIN
f096bf
+ wrapmalloc_LDADD            = `pwd`/wrapmallocso.so
f096bf
+ wrapmalloc_LDFLAGS          = $(AM_FLAG_M3264_PRI)
f096bf
+else
f096bf
+ wrapmalloc_LDADD            = wrapmallocso.so
f096bf
+ wrapmalloc_LDFLAGS          = $(AM_FLAG_M3264_PRI) \
f096bf
+				-Wl,-rpath,$(top_builddir)/memcheck/tests
f096bf
+endif
f096bf
+
f096bf
+wrapmallocso_so_SOURCES      = wrapmallocso.c
f096bf
+wrapmallocso_so_CFLAGS       = $(AM_CFLAGS) -fpic
f096bf
+if VGCONF_OS_IS_DARWIN
f096bf
+ wrapmallocso_so_LDFLAGS     = -fpic $(AM_FLAG_M3264_PRI) -dynamic \
f096bf
+				-dynamiclib -all_load
f096bf
+else
f096bf
+ wrapmallocso_so_LDFLAGS     = -fpic $(AM_FLAG_M3264_PRI) -shared \
f096bf
+				-Wl,-soname -Wl,wrapmallocso.so
f096bf
+endif
f096bf
+
f096bf
 xml1_CFLAGS             = $(AM_CFLAGS) -D_GNU_SOURCE
f096bf
diff --git a/memcheck/tests/new_override.vgtest b/memcheck/tests/new_override.vgtest
f096bf
index 50e6240..435e330 100644
f096bf
--- a/memcheck/tests/new_override.vgtest
f096bf
+++ b/memcheck/tests/new_override.vgtest
f096bf
@@ -1,2 +1,6 @@
f096bf
 prog: new_override
f096bf
+# Don't override the user defined somalloc functions in this test.
f096bf
+# The test depends on some side effects and initializing memory done by
f096bf
+# the user overidden operator new.
f096bf
+vgopts: --soname-synonyms=somalloc=nouseroverride
f096bf
 stderr_filter: filter_allocs
f096bf
diff --git a/memcheck/tests/wrapmalloc.c b/memcheck/tests/wrapmalloc.c
f096bf
new file mode 100644
f096bf
index 0000000..2307e77
f096bf
--- /dev/null
f096bf
+++ b/memcheck/tests/wrapmalloc.c
f096bf
@@ -0,0 +1,14 @@
f096bf
+#include <stdio.h>
f096bf
+#include <stdlib.h>
f096bf
+
f096bf
+/* Test that a program that has malloc/free interposed in a shared
f096bf
+   library is also intercepted. */
f096bf
+
f096bf
+int main ( void )
f096bf
+{
f096bf
+   printf ("start\n");
f096bf
+   void *p = malloc (1024);
f096bf
+   free (p);
f096bf
+   printf ("done\n");
f096bf
+   return 0;
f096bf
+}
f096bf
diff --git a/memcheck/tests/wrapmalloc.stderr.exp b/memcheck/tests/wrapmalloc.stderr.exp
f096bf
new file mode 100644
f096bf
index 0000000..d937776
f096bf
--- /dev/null
f096bf
+++ b/memcheck/tests/wrapmalloc.stderr.exp
f096bf
@@ -0,0 +1,10 @@
f096bf
+
f096bf
+
f096bf
+HEAP SUMMARY:
f096bf
+    in use at exit: 0 bytes in 0 blocks
f096bf
+  total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
f096bf
+
f096bf
+For a detailed leak analysis, rerun with: --leak-check=full
f096bf
+
f096bf
+For counts of detected and suppressed errors, rerun with: -v
f096bf
+ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
f096bf
diff --git a/memcheck/tests/wrapmalloc.stdout.exp b/memcheck/tests/wrapmalloc.stdout.exp
f096bf
new file mode 100644
f096bf
index 0000000..60b5fd2
f096bf
--- /dev/null
f096bf
+++ b/memcheck/tests/wrapmalloc.stdout.exp
f096bf
@@ -0,0 +1,2 @@
f096bf
+start
f096bf
+done
f096bf
diff --git a/memcheck/tests/wrapmalloc.vgtest b/memcheck/tests/wrapmalloc.vgtest
f096bf
new file mode 100644
f096bf
index 0000000..a6dff4e
f096bf
--- /dev/null
f096bf
+++ b/memcheck/tests/wrapmalloc.vgtest
f096bf
@@ -0,0 +1,2 @@
f096bf
+prog: wrapmalloc
f096bf
+
f096bf
diff --git a/memcheck/tests/wrapmallocso.c b/memcheck/tests/wrapmallocso.c
f096bf
new file mode 100644
f096bf
index 0000000..985ce56
f096bf
--- /dev/null
f096bf
+++ b/memcheck/tests/wrapmallocso.c
f096bf
@@ -0,0 +1,17 @@
f096bf
+#include <stdio.h>
f096bf
+#include <stdlib.h>
f096bf
+
f096bf
+/* Fake malloc/free functions that just print something. When run
f096bf
+   under memcheck these functions will be intercepted and not print
f096bf
+   anything. */
f096bf
+
f096bf
+void *malloc ( size_t size )
f096bf
+{
f096bf
+  printf ("malloc\n");
f096bf
+  return NULL;
f096bf
+}
f096bf
+
f096bf
+void free (void *ptr)
f096bf
+{
f096bf
+  printf ("free\n");
f096bf
+}
f096bf
diff --git a/memcheck/tests/wrapmallocstatic.c b/memcheck/tests/wrapmallocstatic.c
f096bf
new file mode 100644
f096bf
index 0000000..be6573b
f096bf
--- /dev/null
f096bf
+++ b/memcheck/tests/wrapmallocstatic.c
f096bf
@@ -0,0 +1,29 @@
f096bf
+#include <stdio.h>
f096bf
+#include <stdlib.h>
f096bf
+
f096bf
+/* Test that a program that has malloc/free interposed in the
f096bf
+   executable is also intercepted. */
f096bf
+
f096bf
+int main ( void )
f096bf
+{
f096bf
+   printf ("start\n");
f096bf
+   void *p = malloc (1024);
f096bf
+   free (p);
f096bf
+   printf ("done\n");
f096bf
+   return 0;
f096bf
+}
f096bf
+
f096bf
+/* Fake malloc/free functions that just print something. When run
f096bf
+   under memcheck these functions will be intercepted and not print
f096bf
+   anything. */
f096bf
+
f096bf
+void *malloc ( size_t size )
f096bf
+{
f096bf
+  printf ("malloc\n");
f096bf
+  return NULL;
f096bf
+}
f096bf
+
f096bf
+void free (void *ptr)
f096bf
+{
f096bf
+  printf ("free\n");
f096bf
+}
f096bf
diff --git a/memcheck/tests/wrapmallocstatic.stderr.exp b/memcheck/tests/wrapmallocstatic.stderr.exp
f096bf
new file mode 100644
f096bf
index 0000000..d937776
f096bf
--- /dev/null
f096bf
+++ b/memcheck/tests/wrapmallocstatic.stderr.exp
f096bf
@@ -0,0 +1,10 @@
f096bf
+
f096bf
+
f096bf
+HEAP SUMMARY:
f096bf
+    in use at exit: 0 bytes in 0 blocks
f096bf
+  total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
f096bf
+
f096bf
+For a detailed leak analysis, rerun with: --leak-check=full
f096bf
+
f096bf
+For counts of detected and suppressed errors, rerun with: -v
f096bf
+ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
f096bf
diff --git a/memcheck/tests/wrapmallocstatic.stdout.exp b/memcheck/tests/wrapmallocstatic.stdout.exp
f096bf
new file mode 100644
f096bf
index 0000000..60b5fd2
f096bf
--- /dev/null
f096bf
+++ b/memcheck/tests/wrapmallocstatic.stdout.exp
f096bf
@@ -0,0 +1,2 @@
f096bf
+start
f096bf
+done
f096bf
diff --git a/memcheck/tests/wrapmallocstatic.vgtest b/memcheck/tests/wrapmallocstatic.vgtest
f096bf
new file mode 100644
f096bf
index 0000000..7b3c068
f096bf
--- /dev/null
f096bf
+++ b/memcheck/tests/wrapmallocstatic.vgtest
f096bf
@@ -0,0 +1,2 @@
f096bf
+prog: wrapmallocstatic
f096bf
+
f096bf
diff -ur valgrind-3.11.0.orig/memcheck/tests/Makefile.in valgrind-3.11.0/memcheck/tests/Makefile.in
f096bf
--- valgrind-3.11.0.orig/memcheck/tests/Makefile.in	2015-11-15 18:08:05.457930383 +0100
f096bf
+++ valgrind-3.11.0/memcheck/tests/Makefile.in	2015-11-15 18:14:10.828008973 +0100
f096bf
@@ -185,7 +185,8 @@
f096bf
 	vcpu_fnfns$(EXEEXT) wcs$(EXEEXT) xml1$(EXEEXT) wrap1$(EXEEXT) \
f096bf
 	wrap2$(EXEEXT) wrap3$(EXEEXT) wrap4$(EXEEXT) wrap5$(EXEEXT) \
f096bf
 	wrap6$(EXEEXT) wrap7$(EXEEXT) wrap7so.so$(EXEEXT) \
f096bf
-	wrap8$(EXEEXT) writev1$(EXEEXT) $(am__EXEEXT_1) \
f096bf
+	wrap8$(EXEEXT) wrapmalloc$(EXEEXT) wrapmallocso.so$(EXEEXT) \
f096bf
+	wrapmallocstatic$(EXEEXT) writev1$(EXEEXT) $(am__EXEEXT_1) \
f096bf
 	$(am__EXEEXT_2) $(am__EXEEXT_3) $(am__EXEEXT_4) \
f096bf
 	$(am__EXEEXT_5)
f096bf
 
f096bf
@@ -736,6 +737,18 @@
f096bf
 wrap8_SOURCES = wrap8.c
f096bf
 wrap8_OBJECTS = wrap8.$(OBJEXT)
f096bf
 wrap8_LDADD = $(LDADD)
f096bf
+am_wrapmalloc_OBJECTS = wrapmalloc.$(OBJEXT)
f096bf
+wrapmalloc_OBJECTS = $(am_wrapmalloc_OBJECTS)
f096bf
+wrapmalloc_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(wrapmalloc_LDFLAGS) \
f096bf
+	$(LDFLAGS) -o $@
f096bf
+am_wrapmallocso_so_OBJECTS = wrapmallocso_so-wrapmallocso.$(OBJEXT)
f096bf
+wrapmallocso_so_OBJECTS = $(am_wrapmallocso_so_OBJECTS)
f096bf
+wrapmallocso_so_LDADD = $(LDADD)
f096bf
+wrapmallocso_so_LINK = $(CCLD) $(wrapmallocso_so_CFLAGS) $(CFLAGS) \
f096bf
+	$(wrapmallocso_so_LDFLAGS) $(LDFLAGS) -o $@
f096bf
+wrapmallocstatic_SOURCES = wrapmallocstatic.c
f096bf
+wrapmallocstatic_OBJECTS = wrapmallocstatic.$(OBJEXT)
f096bf
+wrapmallocstatic_LDADD = $(LDADD)
f096bf
 writev1_SOURCES = writev1.c
f096bf
 writev1_OBJECTS = writev1.$(OBJEXT)
f096bf
 writev1_LDADD = $(LDADD)
f096bf
@@ -826,7 +839,8 @@
f096bf
 	$(varinfo5_SOURCES) $(varinfo5so_so_SOURCES) varinfo6.c \
f096bf
 	varinforestrict.c vcpu_fbench.c vcpu_fnfns.c wcs.c wrap1.c \
f096bf
 	wrap2.c wrap3.c wrap4.c wrap5.c wrap6.c $(wrap7_SOURCES) \
f096bf
-	$(wrap7so_so_SOURCES) wrap8.c writev1.c xml1.c
f096bf
+	$(wrap7so_so_SOURCES) wrap8.c $(wrapmalloc_SOURCES) \
f096bf
+	$(wrapmallocso_so_SOURCES) wrapmallocstatic.c writev1.c xml1.c
f096bf
 DIST_SOURCES = accounting.c addressable.c atomic_incs.c badaddrvalue.c \
f096bf
 	badfree.c badjump.c badjump2.c badloop.c badpoll.c badrw.c \
f096bf
 	big_blocks_freed_list.c brk2.c buflen_check.c bug155125.c \
f096bf
@@ -863,7 +877,8 @@
f096bf
 	$(varinfo5_SOURCES) $(varinfo5so_so_SOURCES) varinfo6.c \
f096bf
 	varinforestrict.c vcpu_fbench.c vcpu_fnfns.c wcs.c wrap1.c \
f096bf
 	wrap2.c wrap3.c wrap4.c wrap5.c wrap6.c $(wrap7_SOURCES) \
f096bf
-	$(wrap7so_so_SOURCES) wrap8.c writev1.c xml1.c
f096bf
+	$(wrap7so_so_SOURCES) wrap8.c $(wrapmalloc_SOURCES) \
f096bf
+	$(wrapmallocso_so_SOURCES) wrapmallocstatic.c writev1.c xml1.c
f096bf
 RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
f096bf
 	ctags-recursive dvi-recursive html-recursive info-recursive \
f096bf
 	install-data-recursive install-dvi-recursive \
f096bf
@@ -1544,6 +1559,9 @@
f096bf
 	wrap7.vgtest wrap7.stdout.exp wrap7.stderr.exp \
f096bf
 	wrap8.vgtest wrap8.stdout.exp wrap8.stderr.exp \
f096bf
 	wrap8.stdout.exp-ppc64 wrap8.stderr.exp-ppc64 \
f096bf
+	wrapmalloc.vgtest wrapmalloc.stdout.exp wrapmalloc.stderr.exp \
f096bf
+	wrapmallocstatic.vgtest wrapmallocstatic.stdout.exp \
f096bf
+	wrapmallocstatic.stderr.exp \
f096bf
 	writev1.stderr.exp writev1.stderr.exp-solaris writev1.vgtest \
f096bf
 	xml1.stderr.exp xml1.stdout.exp xml1.vgtest xml1.stderr.exp-s390x-mvc \
f096bf
 	threadname.vgtest threadname.stderr.exp \
f096bf
@@ -1662,6 +1680,24 @@
f096bf
 @VGCONF_OS_IS_DARWIN_TRUE@wrap7so_so_LDFLAGS = -fpic $(AM_FLAG_M3264_PRI) -dynamic \
f096bf
 @VGCONF_OS_IS_DARWIN_TRUE@				-dynamiclib -all_load
f096bf
 
f096bf
+
f096bf
+# Build shared object for wrapmalloc
f096bf
+wrapmalloc_SOURCES = wrapmalloc.c
f096bf
+wrapmalloc_DEPENDENCIES = wrapmallocso.so
f096bf
+@VGCONF_OS_IS_DARWIN_FALSE@wrapmalloc_LDADD = wrapmallocso.so
f096bf
+@VGCONF_OS_IS_DARWIN_TRUE@wrapmalloc_LDADD = `pwd`/wrapmallocso.so
f096bf
+@VGCONF_OS_IS_DARWIN_FALSE@wrapmalloc_LDFLAGS = $(AM_FLAG_M3264_PRI) \
f096bf
+@VGCONF_OS_IS_DARWIN_FALSE@				-Wl,-rpath,$(top_builddir)/memcheck/tests
f096bf
+
f096bf
+@VGCONF_OS_IS_DARWIN_TRUE@wrapmalloc_LDFLAGS = $(AM_FLAG_M3264_PRI)
f096bf
+wrapmallocso_so_SOURCES = wrapmallocso.c
f096bf
+wrapmallocso_so_CFLAGS = $(AM_CFLAGS) -fpic
f096bf
+@VGCONF_OS_IS_DARWIN_FALSE@wrapmallocso_so_LDFLAGS = -fpic $(AM_FLAG_M3264_PRI) -shared \
f096bf
+@VGCONF_OS_IS_DARWIN_FALSE@				-Wl,-soname -Wl,wrapmallocso.so
f096bf
+
f096bf
+@VGCONF_OS_IS_DARWIN_TRUE@wrapmallocso_so_LDFLAGS = -fpic $(AM_FLAG_M3264_PRI) -dynamic \
f096bf
+@VGCONF_OS_IS_DARWIN_TRUE@				-dynamiclib -all_load
f096bf
+
f096bf
 xml1_CFLAGS = $(AM_CFLAGS) -D_GNU_SOURCE
f096bf
 all: all-recursive
f096bf
 
f096bf
@@ -2286,6 +2322,18 @@
f096bf
 	@rm -f wrap8$(EXEEXT)
f096bf
 	$(AM_V_CCLD)$(LINK) $(wrap8_OBJECTS) $(wrap8_LDADD) $(LIBS)
f096bf
 
f096bf
+wrapmalloc$(EXEEXT): $(wrapmalloc_OBJECTS) $(wrapmalloc_DEPENDENCIES) $(EXTRA_wrapmalloc_DEPENDENCIES) 
f096bf
+	@rm -f wrapmalloc$(EXEEXT)
f096bf
+	$(AM_V_CCLD)$(wrapmalloc_LINK) $(wrapmalloc_OBJECTS) $(wrapmalloc_LDADD) $(LIBS)
f096bf
+
f096bf
+wrapmallocso.so$(EXEEXT): $(wrapmallocso_so_OBJECTS) $(wrapmallocso_so_DEPENDENCIES) $(EXTRA_wrapmallocso_so_DEPENDENCIES) 
f096bf
+	@rm -f wrapmallocso.so$(EXEEXT)
f096bf
+	$(AM_V_CCLD)$(wrapmallocso_so_LINK) $(wrapmallocso_so_OBJECTS) $(wrapmallocso_so_LDADD) $(LIBS)
f096bf
+
f096bf
+wrapmallocstatic$(EXEEXT): $(wrapmallocstatic_OBJECTS) $(wrapmallocstatic_DEPENDENCIES) $(EXTRA_wrapmallocstatic_DEPENDENCIES) 
f096bf
+	@rm -f wrapmallocstatic$(EXEEXT)
f096bf
+	$(AM_V_CCLD)$(LINK) $(wrapmallocstatic_OBJECTS) $(wrapmallocstatic_LDADD) $(LIBS)
f096bf
+
f096bf
 writev1$(EXEEXT): $(writev1_OBJECTS) $(writev1_DEPENDENCIES) $(EXTRA_writev1_DEPENDENCIES) 
f096bf
 	@rm -f writev1$(EXEEXT)
f096bf
 	$(AM_V_CCLD)$(LINK) $(writev1_OBJECTS) $(writev1_LDADD) $(LIBS)
f096bf
@@ -2446,6 +2494,9 @@
f096bf
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrap7.Po@am__quote@
f096bf
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrap7so_so-wrap7so.Po@am__quote@
f096bf
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrap8.Po@am__quote@
f096bf
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapmalloc.Po@am__quote@
f096bf
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapmallocso_so-wrapmallocso.Po@am__quote@
f096bf
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapmallocstatic.Po@am__quote@
f096bf
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writev1.Po@am__quote@
f096bf
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml1-xml1.Po@am__quote@
f096bf
 
f096bf
@@ -3011,6 +3062,20 @@
f096bf
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
f096bf
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(wrap7so_so_CFLAGS) $(CFLAGS) -c -o wrap7so_so-wrap7so.obj `if test -f 'wrap7so.c'; then $(CYGPATH_W) 'wrap7so.c'; else $(CYGPATH_W) '$(srcdir)/wrap7so.c'; fi`
f096bf
 
f096bf
+wrapmallocso_so-wrapmallocso.o: wrapmallocso.c
f096bf
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(wrapmallocso_so_CFLAGS) $(CFLAGS) -MT wrapmallocso_so-wrapmallocso.o -MD -MP -MF $(DEPDIR)/wrapmallocso_so-wrapmallocso.Tpo -c -o wrapmallocso_so-wrapmallocso.o `test -f 'wrapmallocso.c' || echo '$(srcdir)/'`wrapmallocso.c
f096bf
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/wrapmallocso_so-wrapmallocso.Tpo $(DEPDIR)/wrapmallocso_so-wrapmallocso.Po
f096bf
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='wrapmallocso.c' object='wrapmallocso_so-wrapmallocso.o' libtool=no @AMDEPBACKSLASH@
f096bf
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
f096bf
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(wrapmallocso_so_CFLAGS) $(CFLAGS) -c -o wrapmallocso_so-wrapmallocso.o `test -f 'wrapmallocso.c' || echo '$(srcdir)/'`wrapmallocso.c
f096bf
+
f096bf
+wrapmallocso_so-wrapmallocso.obj: wrapmallocso.c
f096bf
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(wrapmallocso_so_CFLAGS) $(CFLAGS) -MT wrapmallocso_so-wrapmallocso.obj -MD -MP -MF $(DEPDIR)/wrapmallocso_so-wrapmallocso.Tpo -c -o wrapmallocso_so-wrapmallocso.obj `if test -f 'wrapmallocso.c'; then $(CYGPATH_W) 'wrapmallocso.c'; else $(CYGPATH_W) '$(srcdir)/wrapmallocso.c'; fi`
f096bf
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/wrapmallocso_so-wrapmallocso.Tpo $(DEPDIR)/wrapmallocso_so-wrapmallocso.Po
f096bf
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='wrapmallocso.c' object='wrapmallocso_so-wrapmallocso.obj' libtool=no @AMDEPBACKSLASH@
f096bf
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
f096bf
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(wrapmallocso_so_CFLAGS) $(CFLAGS) -c -o wrapmallocso_so-wrapmallocso.obj `if test -f 'wrapmallocso.c'; then $(CYGPATH_W) 'wrapmallocso.c'; else $(CYGPATH_W) '$(srcdir)/wrapmallocso.c'; fi`
f096bf
+
f096bf
 xml1-xml1.o: xml1.c
f096bf
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xml1_CFLAGS) $(CFLAGS) -MT xml1-xml1.o -MD -MP -MF $(DEPDIR)/xml1-xml1.Tpo -c -o xml1-xml1.o `test -f 'xml1.c' || echo '$(srcdir)/'`xml1.c
f096bf
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/xml1-xml1.Tpo $(DEPDIR)/xml1-xml1.Po
f096bf
commit d35c2c3197a0ae8398228d19578e1dfcb8401c5f
f096bf
Author: iraisr <iraisr@a5019735-40e9-0310-863c-91ae7b9d1cf9>
f096bf
Date:   Wed Nov 18 04:13:12 2015 +0000
f096bf
f096bf
    Expected stderr of test cases wrapmalloc and wrapmallocstatic are overconstrained.
f096bf
    Fixes BZ#355455.
f096bf
    
f096bf
    
f096bf
    git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15727 a5019735-40e9-0310-863c-91ae7b9d1cf9
f096bf
f096bf
diff --git a/memcheck/tests/wrapmalloc.stderr.exp b/memcheck/tests/wrapmalloc.stderr.exp
f096bf
index d937776..e69de29 100644
f096bf
--- a/memcheck/tests/wrapmalloc.stderr.exp
f096bf
+++ b/memcheck/tests/wrapmalloc.stderr.exp
f096bf
@@ -1,10 +0,0 @@
f096bf
-
f096bf
-
f096bf
-HEAP SUMMARY:
f096bf
-    in use at exit: 0 bytes in 0 blocks
f096bf
-  total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
f096bf
-
f096bf
-For a detailed leak analysis, rerun with: --leak-check=full
f096bf
-
f096bf
-For counts of detected and suppressed errors, rerun with: -v
f096bf
-ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
f096bf
diff --git a/memcheck/tests/wrapmalloc.vgtest b/memcheck/tests/wrapmalloc.vgtest
f096bf
index a6dff4e..c22f241 100644
f096bf
--- a/memcheck/tests/wrapmalloc.vgtest
f096bf
+++ b/memcheck/tests/wrapmalloc.vgtest
f096bf
@@ -1,2 +1,2 @@
f096bf
 prog: wrapmalloc
f096bf
-
f096bf
+vgopts: -q
f096bf
diff --git a/memcheck/tests/wrapmallocstatic.stderr.exp b/memcheck/tests/wrapmallocstatic.stderr.exp
f096bf
index d937776..e69de29 100644
f096bf
--- a/memcheck/tests/wrapmallocstatic.stderr.exp
f096bf
+++ b/memcheck/tests/wrapmallocstatic.stderr.exp
f096bf
@@ -1,10 +0,0 @@
f096bf
-
f096bf
-
f096bf
-HEAP SUMMARY:
f096bf
-    in use at exit: 0 bytes in 0 blocks
f096bf
-  total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
f096bf
-
f096bf
-For a detailed leak analysis, rerun with: --leak-check=full
f096bf
-
f096bf
-For counts of detected and suppressed errors, rerun with: -v
f096bf
-ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
f096bf
diff --git a/memcheck/tests/wrapmallocstatic.vgtest b/memcheck/tests/wrapmallocstatic.vgtest
f096bf
index 7b3c068..f040756 100644
f096bf
--- a/memcheck/tests/wrapmallocstatic.vgtest
f096bf
+++ b/memcheck/tests/wrapmallocstatic.vgtest
f096bf
@@ -1,2 +1,2 @@
f096bf
 prog: wrapmallocstatic
f096bf
-
f096bf
+vgopts: -q
f096bf
f096bf
commit 194731c49eb7d448503a5e8625dd39779c2c9f8b
f096bf
Author: iraisr <iraisr@a5019735-40e9-0310-863c-91ae7b9d1cf9>
f096bf
Date:   Wed Nov 18 20:38:37 2015 +0000
f096bf
f096bf
    When searching for global public symbols (like for the somalloc
f096bf
    synonym symbols), exclude the dynamic (runtime) linker as it is very
f096bf
    special.
f096bf
    Fixes BZ#355454
f096bf
    
f096bf
    
f096bf
    git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15728 a5019735-40e9-0310-863c-91ae7b9d1cf9
f096bf
f096bf
diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c
f096bf
index 3d3f70a..dcf1fb4 100644
f096bf
--- a/coregrind/m_redir.c
f096bf
+++ b/coregrind/m_redir.c
f096bf
@@ -809,8 +809,19 @@ void generate_and_add_actives (
f096bf
    anyMark = False;
f096bf
    for (sp = specs; sp; sp = sp->next) {
f096bf
       sp->done = False;
f096bf
-      sp->mark = VG_(string_match)( sp->from_sopatt, 
f096bf
-                                    VG_(DebugInfo_get_soname)(di) );
f096bf
+      const HChar *soname = VG_(DebugInfo_get_soname)(di);
f096bf
+
f096bf
+      /* When searching for global public symbols (like for the somalloc
f096bf
+         synonym symbols), exclude the dynamic (runtime) linker as it is very
f096bf
+         special. See https://bugs.kde.org/show_bug.cgi?id=355454 */
f096bf
+      if ((VG_(strcmp)(sp->from_sopatt, "*") == 0) &&
f096bf
+          (sp->isGlobal == True) &&
f096bf
+          VG_(is_soname_ld_so)(soname)) {
f096bf
+         sp->mark = False;
f096bf
+         continue;
f096bf
+      }
f096bf
+
f096bf
+      sp->mark = VG_(string_match)( sp->from_sopatt, soname );
f096bf
       anyMark = anyMark || sp->mark;
f096bf
    }
f096bf
 
f096bf
@@ -1179,6 +1190,29 @@ Addr VG_(redir_do_lookup) ( Addr orig, Bool* isWrap )
f096bf
    return r->to_addr;
f096bf
 }
f096bf
 
f096bf
+/* Does the soname represent a dynamic (runtime) linker?
f096bf
+   Considers various VG_U_LD* entries from pub_tool_redir.h. */
f096bf
+Bool VG_(is_soname_ld_so) (const HChar *soname)
f096bf
+{
f096bf
+#  if defined(VGO_linux)
f096bf
+   if (VG_STREQ(soname, VG_U_LD_LINUX_SO_3))         return True;
f096bf
+   if (VG_STREQ(soname, VG_U_LD_LINUX_SO_2))         return True;
f096bf
+   if (VG_STREQ(soname, VG_U_LD_LINUX_X86_64_SO_2))  return True;
f096bf
+   if (VG_STREQ(soname, VG_U_LD64_SO_1))             return True;
f096bf
+   if (VG_STREQ(soname, VG_U_LD64_SO_2))             return True;
f096bf
+   if (VG_STREQ(soname, VG_U_LD_SO_1))               return True;
f096bf
+   if (VG_STREQ(soname, VG_U_LD_LINUX_AARCH64_SO_1)) return True;
f096bf
+   if (VG_STREQ(soname, VG_U_LD_LINUX_ARMHF_SO_3))   return True;
f096bf
+#  elif defined(VGO_darwin)
f096bf
+   if (VG_STREQ(soname, VG_U_DYLD)) return True;
f096bf
+#  elif defined(VGO_solaris)
f096bf
+   if (VG_STREQ(soname, VG_U_LD_SO_1)) return True;
f096bf
+#  else
f096bf
+#    error "Unsupported OS"
f096bf
+#  endif
f096bf
+
f096bf
+   return False;
f096bf
+}
f096bf
 
f096bf
 /*------------------------------------------------------------*/
f096bf
 /*--- INITIALISATION                                       ---*/
f096bf
diff --git a/docs/xml/manual-core.xml b/docs/xml/manual-core.xml
f096bf
index c80aab0..758e2f4 100644
f096bf
--- a/docs/xml/manual-core.xml
f096bf
+++ b/docs/xml/manual-core.xml
f096bf
@@ -2322,7 +2322,7 @@ need to use them.</para>
f096bf
       own versions.  Such replacements are normally done only in shared
f096bf
       libraries whose soname matches a predefined soname pattern (e.g.
f096bf
       <varname>libc.so*</varname> on linux).  By default, no
f096bf
-      replacement is done for a statically linked library or for
f096bf
+      replacement is done for a statically linked binary or for
f096bf
       alternative libraries, except for the allocation functions
f096bf
       (malloc, free, calloc, memalign, realloc, operator new, operator
f096bf
       delete, etc.) Such allocation functions are intercepted by
f096bf
@@ -2392,6 +2392,13 @@ need to use them.</para>
f096bf
 	  </para>
f096bf
 	</listitem>
f096bf
 
f096bf
+      <listitem>
f096bf
+         <para>Shared library of the dynamic (runtime) linker is excluded from
f096bf
+         searching for global public symbols, such as those for the malloc
f096bf
+         related functions (identified by <varname>somalloc</varname> synonym).
f096bf
+         </para>
f096bf
+      </listitem>
f096bf
+
f096bf
       </itemizedlist>
f096bf
    </listitem>
f096bf
   </varlistentry>
f096bf
diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c
f096bf
index ae6eec0..9aed05a 100644
f096bf
--- a/helgrind/hg_main.c
f096bf
+++ b/helgrind/hg_main.c
f096bf
@@ -4589,7 +4589,6 @@ static Bool is_in_dynamic_linker_shared_object( Addr ga )
f096bf
 {
f096bf
    DebugInfo* dinfo;
f096bf
    const HChar* soname;
f096bf
-   if (0) return False;
f096bf
 
f096bf
    dinfo = VG_(find_DebugInfo)( ga );
f096bf
    if (!dinfo) return False;
f096bf
@@ -4598,23 +4597,7 @@ static Bool is_in_dynamic_linker_shared_object( Addr ga )
f096bf
    tl_assert(soname);
f096bf
    if (0) VG_(printf)("%s\n", soname);
f096bf
 
f096bf
-#  if defined(VGO_linux)
f096bf
-   if (VG_STREQ(soname, VG_U_LD_LINUX_SO_3))        return True;
f096bf
-   if (VG_STREQ(soname, VG_U_LD_LINUX_SO_2))        return True;
f096bf
-   if (VG_STREQ(soname, VG_U_LD_LINUX_X86_64_SO_2)) return True;
f096bf
-   if (VG_STREQ(soname, VG_U_LD64_SO_1))            return True;
f096bf
-   if (VG_STREQ(soname, VG_U_LD64_SO_2))            return True;
f096bf
-   if (VG_STREQ(soname, VG_U_LD_SO_1))              return True;
f096bf
-   if (VG_STREQ(soname, VG_U_LD_LINUX_AARCH64_SO_1)) return True;
f096bf
-   if (VG_STREQ(soname, VG_U_LD_LINUX_ARMHF_SO_3))  return True;
f096bf
-#  elif defined(VGO_darwin)
f096bf
-   if (VG_STREQ(soname, VG_U_DYLD)) return True;
f096bf
-#  elif defined(VGO_solaris)
f096bf
-   if (VG_STREQ(soname, VG_U_LD_SO_1)) return True;
f096bf
-#  else
f096bf
-#    error "Unsupported OS"
f096bf
-#  endif
f096bf
-   return False;
f096bf
+   return VG_(is_soname_ld_so)(soname);
f096bf
 }
f096bf
 
f096bf
 static
f096bf
diff --git a/include/pub_tool_redir.h b/include/pub_tool_redir.h
f096bf
index 21d186b..aa879d6 100644
f096bf
--- a/include/pub_tool_redir.h
f096bf
+++ b/include/pub_tool_redir.h
f096bf
@@ -351,6 +351,8 @@
f096bf
 #define SO_SYN_MALLOC VG_SO_SYN(somalloc)
f096bf
 #define SO_SYN_MALLOC_NAME "VgSoSynsomalloc"
f096bf
 
f096bf
+Bool VG_(is_soname_ld_so) (const HChar *soname);
f096bf
+
f096bf
 #endif   // __PUB_TOOL_REDIR_H
f096bf
 
f096bf
 /*--------------------------------------------------------------------*/