Skip to content

Commit bd78c9d

Browse files
committed
modpost: define TO_NATIVE() using bswap_* functions
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>
1 parent ac96a15 commit bd78c9d

2 files changed

Lines changed: 16 additions & 22 deletions

File tree

scripts/mod/modpost.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,15 +1410,10 @@ static void get_rel_type_and_sym(struct elf_info *elf, uint64_t r_info,
14101410
return;
14111411
}
14121412

1413-
if (is_64bit) {
1414-
Elf64_Xword r_info64 = r_info;
1415-
1416-
r_info = TO_NATIVE(r_info64);
1417-
} else {
1418-
Elf32_Word r_info32 = r_info;
1419-
1420-
r_info = TO_NATIVE(r_info32);
1421-
}
1413+
if (is_64bit)
1414+
r_info = TO_NATIVE((Elf64_Xword)r_info);
1415+
else
1416+
r_info = TO_NATIVE((Elf32_Word)r_info);
14221417

14231418
*r_type = ELF_R_TYPE(r_info);
14241419
*r_sym = ELF_R_SYM(r_info);

scripts/mod/modpost.h

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
2+
#include <byteswap.h>
23
#include <stdbool.h>
34
#include <stdio.h>
45
#include <stdlib.h>
@@ -51,21 +52,19 @@
5152
#define ELF_R_TYPE ELF64_R_TYPE
5253
#endif
5354

54-
#if KERNEL_ELFDATA != HOST_ELFDATA
55+
#define bswap(x) \
56+
({ \
57+
_Static_assert(sizeof(x) == 1 || sizeof(x) == 2 || \
58+
sizeof(x) == 4 || sizeof(x) == 8, "bug"); \
59+
(typeof(x))(sizeof(x) == 2 ? bswap_16(x) : \
60+
sizeof(x) == 4 ? bswap_32(x) : \
61+
sizeof(x) == 8 ? bswap_64(x) : \
62+
x); \
63+
})
5564

56-
static inline void __endian(const void *src, void *dest, unsigned int size)
57-
{
58-
unsigned int i;
59-
for (i = 0; i < size; i++)
60-
((unsigned char*)dest)[i] = ((unsigned char*)src)[size - i-1];
61-
}
65+
#if KERNEL_ELFDATA != HOST_ELFDATA
6266

63-
#define TO_NATIVE(x) \
64-
({ \
65-
typeof(x) __x; \
66-
__endian(&(x), &(__x), sizeof(__x)); \
67-
__x; \
68-
})
67+
#define TO_NATIVE(x) (bswap(x))
6968

7069
#else /* endianness matches */
7170

0 commit comments

Comments
 (0)