[PATCH 5/5] Hacky testsuite for memfill() and memset_l()

From: Matthew Wilcox
Date: Wed Mar 08 2017 - 16:02:15 EST


From: Matthew Wilcox <mawilcox@xxxxxxxxxxxxx>

cc -I. -I../../include -g -O2 -Wall -D_LGPL_SOURCE -fno-strict-aliasing \
string.c -o string

Has to be compiled with -fno-strict-aliasing because I do unclean things
with pointers to different types (in the test suite, not the lib).

Signed-off-by: Matthew Wilcox <mawilcox@xxxxxxxxxxxxx>
---
tools/include/linux/compiler.h | 5 +++
tools/include/linux/string.h | 11 ++++++
tools/testing/radix-tree/asm/page.h | 0
tools/testing/radix-tree/asm/word-at-a-time.h | 1 +
tools/testing/radix-tree/linux/ctype.h | 0
tools/testing/radix-tree/linux/kernel.h | 2 +
tools/testing/radix-tree/string.c | 53 +++++++++++++++++++++++++++
7 files changed, 72 insertions(+)
create mode 100644 tools/testing/radix-tree/asm/page.h
create mode 100644 tools/testing/radix-tree/asm/word-at-a-time.h
create mode 100644 tools/testing/radix-tree/linux/ctype.h
create mode 100644 tools/testing/radix-tree/string.c

diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h
index 8de163b17c0d..48dca30b5a7a 100644
--- a/tools/include/linux/compiler.h
+++ b/tools/include/linux/compiler.h
@@ -8,6 +8,7 @@
/* Optimization barrier */
/* The "volatile" is due to gcc bugs */
#define barrier() __asm__ __volatile__("": : :"memory")
+#define barrier_data(ptr) __asm__ __volatile__("": : "r"(ptr) :"memory")

#ifndef __always_inline
# define __always_inline inline __attribute__((always_inline))
@@ -44,6 +45,10 @@
# define __force
#endif

+#ifndef __visible
+# define __visible __attribute__((externally_visible))
+#endif
+
#ifndef __weak
# define __weak __attribute__((weak))
#endif
diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h
index f436d2420a18..ce757cb4737c 100644
--- a/tools/include/linux/string.h
+++ b/tools/include/linux/string.h
@@ -4,6 +4,17 @@

#include <linux/types.h> /* for size_t */

+extern void *memset32(uint32_t *, uint32_t, size_t);
+extern void *memset64(uint64_t *, uint64_t, size_t);
+static inline void *memset_l(unsigned long *p, unsigned long v, size_t n)
+{
+#if BITS_PER_LONG == 32
+ return memset32((uint32_t *)p, v, n);
+#else
+ return memset64((uint64_t *)p, v, n);
+#endif
+}
+
void *memdup(const void *src, size_t len);

int strtobool(const char *s, bool *res);
diff --git a/tools/testing/radix-tree/asm/page.h b/tools/testing/radix-tree/asm/page.h
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tools/testing/radix-tree/asm/word-at-a-time.h b/tools/testing/radix-tree/asm/word-at-a-time.h
new file mode 100644
index 000000000000..2cdbbc249e59
--- /dev/null
+++ b/tools/testing/radix-tree/asm/word-at-a-time.h
@@ -0,0 +1 @@
+#include "../../../include/asm-generic/word-at-a-time.h"
diff --git a/tools/testing/radix-tree/linux/ctype.h b/tools/testing/radix-tree/linux/ctype.h
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tools/testing/radix-tree/linux/kernel.h b/tools/testing/radix-tree/linux/kernel.h
index b21a77fddcf7..9f38f8a42fcb 100644
--- a/tools/testing/radix-tree/linux/kernel.h
+++ b/tools/testing/radix-tree/linux/kernel.h
@@ -16,6 +16,8 @@
#define pr_debug printk
#define pr_cont printk

+#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x))
+
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

#endif /* _KERNEL_H */
diff --git a/tools/testing/radix-tree/string.c b/tools/testing/radix-tree/string.c
new file mode 100644
index 000000000000..147796d76d27
--- /dev/null
+++ b/tools/testing/radix-tree/string.c
@@ -0,0 +1,53 @@
+#include <stddef.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include <string.h>
+#undef strncpy
+#undef strncmp
+#undef strchr
+#undef strsep
+#include "../../../lib/string.c"
+
+#define short_to_int(x) ((x) | ((unsigned long)(x) << 16))
+#define short_to_long(x) (short_to_int(x) | (short_to_int(x) << 16 << 16))
+
+int main(void)
+{
+ unsigned long foo[27] = {0,};
+ unsigned char bar[128];
+ unsigned int i;
+ unsigned short s = 0x1234;
+ char c;
+
+ memset_l(foo, (unsigned long)main, 21);
+
+ assert(foo[21] == 0);
+ assert(foo[20] == (unsigned long)main);
+
+ assert(foo[0] == (unsigned long)main);
+ memset_l(foo, 1, 0);
+ assert(foo[0] == (unsigned long)main);
+
+ memfill(foo, 10 * sizeof(long), &s, sizeof(s));
+ printf("%lx %lx\n", foo[0], short_to_long(s));
+ for (i = 0; i < 10; i++)
+ assert(foo[i] == short_to_long(s));
+ assert(foo[i] == (unsigned long)main);
+
+ memset(bar, 1, sizeof(bar));
+ for (i = 0; i < sizeof(bar); i++)
+ assert(bar[i] == 1);
+
+ c = 2;
+ memfill(bar, sizeof(bar), &c, 1);
+ for (i = 0; i < sizeof(bar); i++)
+ assert(bar[i] == 2);
+
+ s = 0x4321;
+ memfill(bar, 11, &s, sizeof(s));
+ assert(bar[11] == 2);
+ assert(bar[10] == *(unsigned char *)&s);
+
+ return 0;
+}
--
2.11.0