From 0a0f4c0179106ee4b8e56649c549f4175ebba994 Mon Sep 17 00:00:00 2001 From: Jordan Rupprecht Date: Mon, 25 Feb 2019 12:21:01 -0800 Subject: [PATCH] Fix crash when loading dwp files When loading dwp files, we create an array of ELF sections indexed by the ELF section index in the dwp file. The size of this array is calculated by section_count, as returned by bfd_count_sections, plus 1 (to account for the null section at index 0). However, when loading the bfd file, strtab/symtab sections are not added to the list, nor do they increment section_count, so section_count is actually smaller than the number of ELF sections. This happens to work when using GNU dwp, which lays out .debug section first, with sections like .shstrtab coming at the end. Other tools, like llvm-dwp, put .strtab first, and gdb crashes when loading those dwp files. For instance, with the current state of gdb, loading a file like this: $ readelf -SW [ 0] [ 1] .debug_foo PROGBITS ... [ 2] .strtab STRTAB ... ... results in section_count = 2 (.debug is the only thing placed into bfd->sections, so section_count + 1 == 2), and sectp->this_idx = 1 when mapping over .debug_foo in dwarf2_locate_common_dwp_sections, which passes the assertion that 1 < 2. However, using a dwp file produced by llvm-dwp: $ readelf -SW [ 0] [ 1] .strtab STRTAB ... [ 2] .debug_foo PROGBITS ... ... results in section_count = 2 (.debug is the only thing placed into bfd->sections, so section_count + 1 == 2), and sectp->this_idx = 2 when mapping over .debug_foo in dwarf2_locate_common_dwp_sections, which fails the assertion that 2 < 2. The assertion hit is: gdb/dwarf2read.c:13009: internal-error: void dwarf2_locate_common_dwp_sections(bfd*, asection*, void*): Assertion `elf_section_nr < dwp_file->num_sections' failed. This patch changes the calculation of section_count to use elf_numsections, which should return the actual number of ELF sections. --- gdb/ChangeLog | 6 ++++++ gdb/dwarf2read.c | 3 +-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 118f175..c2340e6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2019-02-25 Jordan Rupprecht + + * dwarf2read.c (open_and_init_dwp_file): Call + elf_numsections instead of bfd_count_sections to initialize + dwp_file->num_sections. + 2019-02-25 Tom Tromey * solib-darwin.c (darwin_get_dyld_bfd): Don't release dyld_bfd. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 98f46e0..2908a23 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -13230,8 +13230,7 @@ open_and_init_dwp_file (struct dwarf2_per_objfile *dwarf2_per_objfile) std::unique_ptr dwp_file (new struct dwp_file (name, std::move (dbfd))); - /* +1: section 0 is unused */ - dwp_file->num_sections = bfd_count_sections (dwp_file->dbfd) + 1; + dwp_file->num_sections = elf_numsections (dwp_file->dbfd); dwp_file->elf_sections = OBSTACK_CALLOC (&objfile->objfile_obstack, dwp_file->num_sections, asection *); -- 2.7.4