mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-28 16:52:18 +00:00
modpost: detect endianness on run-time
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>
This commit is contained in:
parent
4f32f799a9
commit
a660deb0f1
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -62,15 +62,8 @@
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user