]> git.itanic.dy.fi Git - linux-stable/commitdiff
modpost: define TO_NATIVE() using bswap_* functions
authorMasahiro Yamada <masahiroy@kernel.org>
Sat, 7 Oct 2023 17:04:46 +0000 (02:04 +0900)
committerMasahiro Yamada <masahiroy@kernel.org>
Wed, 18 Oct 2023 08:16:09 +0000 (17:16 +0900)
The current TO_NATIVE() has some limitations:

 1) You cannot cast the argument.

 2) You cannot pass a variable marked as 'const'.

 3) Passing an array is a bug, but it is not detected.

Impelement TO_NATIVE() using bswap_*() functions. These are GNU
extensions. If we face portability issues, we can port the code from
include/uapi/linux/swab.h.

With this change, get_rel_type_and_sym() can be simplified by casting
the arguments directly.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
scripts/mod/modpost.c
scripts/mod/modpost.h

index 2f3b0fe6f68d9290b4f21f0f1126048f8cb0dc70..99476a9695c520081b23cc0ecbaeab6850c5c936 100644 (file)
@@ -1410,15 +1410,10 @@ static void get_rel_type_and_sym(struct elf_info *elf, uint64_t r_info,
                return;
        }
 
-       if (is_64bit) {
-               Elf64_Xword r_info64 = r_info;
-
-               r_info = TO_NATIVE(r_info64);
-       } else {
-               Elf32_Word r_info32 = r_info;
-
-               r_info = TO_NATIVE(r_info32);
-       }
+       if (is_64bit)
+               r_info = TO_NATIVE((Elf64_Xword)r_info);
+       else
+               r_info = TO_NATIVE((Elf32_Word)r_info);
 
        *r_type = ELF_R_TYPE(r_info);
        *r_sym = ELF_R_SYM(r_info);
index 6413f26fcb6b45078a3b598a3ec6f5ff80075610..1392afec118cb76a6f05c8ef14db9bd82aa07b3e 100644 (file)
@@ -1,4 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 */
+#include <byteswap.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #define ELF_R_TYPE  ELF64_R_TYPE
 #endif
 
-#if KERNEL_ELFDATA != HOST_ELFDATA
+#define bswap(x) \
+({ \
+       _Static_assert(sizeof(x) == 1 || sizeof(x) == 2 || \
+                      sizeof(x) == 4 || sizeof(x) == 8, "bug"); \
+       (typeof(x))(sizeof(x) == 2 ? bswap_16(x) : \
+                   sizeof(x) == 4 ? bswap_32(x) : \
+                   sizeof(x) == 8 ? bswap_64(x) : \
+                   x); \
+})
 
-static inline void __endian(const void *src, void *dest, unsigned int size)
-{
-       unsigned int i;
-       for (i = 0; i < size; i++)
-               ((unsigned char*)dest)[i] = ((unsigned char*)src)[size - i-1];
-}
+#if KERNEL_ELFDATA != HOST_ELFDATA
 
-#define TO_NATIVE(x)                                           \
-({                                                             \
-       typeof(x) __x;                                          \
-       __endian(&(x), &(__x), sizeof(__x));                    \
-       __x;                                                    \
-})
+#define TO_NATIVE(x) (bswap(x))
 
 #else /* endianness matches */