]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
modpost: detect endianness on run-time
authorMasahiro Yamada <masahiroy@kernel.org>
Sat, 27 Jul 2024 07:42:02 +0000 (16:42 +0900)
committerMasahiro Yamada <masahiroy@kernel.org>
Sun, 1 Sep 2024 11:33:32 +0000 (20:33 +0900)
Endianness is currently detected on compile-time, but we can defer this
until run-time. This change avoids re-executing scripts/mod/mk_elfconfig
even if modpost in the linux-headers package needs to be rebuilt for a
foreign architecture.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
scripts/mod/mk_elfconfig.c
scripts/mod/modpost.c
scripts/mod/modpost.h

index aca96b3aada0c28455381d525aed7296c805d8c0..e8cee4e4bc733a29f760722ecad6a19b2c5fb4e9 100644 (file)
@@ -8,7 +8,6 @@ int
 main(int argc, char **argv)
 {
        unsigned char ei[EI_NIDENT];
-       union { short s; char c[2]; } endian_test;
 
        if (fread(ei, 1, EI_NIDENT, stdin) != EI_NIDENT) {
                fprintf(stderr, "Error: input truncated\n");
@@ -28,24 +27,6 @@ main(int argc, char **argv)
        default:
                exit(1);
        }
-       switch (ei[EI_DATA]) {
-       case ELFDATA2LSB:
-               printf("#define KERNEL_ELFDATA ELFDATA2LSB\n");
-               break;
-       case ELFDATA2MSB:
-               printf("#define KERNEL_ELFDATA ELFDATA2MSB\n");
-               break;
-       default:
-               exit(1);
-       }
-
-       endian_test.s = 0x0102;
-       if (memcmp(endian_test.c, "\x01\x02", 2) == 0)
-               printf("#define HOST_ELFDATA ELFDATA2MSB\n");
-       else if (memcmp(endian_test.c, "\x02\x01", 2) == 0)
-               printf("#define HOST_ELFDATA ELFDATA2LSB\n");
-       else
-               exit(1);
 
        return 0;
 }
index d16d0ace277513795f4c4ab6103c6d1fbc085c22..bfd758ad9e4f5f0359b7fbeb4c57bbf5ebe4d449 100644 (file)
@@ -50,6 +50,9 @@ static bool error_occurred;
 
 static bool extra_warn;
 
+bool target_is_big_endian;
+bool host_is_big_endian;
+
 /*
  * Cut off the warnings when there are too many. This typically occurs when
  * vmlinux is missing. ('make modules' without building vmlinux.)
@@ -438,6 +441,18 @@ static int parse_elf(struct elf_info *info, const char *filename)
                /* Not an ELF file - silently ignore it */
                return 0;
        }
+
+       switch (hdr->e_ident[EI_DATA]) {
+       case ELFDATA2LSB:
+               target_is_big_endian = false;
+               break;
+       case ELFDATA2MSB:
+               target_is_big_endian = true;
+               break;
+       default:
+               fatal("target endian is unknown\n");
+       }
+
        /* Fix endianness in ELF header */
        hdr->e_type      = TO_NATIVE(hdr->e_type);
        hdr->e_machine   = TO_NATIVE(hdr->e_machine);
@@ -2117,6 +2132,25 @@ struct dump_list {
        const char *file;
 };
 
+static void check_host_endian(void)
+{
+       static const union {
+               short s;
+               char c[2];
+       } endian_test = { .c = {0x01, 0x02} };
+
+       switch (endian_test.s) {
+       case 0x0102:
+               host_is_big_endian = true;
+               break;
+       case 0x0201:
+               host_is_big_endian = false;
+               break;
+       default:
+               fatal("Unknown host endian\n");
+       }
+}
+
 int main(int argc, char **argv)
 {
        struct module *mod;
@@ -2181,6 +2215,8 @@ int main(int argc, char **argv)
                }
        }
 
+       check_host_endian();
+
        list_for_each_entry_safe(dl, dl2, &dump_lists, list) {
                read_dump(dl->file);
                list_del(&dl->list);
index 58197b34a3c851113ece9230352f9e213233e706..54ba9431713f2b71f8e668d26892a2f936dd61a9 100644 (file)
                    x); \
 })
 
-#if KERNEL_ELFDATA != HOST_ELFDATA
-
-#define TO_NATIVE(x) (bswap(x))
-
-#else /* endianness matches */
-
-#define TO_NATIVE(x) (x)
-
-#endif
+#define TO_NATIVE(x)   \
+       (target_is_big_endian == host_is_big_endian ? x : bswap(x))
 
 #define NOFAIL(ptr)   do_nofail((ptr), #ptr)
 
@@ -187,6 +180,8 @@ void add_moddevtable(struct buffer *buf, struct module *mod);
 void get_src_version(const char *modname, char sum[], unsigned sumlen);
 
 /* from modpost.c */
+extern bool target_is_big_endian;
+extern bool host_is_big_endian;
 char *read_text_file(const char *filename);
 char *get_line(char **stringp);
 void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym);