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