Merge tag 'nolibc-urgent.2022.10.28a' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 1 Nov 2022 20:15:14 +0000 (13:15 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 1 Nov 2022 20:15:14 +0000 (13:15 -0700)
Pull nolibc fixes from Paul McKenney:
 "This contains a couple of fixes for string-function bugs"

* tag 'nolibc-urgent.2022.10.28a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu:
  tools/nolibc/string: Fix memcmp() implementation
  tools/nolibc: Fix missing strlen() definition and infinite loop with gcc-12

tools/include/nolibc/string.h

index bef35be..ad97c0d 100644 (file)
@@ -19,9 +19,9 @@ static __attribute__((unused))
 int memcmp(const void *s1, const void *s2, size_t n)
 {
        size_t ofs = 0;
-       char c1 = 0;
+       int c1 = 0;
 
-       while (ofs < n && !(c1 = ((char *)s1)[ofs] - ((char *)s2)[ofs])) {
+       while (ofs < n && !(c1 = ((unsigned char *)s1)[ofs] - ((unsigned char *)s2)[ofs])) {
                ofs++;
        }
        return c1;
@@ -125,14 +125,18 @@ char *strcpy(char *dst, const char *src)
 }
 
 /* this function is only used with arguments that are not constants or when
- * it's not known because optimizations are disabled.
+ * it's not known because optimizations are disabled. Note that gcc 12
+ * recognizes an strlen() pattern and replaces it with a jump to strlen(),
+ * thus itself, hence the asm() statement below that's meant to disable this
+ * confusing practice.
  */
 static __attribute__((unused))
-size_t nolibc_strlen(const char *str)
+size_t strlen(const char *str)
 {
        size_t len;
 
-       for (len = 0; str[len]; len++);
+       for (len = 0; str[len]; len++)
+               asm("");
        return len;
 }
 
@@ -140,13 +144,12 @@ size_t nolibc_strlen(const char *str)
  * the two branches, then will rely on an external definition of strlen().
  */
 #if defined(__OPTIMIZE__)
+#define nolibc_strlen(x) strlen(x)
 #define strlen(str) ({                          \
        __builtin_constant_p((str)) ?           \
                __builtin_strlen((str)) :       \
                nolibc_strlen((str));           \
 })
-#else
-#define strlen(str) nolibc_strlen((str))
 #endif
 
 static __attribute__((unused))