On Sat, Oct 7, 2023 at 10:05 AM Masahiro Yamada <masahiroy@xxxxxxxxxx> wrote: > > 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@xxxxxxxxxx> > --- > > scripts/mod/modpost.c | 13 ++++--------- > scripts/mod/modpost.h | 25 ++++++++++++------------- > 2 files changed, 16 insertions(+), 22 deletions(-) > > diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c > index 2f3b0fe6f68d..99476a9695c5 100644 > --- a/scripts/mod/modpost.c > +++ b/scripts/mod/modpost.c > @@ -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); > diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h > index 6413f26fcb6b..1392afec118c 100644 > --- a/scripts/mod/modpost.h > +++ b/scripts/mod/modpost.h > @@ -1,4 +1,5 @@ > /* SPDX-License-Identifier: GPL-2.0 */ > +#include <byteswap.h> > #include <stdbool.h> > #include <stdio.h> > #include <stdlib.h> > @@ -51,21 +52,19 @@ > #define ELF_R_TYPE ELF64_R_TYPE > #endif > > +#define bswap(x) \ > +({ \ > + _Static_assert(sizeof(x) == 1 || sizeof(x) == 2 || \ Seems fine, but do we need to support folks trying to swap 1B values? i.e. is someone calling TO_NATIVE with 1B values? Seems silly unless one of these types is variable length dependent on the target machine type? Reviewed-by: Nick Desaulniers <ndesaulniers@xxxxxxxxxx> > + 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); \ > +}) > + > #if KERNEL_ELFDATA != HOST_ELFDATA > > -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]; > -} > - > -#define TO_NATIVE(x) \ > -({ \ > - typeof(x) __x; \ > - __endian(&(x), &(__x), sizeof(__x)); \ > - __x; \ > -}) > +#define TO_NATIVE(x) (bswap(x)) > > #else /* endianness matches */ > > -- > 2.39.2 > -- Thanks, ~Nick Desaulniers