Bernhard Walle wrote:
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.

I like the addition of the machine-type verification error message.

But why bother with the endian check?  Using your ppc64/x86_64
example, an architecture check/error message would make far
more sense.  The "endianness" error message implies that if
they re-compiled their ppc64 kernel little-endian that things
would work.

Dave





Signed-off-by: Bernhard Walle <[EMAIL PROTECTED]>

---
 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
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility


--
Crash-utility mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to