Re: [PATCH 01/16] Add MIPS64 framework code support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Kazu,

On 03/12/2021 04:04 PM, HAGIO KAZUHITO(萩尾 一仁) wrote:
-----Original Message-----
Hi Kazu,

On 03/12/2021 12:21 PM, HAGIO KAZUHITO(萩尾 一仁) wrote:

-----Original Message-----
--- a/diskdump.c
+++ b/diskdump.c
@@ -594,6 +594,9 @@ restart:
    	else if (STRNEQ(header->utsname.machine, "mips") &&
    	    machine_type_mismatch(file, "MIPS", NULL, 0))
    		goto err;
+	else if (STRNEQ(header->utsname.machine, "mips64") &&
+	    machine_type_mismatch(file, "MIPS", NULL, 0))
+		goto err;
Why do you make MACHINE_TYPE the same as the MIPS one?
With this, doesn't a MIPS64 crash match a MIPS vmcore?
The value of the machine type e_machine in mips32 or mips64 is MIPS, which
corresponds to EM_MIPS.
The definition in gdb-7.6/include/elf/common.h:110 is as follows:
       #define EM_MIPS        8        /* MIPS R3000 */
But there is no related definition of EM_MIPS64 or other mips64, so both
mips32 and mips64 should use EM_MIPS, and the corresponding e_machine is
MIPS.

If the MACHINE_TYPE of mips64 is defined as MIPS64, as follows:
       define MACHINE_TYPE     "MIPS64"

The following error will appear when running crash:
       WARNING: machine type mismatch:
                 crash utility: MIPS64
                 vmcore: MIPS
Then, is there any problem with this?
    machine_type_mismatch(file, "MIPS64", NULL, 0))

This can prevent a mips64 crash from trying to open a mips32 vmcore
and the reverse.
Read the ELF header information of vmocre (whether it is mips32 or mips64),
and the obtained machine type is MIPS, not MIPS64. In mips64, if you use
machine_type_mismatch(file, "MIPS64", NULL, 0)), there will be a machine
type
mismatch. You can only use machine_type_mismatch(file, "MIPS", NULL, 0)),
only then It can be successfully matched to the machine type.
Probably I misunderstand something, but then need to know it..

The machine_type_mismatch() doesn't use the ELF's EM_MIPS value.
Why do we need to match crash's MACHINE_TYPE with ELF's EM_MIPS?

int
machine_type(char *type)
{
         return STREQ(MACHINE_TYPE, type);
}

int
machine_type_mismatch(char *file, char *e_machine, char *alt, ulong query)
{
         if (machine_type(e_machine) || machine_type(alt))
                 return FALSE;

         if (query == KDUMP_LOCAL)  /* already printed by NETDUMP_LOCAL */
                 return TRUE;

         error(WARNING, "machine type mismatch:\n");

         fprintf(fp, "         crash utility: %s\n", MACHINE_TYPE);
         fprintf(fp, "         %s: %s%s%s\n\n", file, e_machine,
                 alt ? " or " : "", alt ? alt : "");
return TRUE;
}

Without the following hunk, EM_MIPS has been used only for ELF32 in symbols.c.
In symbols.c

int
is_kernel(char *file)
{
...

    swap = (((eheader[EI_DATA] == ELFDATA2LSB) &&
             (__BYTE_ORDER == __BIG_ENDIAN)) ||
            ((eheader[EI_DATA] == ELFDATA2MSB) &&
             (__BYTE_ORDER == __LITTLE_ENDIAN)));

            if ((elf32->e_ident[EI_CLASS] == ELFCLASS32) &&
            (swap16(elf32->e_type, swap) == ET_EXEC) &&
            (swap32(elf32->e_version, swap) == EV_CURRENT)) {
            switch (swap16(elf32->e_machine, swap))
            {
            ...

            case EM_PPC:
                if (machine_type_mismatch(file, "PPC", NULL, 0))
                    goto bailout;
                break;

            case EM_MIPS:
                if (machine_type_mismatch(file, "MIPS", NULL, 0))
                    goto bailout;
                break;

            case EM_SPARCV9:
                if (machine_type_mismatch(file, "SPARC64", NULL, 0))
                    goto bailout;
                break;

            default:
                if (machine_type_mismatch(file, "(unknown)", NULL, 0))
                    goto bailout;
            }

            if (endian_mismatch(file, elf32->e_ident[EI_DATA], 0))
                goto bailout;

        } else if ((elf64->e_ident[EI_CLASS] == ELFCLASS64) &&
            ((swap16(elf64->e_type, swap) == ET_EXEC) ||
             (swap16(elf64->e_type, swap) == ET_DYN)) &&
            (swap32(elf64->e_version, swap) == EV_CURRENT)) {
            switch (swap16(elf64->e_machine, swap))
            {
            ...

            case EM_AARCH64:
                if (machine_type_mismatch(file, "ARM64", NULL, 0))
                    goto bailout;
                break;

            case EM_MIPS:
                if (machine_type_mismatch(file, "MIPS", NULL, 0))
                    goto bailout;
                break;

            default:
                if (machine_type_mismatch(file, "(unknown)", NULL, 0))
                    goto bailout;
            }
    ...
}

switch (swap16(elf32->e_machine, swap))
switch (swap16(elf64->e_machine, swap))

As can be seen from the above code switch statement, it will read the value
of e_machine in ELF32 or ELF64 to determine which EM_XXX is.
In mips32 and mips64 architectures, the EM_MIPS value is shared by ELF32 and
ELF64, and there is no EM_MIPS64 corresponding to ELF64.
Modify the code similar to the following, replace all the EM_MIPS in the mips64 part with EM_MIPS_X (because there is no ME_MIPS64 in the gdb definition, you
can only find a similar existing definition instead)

    switch (swap16(elf64->e_machine, swap))
    {
    ...
        case EM_MIPS_X:
            if (machine_type_mismatch(file, "MIPS64", NULL, 0))
                goto bailout;
            break;

If the code is changed to the above, there will be an error like the following:
    WARNING: machine type mismatch:
         crash utility: MIPS64
         vmlinux: (unknown)

In my mips64 machine environment, I will enter the if branch of elf64, and then read the value of e_machine, the value read is 8 (EM_MIPS), and there is only
EM_MIPS_X in the case, so it cannot be matched, and it will eventually enter
the default In the branch, the file type obtained is unknown.


Thanks,
Youling
--- a/symbols.c
+++ b/symbols.c
@@ -3636,6 +3636,11 @@ is_kernel(char *file)
                                 goto bailout;
                         break;
+ case EM_MIPS:
+                       if (machine_type_mismatch(file, "MIPS", NULL, 0))
+                               goto bailout;
+                       break;
+
                 default:
                         if (machine_type_mismatch(file, "(unknown)", NULL, 0))
                                 goto bailout;
@@ -3890,6 +3895,11 @@ is_shared_object(char *file)
                         if (machine_type("SPARC64"))
                                 return TRUE;
                         break;
+
+               case EM_MIPS:
+                       if (machine_type("MIPS"))
+                               return TRUE;
+                       break;
                 }

So I thought that meybe we can also change these ELF64 cases to "MIPS64"
with defining MACHINE_TYPE as "MIPS64".

This is wrong?  e.g. mips32 also can use an ELF64 kernel/module binary?

Thanks,
Kazu

# readelf -h vmcore
...
     Type:                              CORE (Core file)
     Machine:                           MIPS R3000
...

Therefore, the MACHINE_TYPE of mips32 and mips64 both define MIPS.

Thanks,
Youling

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://listman.redhat.com/mailman/listinfo/crash-utility




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux