Currently, crash prints always crash: vmcore: not a supported file format if you try to open a dump file which is not supported. However, it can be misleading if you have a valid ELF core dump, but just use crash for the wrong architecture. In the case I observed the user had a ELF64 x86 dump file and assumed it's x86-64. However, it just was a i386 core dump which was ELF64 because kexec was called with --elf64-core-headers which makes sense if the i386 machine has PAE and possibly more than 4 GiB of physical RAM. After that patch is applied, an example output is Looks like a valid ELF dump, but host architecture (X86_64) \ doesn't match dump architecture (IA64). or if I try to open a PPC64 dump on x86-64: Looks like a valid ELF dump, but host endianess (LE) \ doesn't match target endianess (BE) Please review and consider applying. Signed-off-by: Bernhard Walle <bwalle@xxxxxxx> --- defs.h | 3 ++- netdump.c | 48 +++++++++++++++++++++++++++++++++++++++++++----- tools.c | 9 ++++++++- 3 files changed, 53 insertions(+), 7 deletions(-) --- a/defs.h +++ b/defs.h @@ -3198,7 +3198,8 @@ void stall(ulong); char *pages_to_size(ulong, char *); int clean_arg(void); int empty_list(ulong); -int machine_type(char *); +int machine_type(const char *); +int is_big_endian(void); void command_not_supported(void); void option_not_supported(int); void please_wait(char *); --- a/netdump.c +++ b/netdump.c @@ -36,6 +36,32 @@ static void check_dumpfile_size(char *); #define ELFREAD 0 #define MIN_PAGE_SIZE (4096) + + +/* + * Checks if the machine type of the host matches required_type. + * If not, it prints a short error message for the user. + */ +static int machine_type_error(const char *required_type) +{ + if (machine_type(required_type)) + return 1; + else { + fprintf(stderr, "Looks like a valid ELF dump, but host " + "architecture (%s) doesn't match dump " + "architecture (%s).\n", + MACHINE_TYPE, required_type); + return 0; + } +} + +/* + * Returns endianess in a string + */ +static const char *endianess_to_string(int big_endian) +{ + return big_endian ? "BE" : "LE"; +} /* * Determine whether a file is a netdump/diskdump/kdump creation, @@ -98,6 +124,18 @@ is_netdump(char *file, ulong source_quer * If either kdump difference is seen, presume kdump -- this * is obviously subject to change. */ + + /* check endianess */ + if ((STRNEQ(elf32->e_ident, ELFMAG) || STRNEQ(elf64->e_ident, ELFMAG)) && + (elf32->e_type == ET_CORE || elf64->e_type == ET_CORE) && + (elf32->e_ident[EI_DATA] == ELFDATA2LSB && is_big_endian()) || + (elf32->e_ident[EI_DATA] == ELFDATA2MSB && !is_big_endian())) + fprintf(stderr, "Looks like a valid ELF dump, but host " + "endianess (%s) doesn't match target " + "endianess (%s)\n", + endianess_to_string(is_big_endian()), + endianess_to_string(elf32->e_ident[EI_DATA] == ELFDATA2MSB)); + if (STRNEQ(elf32->e_ident, ELFMAG) && (elf32->e_ident[EI_CLASS] == ELFCLASS32) && (elf32->e_ident[EI_DATA] == ELFDATA2LSB) && @@ -108,7 +146,7 @@ is_netdump(char *file, ulong source_quer switch (elf32->e_machine) { case EM_386: - if (machine_type("X86")) + if (machine_type_error("X86")) break; default: goto bailout; @@ -133,28 +171,28 @@ is_netdump(char *file, ulong source_quer { case EM_IA_64: if ((elf64->e_ident[EI_DATA] == ELFDATA2LSB) && - machine_type("IA64")) + machine_type_error("IA64")) break; else goto bailout; case EM_PPC64: if ((elf64->e_ident[EI_DATA] == ELFDATA2MSB) && - machine_type("PPC64")) + machine_type_error("PPC64")) break; else goto bailout; case EM_X86_64: if ((elf64->e_ident[EI_DATA] == ELFDATA2LSB) && - machine_type("X86_64")) + machine_type_error("X86_64")) break; else goto bailout; case EM_386: if ((elf64->e_ident[EI_DATA] == ELFDATA2LSB) && - machine_type("X86")) + machine_type_error("X86")) break; else goto bailout; --- a/tools.c +++ b/tools.c @@ -4518,11 +4518,18 @@ empty_list(ulong list_head_addr) } int -machine_type(char *type) +machine_type(const char *type) { return STREQ(MACHINE_TYPE, type); } +int +is_big_endian(void) +{ + unsigned short value = 0xff; + return *((unsigned char *)&value) != 0xff; +} + void command_not_supported() { -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility