diff options
author | Andrew Burgess <andrew.burgess@embecosm.com> | 2019-12-06 23:12:29 +0000 |
---|---|---|
committer | Andrew Burgess <andrew.burgess@embecosm.com> | 2020-01-13 23:57:42 +0000 |
commit | 44e4c7757a733949d511d97a7d95db913f423f1b (patch) | |
tree | d56563338f8435b7173b4675f6bf1075f78acd41 /gdb/elfread.c | |
parent | d93c6db74b7a9d6154f55f92d96f38819838bc99 (diff) | |
download | gdb-44e4c7757a733949d511d97a7d95db913f423f1b.zip gdb-44e4c7757a733949d511d97a7d95db913f423f1b.tar.gz gdb-44e4c7757a733949d511d97a7d95db913f423f1b.tar.bz2 |
gdb: Handle malformed ELF, symbols in non-allocatable sections
I ended up debugging a malformed ELF where a section containing
executable code was not correctly marked as allocatable. Before
realising the ELF was corrupted I tried to place a breakpoint on a
symbol in the non-allocatable, executable section, and GDB crashed.
Though trying to debug such an ELF clearly isn't going to go well I
would prefer, as far as possible, that any input, no matter how
corrupted, not crash GDB.
The crash occurs when trying to set a breakpoint on the name of a
function from the corrupted section. GDB converts the symbol to a
symtab_and_line, and looks up a suitable section for this.
The problem is that the section is actually an obj_section, which is
stored in the table within the objfile, and we only initialise this
table for allocatable sections (see add_to_objfile_sections_full in
objfiles.c). So, if the symbol is in a non-allocatable section then
we end up referencing an uninitialised obj_section.
Later we call get_sal_arch on the symtab_and_line, which calls
get_objfile_arch, which uses the objfile from the uninitialised
obj_section, which will be nullptr, at which point GDB crashes.
The fix I propose here is that when we setup the section references on
msymbols, we should check if the bfd_section being referenced is
allocatable or not. If it is not then we should set the section
reference back to the default 0 section (see how MSYMBOL_OBJ_SECTION
and SYMBOL_OBJ_SECTION treat the 0 section index).
With this fix in place GDB no longer crashes. Instead GDB creates the
breakpoint at the non-allocated address, and then fails, with an
error, when it tries to insert the breakpoint.
gdb/ChangeLog:
* elfread.c (record_minimal_symbol): Set section index to 0 for
non-allocatable sections.
gdb/testsuite/ChangeLog:
* gdb.dwarf2/dw2-bad-elf-other.S: New file.
* gdb.dwarf2/dw2-bad-elf.c: New file.
* gdb.dwarf2/dw2-bad-elf.exp: New file.
Change-Id: Ie05436ab4c6a71440304d20ee639dfb021223f8b
Diffstat (limited to 'gdb/elfread.c')
-rw-r--r-- | gdb/elfread.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/gdb/elfread.c b/gdb/elfread.c index 9a6ce0e..453bca5 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -210,11 +210,16 @@ record_minimal_symbol (minimal_symbol_reader &reader, || ms_type == mst_text_gnu_ifunc) address = gdbarch_addr_bits_remove (gdbarch, address); + /* We only setup section information for allocatable sections. Usually + we'd only expect to find msymbols for allocatable sections, but if the + ELF is malformed then this might not be the case. In that case don't + create an msymbol that references an uninitialised section object. */ + int section_index = 0; + if ((bfd_section_flags (bfd_section) & SEC_ALLOC) == SEC_ALLOC) + section_index = gdb_bfd_section_index (objfile->obfd, bfd_section); + struct minimal_symbol *result - = reader.record_full (name, copy_name, address, - ms_type, - gdb_bfd_section_index (objfile->obfd, - bfd_section)); + = reader.record_full (name, copy_name, address, ms_type, section_index); if ((objfile->flags & OBJF_MAINLINE) == 0 && (ms_type == mst_data || ms_type == mst_bss)) result->maybe_copied = 1; |