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