PR toolchain/56268

For NetBSD/m68k, program header is erroneously readable from core dump,
although a page containing it is missing. This spoils relocation for
the main executable, and debugging with core dumps becomes impossible,
as described in the PR.

In order to avoid this failure, add consistency check for program header;
for NetBSD, 1st entry of program header refers program header itself. If
this is not the case, we should be reading random garbage from core dump.

Yes, this is a kind of the hackest hack. But, unable to debug with core
dump is critical. Therefore, I commit this workaround temporarily until
the real cause is found and fixed.

Note that this is not a recent regression for GDB nor kernel, as
mentioned in the PR. These from netbsd-8 and -9 fail in the same way
without this hack.
This commit is contained in:
rin 2022-06-26 08:28:07 +00:00
parent 89d3f87095
commit b9429f260c
1 changed files with 34 additions and 0 deletions

View File

@ -541,6 +541,40 @@ read_program_header (int type, int *p_arch_size, CORE_ADDR *base_addr)
if (target_read_memory (sect_addr, buf.data (), sect_size))
return {};
#if defined(__NetBSD__) && defined(__m68k__)
/*
* XXX PR toolchain/56268
*
* For NetBSD/m68k, program header is erroneously readable from core dump,
* although a page containing it is missing. This spoils relocation for
* the main executable, and debugging with core dumps becomes impossible,
* as described in toolchain/56268.
*
* In order to avoid this failure, we carry out consistency check for
* program header; for NetBSD, 1st entry of program header refers program
* header itself. If this is not the case, we should be reading random
* garbage from core dump.
*/
if (type == -1 && arch_size == 32)
{
Elf32_External_Phdr phdr;
int p_type, p_filesz, p_memsz;
if (target_read_memory (at_phdr, (gdb_byte *)&phdr, sizeof (phdr)))
return {};
p_type = extract_unsigned_integer ((gdb_byte *) phdr.p_type, 4,
byte_order);
p_filesz = extract_unsigned_integer ((gdb_byte *)phdr.p_filesz, 4,
byte_order);
p_memsz = extract_unsigned_integer ((gdb_byte *)phdr.p_memsz, 4,
byte_order);
if (p_type != PT_PHDR || p_filesz != sect_size || p_memsz != sect_size)
return {};
}
#endif
if (p_arch_size)
*p_arch_size = arch_size;
if (base_addr)