Skip to content

Commit

Permalink
modpost: define TO_NATIVE() using bswap_* functions
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Nick Desaulniers <[email protected]>
  • Loading branch information
masahir0y committed Oct 18, 2023
1 parent ac96a15 commit bd78c9d
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 22 deletions.
13 changes: 4 additions & 9 deletions scripts/mod/modpost.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
25 changes: 12 additions & 13 deletions scripts/mod/modpost.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <byteswap.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -51,21 +52,19 @@
#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 */

Expand Down

0 comments on commit bd78c9d

Please sign in to comment.