]>
Commit | Line | Data |
---|---|---|
742a207e SL |
1 | From d944d9527b3c2dc21ec3418fa17a37b06328a903 Mon Sep 17 00:00:00 2001 |
2 | From: Nick Desaulniers <ndesaulniers@google.com> | |
3 | Date: Fri, 5 Apr 2019 18:38:45 -0700 | |
4 | Subject: lib/string.c: implement a basic bcmp | |
5 | ||
6 | [ Upstream commit 5f074f3e192f10c9fade898b9b3b8812e3d83342 ] | |
7 | ||
8 | A recent optimization in Clang (r355672) lowers comparisons of the | |
9 | return value of memcmp against zero to comparisons of the return value | |
10 | of bcmp against zero. This helps some platforms that implement bcmp | |
11 | more efficiently than memcmp. glibc simply aliases bcmp to memcmp, but | |
12 | an optimized implementation is in the works. | |
13 | ||
14 | This results in linkage failures for all targets with Clang due to the | |
15 | undefined symbol. For now, just implement bcmp as a tailcail to memcmp | |
16 | to unbreak the build. This routine can be further optimized in the | |
17 | future. | |
18 | ||
19 | Other ideas discussed: | |
20 | ||
21 | * A weak alias was discussed, but breaks for architectures that define | |
22 | their own implementations of memcmp since aliases to declarations are | |
23 | not permitted (only definitions). Arch-specific memcmp | |
24 | implementations typically declare memcmp in C headers, but implement | |
25 | them in assembly. | |
26 | ||
27 | * -ffreestanding also is used sporadically throughout the kernel. | |
28 | ||
29 | * -fno-builtin-bcmp doesn't work when doing LTO. | |
30 | ||
31 | Link: https://bugs.llvm.org/show_bug.cgi?id=41035 | |
32 | Link: https://code.woboq.org/userspace/glibc/string/memcmp.c.html#bcmp | |
33 | Link: https://github.com/llvm/llvm-project/commit/8e16d73346f8091461319a7dfc4ddd18eedcff13 | |
34 | Link: https://github.com/ClangBuiltLinux/linux/issues/416 | |
35 | Link: http://lkml.kernel.org/r/20190313211335.165605-1-ndesaulniers@google.com | |
36 | Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> | |
37 | Reported-by: Nathan Chancellor <natechancellor@gmail.com> | |
38 | Reported-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> | |
39 | Suggested-by: Arnd Bergmann <arnd@arndb.de> | |
40 | Suggested-by: James Y Knight <jyknight@google.com> | |
41 | Suggested-by: Masahiro Yamada <yamada.masahiro@socionext.com> | |
42 | Suggested-by: Nathan Chancellor <natechancellor@gmail.com> | |
43 | Suggested-by: Rasmus Villemoes <linux@rasmusvillemoes.dk> | |
44 | Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org> | |
45 | Reviewed-by: Nathan Chancellor <natechancellor@gmail.com> | |
46 | Tested-by: Nathan Chancellor <natechancellor@gmail.com> | |
47 | Reviewed-by: Masahiro Yamada <yamada.masahiro@socionext.com> | |
48 | Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | |
49 | Cc: David Laight <David.Laight@ACULAB.COM> | |
50 | Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk> | |
51 | Cc: Namhyung Kim <namhyung@kernel.org> | |
52 | Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
53 | Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> | |
54 | Cc: Dan Williams <dan.j.williams@intel.com> | |
55 | Cc: <stable@vger.kernel.org> | |
56 | Signed-off-by: Andrew Morton <akpm@linux-foundation.org> | |
57 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | |
58 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
59 | --- | |
60 | include/linux/string.h | 3 +++ | |
61 | lib/string.c | 20 ++++++++++++++++++++ | |
62 | 2 files changed, 23 insertions(+) | |
63 | ||
64 | diff --git a/include/linux/string.h b/include/linux/string.h | |
65 | index 4a5a0eb7df51..f58e1ef76572 100644 | |
66 | --- a/include/linux/string.h | |
67 | +++ b/include/linux/string.h | |
68 | @@ -143,6 +143,9 @@ extern void * memscan(void *,int,__kernel_size_t); | |
69 | #ifndef __HAVE_ARCH_MEMCMP | |
70 | extern int memcmp(const void *,const void *,__kernel_size_t); | |
71 | #endif | |
72 | +#ifndef __HAVE_ARCH_BCMP | |
73 | +extern int bcmp(const void *,const void *,__kernel_size_t); | |
74 | +#endif | |
75 | #ifndef __HAVE_ARCH_MEMCHR | |
76 | extern void * memchr(const void *,int,__kernel_size_t); | |
77 | #endif | |
78 | diff --git a/lib/string.c b/lib/string.c | |
79 | index 2c0900a5d51a..72125fd5b4a6 100644 | |
80 | --- a/lib/string.c | |
81 | +++ b/lib/string.c | |
82 | @@ -865,6 +865,26 @@ __visible int memcmp(const void *cs, const void *ct, size_t count) | |
83 | EXPORT_SYMBOL(memcmp); | |
84 | #endif | |
85 | ||
86 | +#ifndef __HAVE_ARCH_BCMP | |
87 | +/** | |
88 | + * bcmp - returns 0 if and only if the buffers have identical contents. | |
89 | + * @a: pointer to first buffer. | |
90 | + * @b: pointer to second buffer. | |
91 | + * @len: size of buffers. | |
92 | + * | |
93 | + * The sign or magnitude of a non-zero return value has no particular | |
94 | + * meaning, and architectures may implement their own more efficient bcmp(). So | |
95 | + * while this particular implementation is a simple (tail) call to memcmp, do | |
96 | + * not rely on anything but whether the return value is zero or non-zero. | |
97 | + */ | |
98 | +#undef bcmp | |
99 | +int bcmp(const void *a, const void *b, size_t len) | |
100 | +{ | |
101 | + return memcmp(a, b, len); | |
102 | +} | |
103 | +EXPORT_SYMBOL(bcmp); | |
104 | +#endif | |
105 | + | |
106 | #ifndef __HAVE_ARCH_MEMSCAN | |
107 | /** | |
108 | * memscan - Find a character in an area of memory. | |
109 | -- | |
110 | 2.19.1 | |
111 |