[Crash-utility] [PATCH 01/16] Add MIPS64 framework code support

Youling Tang tangyouling at loongson.cn
Sat Mar 13 03:57:19 UTC 2021


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




More information about the Crash-utility mailing list