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