From 42ca1c480a5bca408a54c6a24d2be2c081d121ac Mon Sep 17 00:00:00 2001 From: Andreas Arnez Date: Thu, 19 May 2022 13:54:06 +0200 Subject: [PATCH] Bug 454040 - Add intercept for memmem on s390x Since memcheck may report false positives in an optimized version of memmem on s390x, add an intercept for memmem on s390x platforms. --- shared/vg_replace_strmem.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/shared/vg_replace_strmem.c b/shared/vg_replace_strmem.c index 5396e83be..d28e74206 100644 --- a/shared/vg_replace_strmem.c +++ b/shared/vg_replace_strmem.c @@ -103,6 +103,7 @@ 20430 WMEMCHR 20440 WCSNLEN 20450 WSTRNCMP + 20460 MEMMEM */ #if defined(VGO_solaris) @@ -1785,6 +1786,41 @@ static inline void my_exit ( int x ) #endif +/*---------------------- memmem ----------------------*/ + +#define MEMMEM(soname, fnname) \ + void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \ + (const void* haystack, SizeT hlen, const void* needle, SizeT nlen); \ + void* VG_REPLACE_FUNCTION_EZU(20460,soname,fnname) \ + (const void* haystack, SizeT hlen, const void* needle, SizeT nlen) \ + { \ + const HChar* h = haystack; \ + const HChar* n = needle; \ + \ + /* If the needle is the empty string, match immediately. */ \ + if (nlen == 0) return CONST_CAST(void *,h); \ + \ + HChar n0 = n[0]; \ + \ + for (; hlen >= nlen; hlen--, h++) { \ + if (h[0] != n0) continue; \ + \ + UWord i; \ + for (i = 1; i < nlen; i++) { \ + if (n[i] != h[i]) \ + break; \ + } \ + if (i == nlen) \ + return CONST_CAST(HChar *,h); \ + \ + } \ + return NULL; \ + } + +#if defined(VGP_s390x_linux) + MEMMEM(VG_Z_LIBC_SONAME, memmem) +#endif + /*---------------------- strpbrk ----------------------*/ -- 2.31.1 From 4d675f309bcd2d4e9e2b9e6f4aba30f85116bb9b Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 19 May 2022 18:08:40 -0400 Subject: [PATCH] Add memmem memcheck tests --- memcheck/tests/Makefile.am | 3 ++ memcheck/tests/filter_memmem | 5 ++ memcheck/tests/memmem.c | 81 ++++++++++++++++++++++++++++++++ memcheck/tests/memmem.stderr.exp | 2 + memcheck/tests/memmem.vgtest | 3 ++ 5 files changed, 94 insertions(+) create mode 100755 memcheck/tests/filter_memmem create mode 100644 memcheck/tests/memmem.c create mode 100644 memcheck/tests/memmem.stderr.exp create mode 100644 memcheck/tests/memmem.vgtest diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index eb9487272..4d181c1ac 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -79,6 +79,7 @@ dist_noinst_SCRIPTS = \ filter_strchr \ filter_varinfo3 \ filter_memcheck \ + filter_memmem \ filter_overlaperror \ filter_malloc_free \ filter_sized_delete @@ -220,6 +221,7 @@ EXTRA_DIST = \ memalign2.stderr.exp memalign2.vgtest \ memcmptest.stderr.exp memcmptest.stderr.exp2 \ memcmptest.stdout.exp memcmptest.vgtest \ + memmem.stderr.exp memmem.vgtest \ mempool.stderr.exp mempool.vgtest \ mempool2.stderr.exp mempool2.vgtest \ metadata.stderr.exp metadata.stdout.exp metadata.vgtest \ @@ -417,6 +419,7 @@ check_PROGRAMS = \ malloc_usable malloc1 malloc2 malloc3 manuel1 manuel2 manuel3 \ match-overrun \ memalign_test memalign2 memcmptest mempool mempool2 mmaptest \ + memmem \ mismatches new_override metadata \ nanoleak_supp nanoleak2 new_nothrow \ noisy_child \ diff --git a/memcheck/tests/filter_memmem b/memcheck/tests/filter_memmem new file mode 100755 index 000000000..f4a40b2d1 --- /dev/null +++ b/memcheck/tests/filter_memmem @@ -0,0 +1,5 @@ +#! /bin/sh + +# Too many memmem implementations and overrides. +# So just keep the main file lines. +./filter_stderr "$@" | grep " main (memmem.c:" diff --git a/memcheck/tests/memmem.c b/memcheck/tests/memmem.c new file mode 100644 index 000000000..d627076e3 --- /dev/null +++ b/memcheck/tests/memmem.c @@ -0,0 +1,81 @@ +#define _GNU_SOURCE +#include +#include +#include + +/* mallocs an mem block and fills it with A. A needs to be a zero + terminated string. The A string chars, minus the terminating zero + are copied into the returned mem block. */ +static void * +create_mem (const char *a) +{ + size_t len = strlen (a); + void *mem = malloc (len); + memcpy (mem, a, len); + return mem; +} + +int +main () +{ + char *haystack; + char *needle; + + haystack = create_mem ("a"); + needle = create_mem ("a"); + assert (memmem (haystack, 0, needle, 0) == haystack); + assert (memmem (haystack, 1, needle, 0) == haystack); + assert (memmem (haystack, 0, needle, 1) == NULL); + assert (memmem (haystack, 1, needle, 1) == haystack); + free (haystack); + free (needle); + + haystack = create_mem ("abc"); + needle = create_mem ("bc"); + assert (memmem (haystack, 3, needle, 0) == haystack); + assert (memmem (haystack, 3, needle, 2) == haystack + 1); + assert (memmem (haystack + 1, 2, needle, 2) == haystack + 1); + assert (memmem (haystack + 2, 1, needle, 2) == NULL); + free (haystack); + free (needle); + + haystack = create_mem ("abcabcabc"); + needle = create_mem ("bca"); + assert (memmem (haystack, 9, needle, 3) == haystack + 1); + free (haystack); + free (needle); + + haystack = create_mem ("abcabcabc"); + needle = create_mem ("bcad"); + assert (memmem (haystack, 9, needle, 4) == NULL); + free (haystack); + free (needle); + + haystack = create_mem ("xxxxxxxxxxxxxxxxxABC"); + needle = create_mem ("ABCD"); + assert (memmem (haystack, 20, needle, 2) == haystack + 17); + assert (memmem (haystack + 3, 17, needle, 2) == haystack + 17); + assert (memmem (haystack + 15, 5, needle, 2) == haystack + 17); + assert (memmem (haystack, 20, needle, 3) == haystack + 17); + assert (memmem (haystack + 3, 17, needle, 3) == haystack + 17); + assert (memmem (haystack + 15, 5, needle, 3) == haystack + 17); + assert (memmem (haystack, 20, needle, 4) == NULL); + assert (memmem (haystack + 3, 5, needle, 4) == NULL); + assert (memmem (haystack + 15, 5, needle, 4) == NULL); + free (haystack); + free (needle); + + haystack = malloc (1); + needle = create_mem ("a"); + assert (memmem (haystack, 1, needle, 1) == NULL); + free (haystack); + free (needle); + + haystack = create_mem ("A"); + needle = malloc (1); + assert (memmem (haystack, 1, needle, 1) == NULL); + free (haystack); + free (needle); + + return 0; +} diff --git a/memcheck/tests/memmem.stderr.exp b/memcheck/tests/memmem.stderr.exp new file mode 100644 index 000000000..b4612fbd4 --- /dev/null +++ b/memcheck/tests/memmem.stderr.exp @@ -0,0 +1,2 @@ + by 0x........: main (memmem.c:70) + by 0x........: main (memmem.c:76) diff --git a/memcheck/tests/memmem.vgtest b/memcheck/tests/memmem.vgtest new file mode 100644 index 000000000..6d12895df --- /dev/null +++ b/memcheck/tests/memmem.vgtest @@ -0,0 +1,3 @@ +prog: memmem +vgopts: -q +stderr_filter: filter_memmem -- 2.18.4