Blame SOURCES/valgrind-3.11.0-wrapmalloc.patch

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