diff --git a/valgrind-3.11.0-aspacemgr.patch b/valgrind-3.11.0-aspacemgr.patch new file mode 100644 index 0000000..0688022 --- /dev/null +++ b/valgrind-3.11.0-aspacemgr.patch @@ -0,0 +1,80 @@ +commit b28a423827a1c7917c6f3f3eba23b9432077dfbd +Author: florian +Date: Sat Jan 16 21:44:31 2016 +0000 + + In ML_(am_allocate_segname) do not set the reference count of the + slot to 1. Rather do that in add_segment which is where the segment + refering to that name actually comes into existence. + Properly handle the case in add_segment where the to-be-added segment + and one (or more) of the segments it replaces have the same name + This may occur when doing a mremap. + + + git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15761 a5019735-40e9-0310-863c-91ae7b9d1cf9 + +diff --git a/coregrind/m_aspacemgr/aspacemgr-linux.c b/coregrind/m_aspacemgr/aspacemgr-linux.c +index 0a8f675..f6c1a41 100644 +--- a/coregrind/m_aspacemgr/aspacemgr-linux.c ++++ b/coregrind/m_aspacemgr/aspacemgr-linux.c +@@ -1445,6 +1445,15 @@ static void add_segment ( const NSegment* seg ) + + split_nsegments_lo_and_hi( sStart, sEnd, &iLo, &iHi ); + ++ /* Increase the reference count of SEG's name. We need to do this ++ *before* decreasing the reference count of the names of the replaced ++ segments. Consider the case where the segment name of SEG and one of ++ the replaced segments are the same. If the refcount of that name is 1, ++ then decrementing first would put the slot for that name on the free ++ list. Attempting to increment the refcount later would then fail ++ because the slot is no longer allocated. */ ++ ML_(am_inc_refcount)(seg->fnIdx); ++ + /* Now iLo .. iHi inclusive is the range of segment indices which + seg will replace. If we're replacing more than one segment, + slide those above the range down to fill the hole. Before doing +diff --git a/coregrind/m_aspacemgr/aspacemgr-segnames.c b/coregrind/m_aspacemgr/aspacemgr-segnames.c +index ef3d3ef..8e74356 100644 +--- a/coregrind/m_aspacemgr/aspacemgr-segnames.c ++++ b/coregrind/m_aspacemgr/aspacemgr-segnames.c +@@ -309,7 +309,7 @@ ML_(am_allocate_segname)(const HChar *name) + freeslot_chain = next_freeslot; + else + put_slotindex(prev, next_freeslot); +- put_refcount(ix, 1); ++ put_refcount(ix, 0); + put_slotsize(ix, size); + VG_(strcpy)(segnames + ix, name); + ++num_segnames; +@@ -336,7 +336,7 @@ ML_(am_allocate_segname)(const HChar *name) + + /* copy it in */ + ix = segnames_used; +- put_refcount(ix, 1); ++ put_refcount(ix, 0); + put_slotsize(ix, len + 1); + VG_(strcpy)(segnames + ix, name); + segnames_used += need; +commit e345eb50c0c5e96ac60b2bc21fbe9f281c20b9e6 +Author: florian +Date: Sat Jan 16 21:12:57 2016 +0000 + + Remove code that has no effect. Looks like a leftover from early + debugging days. + + + git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15760 a5019735-40e9-0310-863c-91ae7b9d1cf9 + +diff --git a/coregrind/m_aspacemgr/aspacemgr-segnames.c b/coregrind/m_aspacemgr/aspacemgr-segnames.c +index 761608d..ef3d3ef 100644 +--- a/coregrind/m_aspacemgr/aspacemgr-segnames.c ++++ b/coregrind/m_aspacemgr/aspacemgr-segnames.c +@@ -250,9 +250,7 @@ dec_refcount(UInt ix) + UInt size = get_slotsize(ix); + /* Chain this slot in the freelist */ + put_slotindex(ix, freeslot_chain); +- get_slotindex(ix); + put_slotsize(ix + slotsize_size, size); +- get_slotindex(ix); + freeslot_chain = ix; + --num_segnames; + if (0) VG_(am_show_nsegments)(0, "AFTER DECREASE rc -> 0"); diff --git a/valgrind-3.11.0-fclose.patch b/valgrind-3.11.0-fclose.patch new file mode 100644 index 0000000..d79fa93 --- /dev/null +++ b/valgrind-3.11.0-fclose.patch @@ -0,0 +1,21 @@ +commit 8c8306308e05e92de228de57e832c85fb976124b +Author: florian +Date: Tue Jan 12 14:32:05 2016 +0000 + + VG_(fclose) ought to close the file, you silly. Fixes BZ #357887. + + + git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15755 a5019735-40e9-0310-863c-91ae7b9d1cf9 + +diff --git a/coregrind/m_libcprint.c b/coregrind/m_libcprint.c +index 1283de5..ce2c038 100644 +--- a/coregrind/m_libcprint.c ++++ b/coregrind/m_libcprint.c +@@ -359,6 +359,7 @@ void VG_(fclose)( VgFile *fp ) + if (fp->num_chars) + VG_(write)(fp->fd, fp->buf, fp->num_chars); + ++ VG_(close)(fp->fd); + VG_(free)(fp); + } + diff --git a/valgrind-3.11.0-is_stmt.patch b/valgrind-3.11.0-is_stmt.patch new file mode 100644 index 0000000..35530d8 --- /dev/null +++ b/valgrind-3.11.0-is_stmt.patch @@ -0,0 +1,254 @@ +commit 434c7524413a8a47ae40e4b141f5821eabc506b7 +Author: iraisr +Date: Fri Dec 4 13:14:10 2015 +0000 + + Dwarf line info reader now correctly interprets 'is_stmt' register + + Line numbers should correctly reflect all instructions belonging to a source line, + regardless of is_stmt value. Previously only instructions covered by + 'is_stmt = 1' were attributed to a source line. + + Fixes BZ#356044 + + + git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15741 a5019735-40e9-0310-863c-91ae7b9d1cf9 + +diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c +index 88d49e9..a95bb3d 100644 +--- a/coregrind/m_debuginfo/readdwarf.c ++++ b/coregrind/m_debuginfo/readdwarf.c +@@ -91,7 +91,6 @@ typedef struct + ULong li_header_length; + UChar li_min_insn_length; + UChar li_max_ops_per_insn; +- UChar li_default_is_stmt; + Int li_line_base; + UChar li_line_range; + UChar li_opcode_base; +@@ -150,7 +149,6 @@ typedef struct + UInt file; + UInt line; + UInt column; +- Int is_stmt; + Int basic_block; + UChar end_sequence; + } LineSMR; +@@ -230,7 +228,7 @@ ULong read_initial_length_field ( DiCursor p_img, /*OUT*/Bool* is64 ) + static LineSMR state_machine_regs; + + static +-void reset_state_machine ( Int is_stmt ) ++void reset_state_machine ( void ) + { + if (0) VG_(printf)("smr.a := %p (reset)\n", NULL ); + state_machine_regs.last_address = 0; +@@ -240,7 +238,6 @@ void reset_state_machine ( Int is_stmt ) + state_machine_regs.file = 1; + state_machine_regs.line = 1; + state_machine_regs.column = 0; +- state_machine_regs.is_stmt = is_stmt; + state_machine_regs.basic_block = 0; + state_machine_regs.end_sequence = 0; + } +@@ -253,7 +250,7 @@ void reset_state_machine ( Int is_stmt ) + static + void process_extended_line_op( struct _DebugInfo* di, + XArray* fndn_ix_xa, +- DiCursor* data, Int is_stmt) ++ DiCursor* data ) + { + UInt len = step_leb128U(data); + if (len == 0) { +@@ -275,19 +272,17 @@ void process_extended_line_op( struct _DebugInfo* di, + reset_state_machine below */ + state_machine_regs.end_sequence = 1; + +- if (state_machine_regs.is_stmt) { +- if (state_machine_regs.last_address) { +- ML_(addLineInfo) ( +- di, +- safe_fndn_ix (fndn_ix_xa, +- state_machine_regs.last_file), +- di->text_debug_bias + state_machine_regs.last_address, +- di->text_debug_bias + state_machine_regs.address, +- state_machine_regs.last_line, 0 +- ); +- } ++ if (state_machine_regs.last_address) { ++ ML_(addLineInfo)( ++ di, ++ safe_fndn_ix(fndn_ix_xa, ++ state_machine_regs.last_file), ++ di->text_debug_bias + state_machine_regs.last_address, ++ di->text_debug_bias + state_machine_regs.address, ++ state_machine_regs.last_line, 0 ++ ); + } +- reset_state_machine (is_stmt); ++ reset_state_machine(); + if (di->ddump_line) + VG_(printf)(" Extended opcode %d: End of Sequence\n\n", + (Int)op_code); +@@ -446,29 +441,9 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di, + info.li_max_ops_per_insn = 1; + } + +- info.li_default_is_stmt = ML_(cur_step_UChar)(&external); +- if (di->ddump_line) +- VG_(printf)(" Initial value of 'is_stmt': %d\n", +- (Int)info.li_default_is_stmt); +- +- /* Josef Weidendorfer (20021021) writes: +- +- It seems to me that the Intel Fortran compiler generates bad +- DWARF2 line info code: It sets "is_stmt" of the state machine in +- the line info reader to be always false. Thus, there is never +- a statement boundary generated and therefore never an instruction +- range/line number mapping generated for valgrind. +- +- Please have a look at the DWARF2 specification, Ch. 6.2 +- (x86.ddj.com/ftp/manuals/tools/dwarf.pdf). Perhaps I understand +- this wrong, but I don't think so. +- +- I just had a look at the GDB DWARF2 reader... They completely +- ignore "is_stmt" when recording line info ;-) That's the reason +- "objdump -S" works on files from the intel fortran compiler. +- +- Therefore: */ +- info.li_default_is_stmt = True; ++ /* Register is_stmt is not tracked as we are interested only ++ in pc -> line info mapping and not other debugger features. */ ++ /* default_is_stmt = */ ML_(cur_step_UChar)(&external); + + /* JRS: changed (UInt*) to (UChar*) */ + info.li_line_base = ML_(cur_step_UChar)(&external); +@@ -495,7 +470,7 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di, + DiCursor end_of_sequence + = ML_(cur_plus)(data, info.li_length + (is64 ? 12 : 4)); + +- reset_state_machine (info.li_default_is_stmt); ++ reset_state_machine(); + + /* Read the contents of the Opcodes table. */ + DiCursor standard_opcodes = external; +@@ -632,55 +607,49 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di, + (Int)op_code, advAddr, state_machine_regs.address, + (Int)adv, (Int)state_machine_regs.line ); + +- if (state_machine_regs.is_stmt) { +- /* only add a statement if there was a previous boundary */ +- if (state_machine_regs.last_address) { +- ML_(addLineInfo)( +- di, +- safe_fndn_ix (fndn_ix_xa, +- state_machine_regs.last_file), +- di->text_debug_bias + state_machine_regs.last_address, +- di->text_debug_bias + state_machine_regs.address, +- state_machine_regs.last_line, +- 0 +- ); +- } +- state_machine_regs.last_address = state_machine_regs.address; +- state_machine_regs.last_file = state_machine_regs.file; +- state_machine_regs.last_line = state_machine_regs.line; ++ /* only add a statement if there was a previous boundary */ ++ if (state_machine_regs.last_address) { ++ ML_(addLineInfo)( ++ di, ++ safe_fndn_ix(fndn_ix_xa, ++ state_machine_regs.last_file), ++ di->text_debug_bias + state_machine_regs.last_address, ++ di->text_debug_bias + state_machine_regs.address, ++ state_machine_regs.last_line, ++ 0 ++ ); + } ++ state_machine_regs.last_address = state_machine_regs.address; ++ state_machine_regs.last_file = state_machine_regs.file; ++ state_machine_regs.last_line = state_machine_regs.line; + } + + else { /* ! (op_code >= info.li_opcode_base) */ + + switch (op_code) { + case DW_LNS_extended_op: +- process_extended_line_op ( +- di, fndn_ix_xa, +- &data, info.li_default_is_stmt); ++ process_extended_line_op(di, fndn_ix_xa, &data); + break; + + case DW_LNS_copy: + if (0) VG_(printf)("1002: di->o %#lx, smr.a %#lx\n", + (UWord)di->text_debug_bias, + state_machine_regs.address ); +- if (state_machine_regs.is_stmt) { +- /* only add a statement if there was a previous boundary */ +- if (state_machine_regs.last_address) { +- ML_(addLineInfo)( +- di, +- safe_fndn_ix (fndn_ix_xa, +- state_machine_regs.last_file), +- di->text_debug_bias + state_machine_regs.last_address, +- di->text_debug_bias + state_machine_regs.address, +- state_machine_regs.last_line, +- 0 +- ); +- } +- state_machine_regs.last_address = state_machine_regs.address; +- state_machine_regs.last_file = state_machine_regs.file; +- state_machine_regs.last_line = state_machine_regs.line; ++ /* only add a statement if there was a previous boundary */ ++ if (state_machine_regs.last_address) { ++ ML_(addLineInfo)( ++ di, ++ safe_fndn_ix(fndn_ix_xa, ++ state_machine_regs.last_file), ++ di->text_debug_bias + state_machine_regs.last_address, ++ di->text_debug_bias + state_machine_regs.address, ++ state_machine_regs.last_line, ++ 0 ++ ); + } ++ state_machine_regs.last_address = state_machine_regs.address; ++ state_machine_regs.last_file = state_machine_regs.file; ++ state_machine_regs.last_line = state_machine_regs.line; + state_machine_regs.basic_block = 0; /* JRS added */ + if (di->ddump_line) + VG_(printf)(" Copy\n"); +@@ -719,9 +688,6 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di, + break; + } + case DW_LNS_negate_stmt: { +- Int adv = state_machine_regs.is_stmt; +- adv = ! adv; +- state_machine_regs.is_stmt = adv; + if (di->ddump_line) + VG_(printf)(" DWARF2-line: negate_stmt\n"); + break; +diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c +index 7b2e26a..e6a9856 100644 +--- a/coregrind/m_debuginfo/storage.c ++++ b/coregrind/m_debuginfo/storage.c +@@ -419,6 +419,21 @@ static void addLoc ( struct _DebugInfo* di, DiLoc* loc, UInt fndn_ix ) + /* Zero-sized locs should have been ignored earlier */ + vg_assert(loc->size > 0); + ++ /* Check if the last entry has adjacent range for the same line. */ ++ if (di->loctab_used > 0) { ++ DiLoc *previous = &di->loctab[di->loctab_used - 1]; ++ if ((previous->lineno == loc->lineno) ++ && (previous->addr + previous->size == loc->addr)) { ++ if (0) ++ VG_(printf)("Merging previous: addr %#lx, size %d, line %d, " ++ "with current: addr %#lx, size %d, line %d.\n", ++ previous->addr, previous->size, previous->lineno, ++ loc->addr, loc->size, loc->lineno); ++ previous->size += loc->size; ++ return; ++ } ++ } ++ + if (di->loctab_used == di->loctab_size) { + UInt new_sz; + DiLoc* new_loctab; diff --git a/valgrind-3.11.0-no-rdrand.patch b/valgrind-3.11.0-no-rdrand.patch new file mode 100644 index 0000000..cb4a49c --- /dev/null +++ b/valgrind-3.11.0-no-rdrand.patch @@ -0,0 +1,26 @@ +commit 1ab61656f71e94ce12b68de87f1e28cf3dc0c18c +Author: mjw +Date: Thu Oct 1 12:31:19 2015 +0000 + + Don't advertise RDRAND in cpuid for Core-i7-4910-like avx2 machine. + + Bug#353370. In amd64g_dirtyhelper_CPUID_avx2 we set the RDRAND bit + but we don't implement support for RDRAND. Turn the bit off so programs + don't try to use RDRAND when running under valgrind. + + git-svn-id: svn://svn.valgrind.org/vex/trunk@3197 8f6e269a-dfd6-0310-a8e1-e2731360e62c + +diff --git a/VEX/priv/guest_amd64_helpers.c b/VEX/priv/guest_amd64_helpers.c +index e77d753..ab53e15 100644 +--- a/VEX/priv/guest_amd64_helpers.c ++++ b/VEX/priv/guest_amd64_helpers.c +@@ -3101,7 +3101,8 @@ void amd64g_dirtyhelper_CPUID_avx2 ( VexGuestAMD64State* st ) + SET_ABCD(0x0000000d, 0x756e6547, 0x6c65746e, 0x49656e69); + break; + case 0x00000001: +- SET_ABCD(0x000306c3, 0x02100800, 0x7ffafbff, 0xbfebfbff); ++ /* Don't advertise RDRAND support, bit 30 in ECX. */ ++ SET_ABCD(0x000306c3, 0x02100800, 0x3ffafbff, 0xbfebfbff); + break; + case 0x00000002: + SET_ABCD(0x76036301, 0x00f0b6ff, 0x00000000, 0x00c10000); diff --git a/valgrind-3.11.0-pthread_barrier.patch b/valgrind-3.11.0-pthread_barrier.patch new file mode 100644 index 0000000..bab74b6 --- /dev/null +++ b/valgrind-3.11.0-pthread_barrier.patch @@ -0,0 +1,513 @@ +commit f4d91a5df8b749c6cdfec25e38a44c02c90ad4be +Author: Mark Wielaard +Date: Tue Jan 19 15:13:47 2016 +0100 + + Bug #358213 helgrind/drd pthread_barrier tests vs new glibc implementation + + glibc 2.23 will have a new pthread_barrier implementation. + This implementation reacts differently on bad usage of barriers. + Because of this the bar_bad testcase will hang indefinitely. + In particular pthread_barrier_destroy will hang when there are + still other threads waiting on a barrier. To solve this we add + extra threads to will "unblock" the hanging destroy by sleeping + for a while and then also waiting on the barrier, which will unblock + the destroy operation. Or if this is the last test, just exit + the whole program since we are done anyway. Also newer glibc is + more picky about destroying uninitialized barriers, we would crash + when zero filling, so we now one fill. Which doesn't crash, but + depending on glibc version might return an error or hang. Since + depending on version we now get slightly different error reports + there are now alternative exp files. + + Tested against glibc 2.17, glibc 2.22 and glibc 2.23-prerelease. + +diff --git a/drd/tests/Makefile.am b/drd/tests/Makefile.am +index 2885391..cfd74d0 100644 +--- a/drd/tests/Makefile.am ++++ b/drd/tests/Makefile.am +@@ -81,8 +81,10 @@ EXTRA_DIST = \ + atomic_var.stderr.exp \ + atomic_var.vgtest \ + bar_bad.stderr.exp \ ++ bar_bad.stderr.exp-nohang \ + bar_bad.vgtest \ + bar_bad_xml.stderr.exp \ ++ bar_bad_xml.stderr.exp-nohang \ + bar_bad_xml.vgtest \ + bar_trivial.stderr.exp \ + bar_trivial.stdout.exp \ +diff --git a/drd/tests/bar_bad.stderr.exp b/drd/tests/bar_bad.stderr.exp +index 75f121f..3581b08 100644 +--- a/drd/tests/bar_bad.stderr.exp ++++ b/drd/tests/bar_bad.stderr.exp +@@ -34,16 +34,5 @@ barrier 0x........ was first observed at: + + + destroy a barrier that was never initialised +-Not a barrier +- at 0x........: pthread_barrier_destroy (drd_pthread_intercepts.c:?) +- by 0x........: main (bar_bad.c:?) +- +-Destruction of barrier that is being waited upon: barrier 0x........ +- at 0x........: free (vg_replace_malloc.c:...) +- by 0x........: main (bar_bad.c:?) +-barrier 0x........ was first observed at: +- at 0x........: pthread_barrier_init (drd_pthread_intercepts.c:?) +- by 0x........: main (bar_bad.c:?) +- + +-ERROR SUMMARY: 7 errors from 6 contexts (suppressed: 0 from 0) ++ERROR SUMMARY: 5 errors from 4 contexts (suppressed: 0 from 0) +diff --git a/drd/tests/bar_bad.stderr.exp b/drd/tests/bar_bad.stderr.exp-nohang +similarity index 79% +copy from drd/tests/bar_bad.stderr.exp +copy to drd/tests/bar_bad.stderr.exp-nohang +index 75f121f..44f9651 100644 +--- a/drd/tests/bar_bad.stderr.exp ++++ b/drd/tests/bar_bad.stderr.exp-nohang +@@ -38,12 +38,5 @@ Not a barrier + at 0x........: pthread_barrier_destroy (drd_pthread_intercepts.c:?) + by 0x........: main (bar_bad.c:?) + +-Destruction of barrier that is being waited upon: barrier 0x........ +- at 0x........: free (vg_replace_malloc.c:...) +- by 0x........: main (bar_bad.c:?) +-barrier 0x........ was first observed at: +- at 0x........: pthread_barrier_init (drd_pthread_intercepts.c:?) +- by 0x........: main (bar_bad.c:?) +- + +-ERROR SUMMARY: 7 errors from 6 contexts (suppressed: 0 from 0) ++ERROR SUMMARY: 6 errors from 5 contexts (suppressed: 0 from 0) +diff --git a/drd/tests/bar_bad_xml.stderr.exp b/drd/tests/bar_bad_xml.stderr.exp +index acb9656..8539f75 100644 +--- a/drd/tests/bar_bad_xml.stderr.exp ++++ b/drd/tests/bar_bad_xml.stderr.exp +@@ -204,78 +204,6 @@ destroy a barrier that has waiting threads + + + destroy a barrier that was never initialised +- +- 0x........ +- ... +- GenericErr +- Not a barrier +- +- +- 0x........ +- ... +- pthread_barrier_destroy +- ... +- drd_pthread_intercepts.c +- ... +- +- +- 0x........ +- ... +- main +- ... +- bar_bad.c +- ... +- +- +- +- +- +- 0x........ +- ... +- BarrierErr +- Destruction of barrier that is being waited upon: barrier 0x........ +- +- +- 0x........ +- ... +- free +- ... +- vg_replace_malloc.c +- ... +- +- +- 0x........ +- ... +- main +- ... +- bar_bad.c +- ... +- +- +- +- barrier +-
0x........
+- +- +- 0x........ +- ... +- pthread_barrier_init +- ... +- drd_pthread_intercepts.c +- ... +- +- +- 0x........ +- ... +- main +- ... +- bar_bad.c +- ... +- +- +-
+-
+- + + + FINISHED +@@ -299,14 +227,6 @@ destroy a barrier that was never initialised + ... + 0x........ + +- +- ... +- 0x........ +- +- +- ... +- 0x........ +- + + + ... +diff --git a/drd/tests/bar_bad_xml.stderr.exp b/drd/tests/bar_bad_xml.stderr.exp-nohang +similarity index 82% +copy from drd/tests/bar_bad_xml.stderr.exp +copy to drd/tests/bar_bad_xml.stderr.exp-nohang +index acb9656..a47cd60 100644 +--- a/drd/tests/bar_bad_xml.stderr.exp ++++ b/drd/tests/bar_bad_xml.stderr.exp-nohang +@@ -229,53 +229,6 @@ destroy a barrier that was never initialised + + + +- +- 0x........ +- ... +- BarrierErr +- Destruction of barrier that is being waited upon: barrier 0x........ +- +- +- 0x........ +- ... +- free +- ... +- vg_replace_malloc.c +- ... +- +- +- 0x........ +- ... +- main +- ... +- bar_bad.c +- ... +- +- +- +- barrier +-
0x........
+- +- +- 0x........ +- ... +- pthread_barrier_init +- ... +- drd_pthread_intercepts.c +- ... +- +- +- 0x........ +- ... +- main +- ... +- bar_bad.c +- ... +- +- +-
+-
+- + + + FINISHED +@@ -303,10 +256,6 @@ destroy a barrier that was never initialised + ... + 0x........ + +- +- ... +- 0x........ +- + + + ... +diff --git a/helgrind/tests/Makefile.am b/helgrind/tests/Makefile.am +index 8a0d6e6..df82169 100644 +--- a/helgrind/tests/Makefile.am ++++ b/helgrind/tests/Makefile.am +@@ -19,6 +19,7 @@ EXTRA_DIST = \ + cond_timedwait_test.vgtest cond_timedwait_test.stdout.exp \ + cond_timedwait_test.stderr.exp \ + bar_bad.vgtest bar_bad.stdout.exp bar_bad.stderr.exp \ ++ bar_bad.stderr.exp-destroy-hang \ + bar_trivial.vgtest bar_trivial.stdout.exp bar_trivial.stderr.exp \ + free_is_write.vgtest free_is_write.stdout.exp \ + free_is_write.stderr.exp \ +diff --git a/helgrind/tests/bar_bad.c b/helgrind/tests/bar_bad.c +index dd6079c..424ae2f 100644 +--- a/helgrind/tests/bar_bad.c ++++ b/helgrind/tests/bar_bad.c +@@ -15,23 +15,27 @@ void* child1 ( void* arg ) + return NULL; + } + ++void *sleep1 ( void* arg ) ++{ ++ /* Long sleep, we hope to never trigger. */ ++ sleep (6); ++ pthread_barrier_wait ( (pthread_barrier_t*)arg ); ++ return NULL; ++} ++ ++void *exit1 ( void* arg ) ++{ ++ /* Sleep a bit, then exit, we are done. */ ++ sleep (1); ++ exit (0); ++ return NULL; ++} ++ + int main ( void ) + { + pthread_barrier_t *bar1, *bar2, *bar3, *bar4, *bar5; +- pthread_t thr1, thr2; + int r; +- +- /* possibly set up a watchdog timer thread here. */ +- +- +- +- +- +- +- +- +- +- ++ pthread_t thr1, thr2, slp1, slp2, ext1; + + /* initialise a barrier with a zero count */ + fprintf(stderr, "\ninitialise a barrier with zero count\n"); +@@ -49,6 +53,9 @@ int main ( void ) + fprintf(stderr, "\ninitialise a barrier which has threads waiting on it\n"); + bar3 = malloc(sizeof(pthread_barrier_t)); + pthread_barrier_init(bar3, NULL, 2); ++ /* create a thread, whose purpose is to "unblock" the barrier after ++ some sleeping in case it keeps being blocked. */ ++ pthread_create(&slp1, NULL, sleep1, (void*)bar3); + /* create a thread, whose only purpose is to block on the barrier */ + pthread_create(&thr1, NULL, child1, (void*)bar3); + /* guarantee that it gets there first */ +@@ -61,6 +68,12 @@ int main ( void ) + /* once again, create a thread, whose only purpose is to block. */ + bar4 = malloc(sizeof(pthread_barrier_t)); + pthread_barrier_init(bar4, NULL, 2); ++ /* create a thread, whose purpose is to "unblock" the barrier after ++ some sleeping in case it keeps being blocked. We hope it isn't ++ needed, but if it is, because pthread_barier_destroy hangs ++ and we will get an extra warning about the barrier being already ++ destroyed. */ ++ pthread_create(&slp2, NULL, sleep1, (void*)bar4); + /* create a thread, whose only purpose is to block on the barrier */ + pthread_create(&thr2, NULL, child1, (void*)bar4); + /* guarantee that it gets there first */ +@@ -70,13 +83,16 @@ int main ( void ) + + /* destroy a barrier that was never initialised. This is a bit + tricky, in that we have to fill the barrier with bytes which +- ensure that the pthread_barrier_destroy call doesn't hang for +- some reason. Zero-fill seems to work ok on amd64-linux (glibc ++ ensure that the pthread_barrier_destroy call doesn't crash for ++ some reason. One-fill seems to work ok on amd64-linux (glibc + 2.8). */ + fprintf(stderr, "\ndestroy a barrier that was never initialised\n"); ++ /* Create a thread that just exits the process after some sleep. ++ We are really done at this point, even if we hang. */ ++ pthread_create(&ext1, NULL, exit1, NULL); + bar5 = malloc(sizeof(pthread_barrier_t)); + assert(bar5); +- memset(bar5, 0, sizeof(*bar5)); ++ memset(bar5, 1, sizeof(*bar5)); + pthread_barrier_destroy(bar5); + + /* now we need to clean up the mess .. */ +@@ -85,5 +101,6 @@ int main ( void ) + + free(bar1); free(bar2); free(bar3); free(bar4); free(bar5); + +- return 0; ++ /* Use exit, we want to kill any "sleeper threads". */ ++ exit (0); + } +diff --git a/helgrind/tests/bar_bad.stderr.exp b/helgrind/tests/bar_bad.stderr.exp +index 74af4fa..d0901b2 100644 +--- a/helgrind/tests/bar_bad.stderr.exp ++++ b/helgrind/tests/bar_bad.stderr.exp +@@ -8,14 +8,14 @@ Thread #x is the program's root thread + + Thread #x: pthread_barrier_init: 'count' argument is zero + at 0x........: pthread_barrier_init (hg_intercepts.c:...) +- by 0x........: main (bar_bad.c:39) ++ by 0x........: main (bar_bad.c:43) + + ---------------------------------------------------------------- + + Thread #x's call to pthread_barrier_init failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: pthread_barrier_init (hg_intercepts.c:...) +- by 0x........: main (bar_bad.c:39) ++ by 0x........: main (bar_bad.c:43) + + + initialise a barrier twice +@@ -23,7 +23,7 @@ initialise a barrier twice + + Thread #x: pthread_barrier_init: barrier is already initialised + at 0x........: pthread_barrier_init (hg_intercepts.c:...) +- by 0x........: main (bar_bad.c:45) ++ by 0x........: main (bar_bad.c:49) + + + initialise a barrier which has threads waiting on it +@@ -31,13 +31,13 @@ initialise a barrier which has threads waiting on it + + Thread #x: pthread_barrier_init: barrier is already initialised + at 0x........: pthread_barrier_init (hg_intercepts.c:...) +- by 0x........: main (bar_bad.c:57) ++ by 0x........: main (bar_bad.c:64) + + ---------------------------------------------------------------- + + Thread #x: pthread_barrier_init: threads are waiting at barrier + at 0x........: pthread_barrier_init (hg_intercepts.c:...) +- by 0x........: main (bar_bad.c:57) ++ by 0x........: main (bar_bad.c:64) + + + destroy a barrier that has waiting threads +@@ -45,14 +45,14 @@ destroy a barrier that has waiting threads + + Thread #x: pthread_barrier_destroy: threads are waiting at barrier + at 0x........: pthread_barrier_destroy (hg_intercepts.c:...) +- by 0x........: main (bar_bad.c:69) ++ by 0x........: main (bar_bad.c:82) + + ---------------------------------------------------------------- + + Thread #x's call to pthread_barrier_destroy failed + with error code 16 (EBUSY: Device or resource busy) + at 0x........: pthread_barrier_destroy (hg_intercepts.c:...) +- by 0x........: main (bar_bad.c:69) ++ by 0x........: main (bar_bad.c:82) + + + destroy a barrier that was never initialised +@@ -60,5 +60,5 @@ destroy a barrier that was never initialised + + Thread #x: pthread_barrier_destroy: barrier was never initialised + at 0x........: pthread_barrier_destroy (hg_intercepts.c:...) +- by 0x........: main (bar_bad.c:80) ++ by 0x........: main (bar_bad.c:96) + +diff --git a/helgrind/tests/bar_bad.stderr.exp b/helgrind/tests/bar_bad.stderr.exp-destroy-hang +similarity index 72% +copy from helgrind/tests/bar_bad.stderr.exp +copy to helgrind/tests/bar_bad.stderr.exp-destroy-hang +index 74af4fa..ddf5624 100644 +--- a/helgrind/tests/bar_bad.stderr.exp ++++ b/helgrind/tests/bar_bad.stderr.exp-destroy-hang +@@ -8,14 +8,14 @@ Thread #x is the program's root thread + + Thread #x: pthread_barrier_init: 'count' argument is zero + at 0x........: pthread_barrier_init (hg_intercepts.c:...) +- by 0x........: main (bar_bad.c:39) ++ by 0x........: main (bar_bad.c:43) + + ---------------------------------------------------------------- + + Thread #x's call to pthread_barrier_init failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: pthread_barrier_init (hg_intercepts.c:...) +- by 0x........: main (bar_bad.c:39) ++ by 0x........: main (bar_bad.c:43) + + + initialise a barrier twice +@@ -23,7 +23,7 @@ initialise a barrier twice + + Thread #x: pthread_barrier_init: barrier is already initialised + at 0x........: pthread_barrier_init (hg_intercepts.c:...) +- by 0x........: main (bar_bad.c:45) ++ by 0x........: main (bar_bad.c:49) + + + initialise a barrier which has threads waiting on it +@@ -31,13 +31,13 @@ initialise a barrier which has threads waiting on it + + Thread #x: pthread_barrier_init: barrier is already initialised + at 0x........: pthread_barrier_init (hg_intercepts.c:...) +- by 0x........: main (bar_bad.c:57) ++ by 0x........: main (bar_bad.c:64) + + ---------------------------------------------------------------- + + Thread #x: pthread_barrier_init: threads are waiting at barrier + at 0x........: pthread_barrier_init (hg_intercepts.c:...) +- by 0x........: main (bar_bad.c:57) ++ by 0x........: main (bar_bad.c:64) + + + destroy a barrier that has waiting threads +@@ -45,14 +45,22 @@ destroy a barrier that has waiting threads + + Thread #x: pthread_barrier_destroy: threads are waiting at barrier + at 0x........: pthread_barrier_destroy (hg_intercepts.c:...) +- by 0x........: main (bar_bad.c:69) ++ by 0x........: main (bar_bad.c:82) ++ ++---Thread-Announcement------------------------------------------ ++ ++Thread #x was created ++ ... ++ by 0x........: pthread_create@* (hg_intercepts.c:...) ++ by 0x........: main (bar_bad.c:76) + + ---------------------------------------------------------------- + +-Thread #x's call to pthread_barrier_destroy failed +- with error code 16 (EBUSY: Device or resource busy) +- at 0x........: pthread_barrier_destroy (hg_intercepts.c:...) +- by 0x........: main (bar_bad.c:69) ++Thread #x: pthread_barrier_wait: barrier is uninitialised ++ at 0x........: pthread_barrier_wait (hg_intercepts.c:...) ++ by 0x........: sleep1 (bar_bad.c:22) ++ by 0x........: mythread_wrapper (hg_intercepts.c:...) ++ ... + + + destroy a barrier that was never initialised +@@ -60,5 +68,5 @@ destroy a barrier that was never initialised + + Thread #x: pthread_barrier_destroy: barrier was never initialised + at 0x........: pthread_barrier_destroy (hg_intercepts.c:...) +- by 0x........: main (bar_bad.c:80) ++ by 0x........: main (bar_bad.c:96) + diff --git a/valgrind-3.11.0-pthread_spin_destroy.patch b/valgrind-3.11.0-pthread_spin_destroy.patch new file mode 100644 index 0000000..1e83e18 --- /dev/null +++ b/valgrind-3.11.0-pthread_spin_destroy.patch @@ -0,0 +1,1244 @@ +commit c69445c1e07425e827ce936d7c416f7972b51aa2 +Author: iraisr +Date: Tue Jan 12 20:31:15 2016 +0000 + + Fix typo in Helgrind's wrapper of pthread_spin_destroy(). + Patch provided by: Jason Dillaman . + Fixes BZ #357871. + + + git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15756 a5019735-40e9-0310-863c-91ae7b9d1cf9 + +diff --git a/helgrind/hg_intercepts.c b/helgrind/hg_intercepts.c +index fd53208..ff36e93 100644 +--- a/helgrind/hg_intercepts.c ++++ b/helgrind/hg_intercepts.c +@@ -1854,13 +1854,13 @@ static int pthread_spin_destroy_WRK(pthread_spinlock_t *lock) + return ret; + } + #if defined(VGO_linux) +- PTH_FUNC(int, pthreadZuspinZusdestroy, // pthread_spin_destroy ++ PTH_FUNC(int, pthreadZuspinZudestroy, // pthread_spin_destroy + pthread_spinlock_t *lock) { + return pthread_spin_destroy_WRK(lock); + } + #elif defined(VGO_darwin) + #elif defined(VGO_solaris) +- PTH_FUNC(int, pthreadZuspinZusdestroy, // pthread_spin_destroy ++ PTH_FUNC(int, pthreadZuspinZudestroy, // pthread_spin_destroy + pthread_spinlock_t *lock) { + return pthread_spin_destroy_WRK(lock); + } +diff --git a/helgrind/tests/tc20_verifywrap.c b/helgrind/tests/tc20_verifywrap.c +index f71c7f8..c110000 100644 +--- a/helgrind/tests/tc20_verifywrap.c ++++ b/helgrind/tests/tc20_verifywrap.c +@@ -29,6 +29,11 @@ + #endif + #endif /* __sun__ */ + ++typedef union { ++ pthread_spinlock_t spinlock; ++ pthread_rwlock_t rwlock; ++} spin_rw_lock; ++ + short unprotected = 0; + + void* lazy_child ( void* v ) { +@@ -236,6 +241,20 @@ int main ( void ) + r= pthread_rwlock_init( &rwl3, NULL ); assert(!r); + r= pthread_rwlock_rdlock( &rwl3 ); assert(!r); + ++ /* --------- pthread_spin_* --------- */ ++ ++ fprintf(stderr, ++ "\n---------------- pthread_spin_* ----------------\n\n"); ++ ++ /* The following sequence verifies correct wrapping of pthread_spin_init() ++ and pthread_spin_destroy(). */ ++ spin_rw_lock srwl1; ++ pthread_spin_init(&srwl1.spinlock, PTHREAD_PROCESS_PRIVATE); ++ pthread_spin_destroy(&srwl1.spinlock); ++ ++ pthread_rwlock_init(&srwl1.rwlock, NULL); ++ pthread_rwlock_destroy(&srwl1.rwlock); ++ + /* ------------- sem_* ------------- */ + + /* This is pretty lame, and duplicates tc18_semabuse.c. */ +diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp b/helgrind/tests/tc20_verifywrap.stderr.exp +index d9019d4..372daea 100644 +--- a/helgrind/tests/tc20_verifywrap.stderr.exp ++++ b/helgrind/tests/tc20_verifywrap.stderr.exp +@@ -14,21 +14,21 @@ Thread #x is the program's root thread + Thread #x was created + ... + by 0x........: pthread_create@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:81) ++ by 0x........: main (tc20_verifywrap.c:86) + + ---------------------------------------------------------------- + + Possible data race during write of size 2 at 0x........ by thread #x + Locks held: none +- at 0x........: main (tc20_verifywrap.c:83) ++ at 0x........: main (tc20_verifywrap.c:88) + + This conflicts with a previous write of size 2 by thread #x + Locks held: none +- at 0x........: racy_child (tc20_verifywrap.c:39) ++ at 0x........: racy_child (tc20_verifywrap.c:44) + by 0x........: mythread_wrapper (hg_intercepts.c:...) + ... + Location 0x........ is 0 bytes inside global var "unprotected" +- declared at tc20_verifywrap.c:32 ++ declared at tc20_verifywrap.c:37 + + ---------------------------------------------------------------- + +@@ -36,7 +36,7 @@ Thread #x's call to pthread_join failed + with error code 35 (EDEADLK: Resource deadlock would occur) + at 0x........: pthread_join_WRK (hg_intercepts.c:...) + by 0x........: pthread_join (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:88) ++ by 0x........: main (tc20_verifywrap.c:93) + + + ---------------- pthread_mutex_lock et al ---------------- +@@ -46,14 +46,14 @@ Thread #x's call to pthread_join failed + Thread #x's call to pthread_mutex_init failed + with error code 95 (EOPNOTSUPP: Operation not supported on transport endpoint) + at 0x........: pthread_mutex_init (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:102) ++ by 0x........: main (tc20_verifywrap.c:107) + + ---------------------------------------------------------------- + + Thread #x: pthread_mutex_destroy of a locked mutex + at 0x........: mutex_destroy_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_destroy (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:112) ++ by 0x........: main (tc20_verifywrap.c:117) + + ---------------------------------------------------------------- + +@@ -61,7 +61,7 @@ Thread #x's call to pthread_mutex_destroy failed + with error code 16 (EBUSY: Device or resource busy) + at 0x........: mutex_destroy_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_destroy (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:112) ++ by 0x........: main (tc20_verifywrap.c:117) + + ---------------------------------------------------------------- + +@@ -69,7 +69,7 @@ Thread #x's call to pthread_mutex_lock failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: mutex_lock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_lock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:118) ++ by 0x........: main (tc20_verifywrap.c:123) + + ---------------------------------------------------------------- + +@@ -77,7 +77,7 @@ Thread #x's call to pthread_mutex_trylock failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: mutex_trylock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_trylock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:126) ++ by 0x........: main (tc20_verifywrap.c:131) + + ---------------------------------------------------------------- + +@@ -85,14 +85,14 @@ Thread #x's call to pthread_mutex_timedlock failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: mutex_timedlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_timedlock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:131) ++ by 0x........: main (tc20_verifywrap.c:136) + + ---------------------------------------------------------------- + + Thread #x unlocked an invalid lock at 0x........ + at 0x........: mutex_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_unlock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:135) ++ by 0x........: main (tc20_verifywrap.c:140) + + ---------------------------------------------------------------- + +@@ -100,7 +100,7 @@ Thread #x's call to pthread_mutex_unlock failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: mutex_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_unlock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:135) ++ by 0x........: main (tc20_verifywrap.c:140) + + + ---------------- pthread_cond_wait et al ---------------- +@@ -110,7 +110,7 @@ Thread #x's call to pthread_mutex_unlock failed + Thread #x: pthread_cond_{timed}wait called with un-held mutex + at 0x........: pthread_cond_wait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_wait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:157) ++ by 0x........: main (tc20_verifywrap.c:162) + + ---------------------------------------------------------------- + +@@ -118,14 +118,14 @@ Thread #x's call to pthread_cond_wait failed + with error code 1 (EPERM: Operation not permitted) + at 0x........: pthread_cond_wait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_wait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:157) ++ by 0x........: main (tc20_verifywrap.c:162) + + ---------------------------------------------------------------- + + Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread + at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:162) ++ by 0x........: main (tc20_verifywrap.c:167) + + + FIXME: can't figure out how to verify wrap of pthread_cond_signal +@@ -135,7 +135,7 @@ FIXME: can't figure out how to verify wrap of pthread_cond_signal + Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread + at 0x........: pthread_cond_broadcast_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_broadcast@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:168) ++ by 0x........: main (tc20_verifywrap.c:173) + + + FIXME: can't figure out how to verify wrap of pthread_broadcast_signal +@@ -145,7 +145,7 @@ FIXME: can't figure out how to verify wrap of pthread_broadcast_signal + Thread #x: pthread_cond_{timed}wait called with un-held mutex + at 0x........: pthread_cond_timedwait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_timedwait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:175) ++ by 0x........: main (tc20_verifywrap.c:180) + + ---------------------------------------------------------------- + +@@ -153,7 +153,7 @@ Thread #x's call to pthread_cond_timedwait failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: pthread_cond_timedwait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_timedwait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:175) ++ by 0x........: main (tc20_verifywrap.c:180) + + + ---------------- pthread_rwlock_* ---------------- +@@ -164,13 +164,13 @@ Thread #x unlocked a not-locked lock at 0x........ + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:189) ++ by 0x........: main (tc20_verifywrap.c:194) + Lock at 0x........ was first observed + at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_init (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:188) ++ by 0x........: main (tc20_verifywrap.c:193) + Location 0x........ is 0 bytes inside local var "rwl" +- declared at tc20_verifywrap.c:52, in frame #x of thread x ++ declared at tc20_verifywrap.c:57, in frame #x of thread x + + + (1) no error on next line +@@ -182,13 +182,13 @@ Thread #x unlocked a not-locked lock at 0x........ + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:206) ++ by 0x........: main (tc20_verifywrap.c:211) + Lock at 0x........ was first observed + at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_init (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:196) ++ by 0x........: main (tc20_verifywrap.c:201) + Location 0x........ is 0 bytes inside local var "rwl2" +- declared at tc20_verifywrap.c:53, in frame #x of thread x ++ declared at tc20_verifywrap.c:58, in frame #x of thread x + + + (4) no error on next line +@@ -202,14 +202,17 @@ Thread #x unlocked a not-locked lock at 0x........ + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:227) ++ by 0x........: main (tc20_verifywrap.c:232) + Lock at 0x........ was first observed + at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_init (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:196) ++ by 0x........: main (tc20_verifywrap.c:201) + Location 0x........ is 0 bytes inside local var "rwl2" +- declared at tc20_verifywrap.c:53, in frame #x of thread x ++ declared at tc20_verifywrap.c:58, in frame #x of thread x ++ ++ + ++---------------- pthread_spin_* ---------------- + + + ---------------- sem_* ---------------- +@@ -220,7 +223,7 @@ Thread #x's call to sem_init failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: sem_init_WRK (hg_intercepts.c:...) + by 0x........: sem_init@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:248) ++ by 0x........: main (tc20_verifywrap.c:267) + + + FIXME: can't figure out how to verify wrap of sem_destroy +@@ -230,7 +233,7 @@ FIXME: can't figure out how to verify wrap of sem_destroy + Thread #x: Bug in libpthread: sem_wait succeeded on semaphore without prior sem_post + at 0x........: sem_wait_WRK (hg_intercepts.c:...) + by 0x........: sem_wait (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:262) ++ by 0x........: main (tc20_verifywrap.c:281) + + ---------------------------------------------------------------- + +@@ -239,7 +242,7 @@ Thread #x's call to sem_post failed + at 0x........: sem_post_WRK (hg_intercepts.c:...) + by 0x........: sem_post (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:265) ++ by 0x........: main (tc20_verifywrap.c:284) + + + FIXME: can't figure out how to verify wrap of sem_post +diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 b/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 +index f109673..b823d40 100644 +--- a/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 ++++ b/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.18 +@@ -14,21 +14,21 @@ Thread #x is the program's root thread + Thread #x was created + ... + by 0x........: pthread_create@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:81) ++ by 0x........: main (tc20_verifywrap.c:86) + + ---------------------------------------------------------------- + + Possible data race during write of size 2 at 0x........ by thread #x + Locks held: none +- at 0x........: main (tc20_verifywrap.c:83) ++ at 0x........: main (tc20_verifywrap.c:88) + + This conflicts with a previous write of size 2 by thread #x + Locks held: none +- at 0x........: racy_child (tc20_verifywrap.c:39) ++ at 0x........: racy_child (tc20_verifywrap.c:44) + by 0x........: mythread_wrapper (hg_intercepts.c:...) + ... + Location 0x........ is 0 bytes inside global var "unprotected" +- declared at tc20_verifywrap.c:32 ++ declared at tc20_verifywrap.c:37 + + ---------------------------------------------------------------- + +@@ -36,7 +36,7 @@ Thread #x's call to pthread_join failed + with error code 35 (EDEADLK: Resource deadlock would occur) + at 0x........: pthread_join_WRK (hg_intercepts.c:...) + by 0x........: pthread_join (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:88) ++ by 0x........: main (tc20_verifywrap.c:93) + + + ---------------- pthread_mutex_lock et al ---------------- +@@ -46,14 +46,14 @@ Thread #x's call to pthread_join failed + Thread #x's call to pthread_mutex_init failed + with error code 95 (EOPNOTSUPP: Operation not supported on transport endpoint) + at 0x........: pthread_mutex_init (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:102) ++ by 0x........: main (tc20_verifywrap.c:107) + + ---------------------------------------------------------------- + + Thread #x: pthread_mutex_destroy of a locked mutex + at 0x........: mutex_destroy_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_destroy (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:112) ++ by 0x........: main (tc20_verifywrap.c:117) + + ---------------------------------------------------------------- + +@@ -61,7 +61,7 @@ Thread #x's call to pthread_mutex_lock failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: mutex_lock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_lock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:118) ++ by 0x........: main (tc20_verifywrap.c:123) + + ---------------------------------------------------------------- + +@@ -69,7 +69,7 @@ Thread #x's call to pthread_mutex_trylock failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: mutex_trylock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_trylock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:126) ++ by 0x........: main (tc20_verifywrap.c:131) + + ---------------------------------------------------------------- + +@@ -77,14 +77,14 @@ Thread #x's call to pthread_mutex_timedlock failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: mutex_timedlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_timedlock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:131) ++ by 0x........: main (tc20_verifywrap.c:136) + + ---------------------------------------------------------------- + + Thread #x unlocked an invalid lock at 0x........ + at 0x........: mutex_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_unlock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:135) ++ by 0x........: main (tc20_verifywrap.c:140) + + ---------------------------------------------------------------- + +@@ -92,7 +92,7 @@ Thread #x's call to pthread_mutex_unlock failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: mutex_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_unlock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:135) ++ by 0x........: main (tc20_verifywrap.c:140) + + + ---------------- pthread_cond_wait et al ---------------- +@@ -102,7 +102,7 @@ Thread #x's call to pthread_mutex_unlock failed + Thread #x: pthread_cond_{timed}wait called with un-held mutex + at 0x........: pthread_cond_wait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_wait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:157) ++ by 0x........: main (tc20_verifywrap.c:162) + + ---------------------------------------------------------------- + +@@ -110,14 +110,14 @@ Thread #x's call to pthread_cond_wait failed + with error code 1 (EPERM: Operation not permitted) + at 0x........: pthread_cond_wait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_wait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:157) ++ by 0x........: main (tc20_verifywrap.c:162) + + ---------------------------------------------------------------- + + Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread + at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:162) ++ by 0x........: main (tc20_verifywrap.c:167) + + + FIXME: can't figure out how to verify wrap of pthread_cond_signal +@@ -127,7 +127,7 @@ FIXME: can't figure out how to verify wrap of pthread_cond_signal + Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread + at 0x........: pthread_cond_broadcast_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_broadcast@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:168) ++ by 0x........: main (tc20_verifywrap.c:173) + + + FIXME: can't figure out how to verify wrap of pthread_broadcast_signal +@@ -137,7 +137,7 @@ FIXME: can't figure out how to verify wrap of pthread_broadcast_signal + Thread #x: pthread_cond_{timed}wait called with un-held mutex + at 0x........: pthread_cond_timedwait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_timedwait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:175) ++ by 0x........: main (tc20_verifywrap.c:180) + + ---------------------------------------------------------------- + +@@ -145,7 +145,7 @@ Thread #x's call to pthread_cond_timedwait failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: pthread_cond_timedwait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_timedwait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:175) ++ by 0x........: main (tc20_verifywrap.c:180) + + + ---------------- pthread_rwlock_* ---------------- +@@ -156,11 +156,11 @@ Thread #x unlocked a not-locked lock at 0x........ + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:189) ++ by 0x........: main (tc20_verifywrap.c:194) + Lock at 0x........ was first observed + at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_init (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:188) ++ by 0x........: main (tc20_verifywrap.c:193) + + (1) no error on next line + (2) no error on next line +@@ -171,11 +171,11 @@ Thread #x unlocked a not-locked lock at 0x........ + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:206) ++ by 0x........: main (tc20_verifywrap.c:211) + Lock at 0x........ was first observed + at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_init (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:196) ++ by 0x........: main (tc20_verifywrap.c:201) + + (4) no error on next line + (5) no error on next line +@@ -187,11 +187,15 @@ Thread #x unlocked a not-locked lock at 0x........ + Thread #x unlocked a not-locked lock at 0x........ + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:227) ++ by 0x........: main (tc20_verifywrap.c:232) + Lock at 0x........ was first observed + at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_init (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:196) ++ by 0x........: main (tc20_verifywrap.c:201) ++ ++ ++ ++---------------- pthread_spin_* ---------------- + + + ---------------- sem_* ---------------- +@@ -202,7 +206,7 @@ Thread #x's call to sem_init failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: sem_init_WRK (hg_intercepts.c:...) + by 0x........: sem_init@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:243) ++ by 0x........: main (tc20_verifywrap.c:267) + + + FIXME: can't figure out how to verify wrap of sem_destroy +@@ -212,7 +216,7 @@ FIXME: can't figure out how to verify wrap of sem_destroy + Thread #x: Bug in libpthread: sem_wait succeeded on semaphore without prior sem_post + at 0x........: sem_wait_WRK (hg_intercepts.c:...) + by 0x........: sem_wait (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:257) ++ by 0x........: main (tc20_verifywrap.c:281) + + ---------------------------------------------------------------- + +@@ -220,7 +224,7 @@ Thread #x's call to sem_post failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: sem_post_WRK (hg_intercepts.c:...) + by 0x........: sem_post (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:260) ++ by 0x........: main (tc20_verifywrap.c:284) + + + FIXME: can't figure out how to verify wrap of sem_post +diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.21 b/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.21 +index 7f4eb21..2a2ee9b 100644 +--- a/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.21 ++++ b/helgrind/tests/tc20_verifywrap.stderr.exp-glibc-2.21 +@@ -14,21 +14,21 @@ Thread #x is the program's root thread + Thread #x was created + ... + by 0x........: pthread_create@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:81) ++ by 0x........: main (tc20_verifywrap.c:86) + + ---------------------------------------------------------------- + + Possible data race during write of size 2 at 0x........ by thread #x + Locks held: none +- at 0x........: main (tc20_verifywrap.c:83) ++ at 0x........: main (tc20_verifywrap.c:88) + + This conflicts with a previous write of size 2 by thread #x + Locks held: none +- at 0x........: racy_child (tc20_verifywrap.c:39) ++ at 0x........: racy_child (tc20_verifywrap.c:44) + by 0x........: mythread_wrapper (hg_intercepts.c:...) + ... + Location 0x........ is 0 bytes inside global var "unprotected" +- declared at tc20_verifywrap.c:32 ++ declared at tc20_verifywrap.c:37 + + ---------------------------------------------------------------- + +@@ -36,7 +36,7 @@ Thread #x's call to pthread_join failed + with error code 35 (EDEADLK: Resource deadlock would occur) + at 0x........: pthread_join_WRK (hg_intercepts.c:...) + by 0x........: pthread_join (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:88) ++ by 0x........: main (tc20_verifywrap.c:93) + + + ---------------- pthread_mutex_lock et al ---------------- +@@ -46,14 +46,14 @@ Thread #x's call to pthread_join failed + Thread #x's call to pthread_mutex_init failed + with error code 95 (EOPNOTSUPP: Operation not supported on transport endpoint) + at 0x........: pthread_mutex_init (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:102) ++ by 0x........: main (tc20_verifywrap.c:107) + + ---------------------------------------------------------------- + + Thread #x: pthread_mutex_destroy of a locked mutex + at 0x........: mutex_destroy_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_destroy (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:112) ++ by 0x........: main (tc20_verifywrap.c:117) + + ---------------------------------------------------------------- + +@@ -61,7 +61,7 @@ Thread #x's call to pthread_mutex_destroy failed + with error code 16 (EBUSY: Device or resource busy) + at 0x........: mutex_destroy_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_destroy (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:112) ++ by 0x........: main (tc20_verifywrap.c:117) + + ---------------------------------------------------------------- + +@@ -69,7 +69,7 @@ Thread #x's call to pthread_mutex_lock failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: mutex_lock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_lock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:118) ++ by 0x........: main (tc20_verifywrap.c:123) + + ---------------------------------------------------------------- + +@@ -77,7 +77,7 @@ Thread #x's call to pthread_mutex_trylock failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: mutex_trylock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_trylock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:126) ++ by 0x........: main (tc20_verifywrap.c:131) + + ---------------------------------------------------------------- + +@@ -85,14 +85,14 @@ Thread #x's call to pthread_mutex_timedlock failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: mutex_timedlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_timedlock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:131) ++ by 0x........: main (tc20_verifywrap.c:136) + + ---------------------------------------------------------------- + + Thread #x unlocked an invalid lock at 0x........ + at 0x........: mutex_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_unlock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:135) ++ by 0x........: main (tc20_verifywrap.c:140) + + ---------------------------------------------------------------- + +@@ -100,7 +100,7 @@ Thread #x's call to pthread_mutex_unlock failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: mutex_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_unlock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:135) ++ by 0x........: main (tc20_verifywrap.c:140) + + + ---------------- pthread_cond_wait et al ---------------- +@@ -110,7 +110,7 @@ Thread #x's call to pthread_mutex_unlock failed + Thread #x: pthread_cond_{timed}wait called with un-held mutex + at 0x........: pthread_cond_wait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_wait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:157) ++ by 0x........: main (tc20_verifywrap.c:162) + + ---------------------------------------------------------------- + +@@ -118,14 +118,14 @@ Thread #x's call to pthread_cond_wait failed + with error code 1 (EPERM: Operation not permitted) + at 0x........: pthread_cond_wait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_wait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:157) ++ by 0x........: main (tc20_verifywrap.c:162) + + ---------------------------------------------------------------- + + Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread + at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:162) ++ by 0x........: main (tc20_verifywrap.c:167) + + + FIXME: can't figure out how to verify wrap of pthread_cond_signal +@@ -135,7 +135,7 @@ FIXME: can't figure out how to verify wrap of pthread_cond_signal + Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread + at 0x........: pthread_cond_broadcast_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_broadcast@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:168) ++ by 0x........: main (tc20_verifywrap.c:173) + + + FIXME: can't figure out how to verify wrap of pthread_broadcast_signal +@@ -145,7 +145,7 @@ FIXME: can't figure out how to verify wrap of pthread_broadcast_signal + Thread #x: pthread_cond_{timed}wait called with un-held mutex + at 0x........: pthread_cond_timedwait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_timedwait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:175) ++ by 0x........: main (tc20_verifywrap.c:180) + + ---------------------------------------------------------------- + +@@ -153,7 +153,7 @@ Thread #x's call to pthread_cond_timedwait failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: pthread_cond_timedwait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_timedwait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:175) ++ by 0x........: main (tc20_verifywrap.c:180) + + + ---------------- pthread_rwlock_* ---------------- +@@ -164,13 +164,13 @@ Thread #x unlocked a not-locked lock at 0x........ + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:189) ++ by 0x........: main (tc20_verifywrap.c:194) + Lock at 0x........ was first observed + at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_init (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:188) ++ by 0x........: main (tc20_verifywrap.c:193) + Location 0x........ is 0 bytes inside local var "rwl" +- declared at tc20_verifywrap.c:52, in frame #x of thread x ++ declared at tc20_verifywrap.c:57, in frame #x of thread x + + + (1) no error on next line +@@ -182,13 +182,13 @@ Thread #x unlocked a not-locked lock at 0x........ + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:206) ++ by 0x........: main (tc20_verifywrap.c:211) + Lock at 0x........ was first observed + at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_init (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:196) ++ by 0x........: main (tc20_verifywrap.c:201) + Location 0x........ is 0 bytes inside local var "rwl2" +- declared at tc20_verifywrap.c:53, in frame #x of thread x ++ declared at tc20_verifywrap.c:58, in frame #x of thread x + + + (4) no error on next line +@@ -202,14 +202,17 @@ Thread #x unlocked a not-locked lock at 0x........ + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:227) ++ by 0x........: main (tc20_verifywrap.c:232) + Lock at 0x........ was first observed + at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_init (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:196) ++ by 0x........: main (tc20_verifywrap.c:201) + Location 0x........ is 0 bytes inside local var "rwl2" +- declared at tc20_verifywrap.c:53, in frame #x of thread x ++ declared at tc20_verifywrap.c:58, in frame #x of thread x ++ ++ + ++---------------- pthread_spin_* ---------------- + + + ---------------- sem_* ---------------- +@@ -220,7 +223,7 @@ Thread #x's call to sem_init failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: sem_init_WRK (hg_intercepts.c:...) + by 0x........: sem_init@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:248) ++ by 0x........: main (tc20_verifywrap.c:267) + + + FIXME: can't figure out how to verify wrap of sem_destroy +@@ -230,7 +233,7 @@ FIXME: can't figure out how to verify wrap of sem_destroy + Thread #x: Bug in libpthread: sem_wait succeeded on semaphore without prior sem_post + at 0x........: sem_wait_WRK (hg_intercepts.c:...) + by 0x........: sem_wait (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:262) ++ by 0x........: main (tc20_verifywrap.c:281) + + + FIXME: can't figure out how to verify wrap of sem_post +diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-s390x b/helgrind/tests/tc20_verifywrap.stderr.exp-s390x +index 3f60f79..f19215e 100644 +--- a/helgrind/tests/tc20_verifywrap.stderr.exp-s390x ++++ b/helgrind/tests/tc20_verifywrap.stderr.exp-s390x +@@ -15,22 +15,22 @@ Thread #x was created + ... + by 0x........: pthread_create_WRK (hg_intercepts.c:...) + by 0x........: pthread_create@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:81) ++ by 0x........: main (tc20_verifywrap.c:86) + + ---------------------------------------------------------------- + + Possible data race during write of size 2 at 0x........ by thread #x + Locks held: none +- at 0x........: main (tc20_verifywrap.c:83) ++ at 0x........: main (tc20_verifywrap.c:88) + + This conflicts with a previous write of size 2 by thread #x + Locks held: none +- at 0x........: racy_child (tc20_verifywrap.c:39) ++ at 0x........: racy_child (tc20_verifywrap.c:44) + by 0x........: mythread_wrapper (hg_intercepts.c:...) + ... + + Location 0x........ is 0 bytes inside global var "unprotected" +-declared at tc20_verifywrap.c:32 ++declared at tc20_verifywrap.c:37 + + ---------------------------------------------------------------- + +@@ -38,7 +38,7 @@ Thread #x's call to pthread_join failed + with error code 35 (EDEADLK: Resource deadlock would occur) + at 0x........: pthread_join_WRK (hg_intercepts.c:...) + by 0x........: pthread_join (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:88) ++ by 0x........: main (tc20_verifywrap.c:93) + + + ---------------- pthread_mutex_lock et al ---------------- +@@ -48,14 +48,14 @@ Thread #x's call to pthread_join failed + Thread #x's call to pthread_mutex_init failed + with error code 95 (EOPNOTSUPP: Operation not supported on transport endpoint) + at 0x........: pthread_mutex_init (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:102) ++ by 0x........: main (tc20_verifywrap.c:107) + + ---------------------------------------------------------------- + + Thread #x: pthread_mutex_destroy of a locked mutex + at 0x........: mutex_destroy_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_destroy (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:112) ++ by 0x........: main (tc20_verifywrap.c:117) + + ---------------------------------------------------------------- + +@@ -63,7 +63,7 @@ Thread #x's call to pthread_mutex_destroy failed + with error code 16 (EBUSY: Device or resource busy) + at 0x........: mutex_destroy_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_destroy (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:112) ++ by 0x........: main (tc20_verifywrap.c:117) + + ---------------------------------------------------------------- + +@@ -71,7 +71,7 @@ Thread #x's call to pthread_mutex_lock failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: mutex_lock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_lock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:118) ++ by 0x........: main (tc20_verifywrap.c:123) + + ---------------------------------------------------------------- + +@@ -79,7 +79,7 @@ Thread #x's call to pthread_mutex_trylock failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: mutex_trylock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_trylock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:126) ++ by 0x........: main (tc20_verifywrap.c:131) + + ---------------------------------------------------------------- + +@@ -87,14 +87,14 @@ Thread #x's call to pthread_mutex_timedlock failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: mutex_timedlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_timedlock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:131) ++ by 0x........: main (tc20_verifywrap.c:136) + + ---------------------------------------------------------------- + + Thread #x unlocked an invalid lock at 0x........ + at 0x........: mutex_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_unlock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:135) ++ by 0x........: main (tc20_verifywrap.c:140) + + ---------------------------------------------------------------- + +@@ -102,7 +102,7 @@ Thread #x's call to pthread_mutex_unlock failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: mutex_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_unlock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:135) ++ by 0x........: main (tc20_verifywrap.c:140) + + + ---------------- pthread_cond_wait et al ---------------- +@@ -112,7 +112,7 @@ Thread #x's call to pthread_mutex_unlock failed + Thread #x: pthread_cond_{timed}wait called with un-held mutex + at 0x........: pthread_cond_wait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_wait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:157) ++ by 0x........: main (tc20_verifywrap.c:162) + + ---------------------------------------------------------------- + +@@ -120,14 +120,14 @@ Thread #x's call to pthread_cond_wait failed + with error code 1 (EPERM: Operation not permitted) + at 0x........: pthread_cond_wait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_wait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:157) ++ by 0x........: main (tc20_verifywrap.c:162) + + ---------------------------------------------------------------- + + Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread + at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:162) ++ by 0x........: main (tc20_verifywrap.c:167) + + + FIXME: can't figure out how to verify wrap of pthread_cond_signal +@@ -137,7 +137,7 @@ FIXME: can't figure out how to verify wrap of pthread_cond_signal + Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread + at 0x........: pthread_cond_broadcast_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_broadcast@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:168) ++ by 0x........: main (tc20_verifywrap.c:173) + + + FIXME: can't figure out how to verify wrap of pthread_broadcast_signal +@@ -147,7 +147,7 @@ FIXME: can't figure out how to verify wrap of pthread_broadcast_signal + Thread #x: pthread_cond_{timed}wait called with un-held mutex + at 0x........: pthread_cond_timedwait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_timedwait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:175) ++ by 0x........: main (tc20_verifywrap.c:180) + + ---------------------------------------------------------------- + +@@ -155,7 +155,7 @@ Thread #x's call to pthread_cond_timedwait failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: pthread_cond_timedwait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_timedwait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:175) ++ by 0x........: main (tc20_verifywrap.c:180) + + + ---------------- pthread_rwlock_* ---------------- +@@ -166,11 +166,11 @@ Thread #x unlocked a not-locked lock at 0x........ + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:189) ++ by 0x........: main (tc20_verifywrap.c:194) + Lock at 0x........ was first observed + at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_init (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:188) ++ by 0x........: main (tc20_verifywrap.c:193) + + (1) no error on next line + (2) no error on next line +@@ -181,11 +181,11 @@ Thread #x unlocked a not-locked lock at 0x........ + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:206) ++ by 0x........: main (tc20_verifywrap.c:211) + Lock at 0x........ was first observed + at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_init (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:196) ++ by 0x........: main (tc20_verifywrap.c:201) + + (4) no error on next line + (5) no error on next line +@@ -198,11 +198,15 @@ Thread #x unlocked a not-locked lock at 0x........ + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:227) ++ by 0x........: main (tc20_verifywrap.c:232) + Lock at 0x........ was first observed + at 0x........: pthread_rwlock_init_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_init (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:196) ++ by 0x........: main (tc20_verifywrap.c:201) ++ ++ ++ ++---------------- pthread_spin_* ---------------- + + + ---------------- sem_* ---------------- +@@ -213,7 +217,7 @@ Thread #x's call to sem_init failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: sem_init_WRK (hg_intercepts.c:...) + by 0x........: sem_init@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:243) ++ by 0x........: main (tc20_verifywrap.c:267) + + + FIXME: can't figure out how to verify wrap of sem_destroy +@@ -223,7 +227,7 @@ FIXME: can't figure out how to verify wrap of sem_destroy + Thread #x: Bug in libpthread: sem_wait succeeded on semaphore without prior sem_post + at 0x........: sem_wait_WRK (hg_intercepts.c:...) + by 0x........: sem_wait (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:257) ++ by 0x........: main (tc20_verifywrap.c:281) + + + FIXME: can't figure out how to verify wrap of sem_post +diff --git a/helgrind/tests/tc20_verifywrap.stderr.exp-solaris b/helgrind/tests/tc20_verifywrap.stderr.exp-solaris +index 921ebf5..072cc18 100644 +--- a/helgrind/tests/tc20_verifywrap.stderr.exp-solaris ++++ b/helgrind/tests/tc20_verifywrap.stderr.exp-solaris +@@ -14,21 +14,21 @@ Thread #x is the program's root thread + Thread #x was created + ... + by 0x........: pthread_create@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:81) ++ by 0x........: main (tc20_verifywrap.c:86) + + ---------------------------------------------------------------- + + Possible data race during write of size 2 at 0x........ by thread #x + Locks held: none +- at 0x........: main (tc20_verifywrap.c:83) ++ at 0x........: main (tc20_verifywrap.c:88) + + This conflicts with a previous write of size 2 by thread #x + Locks held: none +- at 0x........: racy_child (tc20_verifywrap.c:39) ++ at 0x........: racy_child (tc20_verifywrap.c:44) + by 0x........: mythread_wrapper (hg_intercepts.c:...) + ... + Location 0x........ is 0 bytes inside global var "unprotected" +- declared at tc20_verifywrap.c:32 ++ declared at tc20_verifywrap.c:37 + + ---------------------------------------------------------------- + +@@ -36,7 +36,7 @@ Thread #x's call to pthread_join failed + with error code 45 (EDEADLK: Resource deadlock would occur) + at 0x........: pthread_join_WRK (hg_intercepts.c:...) + by 0x........: pthread_join (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:88) ++ by 0x........: main (tc20_verifywrap.c:93) + + + ---------------- pthread_mutex_lock et al ---------------- +@@ -46,14 +46,14 @@ Thread #x's call to pthread_join failed + Thread #x's call to mutex_init failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: pthread_mutex_init (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:102) ++ by 0x........: main (tc20_verifywrap.c:107) + + ---------------------------------------------------------------- + + Thread #x: pthread_mutex_destroy of a locked mutex + at 0x........: mutex_destroy_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_destroy (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:112) ++ by 0x........: main (tc20_verifywrap.c:117) + + ---------------------------------------------------------------- + +@@ -61,7 +61,7 @@ Thread #x's call to pthread_mutex_lock failed + with error code 1 (EPERM: Operation not permitted) + at 0x........: mutex_lock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_lock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:118) ++ by 0x........: main (tc20_verifywrap.c:123) + + ---------------------------------------------------------------- + +@@ -69,7 +69,7 @@ Thread #x's call to pthread_mutex_trylock failed + with error code 1 (EPERM: Operation not permitted) + at 0x........: mutex_trylock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_trylock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:126) ++ by 0x........: main (tc20_verifywrap.c:131) + + ---------------------------------------------------------------- + +@@ -77,14 +77,14 @@ Thread #x's call to pthread_mutex_timedlock failed + with error code 1 (EPERM: Operation not permitted) + at 0x........: mutex_timedlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_timedlock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:131) ++ by 0x........: main (tc20_verifywrap.c:136) + + ---------------------------------------------------------------- + + Thread #x unlocked an invalid lock at 0x........ + at 0x........: mutex_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_unlock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:135) ++ by 0x........: main (tc20_verifywrap.c:140) + + ---------------------------------------------------------------- + +@@ -92,7 +92,7 @@ Thread #x's call to pthread_mutex_unlock failed + with error code 1 (EPERM: Operation not permitted) + at 0x........: mutex_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_mutex_unlock (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:135) ++ by 0x........: main (tc20_verifywrap.c:140) + + + ---------------- pthread_cond_wait et al ---------------- +@@ -102,7 +102,7 @@ Thread #x's call to pthread_mutex_unlock failed + Thread #x: pthread_cond_{timed}wait called with un-held mutex + at 0x........: pthread_cond_wait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_wait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:157) ++ by 0x........: main (tc20_verifywrap.c:162) + + ---------------------------------------------------------------- + +@@ -110,14 +110,14 @@ Thread #x's call to pthread_cond_wait failed + with error code 1 (EPERM: Operation not permitted) + at 0x........: pthread_cond_wait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_wait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:157) ++ by 0x........: main (tc20_verifywrap.c:162) + + ---------------------------------------------------------------- + + Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread + at 0x........: pthread_cond_signal_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_signal@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:162) ++ by 0x........: main (tc20_verifywrap.c:167) + + + FIXME: can't figure out how to verify wrap of pthread_cond_signal +@@ -127,7 +127,7 @@ FIXME: can't figure out how to verify wrap of pthread_cond_signal + Thread #x: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread + at 0x........: pthread_cond_broadcast_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_broadcast@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:168) ++ by 0x........: main (tc20_verifywrap.c:173) + + + FIXME: can't figure out how to verify wrap of pthread_broadcast_signal +@@ -137,7 +137,7 @@ FIXME: can't figure out how to verify wrap of pthread_broadcast_signal + Thread #x: pthread_cond_{timed}wait called with un-held mutex + at 0x........: pthread_cond_timedwait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_timedwait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:175) ++ by 0x........: main (tc20_verifywrap.c:180) + + ---------------------------------------------------------------- + +@@ -145,7 +145,7 @@ Thread #x's call to pthread_cond_timedwait failed + with error code 1 (EPERM: Operation not permitted) + at 0x........: pthread_cond_timedwait_WRK (hg_intercepts.c:...) + by 0x........: pthread_cond_timedwait@* (hg_intercepts.c:...) +- by 0x........: main (tc20_verifywrap.c:175) ++ by 0x........: main (tc20_verifywrap.c:180) + + + ---------------- pthread_rwlock_* ---------------- +@@ -156,13 +156,13 @@ Thread #x unlocked a not-locked lock at 0x........ + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:189) ++ by 0x........: main (tc20_verifywrap.c:194) + Lock at 0x........ was first observed + at 0x........: pthread_rwlock_init (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:188) ++ by 0x........: main (tc20_verifywrap.c:193) + Location 0x........ is 0 bytes inside rwl.__pthread_rwlock_readers, +- declared at tc20_verifywrap.c:52, in frame #x of thread x ++ declared at tc20_verifywrap.c:57, in frame #x of thread x + + + ---------------------------------------------------------------- +@@ -172,7 +172,7 @@ Thread #x's call to pthread_rwlock_unlock failed + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:189) ++ by 0x........: main (tc20_verifywrap.c:194) + + (1) no error on next line + (2) no error on next line +@@ -183,13 +183,13 @@ Thread #x unlocked a not-locked lock at 0x........ + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:206) ++ by 0x........: main (tc20_verifywrap.c:211) + Lock at 0x........ was first observed + at 0x........: pthread_rwlock_init (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:196) ++ by 0x........: main (tc20_verifywrap.c:201) + Location 0x........ is 0 bytes inside rwl2.__pthread_rwlock_readers, +- declared at tc20_verifywrap.c:53, in frame #x of thread x ++ declared at tc20_verifywrap.c:58, in frame #x of thread x + + + ---------------------------------------------------------------- +@@ -199,7 +199,7 @@ Thread #x's call to pthread_rwlock_unlock failed + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:206) ++ by 0x........: main (tc20_verifywrap.c:211) + + (4) no error on next line + (5) no error on next line +@@ -212,13 +212,13 @@ Thread #x unlocked a not-locked lock at 0x........ + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:227) ++ by 0x........: main (tc20_verifywrap.c:232) + Lock at 0x........ was first observed + at 0x........: pthread_rwlock_init (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:196) ++ by 0x........: main (tc20_verifywrap.c:201) + Location 0x........ is 0 bytes inside rwl2.__pthread_rwlock_readers, +- declared at tc20_verifywrap.c:53, in frame #x of thread x ++ declared at tc20_verifywrap.c:58, in frame #x of thread x + + + ---------------------------------------------------------------- +@@ -228,7 +228,11 @@ Thread #x's call to pthread_rwlock_unlock failed + at 0x........: pthread_rwlock_unlock_WRK (hg_intercepts.c:...) + by 0x........: pthread_rwlock_unlock (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:227) ++ by 0x........: main (tc20_verifywrap.c:232) ++ ++ ++ ++---------------- pthread_spin_* ---------------- + + + ---------------- sem_* ---------------- +@@ -239,7 +243,7 @@ Thread #x's call to sema_init failed + with error code 22 (EINVAL: Invalid argument) + at 0x........: sema_init (hg_intercepts.c:...) + ... +- by 0x........: main (tc20_verifywrap.c:248) ++ by 0x........: main (tc20_verifywrap.c:267) + + + FIXME: can't figure out how to verify wrap of sem_destroy diff --git a/valgrind-3.11.0-rexw-cvtps2pd.patch b/valgrind-3.11.0-rexw-cvtps2pd.patch new file mode 100644 index 0000000..12cef42 --- /dev/null +++ b/valgrind-3.11.0-rexw-cvtps2pd.patch @@ -0,0 +1,76 @@ +diff --git a/VEX/priv/guest_amd64_toIR.c b/VEX/priv/guest_amd64_toIR.c +index 98596d2..06552e8 100644 +--- a/VEX/priv/guest_amd64_toIR.c ++++ b/VEX/priv/guest_amd64_toIR.c +@@ -13396,7 +13396,8 @@ Long dis_ESC_0F__SSE2 ( Bool* decode_OK, + case 0x5A: + /* 0F 5A = CVTPS2PD -- convert 2 x F32 in low half mem/xmm to 2 x + F64 in xmm(G). */ +- if (haveNo66noF2noF3(pfx) && sz == 4) { ++ if (haveNo66noF2noF3(pfx) ++ && (sz == 4 || /* ignore redundant REX.W */ sz == 8)) { + delta = dis_CVTPS2PD_128( vbi, pfx, delta, False/*!isAvx*/ ); + goto decode_success; + } +diff --git a/none/tests/amd64/redundantRexW.c b/none/tests/amd64/redundantRexW.c +index e189267..0a50c3b 100644 +--- a/none/tests/amd64/redundantRexW.c ++++ b/none/tests/amd64/redundantRexW.c +@@ -596,6 +596,23 @@ int main ( void ) + after_test( "rex.WB subsd -0x8(%r13),%xmm1", regs, mem ); + } + ++ /* cvtps2pd mem, reg 48 0f 5a 07 rex.W cvtps2pd (%rdi),%xmm0 */ ++ { ++ before_test( regs, mem ); ++ __asm__ __volatile__( ++ "movq %0, %%r14\n" ++ "\tmovq %1, %%r15\n" ++ LOAD_XMMREGS_from_r14 ++ "\tmovq %%r15, %%rdi\n" ++ "\t.byte 0x48,0x0f,0x5a,0x07\n" ++ SAVE_XMMREGS_to_r14 ++ : /*out*/ : /*in*/ "r"(regs), "r"( -0 + (char*)&mem->dqw[2] ) ++ : /*trash*/ "r14","r15","memory", XMMREGS, ++ "rdi" ++ ); ++ after_test( "rex.W cvtps2pd (%rdi),%xmm0", regs, mem ); ++ } ++ + free(regs); + free(mem); + return 0; +diff --git a/none/tests/amd64/redundantRexW.stdout.exp b/none/tests/amd64/redundantRexW.stdout.exp +index dd1697a..94b255a 100644 +--- a/none/tests/amd64/redundantRexW.stdout.exp ++++ b/none/tests/amd64/redundantRexW.stdout.exp +@@ -648,3 +648,29 @@ after "rex.WB subsd -0x8(%r13),%xmm1" (xmms in order [15..0]) { + %xmm15 ................................ + } + ++after "rex.W cvtps2pd (%rdi),%xmm0" (dqws in order [15 .. 0]) { ++ [0] ................................ ++ [1] ................................ ++ [2] ................................ ++ [3] ................................ ++ [4] ................................ ++} ++after "rex.W cvtps2pd (%rdi),%xmm0" (xmms in order [15..0]) { ++ %xmm 0 113a1c7d5554535213bd9cffd4535251 ++ %xmm 1 ................................ ++ %xmm 2 ................................ ++ %xmm 3 ................................ ++ %xmm 4 ................................ ++ %xmm 5 ................................ ++ %xmm 6 ................................ ++ %xmm 7 ................................ ++ %xmm 8 ................................ ++ %xmm 9 ................................ ++ %xmm10 ................................ ++ %xmm11 ................................ ++ %xmm12 ................................ ++ %xmm13 ................................ ++ %xmm14 ................................ ++ %xmm15 ................................ ++} ++ diff --git a/valgrind-3.11.0-rlimit_data.patch b/valgrind-3.11.0-rlimit_data.patch new file mode 100644 index 0000000..8c1c1fd --- /dev/null +++ b/valgrind-3.11.0-rlimit_data.patch @@ -0,0 +1,116 @@ +diff --git a/coregrind/m_libcproc.c b/coregrind/m_libcproc.c +index f314b55..a30f7dc 100644 +--- a/coregrind/m_libcproc.c ++++ b/coregrind/m_libcproc.c +@@ -450,9 +450,6 @@ void VG_(execv) ( const HChar* filename, const HChar** argv ) + HChar** envp; + SysRes res; + +- /* restore the DATA rlimit for the child */ +- VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data)); +- + envp = VG_(env_clone)(VG_(client_envp)); + VG_(env_remove_valgrind_env_stuff)( envp, True /*ro_strings*/, NULL ); + +@@ -511,17 +508,9 @@ Int VG_(spawn) ( const HChar *filename, const HChar **argv ) + # undef COPY_CHAR_TO_ARGENV + # undef COPY_STRING_TOARGENV + +- /* HACK: Temporarily restore the DATA rlimit for spawned child. */ +- VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data)); +- + SysRes res = VG_(do_syscall5)(__NR_spawn, (UWord) filename, (UWord) NULL, 0, + (UWord) argenv, argenv_size); + +- /* Restore DATA rlimit back to its previous value set in m_main.c. */ +- struct vki_rlimit zero = { 0, 0 }; +- zero.rlim_max = VG_(client_rlimit_data).rlim_max; +- VG_(setrlimit)(VKI_RLIMIT_DATA, &zero); +- + VG_(free)(argenv); + for (HChar **p = envp; *p != NULL; p++) { + VG_(free)(*p); +diff --git a/coregrind/m_main.c b/coregrind/m_main.c +index 1821c94..9b659ae 100644 +--- a/coregrind/m_main.c ++++ b/coregrind/m_main.c +@@ -1627,7 +1627,6 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) + Bool logging_to_fd = False; + const HChar* xml_fname_unexpanded = NULL; + Int loglevel, i; +- struct vki_rlimit zero = { 0, 0 }; + XArray* addr2dihandle = NULL; + + //============================================================ +@@ -1800,13 +1799,15 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) + VG_(debugLog)(1, "main", "... %s\n", VG_(name_of_launcher)); + + //-------------------------------------------------------------- +- // Get the current process datasize rlimit, and set it to zero. +- // This prevents any internal uses of brk() from having any effect. +- // We remember the old value so we can restore it on exec, so that +- // child processes will have a reasonable brk value. ++ // We used to set the process datasize rlimit to zero to prevent ++ // any internal use of brk() from having any effect. But later ++ // linux kernels redefine RLIMIT_DATA as the size of any data ++ // areas, including some dynamic mmap memory allocations. ++ // See bug #357833 for the commit that went into linux 4.5 ++ // changing the definition of RLIMIT_DATA. So don't mess with ++ // RLIMIT_DATA here now anymore. Just remember it for use in ++ // the syscall wrappers. + VG_(getrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data)); +- zero.rlim_max = VG_(client_rlimit_data).rlim_max; +- VG_(setrlimit)(VKI_RLIMIT_DATA, &zero); + + // Get the current process stack rlimit. + VG_(getrlimit)(VKI_RLIMIT_STACK, &VG_(client_rlimit_stack)); +diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c +index aa60d67..061c1e1 100644 +--- a/coregrind/m_syswrap/syswrap-generic.c ++++ b/coregrind/m_syswrap/syswrap-generic.c +@@ -3014,9 +3014,6 @@ PRE(sys_execve) + vg_assert(j == tot_args+1); + } + +- /* restore the DATA rlimit for the child */ +- VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data)); +- + /* + Set the signal state up for exec. + +diff --git a/coregrind/m_syswrap/syswrap-solaris.c b/coregrind/m_syswrap/syswrap-solaris.c +index 4e2662c..c700b59 100644 +--- a/coregrind/m_syswrap/syswrap-solaris.c ++++ b/coregrind/m_syswrap/syswrap-solaris.c +@@ -1589,21 +1589,12 @@ PRE(sys_spawn) + #undef COPY_CHAR_TO_ARGENV + #undef COPY_STRING_TOARGENV + +- /* HACK: Temporarily restore the DATA rlimit for spawned child. +- This is a terrible hack to provide sensible brk limit for child. */ +- VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data)); +- + /* Actual spawn() syscall. */ + SysRes res = VG_(do_syscall5)(__NR_spawn, (UWord) path, (UWord) attrs, + attrs_size, (UWord) argenv, argenv_size); + SET_STATUS_from_SysRes(res); + VG_(free)(argenv); + +- /* Restore DATA rlimit back to its previous value set in m_main.c. */ +- struct vki_rlimit zero = { 0, 0 }; +- zero.rlim_max = VG_(client_rlimit_data).rlim_max; +- VG_(setrlimit)(VKI_RLIMIT_DATA, &zero); +- + if (SUCCESS) { + PRINT(" spawn: process %d spawned child %ld\n", VG_(getpid)(), RES); + } +@@ -3794,9 +3785,6 @@ PRE(sys_execve) + VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL); + } + +- /* Restore the DATA rlimit for the child. */ +- VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data)); +- + /* Debug-only printing. */ + if (0) { + HChar **cpp; diff --git a/valgrind-3.11.0-s390-hwcap.patch b/valgrind-3.11.0-s390-hwcap.patch new file mode 100644 index 0000000..4413a8e --- /dev/null +++ b/valgrind-3.11.0-s390-hwcap.patch @@ -0,0 +1,70 @@ +On a zEC12 or z13, a glibc with lock elision enabled infers from HWCAP +that the prerequisites for lock elision are met. Then it may use TBEGIN +and other transactional-execution instructions which are not implemented +by Valgrind. Likewise, the upcoming glibc 2.23 will exploit vector +instructions if they are advertised by HWCAP; and those are currently +not implemented by Valgrind either. In general, the increased use of +ifunc may lead to more such cases in the future. + +This patch suppresses the advertising of those hardware features via +HWCAP which are either not known to Valgrind or currently unsupported. + +Patch by Andreas Arnez (arnez@linux.vnet.ibm.com). +Fixes BZ #353680. + +Modified: trunk/README.s390 +============================================================================== +--- trunk/README.s390 (original) ++++ trunk/README.s390 Mon Oct 12 21:35:56 2015 +@@ -22,6 +22,9 @@ + - Some gcc versions use mvc to copy 4/8 byte values. This will affect + certain debug messages. For example, memcheck will complain about + 4 one-byte reads/writes instead of just a single read/write. ++- The transactional-execution facility is not supported; it is masked ++ off from HWCAP. ++- The vector facility is not supported; it is masked off from HWCAP. + + + Hardware facilities + +Modified: trunk/coregrind/m_initimg/initimg-linux.c +============================================================================== +--- trunk/coregrind/m_initimg/initimg-linux.c (original) ++++ trunk/coregrind/m_initimg/initimg-linux.c Mon Oct 12 21:35:56 2015 +@@ -701,6 +701,12 @@ + in syswrap-arm-linux.c rather than to base this on + conditional compilation. */ + } ++# elif defined(VGP_s390x_linux) ++ { ++ /* Advertise hardware features "below" TE only. TE and VXRS ++ (and anything above) are not supported by Valgrind. */ ++ auxv->u.a_val &= VKI_HWCAP_S390_TE - 1; ++ } + # endif + break; + # if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) + +Modified: trunk/include/vki/vki-s390x-linux.h +============================================================================== +--- trunk/include/vki/vki-s390x-linux.h (original) ++++ trunk/include/vki/vki-s390x-linux.h Mon Oct 12 21:35:56 2015 +@@ -800,12 +800,15 @@ + #define VKI_PTRACE_POKEUSR_AREA 0x5001 + + //---------------------------------------------------------------------- +-// From linux-2.6.16.60/include/asm-s390/elf.h ++// From linux-3.18/include/asm-s390/elf.h + //---------------------------------------------------------------------- + + typedef vki_s390_fp_regs vki_elf_fpregset_t; + typedef vki_s390_regs vki_elf_gregset_t; + ++#define VKI_HWCAP_S390_TE 1024 ++#define VKI_HWCAP_S390_VXRS 2048 ++ + + //---------------------------------------------------------------------- + // From linux-2.6.16.60/include/asm-s390/ucontext.h + + diff --git a/valgrind-3.11.0-socketcall-x86-linux.patch b/valgrind-3.11.0-socketcall-x86-linux.patch new file mode 100644 index 0000000..fe30d0f --- /dev/null +++ b/valgrind-3.11.0-socketcall-x86-linux.patch @@ -0,0 +1,70 @@ +commit 266d48ed3aa5f5a6c422805d56abc5a32b90c09c +Author: mjw +Date: Wed Jan 20 22:24:43 2016 +0000 + + Bug #358030 Support direct socket calls on x86 32bit (new in linux 4.3) + + Patch by ronald.wahl@raritan.com. + + git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15764 a5019735-40e9-0310-863c-91ae7b9d1cf9 + +diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c +index 24d7dc1..3c80e6a 100644 +--- a/coregrind/m_syswrap/syswrap-x86-linux.c ++++ b/coregrind/m_syswrap/syswrap-x86-linux.c +@@ -1824,8 +1824,23 @@ static SyscallTableEntry syscall_table[] = { + // LIN__(__NR_seccomp, sys_ni_syscall), // 354 + + LINXY(__NR_getrandom, sys_getrandom), // 355 +- LINXY(__NR_memfd_create, sys_memfd_create) // 356 +-// LIN__(__NR_bpf, sys_ni_syscall) // 357 ++ LINXY(__NR_memfd_create, sys_memfd_create), // 356 ++// LIN__(__NR_bpf, sys_ni_syscall), // 357 ++ LINXY(__NR_socket, sys_socket), // 359 ++ LINXY(__NR_socketpair, sys_socketpair), // 360 ++ LINX_(__NR_bind, sys_bind), // 361 ++ LINX_(__NR_connect, sys_connect), // 362 ++ LINX_(__NR_listen, sys_listen), // 363 ++ LINXY(__NR_accept4, sys_accept4), // 364 ++ LINXY(__NR_getsockopt, sys_getsockopt), // 365 ++ LINX_(__NR_setsockopt, sys_setsockopt), // 366 ++ LINXY(__NR_getsockname, sys_getsockname), // 367 ++ LINXY(__NR_getpeername, sys_getpeername), // 368 ++ LINX_(__NR_sendto, sys_sendto), // 369 ++ LINX_(__NR_sendmsg, sys_sendmsg), // 370 ++ LINXY(__NR_recvfrom, sys_recvfrom), // 371 ++ LINXY(__NR_recvmsg, sys_recvmsg), // 372 ++ LINX_(__NR_shutdown, sys_shutdown) // 373 + }; + + SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno ) +diff --git a/include/vki/vki-scnums-x86-linux.h b/include/vki/vki-scnums-x86-linux.h +index 5479b3e..a4e75a7 100644 +--- a/include/vki/vki-scnums-x86-linux.h ++++ b/include/vki/vki-scnums-x86-linux.h +@@ -392,6 +392,25 @@ + #define __NR_getrandom 355 + #define __NR_memfd_create 356 + #define __NR_bpf 357 ++#define __NR_execveat 358 ++#define __NR_socket 359 ++#define __NR_socketpair 360 ++#define __NR_bind 361 ++#define __NR_connect 362 ++#define __NR_listen 363 ++#define __NR_accept4 364 ++#define __NR_getsockopt 365 ++#define __NR_setsockopt 366 ++#define __NR_getsockname 367 ++#define __NR_getpeername 368 ++#define __NR_sendto 369 ++#define __NR_sendmsg 370 ++#define __NR_recvfrom 371 ++#define __NR_recvmsg 372 ++#define __NR_shutdown 373 ++#define __NR_userfaultfd 374 ++#define __NR_membarrier 375 ++#define __NR_mlock2 376 + + #endif /* __VKI_SCNUMS_X86_LINUX_H */ + diff --git a/valgrind-3.11.0-wrapmalloc.patch b/valgrind-3.11.0-wrapmalloc.patch new file mode 100644 index 0000000..064163f --- /dev/null +++ b/valgrind-3.11.0-wrapmalloc.patch @@ -0,0 +1,1176 @@ +commit 13693666bd9fc7be37a907302e5d3d4f4b2c9358 +Author: mjw +Date: Sun Nov 15 16:50:43 2015 +0000 + + BZ#355188 valgrind should intercept all malloc related global functions. + + This implements the interception of all globally public allocation + functions by default. It works by adding a flag to the spec to say the + interception only applies to global functions. Which is set for the + somalloc spec. The librarypath to match is set to "*" unless the user + overrides it. Then each DiSym keeps track of whether the symbol is local + or global. For a spec which has isGlobal set only isGlobal symbols will + match. + + Note that because of padding to keep the addresses in DiSym aligned the + addition of the extra bool isGlobal doesn't actually grow the struct. + The comments explain how the struct could be made more compact on 32bit + systems, but this isn't as easy on 64bit systems. So I didn't try to do + that in this patch. + + For ELF symbols keeping track of which are global is trivial. For pdb I + had to guess and made only the "Public" symbols global. I don't know + how/if macho keeps track of global symbols or not. For now I just mark + all of them local (which just means things work as previously on platforms + that use machos, no non-system symbols are matches by default for somalloc + unless the user explicitly tells which library name to match). + + Included are two testcases for shared libraries (wrapmalloc) and staticly + linked (wrapmallocstatic) malloc/free overrides that depend on the new + default. One existing testcase (new_override) was adjusted to explicitly + not use the new somalloc default because it depends on a user defined + new implementation that has side-effects and should explicitly not be + intercepted. + + git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15726 a5019735-40e9-0310-863c-91ae7b9d1cf9 + +diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c +index 6f11cd2..4dc1129 100644 +--- a/coregrind/m_debuginfo/debuginfo.c ++++ b/coregrind/m_debuginfo/debuginfo.c +@@ -4306,7 +4306,8 @@ void VG_(DebugInfo_syms_getidx) ( const DebugInfo *si, + /*OUT*/const HChar** pri_name, + /*OUT*/const HChar*** sec_names, + /*OUT*/Bool* isText, +- /*OUT*/Bool* isIFunc ) ++ /*OUT*/Bool* isIFunc, ++ /*OUT*/Bool* isGlobal ) + { + vg_assert(idx >= 0 && idx < si->symtab_used); + if (avmas) *avmas = si->symtab[idx].avmas; +@@ -4315,6 +4316,7 @@ void VG_(DebugInfo_syms_getidx) ( const DebugInfo *si, + if (sec_names) *sec_names = si->symtab[idx].sec_names; + if (isText) *isText = si->symtab[idx].isText; + if (isIFunc) *isIFunc = si->symtab[idx].isIFunc; ++ if (isGlobal) *isGlobal = si->symtab[idx].isGlobal; + } + + +diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h +index aa1d9f9..a43720a 100644 +--- a/coregrind/m_debuginfo/priv_storage.h ++++ b/coregrind/m_debuginfo/priv_storage.h +@@ -75,14 +75,18 @@ typedef + the macros defined in pub_core_debuginfo.h */ + const HChar* pri_name; /* primary name, never NULL */ + const HChar** sec_names; /* NULL, or a NULL term'd array of other names */ +- // XXX: this could be shrunk (on 32-bit platforms) by using 30 +- // bits for the size and 1 bit each for isText and isIFunc. If you +- // do this, make sure that all assignments to the latter two use +- // 0 or 1 (or True or False), and that a positive number larger +- // than 1 is never used to represent True. ++ // XXX: DiSym could be shrunk (on 32-bit platforms to exactly 16 ++ // bytes, on 64-bit platforms the first 3 pointers already add ++ // up to 24 bytes, so size plus bits will extend to 32 bytes ++ // anyway) by using 29 bits for the size and 1 bit each for ++ // isText, isIFunc and isGlobal. If you do this, make sure that ++ // all assignments to the latter two use 0 or 1 (or True or ++ // False), and that a positive number larger than 1 is never ++ // used to represent True. + UInt size; /* size in bytes */ + Bool isText; + Bool isIFunc; /* symbol is an indirect function? */ ++ Bool isGlobal; /* Is this symbol globally visible? */ + } + DiSym; + +diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c +index 0861725..3820965 100644 +--- a/coregrind/m_debuginfo/readelf.c ++++ b/coregrind/m_debuginfo/readelf.c +@@ -241,7 +241,8 @@ Bool get_elf_symbol_info ( + Bool* from_opd_out, /* ppc64be-linux only: did we deref an + .opd entry? */ + Bool* is_text_out, /* is this a text symbol? */ +- Bool* is_ifunc /* is this a STT_GNU_IFUNC function ?*/ ++ Bool* is_ifunc_out, /* is this a STT_GNU_IFUNC function ?*/ ++ Bool* is_global_out /* is this a global symbol ?*/ + ) + { + Bool plausible; +@@ -259,7 +260,8 @@ Bool get_elf_symbol_info ( + SET_TOCPTR_AVMA(*sym_avmas_out, 0); /* default to unknown/inapplicable */ + SET_LOCAL_EP_AVMA(*sym_avmas_out, 0); /* default to unknown/inapplicable */ + *from_opd_out = False; +- *is_ifunc = False; ++ *is_ifunc_out = False; ++ *is_global_out = False; + + /* Get the symbol size, but restrict it to fit in a signed 32 bit + int. Also, deal with the stupid case of negative size by making +@@ -373,10 +375,14 @@ Bool get_elf_symbol_info ( + /* Check for indirect functions. */ + if (*is_text_out + && ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC) { +- *is_ifunc = True; ++ *is_ifunc_out = True; + } + # endif + ++ if (ELFXX_ST_BIND(sym->st_info) == STB_GLOBAL) { ++ *is_global_out = True; ++ } ++ + # if defined(VGP_ppc64be_linux) + /* Allow STT_NOTYPE in the very special case where we're running on + ppc64be-linux and the symbol is one which the .opd-chasing hack +@@ -777,6 +783,7 @@ void read_elf_symtab__normal( + SymAVMAs sym_avmas_really; + Int sym_size = 0; + Bool from_opd = False, is_text = False, is_ifunc = False; ++ Bool is_global = False; + DiOffT sym_name_really = DiOffT_INVALID; + sym_avmas_really.main = 0; + SET_TOCPTR_AVMA(sym_avmas_really, 0); +@@ -787,7 +794,7 @@ void read_elf_symtab__normal( + &sym_name_really, + &sym_avmas_really, + &sym_size, +- &from_opd, &is_text, &is_ifunc)) { ++ &from_opd, &is_text, &is_ifunc, &is_global)) { + + DiSym disym; + VG_(memset)(&disym, 0, sizeof(disym)); +@@ -799,6 +806,7 @@ void read_elf_symtab__normal( + disym.size = sym_size; + disym.isText = is_text; + disym.isIFunc = is_ifunc; ++ disym.isGlobal = is_global; + if (cstr) { ML_(dinfo_free)(cstr); cstr = NULL; } + vg_assert(disym.pri_name); + vg_assert(GET_TOCPTR_AVMA(disym.avmas) == 0); +@@ -847,6 +855,7 @@ typedef + Bool from_opd; + Bool is_text; + Bool is_ifunc; ++ Bool is_global; + } + TempSym; + +@@ -911,6 +920,7 @@ void read_elf_symtab__ppc64be_linux( + SymAVMAs sym_avmas_really; + Int sym_size = 0; + Bool from_opd = False, is_text = False, is_ifunc = False; ++ Bool is_global = False; + DiOffT sym_name_really = DiOffT_INVALID; + DiSym disym; + VG_(memset)(&disym, 0, sizeof(disym)); +@@ -923,7 +933,7 @@ void read_elf_symtab__ppc64be_linux( + &sym_name_really, + &sym_avmas_really, + &sym_size, +- &from_opd, &is_text, &is_ifunc)) { ++ &from_opd, &is_text, &is_ifunc, &is_global)) { + + /* Check if we've seen this (name,addr) key before. */ + key.addr = sym_avmas_really.main; +@@ -996,6 +1006,7 @@ void read_elf_symtab__ppc64be_linux( + elem->from_opd = from_opd; + elem->is_text = is_text; + elem->is_ifunc = is_ifunc; ++ elem->is_global = is_global; + VG_(OSetGen_Insert)(oset, elem); + if (di->trace_symtab) { + HChar* str = ML_(img_strdup)(escn_strtab->img, "di.respl.2", +@@ -1034,14 +1045,17 @@ void read_elf_symtab__ppc64be_linux( + disym.size = elem->size; + disym.isText = elem->is_text; + disym.isIFunc = elem->is_ifunc; ++ disym.isGlobal = elem->is_global; + if (cstr) { ML_(dinfo_free)(cstr); cstr = NULL; } + vg_assert(disym.pri_name != NULL); + + ML_(addSym) ( di, &disym ); + if (di->trace_symtab) { +- VG_(printf)(" rec(%c) [%4ld]: " ++ VG_(printf)(" rec(%c%c%c) [%4ld]: " + " val %#010lx, toc %#010lx, sz %4d %s\n", + disym.isText ? 't' : 'd', ++ disym.isIFunc ? 'i' : '-', ++ disym.isGlobal ? 'g' : 'l', + i, + disym.avmas.main, + GET_TOCPTR_AVMA(disym.avmas), +diff --git a/coregrind/m_debuginfo/readmacho.c b/coregrind/m_debuginfo/readmacho.c +index 98ab048..3d406a4 100644 +--- a/coregrind/m_debuginfo/readmacho.c ++++ b/coregrind/m_debuginfo/readmacho.c +@@ -365,6 +365,7 @@ void read_symtab( /*OUT*/XArray* /* DiSym */ syms, + di->text_avma+di->text_size - sym_addr; + disym.isText = True; + disym.isIFunc = False; ++ disym.isGlobal = False; + // Lots of user function names get prepended with an underscore. Eg. the + // function 'f' becomes the symbol '_f'. And the "below main" + // function is called "start". So we skip the leading underscore, and +diff --git a/coregrind/m_debuginfo/readpdb.c b/coregrind/m_debuginfo/readpdb.c +index 8b63e95..1ebf863 100644 +--- a/coregrind/m_debuginfo/readpdb.c ++++ b/coregrind/m_debuginfo/readpdb.c +@@ -1272,6 +1272,7 @@ static ULong DEBUG_SnarfCodeView( + // FIXME: .namelen is sizeof(.data) including .name[] + vsym.isText = (sym->generic.id == S_PUB_V1); + vsym.isIFunc = False; ++ vsym.isGlobal = True; + ML_(addSym)( di, &vsym ); + n_syms_read++; + } +@@ -1299,6 +1300,7 @@ static ULong DEBUG_SnarfCodeView( + vsym.isText = !!(IMAGE_SCN_CNT_CODE + & sectp[sym->data_v2.segment-1].Characteristics); + vsym.isIFunc = False; ++ vsym.isGlobal = True; + ML_(addSym)( di, &vsym ); + n_syms_read++; + } +@@ -1332,6 +1334,7 @@ static ULong DEBUG_SnarfCodeView( + vsym.isText = !!(IMAGE_SCN_CNT_CODE + & sectp[sym->data_v2.segment-1].Characteristics); + vsym.isIFunc = False; ++ vsym.isGlobal = True; + ML_(addSym)( di, &vsym ); + n_syms_read++; + } +@@ -1365,6 +1368,7 @@ static ULong DEBUG_SnarfCodeView( + vsym.size = sym->proc_v1.proc_len; + vsym.isText = True; + vsym.isIFunc = False; ++ vsym.isGlobal = sym->generic.id == S_GPROC_V1; + if (debug) + VG_(umsg)(" Adding function %s addr=%#lx length=%u\n", + symname, vsym.avmas.main, vsym.size ); +@@ -1386,6 +1390,7 @@ static ULong DEBUG_SnarfCodeView( + vsym.size = sym->proc_v2.proc_len; + vsym.isText = True; + vsym.isIFunc = False; ++ vsym.isGlobal = sym->generic.id == S_GPROC_V2; + if (debug) + VG_(umsg)(" Adding function %s addr=%#lx length=%u\n", + symname, vsym.avmas.main, vsym.size ); +@@ -1408,6 +1413,7 @@ static ULong DEBUG_SnarfCodeView( + vsym.size = sym->proc_v3.proc_len; + vsym.isText = 1; + vsym.isIFunc = False; ++ vsym.isGlobal = sym->generic.id == S_GPROC_V3; + ML_(addSym)( di, &vsym ); + n_syms_read++; + } +diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c +index 45bc135..7b2e26a 100644 +--- a/coregrind/m_debuginfo/storage.c ++++ b/coregrind/m_debuginfo/storage.c +@@ -98,10 +98,11 @@ void ML_(ppSym) ( Int idx, const DiSym* sym ) + vg_assert(sym->pri_name); + if (sec_names) + vg_assert(sec_names); +- VG_(printf)( "%5d: %c%c %#8lx .. %#8lx (%u) %s%s", ++ VG_(printf)( "%5d: %c%c%c %#8lx .. %#8lx (%u) %s%s", + idx, + sym->isText ? 'T' : '-', + sym->isIFunc ? 'I' : '-', ++ sym->isGlobal ? 'G' : '-', + sym->avmas.main, + sym->avmas.main + sym->size - 1, sym->size, + sym->pri_name, sec_names ? " " : "" ); +@@ -1646,7 +1647,7 @@ static void canonicaliseSymtab ( struct _DebugInfo* di ) + Word i, j, n_truncated; + Addr sta1, sta2, end1, end2, toc1, toc2; + const HChar *pri1, *pri2, **sec1, **sec2; +- Bool ist1, ist2, isf1, isf2; ++ Bool ist1, ist2, isf1, isf2, isg1, isg2; + + # define SWAP(ty,aa,bb) \ + do { ty tt = (aa); (aa) = (bb); (bb) = tt; } while (0) +@@ -1693,6 +1694,8 @@ static void canonicaliseSymtab ( struct _DebugInfo* di ) + } + /* mark w as an IFunc if either w or r are */ + di->symtab[w].isIFunc = di->symtab[w].isIFunc || di->symtab[r].isIFunc; ++ /* likewise for global symbols */ ++ di->symtab[w].isGlobal = di->symtab[w].isGlobal || di->symtab[r].isGlobal; + /* and use ::pri_names to indicate this slot is no longer in use */ + di->symtab[r].pri_name = NULL; + if (di->symtab[r].sec_names) { +@@ -1796,6 +1799,7 @@ static void canonicaliseSymtab ( struct _DebugInfo* di ) + sec1 = di->symtab[i].sec_names; + ist1 = di->symtab[i].isText; + isf1 = di->symtab[i].isIFunc; ++ isg1 = di->symtab[i].isGlobal; + + sta2 = di->symtab[i+1].avmas.main; + end2 = sta2 + di->symtab[i+1].size - 1; +@@ -1805,6 +1809,7 @@ static void canonicaliseSymtab ( struct _DebugInfo* di ) + sec2 = di->symtab[i+1].sec_names; + ist2 = di->symtab[i+1].isText; + isf2 = di->symtab[i+1].isIFunc; ++ isg2 = di->symtab[i+1].isGlobal; + + if (sta1 < sta2) { + end1 = sta2 - 1; +@@ -1814,7 +1819,7 @@ static void canonicaliseSymtab ( struct _DebugInfo* di ) + sta1 = end2 + 1; + SWAP(Addr,sta1,sta2); SWAP(Addr,end1,end2); SWAP(Addr,toc1,toc2); + SWAP(const HChar*,pri1,pri2); SWAP(const HChar**,sec1,sec2); +- SWAP(Bool,ist1,ist2); SWAP(Bool,isf1,isf2); ++ SWAP(Bool,ist1,ist2); SWAP(Bool,isf1,isf2); SWAP(Bool, isg1, isg2); + } else + if (end1 < end2) { + sta2 = end1 + 1; +@@ -1831,6 +1836,7 @@ static void canonicaliseSymtab ( struct _DebugInfo* di ) + di->symtab[i].sec_names = sec1; + di->symtab[i].isText = ist1; + di->symtab[i].isIFunc = isf1; ++ di->symtab[i].isGlobal = isg1; + + di->symtab[i+1].avmas.main = sta2; + di->symtab[i+1].size = end2 - sta2 + 1; +@@ -1840,6 +1846,7 @@ static void canonicaliseSymtab ( struct _DebugInfo* di ) + di->symtab[i+1].sec_names = sec2; + di->symtab[i+1].isText = ist2; + di->symtab[i+1].isIFunc = isf2; ++ di->symtab[i+1].isGlobal = isg2; + + vg_assert(sta1 <= sta2); + vg_assert(di->symtab[i].size > 0); +diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c +index 7e4df8d..3d3f70a 100644 +--- a/coregrind/m_redir.c ++++ b/coregrind/m_redir.c +@@ -233,6 +233,7 @@ typedef + HChar* from_fnpatt; /* from fnname pattern */ + Addr to_addr; /* where redirecting to */ + Bool isWrap; /* wrap or replacement? */ ++ Bool isGlobal; /* must the symbol to replace be global? */ + Int becTag; /* 0 through 9999. Behavioural equivalance class tag. + If two wrappers have the same (non-zero) tag, they + are promising that they behave identically. */ +@@ -388,7 +389,7 @@ static HChar const* advance_to_comma ( HChar const* c ) { + + void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) + { +- Bool ok, isWrap; ++ Bool ok, isWrap, isGlobal; + Int i, nsyms, becTag, becPrio; + Spec* specList; + Spec* spec; +@@ -518,13 +519,14 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) + for (i = 0; i < nsyms; i++) { + VG_(DebugInfo_syms_getidx)( newdi, i, &sym_avmas, + NULL, &sym_name_pri, &sym_names_sec, +- &isText, NULL ); ++ &isText, NULL, NULL ); + /* Set up to conveniently iterate over all names for this symbol. */ + const HChar* twoslots[2]; + const HChar** names_init = + alloc_symname_array(sym_name_pri, sym_names_sec, &twoslots[0]); + const HChar** names; + for (names = names_init; *names; names++) { ++ isGlobal = False; + ok = VG_(maybe_Z_demangle)( *names, + &demangled_sopatt, + &demangled_fnpatt, +@@ -579,15 +581,12 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) + have a matching lib synonym, then replace the sopatt. + Otherwise, just ignore this redirection spec. */ + +- if (!VG_(clo_soname_synonyms)) +- continue; // No synonyms => skip the redir. +- + /* Search for a matching synonym=newname*/ + SizeT const sopatt_syn_len + = VG_(strlen)(demangled_sopatt+VG_SO_SYN_PREFIX_LEN); + HChar const* last = VG_(clo_soname_synonyms); + +- while (*last) { ++ while (last != NULL && *last) { + HChar const* first = last; + last = advance_to_equal(first); + +@@ -611,6 +610,17 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) + last++; + } + ++ // If the user didn't set it then somalloc is special. We ++ // want to match public/global symbols that match the ++ // fnpatt everywhere. ++ if (replaced_sopatt == NULL ++ && VG_(strcmp) ( demangled_sopatt, SO_SYN_MALLOC_NAME ) == 0) ++ { ++ replaced_sopatt = VG_(strdup)("m_redir.rnnD.1", "*"); ++ demangled_sopatt = replaced_sopatt; ++ isGlobal = True; ++ } ++ + // If we have not replaced the sopatt, then skip the redir. + if (replaced_sopatt == NULL) + continue; +@@ -621,6 +631,7 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) + spec->from_fnpatt = dinfo_strdup("redir.rnnD.3", demangled_fnpatt); + spec->to_addr = sym_avmas.main; + spec->isWrap = isWrap; ++ spec->isGlobal = isGlobal; + spec->becTag = becTag; + spec->becPrio = becPrio; + /* check we're not adding manifestly stupid destinations */ +@@ -653,7 +664,7 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) + for (i = 0; i < nsyms; i++) { + VG_(DebugInfo_syms_getidx)( newdi, i, &sym_avmas, + NULL, &sym_name_pri, &sym_names_sec, +- &isText, NULL ); ++ &isText, NULL, NULL ); + const HChar* twoslots[2]; + const HChar** names_init = + alloc_symname_array(sym_name_pri, sym_names_sec, &twoslots[0]); +@@ -785,7 +796,7 @@ void generate_and_add_actives ( + ) + { + Spec* sp; +- Bool anyMark, isText, isIFunc; ++ Bool anyMark, isText, isIFunc, isGlobal; + Active act; + Int nsyms, i; + SymAVMAs sym_avmas; +@@ -813,7 +824,7 @@ void generate_and_add_actives ( + for (i = 0; i < nsyms; i++) { + VG_(DebugInfo_syms_getidx)( di, i, &sym_avmas, + NULL, &sym_name_pri, &sym_names_sec, +- &isText, &isIFunc ); ++ &isText, &isIFunc, &isGlobal ); + const HChar* twoslots[2]; + const HChar** names_init = + alloc_symname_array(sym_name_pri, sym_names_sec, &twoslots[0]); +@@ -827,7 +838,8 @@ void generate_and_add_actives ( + for (sp = specs; sp; sp = sp->next) { + if (!sp->mark) + continue; /* soname doesn't match */ +- if (VG_(string_match)( sp->from_fnpatt, *names )) { ++ if (VG_(string_match)( sp->from_fnpatt, *names ) ++ && (sp->isGlobal == False || isGlobal == True)) { + /* got a new binding. Add to collection. */ + act.from_addr = sym_avmas.main; + act.to_addr = sp->to_addr; +@@ -1220,6 +1232,7 @@ static void add_hardwired_spec (const HChar* sopatt, const HChar* fnpatt, + spec->from_fnpatt = CONST_CAST(HChar *,fnpatt); + spec->to_addr = to_addr; + spec->isWrap = False; ++ spec->isGlobal = False; + spec->mandatory = mandatory; + /* VARIABLE PARTS */ + spec->mark = False; /* not significant */ +@@ -1719,7 +1732,7 @@ static void handle_require_text_symbols ( const DebugInfo* di ) + const HChar** sym_names_sec = NULL; + VG_(DebugInfo_syms_getidx)( di, j, NULL, + NULL, &sym_name_pri, &sym_names_sec, +- &isText, NULL ); ++ &isText, NULL, NULL ); + const HChar* twoslots[2]; + const HChar** names_init = + alloc_symname_array(sym_name_pri, sym_names_sec, &twoslots[0]); +@@ -1773,10 +1786,11 @@ static void handle_require_text_symbols ( const DebugInfo* di ) + static void show_spec ( const HChar* left, const Spec* spec ) + { + VG_(message)( Vg_DebugMsg, +- "%s%-25s %-30s %s-> (%04d.%d) 0x%08lx\n", ++ "%s%-25s %-30s %s%s-> (%04d.%d) 0x%08lx\n", + left, + spec->from_sopatt, spec->from_fnpatt, + spec->isWrap ? "W" : "R", ++ spec->isGlobal ? "G" : "L", + spec->becTag, spec->becPrio, + spec->to_addr ); + } +diff --git a/coregrind/m_replacemalloc/vg_replace_malloc.c b/coregrind/m_replacemalloc/vg_replace_malloc.c +index ccac130..3c79c8a 100644 +--- a/coregrind/m_replacemalloc/vg_replace_malloc.c ++++ b/coregrind/m_replacemalloc/vg_replace_malloc.c +@@ -291,7 +291,6 @@ static void init(void); + // For some lines, we will also define a replacement function + // whose only purpose is to be a soname synonym place holder + // that can be replaced using --soname-synonyms. +-#define SO_SYN_MALLOC VG_SO_SYN(somalloc) + + // malloc + #if defined(VGO_linux) +diff --git a/coregrind/pub_core_debuginfo.h b/coregrind/pub_core_debuginfo.h +index b698f2c..8f26f25 100644 +--- a/coregrind/pub_core_debuginfo.h ++++ b/coregrind/pub_core_debuginfo.h +@@ -216,7 +216,8 @@ void VG_(DebugInfo_syms_getidx) ( const DebugInfo *di, + /*OUT*/const HChar** pri_name, + /*OUT*/const HChar*** sec_names, + /*OUT*/Bool* isText, +- /*OUT*/Bool* isIFunc ); ++ /*OUT*/Bool* isIFunc, ++ /*OUT*/Bool* isGlobal ); + /* ppc64-linux only: find the TOC pointer (R2 value) that should be in + force at the entry point address of the function containing + guest_code_addr. Returns 0 if not known. */ +diff --git a/docs/xml/manual-core.xml b/docs/xml/manual-core.xml +index edda8a1..c80aab0 100644 +--- a/docs/xml/manual-core.xml ++++ b/docs/xml/manual-core.xml +@@ -2315,18 +2315,26 @@ need to use them. + + + +- When a shared library is loaded, Valgrind checks for +- functions in the library that must be replaced or wrapped. +- For example, Memcheck replaces all malloc related +- functions (malloc, free, calloc, ...) with its own versions. +- Such replacements are done by default only in shared libraries whose +- soname matches a predefined soname pattern (e.g. +- libc.so* on linux). +- By default, no replacement is done for a statically linked +- library or for alternative libraries such as tcmalloc. ++ When a shared library is loaded, Valgrind checks for ++ functions in the library that must be replaced or wrapped. For ++ example, Memcheck replaces some string and memory functions ++ (strchr, strlen, strcpy, memchr, memcpy, memmove, etc.) with its ++ own versions. Such replacements are normally done only in shared ++ libraries whose soname matches a predefined soname pattern (e.g. ++ libc.so* on linux). By default, no ++ replacement is done for a statically linked library or for ++ alternative libraries, except for the allocation functions ++ (malloc, free, calloc, memalign, realloc, operator new, operator ++ delete, etc.) Such allocation functions are intercepted by ++ default in any shared library or in the executable if they are ++ exported as global symbols. This means that if a replacement ++ allocation library such as tcmalloc is found, its functions are ++ also intercepted by default. ++ + In some cases, the replacements allow + to specify one additional +- synonym pattern, giving flexibility in the replacement. ++ synonym pattern, giving flexibility in the replacement. Or to ++ prevent interception of all public allocation symbols. + + Currently, this flexibility is only allowed for the + malloc related functions, using the +@@ -2339,27 +2347,31 @@ need to use them. + + + Alternate malloc library: to replace the malloc +- related functions in an alternate library with +- soname mymalloclib.so, give the ++ related functions in a specific alternate library with ++ soname mymalloclib.so (and not in any ++ others), give the + option . + A pattern can be used to match multiple libraries sonames. + For + example, +- will match the soname of all variants of the tcmalloc library +- (native, debug, profiled, ... tcmalloc variants). ++ will match the soname of all variants of the tcmalloc ++ library (native, debug, profiled, ... tcmalloc ++ variants). + Note: the soname of a elf shared library can be + retrieved using the readelf utility. + + + + +- Replacements in a statically linked library are done by +- using the NONE pattern. For example, if +- you link with libtcmalloc.a, memcheck +- will properly work when you give the +- option . Note +- that a NONE pattern will match the main executable and any +- shared library having no soname. ++ Replacements in a statically linked library are done ++ by using the NONE pattern. For example, ++ if you link with libtcmalloc.a, and only ++ want to intercept the malloc related functions in the ++ executable (and standard libraries) themselves, but not any ++ other shared libraries, you can give the ++ option . ++ Note that a NONE pattern will match the main executable and ++ any shared library having no soname. + + + +@@ -2369,6 +2381,17 @@ need to use them. + + + ++ ++ To only intercept allocation symbols in the default ++ system libraries, but not in any other shared library or the ++ executable defining public malloc or operator new related ++ functions use a non-existing library name ++ like ++ (where nouserintercepts can be any ++ non-existing library name). ++ ++ ++ + + + +diff --git a/include/pub_tool_redir.h b/include/pub_tool_redir.h +index bac00d7..21d186b 100644 +--- a/include/pub_tool_redir.h ++++ b/include/pub_tool_redir.h +@@ -345,6 +345,12 @@ + #define VG_SO_SYN_PREFIX "VgSoSyn" + #define VG_SO_SYN_PREFIX_LEN 7 + ++// Special soname synonym place holder for the malloc symbols that can ++// be replaced using --soname-synonyms. Otherwise will match all ++// public symbols in any shared library/executable. ++#define SO_SYN_MALLOC VG_SO_SYN(somalloc) ++#define SO_SYN_MALLOC_NAME "VgSoSynsomalloc" ++ + #endif // __PUB_TOOL_REDIR_H + + /*--------------------------------------------------------------------*/ +diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am +index 68d9ca1..0f34127 100644 +--- a/memcheck/tests/Makefile.am ++++ b/memcheck/tests/Makefile.am +@@ -291,6 +291,9 @@ EXTRA_DIST = \ + wrap7.vgtest wrap7.stdout.exp wrap7.stderr.exp \ + wrap8.vgtest wrap8.stdout.exp wrap8.stderr.exp \ + wrap8.stdout.exp-ppc64 wrap8.stderr.exp-ppc64 \ ++ wrapmalloc.vgtest wrapmalloc.stdout.exp wrapmalloc.stderr.exp \ ++ wrapmallocstatic.vgtest wrapmallocstatic.stdout.exp \ ++ wrapmallocstatic.stderr.exp \ + writev1.stderr.exp writev1.stderr.exp-solaris writev1.vgtest \ + xml1.stderr.exp xml1.stdout.exp xml1.vgtest xml1.stderr.exp-s390x-mvc \ + threadname.vgtest threadname.stderr.exp \ +@@ -375,6 +378,7 @@ check_PROGRAMS = \ + wcs \ + xml1 \ + wrap1 wrap2 wrap3 wrap4 wrap5 wrap6 wrap7 wrap7so.so wrap8 \ ++ wrapmalloc wrapmallocso.so wrapmallocstatic \ + writev1 + + if !SOLARIS_SUN_STUDIO_AS +@@ -570,4 +574,26 @@ else + -Wl,-soname -Wl,wrap7so.so + endif + ++# Build shared object for wrapmalloc ++wrapmalloc_SOURCES = wrapmalloc.c ++wrapmalloc_DEPENDENCIES = wrapmallocso.so ++if VGCONF_OS_IS_DARWIN ++ wrapmalloc_LDADD = `pwd`/wrapmallocso.so ++ wrapmalloc_LDFLAGS = $(AM_FLAG_M3264_PRI) ++else ++ wrapmalloc_LDADD = wrapmallocso.so ++ wrapmalloc_LDFLAGS = $(AM_FLAG_M3264_PRI) \ ++ -Wl,-rpath,$(top_builddir)/memcheck/tests ++endif ++ ++wrapmallocso_so_SOURCES = wrapmallocso.c ++wrapmallocso_so_CFLAGS = $(AM_CFLAGS) -fpic ++if VGCONF_OS_IS_DARWIN ++ wrapmallocso_so_LDFLAGS = -fpic $(AM_FLAG_M3264_PRI) -dynamic \ ++ -dynamiclib -all_load ++else ++ wrapmallocso_so_LDFLAGS = -fpic $(AM_FLAG_M3264_PRI) -shared \ ++ -Wl,-soname -Wl,wrapmallocso.so ++endif ++ + xml1_CFLAGS = $(AM_CFLAGS) -D_GNU_SOURCE +diff --git a/memcheck/tests/new_override.vgtest b/memcheck/tests/new_override.vgtest +index 50e6240..435e330 100644 +--- a/memcheck/tests/new_override.vgtest ++++ b/memcheck/tests/new_override.vgtest +@@ -1,2 +1,6 @@ + prog: new_override ++# Don't override the user defined somalloc functions in this test. ++# The test depends on some side effects and initializing memory done by ++# the user overidden operator new. ++vgopts: --soname-synonyms=somalloc=nouseroverride + stderr_filter: filter_allocs +diff --git a/memcheck/tests/wrapmalloc.c b/memcheck/tests/wrapmalloc.c +new file mode 100644 +index 0000000..2307e77 +--- /dev/null ++++ b/memcheck/tests/wrapmalloc.c +@@ -0,0 +1,14 @@ ++#include ++#include ++ ++/* Test that a program that has malloc/free interposed in a shared ++ library is also intercepted. */ ++ ++int main ( void ) ++{ ++ printf ("start\n"); ++ void *p = malloc (1024); ++ free (p); ++ printf ("done\n"); ++ return 0; ++} +diff --git a/memcheck/tests/wrapmalloc.stderr.exp b/memcheck/tests/wrapmalloc.stderr.exp +new file mode 100644 +index 0000000..d937776 +--- /dev/null ++++ b/memcheck/tests/wrapmalloc.stderr.exp +@@ -0,0 +1,10 @@ ++ ++ ++HEAP SUMMARY: ++ in use at exit: 0 bytes in 0 blocks ++ total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated ++ ++For a detailed leak analysis, rerun with: --leak-check=full ++ ++For counts of detected and suppressed errors, rerun with: -v ++ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) +diff --git a/memcheck/tests/wrapmalloc.stdout.exp b/memcheck/tests/wrapmalloc.stdout.exp +new file mode 100644 +index 0000000..60b5fd2 +--- /dev/null ++++ b/memcheck/tests/wrapmalloc.stdout.exp +@@ -0,0 +1,2 @@ ++start ++done +diff --git a/memcheck/tests/wrapmalloc.vgtest b/memcheck/tests/wrapmalloc.vgtest +new file mode 100644 +index 0000000..a6dff4e +--- /dev/null ++++ b/memcheck/tests/wrapmalloc.vgtest +@@ -0,0 +1,2 @@ ++prog: wrapmalloc ++ +diff --git a/memcheck/tests/wrapmallocso.c b/memcheck/tests/wrapmallocso.c +new file mode 100644 +index 0000000..985ce56 +--- /dev/null ++++ b/memcheck/tests/wrapmallocso.c +@@ -0,0 +1,17 @@ ++#include ++#include ++ ++/* Fake malloc/free functions that just print something. When run ++ under memcheck these functions will be intercepted and not print ++ anything. */ ++ ++void *malloc ( size_t size ) ++{ ++ printf ("malloc\n"); ++ return NULL; ++} ++ ++void free (void *ptr) ++{ ++ printf ("free\n"); ++} +diff --git a/memcheck/tests/wrapmallocstatic.c b/memcheck/tests/wrapmallocstatic.c +new file mode 100644 +index 0000000..be6573b +--- /dev/null ++++ b/memcheck/tests/wrapmallocstatic.c +@@ -0,0 +1,29 @@ ++#include ++#include ++ ++/* Test that a program that has malloc/free interposed in the ++ executable is also intercepted. */ ++ ++int main ( void ) ++{ ++ printf ("start\n"); ++ void *p = malloc (1024); ++ free (p); ++ printf ("done\n"); ++ return 0; ++} ++ ++/* Fake malloc/free functions that just print something. When run ++ under memcheck these functions will be intercepted and not print ++ anything. */ ++ ++void *malloc ( size_t size ) ++{ ++ printf ("malloc\n"); ++ return NULL; ++} ++ ++void free (void *ptr) ++{ ++ printf ("free\n"); ++} +diff --git a/memcheck/tests/wrapmallocstatic.stderr.exp b/memcheck/tests/wrapmallocstatic.stderr.exp +new file mode 100644 +index 0000000..d937776 +--- /dev/null ++++ b/memcheck/tests/wrapmallocstatic.stderr.exp +@@ -0,0 +1,10 @@ ++ ++ ++HEAP SUMMARY: ++ in use at exit: 0 bytes in 0 blocks ++ total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated ++ ++For a detailed leak analysis, rerun with: --leak-check=full ++ ++For counts of detected and suppressed errors, rerun with: -v ++ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) +diff --git a/memcheck/tests/wrapmallocstatic.stdout.exp b/memcheck/tests/wrapmallocstatic.stdout.exp +new file mode 100644 +index 0000000..60b5fd2 +--- /dev/null ++++ b/memcheck/tests/wrapmallocstatic.stdout.exp +@@ -0,0 +1,2 @@ ++start ++done +diff --git a/memcheck/tests/wrapmallocstatic.vgtest b/memcheck/tests/wrapmallocstatic.vgtest +new file mode 100644 +index 0000000..7b3c068 +--- /dev/null ++++ b/memcheck/tests/wrapmallocstatic.vgtest +@@ -0,0 +1,2 @@ ++prog: wrapmallocstatic ++ +diff -ur valgrind-3.11.0.orig/memcheck/tests/Makefile.in valgrind-3.11.0/memcheck/tests/Makefile.in +--- valgrind-3.11.0.orig/memcheck/tests/Makefile.in 2015-11-15 18:08:05.457930383 +0100 ++++ valgrind-3.11.0/memcheck/tests/Makefile.in 2015-11-15 18:14:10.828008973 +0100 +@@ -185,7 +185,8 @@ + vcpu_fnfns$(EXEEXT) wcs$(EXEEXT) xml1$(EXEEXT) wrap1$(EXEEXT) \ + wrap2$(EXEEXT) wrap3$(EXEEXT) wrap4$(EXEEXT) wrap5$(EXEEXT) \ + wrap6$(EXEEXT) wrap7$(EXEEXT) wrap7so.so$(EXEEXT) \ +- wrap8$(EXEEXT) writev1$(EXEEXT) $(am__EXEEXT_1) \ ++ wrap8$(EXEEXT) wrapmalloc$(EXEEXT) wrapmallocso.so$(EXEEXT) \ ++ wrapmallocstatic$(EXEEXT) writev1$(EXEEXT) $(am__EXEEXT_1) \ + $(am__EXEEXT_2) $(am__EXEEXT_3) $(am__EXEEXT_4) \ + $(am__EXEEXT_5) + +@@ -736,6 +737,18 @@ + wrap8_SOURCES = wrap8.c + wrap8_OBJECTS = wrap8.$(OBJEXT) + wrap8_LDADD = $(LDADD) ++am_wrapmalloc_OBJECTS = wrapmalloc.$(OBJEXT) ++wrapmalloc_OBJECTS = $(am_wrapmalloc_OBJECTS) ++wrapmalloc_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(wrapmalloc_LDFLAGS) \ ++ $(LDFLAGS) -o $@ ++am_wrapmallocso_so_OBJECTS = wrapmallocso_so-wrapmallocso.$(OBJEXT) ++wrapmallocso_so_OBJECTS = $(am_wrapmallocso_so_OBJECTS) ++wrapmallocso_so_LDADD = $(LDADD) ++wrapmallocso_so_LINK = $(CCLD) $(wrapmallocso_so_CFLAGS) $(CFLAGS) \ ++ $(wrapmallocso_so_LDFLAGS) $(LDFLAGS) -o $@ ++wrapmallocstatic_SOURCES = wrapmallocstatic.c ++wrapmallocstatic_OBJECTS = wrapmallocstatic.$(OBJEXT) ++wrapmallocstatic_LDADD = $(LDADD) + writev1_SOURCES = writev1.c + writev1_OBJECTS = writev1.$(OBJEXT) + writev1_LDADD = $(LDADD) +@@ -826,7 +839,8 @@ + $(varinfo5_SOURCES) $(varinfo5so_so_SOURCES) varinfo6.c \ + varinforestrict.c vcpu_fbench.c vcpu_fnfns.c wcs.c wrap1.c \ + wrap2.c wrap3.c wrap4.c wrap5.c wrap6.c $(wrap7_SOURCES) \ +- $(wrap7so_so_SOURCES) wrap8.c writev1.c xml1.c ++ $(wrap7so_so_SOURCES) wrap8.c $(wrapmalloc_SOURCES) \ ++ $(wrapmallocso_so_SOURCES) wrapmallocstatic.c writev1.c xml1.c + DIST_SOURCES = accounting.c addressable.c atomic_incs.c badaddrvalue.c \ + badfree.c badjump.c badjump2.c badloop.c badpoll.c badrw.c \ + big_blocks_freed_list.c brk2.c buflen_check.c bug155125.c \ +@@ -863,7 +877,8 @@ + $(varinfo5_SOURCES) $(varinfo5so_so_SOURCES) varinfo6.c \ + varinforestrict.c vcpu_fbench.c vcpu_fnfns.c wcs.c wrap1.c \ + wrap2.c wrap3.c wrap4.c wrap5.c wrap6.c $(wrap7_SOURCES) \ +- $(wrap7so_so_SOURCES) wrap8.c writev1.c xml1.c ++ $(wrap7so_so_SOURCES) wrap8.c $(wrapmalloc_SOURCES) \ ++ $(wrapmallocso_so_SOURCES) wrapmallocstatic.c writev1.c xml1.c + RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ +@@ -1544,6 +1559,9 @@ + wrap7.vgtest wrap7.stdout.exp wrap7.stderr.exp \ + wrap8.vgtest wrap8.stdout.exp wrap8.stderr.exp \ + wrap8.stdout.exp-ppc64 wrap8.stderr.exp-ppc64 \ ++ wrapmalloc.vgtest wrapmalloc.stdout.exp wrapmalloc.stderr.exp \ ++ wrapmallocstatic.vgtest wrapmallocstatic.stdout.exp \ ++ wrapmallocstatic.stderr.exp \ + writev1.stderr.exp writev1.stderr.exp-solaris writev1.vgtest \ + xml1.stderr.exp xml1.stdout.exp xml1.vgtest xml1.stderr.exp-s390x-mvc \ + threadname.vgtest threadname.stderr.exp \ +@@ -1662,6 +1680,24 @@ + @VGCONF_OS_IS_DARWIN_TRUE@wrap7so_so_LDFLAGS = -fpic $(AM_FLAG_M3264_PRI) -dynamic \ + @VGCONF_OS_IS_DARWIN_TRUE@ -dynamiclib -all_load + ++ ++# Build shared object for wrapmalloc ++wrapmalloc_SOURCES = wrapmalloc.c ++wrapmalloc_DEPENDENCIES = wrapmallocso.so ++@VGCONF_OS_IS_DARWIN_FALSE@wrapmalloc_LDADD = wrapmallocso.so ++@VGCONF_OS_IS_DARWIN_TRUE@wrapmalloc_LDADD = `pwd`/wrapmallocso.so ++@VGCONF_OS_IS_DARWIN_FALSE@wrapmalloc_LDFLAGS = $(AM_FLAG_M3264_PRI) \ ++@VGCONF_OS_IS_DARWIN_FALSE@ -Wl,-rpath,$(top_builddir)/memcheck/tests ++ ++@VGCONF_OS_IS_DARWIN_TRUE@wrapmalloc_LDFLAGS = $(AM_FLAG_M3264_PRI) ++wrapmallocso_so_SOURCES = wrapmallocso.c ++wrapmallocso_so_CFLAGS = $(AM_CFLAGS) -fpic ++@VGCONF_OS_IS_DARWIN_FALSE@wrapmallocso_so_LDFLAGS = -fpic $(AM_FLAG_M3264_PRI) -shared \ ++@VGCONF_OS_IS_DARWIN_FALSE@ -Wl,-soname -Wl,wrapmallocso.so ++ ++@VGCONF_OS_IS_DARWIN_TRUE@wrapmallocso_so_LDFLAGS = -fpic $(AM_FLAG_M3264_PRI) -dynamic \ ++@VGCONF_OS_IS_DARWIN_TRUE@ -dynamiclib -all_load ++ + xml1_CFLAGS = $(AM_CFLAGS) -D_GNU_SOURCE + all: all-recursive + +@@ -2286,6 +2322,18 @@ + @rm -f wrap8$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(wrap8_OBJECTS) $(wrap8_LDADD) $(LIBS) + ++wrapmalloc$(EXEEXT): $(wrapmalloc_OBJECTS) $(wrapmalloc_DEPENDENCIES) $(EXTRA_wrapmalloc_DEPENDENCIES) ++ @rm -f wrapmalloc$(EXEEXT) ++ $(AM_V_CCLD)$(wrapmalloc_LINK) $(wrapmalloc_OBJECTS) $(wrapmalloc_LDADD) $(LIBS) ++ ++wrapmallocso.so$(EXEEXT): $(wrapmallocso_so_OBJECTS) $(wrapmallocso_so_DEPENDENCIES) $(EXTRA_wrapmallocso_so_DEPENDENCIES) ++ @rm -f wrapmallocso.so$(EXEEXT) ++ $(AM_V_CCLD)$(wrapmallocso_so_LINK) $(wrapmallocso_so_OBJECTS) $(wrapmallocso_so_LDADD) $(LIBS) ++ ++wrapmallocstatic$(EXEEXT): $(wrapmallocstatic_OBJECTS) $(wrapmallocstatic_DEPENDENCIES) $(EXTRA_wrapmallocstatic_DEPENDENCIES) ++ @rm -f wrapmallocstatic$(EXEEXT) ++ $(AM_V_CCLD)$(LINK) $(wrapmallocstatic_OBJECTS) $(wrapmallocstatic_LDADD) $(LIBS) ++ + writev1$(EXEEXT): $(writev1_OBJECTS) $(writev1_DEPENDENCIES) $(EXTRA_writev1_DEPENDENCIES) + @rm -f writev1$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(writev1_OBJECTS) $(writev1_LDADD) $(LIBS) +@@ -2446,6 +2494,9 @@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrap7.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrap7so_so-wrap7so.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrap8.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapmalloc.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapmallocso_so-wrapmallocso.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapmallocstatic.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writev1.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml1-xml1.Po@am__quote@ + +@@ -3011,6 +3062,20 @@ + @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + @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` + ++wrapmallocso_so-wrapmallocso.o: wrapmallocso.c ++@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 ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/wrapmallocso_so-wrapmallocso.Tpo $(DEPDIR)/wrapmallocso_so-wrapmallocso.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wrapmallocso.c' object='wrapmallocso_so-wrapmallocso.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@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 ++ ++wrapmallocso_so-wrapmallocso.obj: wrapmallocso.c ++@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` ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/wrapmallocso_so-wrapmallocso.Tpo $(DEPDIR)/wrapmallocso_so-wrapmallocso.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wrapmallocso.c' object='wrapmallocso_so-wrapmallocso.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@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` ++ + xml1-xml1.o: xml1.c + @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 + @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xml1-xml1.Tpo $(DEPDIR)/xml1-xml1.Po +commit d35c2c3197a0ae8398228d19578e1dfcb8401c5f +Author: iraisr +Date: Wed Nov 18 04:13:12 2015 +0000 + + Expected stderr of test cases wrapmalloc and wrapmallocstatic are overconstrained. + Fixes BZ#355455. + + + git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15727 a5019735-40e9-0310-863c-91ae7b9d1cf9 + +diff --git a/memcheck/tests/wrapmalloc.stderr.exp b/memcheck/tests/wrapmalloc.stderr.exp +index d937776..e69de29 100644 +--- a/memcheck/tests/wrapmalloc.stderr.exp ++++ b/memcheck/tests/wrapmalloc.stderr.exp +@@ -1,10 +0,0 @@ +- +- +-HEAP SUMMARY: +- in use at exit: 0 bytes in 0 blocks +- total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated +- +-For a detailed leak analysis, rerun with: --leak-check=full +- +-For counts of detected and suppressed errors, rerun with: -v +-ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) +diff --git a/memcheck/tests/wrapmalloc.vgtest b/memcheck/tests/wrapmalloc.vgtest +index a6dff4e..c22f241 100644 +--- a/memcheck/tests/wrapmalloc.vgtest ++++ b/memcheck/tests/wrapmalloc.vgtest +@@ -1,2 +1,2 @@ + prog: wrapmalloc +- ++vgopts: -q +diff --git a/memcheck/tests/wrapmallocstatic.stderr.exp b/memcheck/tests/wrapmallocstatic.stderr.exp +index d937776..e69de29 100644 +--- a/memcheck/tests/wrapmallocstatic.stderr.exp ++++ b/memcheck/tests/wrapmallocstatic.stderr.exp +@@ -1,10 +0,0 @@ +- +- +-HEAP SUMMARY: +- in use at exit: 0 bytes in 0 blocks +- total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated +- +-For a detailed leak analysis, rerun with: --leak-check=full +- +-For counts of detected and suppressed errors, rerun with: -v +-ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) +diff --git a/memcheck/tests/wrapmallocstatic.vgtest b/memcheck/tests/wrapmallocstatic.vgtest +index 7b3c068..f040756 100644 +--- a/memcheck/tests/wrapmallocstatic.vgtest ++++ b/memcheck/tests/wrapmallocstatic.vgtest +@@ -1,2 +1,2 @@ + prog: wrapmallocstatic +- ++vgopts: -q + +commit 194731c49eb7d448503a5e8625dd39779c2c9f8b +Author: iraisr +Date: Wed Nov 18 20:38:37 2015 +0000 + + When searching for global public symbols (like for the somalloc + synonym symbols), exclude the dynamic (runtime) linker as it is very + special. + Fixes BZ#355454 + + + git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15728 a5019735-40e9-0310-863c-91ae7b9d1cf9 + +diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c +index 3d3f70a..dcf1fb4 100644 +--- a/coregrind/m_redir.c ++++ b/coregrind/m_redir.c +@@ -809,8 +809,19 @@ void generate_and_add_actives ( + anyMark = False; + for (sp = specs; sp; sp = sp->next) { + sp->done = False; +- sp->mark = VG_(string_match)( sp->from_sopatt, +- VG_(DebugInfo_get_soname)(di) ); ++ const HChar *soname = VG_(DebugInfo_get_soname)(di); ++ ++ /* When searching for global public symbols (like for the somalloc ++ synonym symbols), exclude the dynamic (runtime) linker as it is very ++ special. See https://bugs.kde.org/show_bug.cgi?id=355454 */ ++ if ((VG_(strcmp)(sp->from_sopatt, "*") == 0) && ++ (sp->isGlobal == True) && ++ VG_(is_soname_ld_so)(soname)) { ++ sp->mark = False; ++ continue; ++ } ++ ++ sp->mark = VG_(string_match)( sp->from_sopatt, soname ); + anyMark = anyMark || sp->mark; + } + +@@ -1179,6 +1190,29 @@ Addr VG_(redir_do_lookup) ( Addr orig, Bool* isWrap ) + return r->to_addr; + } + ++/* Does the soname represent a dynamic (runtime) linker? ++ Considers various VG_U_LD* entries from pub_tool_redir.h. */ ++Bool VG_(is_soname_ld_so) (const HChar *soname) ++{ ++# if defined(VGO_linux) ++ if (VG_STREQ(soname, VG_U_LD_LINUX_SO_3)) return True; ++ if (VG_STREQ(soname, VG_U_LD_LINUX_SO_2)) return True; ++ if (VG_STREQ(soname, VG_U_LD_LINUX_X86_64_SO_2)) return True; ++ if (VG_STREQ(soname, VG_U_LD64_SO_1)) return True; ++ if (VG_STREQ(soname, VG_U_LD64_SO_2)) return True; ++ if (VG_STREQ(soname, VG_U_LD_SO_1)) return True; ++ if (VG_STREQ(soname, VG_U_LD_LINUX_AARCH64_SO_1)) return True; ++ if (VG_STREQ(soname, VG_U_LD_LINUX_ARMHF_SO_3)) return True; ++# elif defined(VGO_darwin) ++ if (VG_STREQ(soname, VG_U_DYLD)) return True; ++# elif defined(VGO_solaris) ++ if (VG_STREQ(soname, VG_U_LD_SO_1)) return True; ++# else ++# error "Unsupported OS" ++# endif ++ ++ return False; ++} + + /*------------------------------------------------------------*/ + /*--- INITIALISATION ---*/ +diff --git a/docs/xml/manual-core.xml b/docs/xml/manual-core.xml +index c80aab0..758e2f4 100644 +--- a/docs/xml/manual-core.xml ++++ b/docs/xml/manual-core.xml +@@ -2322,7 +2322,7 @@ need to use them. + own versions. Such replacements are normally done only in shared + libraries whose soname matches a predefined soname pattern (e.g. + libc.so* on linux). By default, no +- replacement is done for a statically linked library or for ++ replacement is done for a statically linked binary or for + alternative libraries, except for the allocation functions + (malloc, free, calloc, memalign, realloc, operator new, operator + delete, etc.) Such allocation functions are intercepted by +@@ -2392,6 +2392,13 @@ need to use them. + + + ++ ++ Shared library of the dynamic (runtime) linker is excluded from ++ searching for global public symbols, such as those for the malloc ++ related functions (identified by somalloc synonym). ++ ++ ++ + + + +diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c +index ae6eec0..9aed05a 100644 +--- a/helgrind/hg_main.c ++++ b/helgrind/hg_main.c +@@ -4589,7 +4589,6 @@ static Bool is_in_dynamic_linker_shared_object( Addr ga ) + { + DebugInfo* dinfo; + const HChar* soname; +- if (0) return False; + + dinfo = VG_(find_DebugInfo)( ga ); + if (!dinfo) return False; +@@ -4598,23 +4597,7 @@ static Bool is_in_dynamic_linker_shared_object( Addr ga ) + tl_assert(soname); + if (0) VG_(printf)("%s\n", soname); + +-# if defined(VGO_linux) +- if (VG_STREQ(soname, VG_U_LD_LINUX_SO_3)) return True; +- if (VG_STREQ(soname, VG_U_LD_LINUX_SO_2)) return True; +- if (VG_STREQ(soname, VG_U_LD_LINUX_X86_64_SO_2)) return True; +- if (VG_STREQ(soname, VG_U_LD64_SO_1)) return True; +- if (VG_STREQ(soname, VG_U_LD64_SO_2)) return True; +- if (VG_STREQ(soname, VG_U_LD_SO_1)) return True; +- if (VG_STREQ(soname, VG_U_LD_LINUX_AARCH64_SO_1)) return True; +- if (VG_STREQ(soname, VG_U_LD_LINUX_ARMHF_SO_3)) return True; +-# elif defined(VGO_darwin) +- if (VG_STREQ(soname, VG_U_DYLD)) return True; +-# elif defined(VGO_solaris) +- if (VG_STREQ(soname, VG_U_LD_SO_1)) return True; +-# else +-# error "Unsupported OS" +-# endif +- return False; ++ return VG_(is_soname_ld_so)(soname); + } + + static +diff --git a/include/pub_tool_redir.h b/include/pub_tool_redir.h +index 21d186b..aa879d6 100644 +--- a/include/pub_tool_redir.h ++++ b/include/pub_tool_redir.h +@@ -351,6 +351,8 @@ + #define SO_SYN_MALLOC VG_SO_SYN(somalloc) + #define SO_SYN_MALLOC_NAME "VgSoSynsomalloc" + ++Bool VG_(is_soname_ld_so) (const HChar *soname); ++ + #endif // __PUB_TOOL_REDIR_H + + /*--------------------------------------------------------------------*/ diff --git a/valgrind-3.11.0-x86_unwind.patch b/valgrind-3.11.0-x86_unwind.patch new file mode 100644 index 0000000..ca0063b --- /dev/null +++ b/valgrind-3.11.0-x86_unwind.patch @@ -0,0 +1,109 @@ +commit f250c4d3241c156f8e65398e2af76e3e2ee1ccb5 +Author: philippe +Date: Wed Nov 18 20:56:55 2015 +0000 + + Fix incorrect (or infinite loop) unwind on RHEL7 x86 32 bits. + + On RHEL7 x86 32 bits, Valgrind unwinder cannot properly unwind + the stack just after a thread creation : the unwinder always retrieves + the same pc/sp/bp. + See below for an example. + This has as consequences that some stack traces are bigger than + needed (i.e. they always fill up the ips array). If + --merge-recursive-frames is given, then the unwinder enters in an + infinite loop (as identical frames will be merged, and the ips array + will never be filled in). + Thi patch adds an additional exit condition : after unwinding + a frame, if the previous sp is >= new sp, then unwinding stops. + Patch has been tested on debian 8/x86, RHEL7/x86. + + + + 0x0417db67 <+55>: mov 0x18(%esp),%ebx + 0x0417db6b <+59>: mov 0x28(%esp),%edi + 0x0417db6f <+63>: mov $0x78,%eax + 0x0417db74 <+68>: mov %ebx,(%ecx) + 0x0417db76 <+70>: int $0x80 + => 0x0417db78 <+72>: pop %edi + 0x0417db79 <+73>: pop %esi + 0x0417db7a <+74>: pop %ebx + 0x0417db7b <+75>: test %eax,%eax + + Valgrind stacktrace gives: + ==21261== at 0x417DB78: clone (clone.S:110) + ==21261== by 0x424702F: ??? + ==21261== by 0x424702F: ??? + ==21261== by 0x424702F: ??? + ==21261== by 0x424702F: ??? + ==21261== by 0x424702F: ??? + ==21261== by 0x424702F: ??? + ==21261== by 0x424702F: ??? + ... + (till the array of ips is full) + + while gdb stacktrace gives: + (gdb) bt + #0 clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:110 + #1 0x00000000 in ?? () + (gdb) p $pc + $2 = (void (*)()) 0x417db78 + (gdb) + + + With the fix, valgrind gives: + ==21261== at 0x417DB78: clone (clone.S:110) + ==21261== by 0x424702F: ??? + which looks more reasonable. + + + + + git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15729 a5019735-40e9-0310-863c-91ae7b9d1cf9 + +diff --git a/coregrind/m_stacktrace.c b/coregrind/m_stacktrace.c +index 8c1e9a4..137e780 100644 +--- a/coregrind/m_stacktrace.c ++++ b/coregrind/m_stacktrace.c +@@ -350,6 +350,8 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known, + uregs.xbp <= fp_max - 1 * sizeof(UWord)/*see comment below*/ && + VG_IS_4_ALIGNED(uregs.xbp)) + { ++ Addr old_xsp; ++ + /* fp looks sane, so use it. */ + uregs.xip = (((UWord*)uregs.xbp)[1]); + // We stop if we hit a zero (the traditional end-of-stack +@@ -382,6 +384,7 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known, + } + } + ++ old_xsp = uregs.xsp; + uregs.xsp = uregs.xbp + sizeof(Addr) /*saved %ebp*/ + + sizeof(Addr) /*ra*/; + uregs.xbp = (((UWord*)uregs.xbp)[0]); +@@ -393,6 +396,12 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known, + if (debug) VG_(printf)(" cache FPUNWIND >2\n"); + if (debug) unwind_case = "FO"; + if (do_stats) stats.FO++; ++ if (old_xsp >= uregs.xsp) { ++ if (debug) ++ VG_(printf) (" FO end of stack old_xsp %p >= xsp %p\n", ++ (void*)old_xsp, (void*)uregs.xsp); ++ break; ++ } + } else { + fp_CF_verif_cache [hash] = xip_verified ^ CFUNWIND; + if (debug) VG_(printf)(" cache CFUNWIND >2\n"); +@@ -406,6 +415,12 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known, + } else { + if (debug) unwind_case = "FF"; + if (do_stats) stats.FF++; ++ if (old_xsp >= uregs.xsp) { ++ if (debug) ++ VG_(printf) (" FF end of stack old_xsp %p >= xsp %p\n", ++ (void*)old_xsp, (void*)uregs.xsp); ++ break; ++ } + } + goto unwind_done; + } else { diff --git a/valgrind.spec b/valgrind.spec index 4d46db6..1f983be 100644 --- a/valgrind.spec +++ b/valgrind.spec @@ -3,7 +3,7 @@ Summary: Tool for finding memory management bugs in programs Name: %{?scl_prefix}valgrind Version: 3.11.0 -Release: 1%{?dist} +Release: 8%{?dist} Epoch: 1 License: GPLv2+ URL: http://www.valgrind.org/ @@ -38,10 +38,11 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %global build_openmpi 0 %endif -# Don't run dwz or generate minisymtab, valgrind doesn't handle compressed -# DWARF very well and it might read its own vgpreload libraries. Generating -# minisymtabs doesn't really work for the staticly linked tools. -%define _find_debuginfo_dwz_opts %{nil} +# Generating minisymtabs doesn't really work for the staticly linked +# tools. Note (below) that we don't strip the vgpreload libraries at all +# because valgrind might read and need the debuginfo in those (client) +# libraries for better error reporting and sometimes correctly unwinding. +# So those will already have their full symbol table. %undefine _include_minidebuginfo Source0: http://www.valgrind.org/downloads/valgrind-%{version}.tar.bz2 @@ -61,6 +62,42 @@ Patch4: valgrind-3.11.0-arm64-xattr.patch # KDE#353084 arm64 doesn't support sigpending system call. Patch5: valgrind-3.11.0-arm64-sigpending.patch +# KDE#353370 don't advertise RDRAND in cpuid for Core-i7-4910-like avx2 +Patch6: valgrind-3.11.0-no-rdrand.patch + +# KDE#278744 cvtps2pd with redundant RexW +Patch7: valgrind-3.11.0-rexw-cvtps2pd.patch + +# KDE#353680 Crash with certain glibc versions due to non-implemented TBEGIN +Patch8: valgrind-3.11.0-s390-hwcap.patch + +# KDE#355188 valgrind should intercept all malloc related global functions +Patch9: valgrind-3.11.0-wrapmalloc.patch + +# RHBZ#1283774 - Valgrind: FATAL: aspacem assertion failed +Patch10: valgrind-3.11.0-aspacemgr.patch + +# KDE#358213 - helgrind bar_bad testcase hangs with new glibc pthread barrier +Patch11: valgrind-3.11.0-pthread_barrier.patch + +# KDE#357833 - Valgrind is broken on recent linux kernel (RLIMIT_DATA) +Patch12: valgrind-3.11.0-rlimit_data.patch + +# KDE#357887 VG_(fclose) ought to close the file, you silly. +Patch13: valgrind-3.11.0-fclose.patch + +# KDE#357871 Fix helgrind wrapper of pthread_spin_destroy +Patch14: valgrind-3.11.0-pthread_spin_destroy.patch + +# KDE#358030 Support direct socket calls on x86 32bit (new in linux 4.3) +Patch15: valgrind-3.11.0-socketcall-x86-linux.patch + +# KDE#356044 Dwarf line info reader misinterprets is_stmt register +Patch16: valgrind-3.11.0-is_stmt.patch + +# Fix incorrect (or infinite loop) unwind on RHEL7 x86 32 bits. (svn r15729) +Patch17: valgrind-3.11.0-x86_unwind.patch + %if %{build_multilib} # Ensure glibc{,-devel} is installed for both multilib arches BuildRequires: /lib/libc.so.6 /usr/lib/libc.so /lib64/libc.so.6 /usr/lib64/libc.so @@ -170,6 +207,18 @@ Valgrind User Manual for details. %patch3 -p1 %patch4 -p1 %patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 %build # We need to use the software collection compiler and binutils if available. @@ -272,6 +321,11 @@ for i in HAVE_PTHREAD_CREATE_GLIBC_2_0 HAVE_PTRACE_GETREGS \ done %endif +# We don't want debuginfo generated for the vgpreload libraries. +# Turn off execute bit so they aren't included in the debuginfo.list. +# We'll turn the execute bit on again in %%files. +chmod 644 $RPM_BUILD_ROOT%{_libdir}/valgrind/vgpreload*-%{valarch}-*so + %check # Make sure some info about the system is in the build.log uname -a @@ -325,8 +379,20 @@ echo ===============END TESTING=============== %doc docs/installed/html docs/installed/*.pdf %{_bindir}/* %dir %{_libdir}/valgrind +# Install everything in the libdir except the .so and .a files. +# The vgpreload so files might file mode adjustment (see below). +# The libmpiwrap so files go in the valgrind-openmpi package. +# The .a archives go into the valgrind-devel package. %{_libdir}/valgrind/*[^ao] -%{_libdir}/valgrind/[^l]*o +# Turn on executable bit again for vgpreload libraries. +# Was disabled in %%install to prevent debuginfo stripping. +%attr(0755,root,root) %{_libdir}/valgrind/vgpreload*-%{valarch}-*so +# And install the symlinks to the secarch files if the exist. +# These are separate from the above because %%attr doesn't work +# on symlinks. +%if "%{valsecarch}" != "" +%{_libdir}/valgrind/vgpreload*-%{valsecarch}-*so +%endif %{_mandir}/man1/* %files devel @@ -345,6 +411,35 @@ echo ===============END TESTING=============== %endif %changelog +* Thu Jan 21 2016 Mark Wielaard - 3.11.0-8 +- Add valgrind-3.11.0-rlimit_data.patch +- Add valgrind-3.11.0-fclose.patch +- Add valgrind-3.11.0-pthread_spin_destroy.patch +- Add valgrind-3.11.0-socketcall-x86-linux.patch +- Don't strip debuginfo from vgpreload libaries. + Enable dwz for everything else again. +- Add valgrind-3.11.0-is_stmt.patch +- Add valgrind-3.11.0-x86_unwind.patch + +* Tue Jan 19 2016 Mark Wielaard - 3.11.0-7 +- Add valgrind-3.11.0-pthread_barrier.patch + +* Sat Jan 16 2016 Mark Wielaard - 3.11.0-6 +- Add valgrind-3.11.0-aspacemgr.patch (#1283774) + +* Sun Nov 15 2015 Mark Wielaard - 3.11.0-5 +- Add valgrind-3.11.0-wrapmalloc.patch + +* Mon Oct 12 2015 Mark Wielaard - 3.11.0-4 +- Fix parenthesis in valgrind-3.11.0-rexw-cvtps2pd.patch. +- Add valgrind-3.11.0-s390-hwcap.patch + +* Mon Oct 12 2015 Mark Wielaard - 3.11.0-3 +- Add valgrind-3.11.0-rexw-cvtps2pd.patch. + +* Thu Oct 01 2015 Mark Wielaard - 3.11.0-2 +- Add valgrind-3.11.0-no-rdrand.patch + * Wed Sep 23 2015 Mark Wielaard - 3.11.0-1 - Upgrade to valgrind 3.11.0 final - Drop patches included upstream