]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[gdb/symtab] Fix segfault with dwp file
authorTom de Vries <tdevries@suse.de>
Fri, 15 Nov 2024 21:48:37 +0000 (22:48 +0100)
committerTom de Vries <tdevries@suse.de>
Fri, 15 Nov 2024 21:48:37 +0000 (22:48 +0100)
Consider the following test-case:
...
$ cat test.c
int main (void) { return 0; }
$ clang -g -gsplit-dwarf test.c -o test
$ llvm-dwp -e test -o test.dwp
...

This runs into a segmentation fault:
...
$ gdb -q -batch test
Fatal signal: Segmentation fault
...

The segmentation fault happens because in read_dwo_str_index this line sets p
to nullptr:
...
  const gdb_byte *p = reader->dwo_file->sections.str_offsets.buffer;
...
while the following code expects it to point to some data.

The section we're trying to read is:
...
(gdb) p reader->dwo_file->sections.str_offsets
$4 = {s = {section = 0xffffcc00a9d0, containing_section = 0xffffcc00a9d0},
  buffer = 0x0, size = 28, virtual_offset = 0, readin = false, is_virtual = true}
...

At first glance, the section is not readin, but actually it is.

This is a virtual section, meaning part of a containing section:
...
(gdb) p *reader->dwo_file->sections.str_offsets.s.containing_section
$8 = {s = {section = 0xffffcc00cde8, containing_section = 0xffffcc00cde8},
  buffer = 0xffffcc009650 "\030", size = 28, virtual_offset = 0, readin = true,
  is_virtual = false}
...
which is readin.

Fix this in create_dwp_v2_or_v5_section by initializing the buffer of the
virtual section using the buffer of the containing section:
...
  result.buffer = section->buffer + offset;
...

Unfortunately it's difficult to write a test-case for this.  We'll have to
teach the dwarf assembler to generate dwp files.

Tested on aarch64-linux.

This is a partial fix for PR symtab/31497.

Approved-By: Tom Tromey <tom@tromey.com>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31497

gdb/dwarf2/read.c

index 5f0b0d4e5d68710f249ffa080534991bb179b052..1c9706dcd2a0b89654688636e340c8420d80f29a 100644 (file)
@@ -8615,6 +8615,9 @@ create_dwp_v2_or_v5_section (dwarf2_per_objfile *per_objfile,
 
   result.virtual_offset = offset;
   result.size = size;
+  gdb_assert (section->readin);
+  result.readin = true;
+  result.buffer = section->buffer + offset;
   return result;
 }