gdb/bfd: avoid crash when architecture is forced to csky or riscv
I built GDB with `--enable-targets=all`, then started GDB passing it an x86-64 executable, finally I ran 'maint selftest', and observed GDB crash like this: BFD: BFD (GNU Binutils) 2.36.50.20210519 assertion fail ../../src/bfd/hash.c:438 Aborted (core dumped) The problem originates from two locations, for example in csky-dis.c (csky_get_disassembler) where we do this: const char *sec_name = NULL; ... sec_name = get_elf_backend_data (abfd)->obj_attrs_section; if (bfd_get_section_by_name (abfd, sec_name) != NULL) ... We end up in here because during the selftests GDB forces the architecture to be csky, but the BFD being accessed is still of type x86-64. As a result obj_attrs_section returns NULL, which means we end up passing NULL to bfd_get_section_by_name. If we follow the function calls from bfd_get_section_by_name we eventually end up in bfd_hash_hash, which asserts that the string (i.e. the name) is not NULL. The same crash can be reproduced in GDB without using the selftests, for example: (gdb) file x86_64.elf (gdb) start (gdb) set architecture csky (gdb) disassemble main Dump of assembler code for function main: BFD: BFD (GNU Binutils) 2.36.50.20210519 assertion fail ../../src/bfd/hash.c:438 Aborted (core dumped) The fix I propose here is to have bfd_get_section_by_name return NULL if name is ever NULL. For consistency I updated bfd_get_section_by_name_if in the same way, even though I'm not hitting any problems along that code path right now. I looked through the source tree and removed two NULL checks in bfd/dwarf2.c which are no longer needed, its possible that there are additional NULL checks that could be removed, I just didn't find them. bfd/ChangeLog: * section.c (bfd_get_section_by_name): Return NULL if name is NULL. (bfd_get_section_by_name_if): Likewise. * dwarf2.c (read_section): Remove unneeded NULL check. (find_debug_info): Likewise.
This commit is contained in:
parent
8baee38bfe
commit
427e4066af
3 changed files with 18 additions and 8 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2021-05-20 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
|
* section.c (bfd_get_section_by_name): Return NULL if name is
|
||||||
|
NULL.
|
||||||
|
(bfd_get_section_by_name_if): Likewise.
|
||||||
|
* dwarf2.c (read_section): Remove unneeded NULL check.
|
||||||
|
(find_debug_info): Likewise.
|
||||||
|
|
||||||
2021-05-19 Nick Clifton <nickc@redhat.com>
|
2021-05-19 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* plugin.c (bfd_plugin_open_input): Inform the user if the limit
|
* plugin.c (bfd_plugin_open_input): Inform the user if the limit
|
||||||
|
|
12
bfd/dwarf2.c
12
bfd/dwarf2.c
|
@ -545,8 +545,7 @@ read_section (bfd * abfd,
|
||||||
if (msec == NULL)
|
if (msec == NULL)
|
||||||
{
|
{
|
||||||
section_name = sec->compressed_name;
|
section_name = sec->compressed_name;
|
||||||
if (section_name != NULL)
|
msec = bfd_get_section_by_name (abfd, section_name);
|
||||||
msec = bfd_get_section_by_name (abfd, section_name);
|
|
||||||
}
|
}
|
||||||
if (msec == NULL)
|
if (msec == NULL)
|
||||||
{
|
{
|
||||||
|
@ -4226,12 +4225,9 @@ find_debug_info (bfd *abfd, const struct dwarf_debug_section *debug_sections,
|
||||||
return msec;
|
return msec;
|
||||||
|
|
||||||
look = debug_sections[debug_info].compressed_name;
|
look = debug_sections[debug_info].compressed_name;
|
||||||
if (look != NULL)
|
msec = bfd_get_section_by_name (abfd, look);
|
||||||
{
|
if (msec != NULL)
|
||||||
msec = bfd_get_section_by_name (abfd, look);
|
return msec;
|
||||||
if (msec != NULL)
|
|
||||||
return msec;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (msec = abfd->sections; msec != NULL; msec = msec->next)
|
for (msec = abfd->sections; msec != NULL; msec = msec->next)
|
||||||
if (startswith (msec->name, GNU_LINKONCE_INFO))
|
if (startswith (msec->name, GNU_LINKONCE_INFO))
|
||||||
|
|
|
@ -898,6 +898,9 @@ bfd_get_section_by_name (bfd *abfd, const char *name)
|
||||||
{
|
{
|
||||||
struct section_hash_entry *sh;
|
struct section_hash_entry *sh;
|
||||||
|
|
||||||
|
if (name == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
sh = section_hash_lookup (&abfd->section_htab, name, false, false);
|
sh = section_hash_lookup (&abfd->section_htab, name, false, false);
|
||||||
if (sh != NULL)
|
if (sh != NULL)
|
||||||
return &sh->section;
|
return &sh->section;
|
||||||
|
@ -1006,6 +1009,9 @@ bfd_get_section_by_name_if (bfd *abfd, const char *name,
|
||||||
struct section_hash_entry *sh;
|
struct section_hash_entry *sh;
|
||||||
unsigned long hash;
|
unsigned long hash;
|
||||||
|
|
||||||
|
if (name == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
sh = section_hash_lookup (&abfd->section_htab, name, false, false);
|
sh = section_hash_lookup (&abfd->section_htab, name, false, false);
|
||||||
if (sh == NULL)
|
if (sh == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue