[gdb/symtab] Work around a gcc PR fixed in gcc 9
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gdb_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-arm |
success
|
Test passed
|
Commit Message
When running test-case gdb.base/bg-execution-repeat.exp with target board
dwarf5-fission-debug-types, I get:
...
(gdb) break -qualified main^M
Offset from DW_FORM_GNU_str_index or DW_FORM_strx pointing outside of \
.debug_str.dwo section in CU at offset 0x0 [in module bg-execution-repeat]^M
Offset from DW_FORM_GNU_str_index or DW_FORM_strx pointing outside of \
.debug_str.dwo section in CU at offset 0x0 [in module bg-execution-repeat]^M
(gdb) FAIL: $exp: c&: gdb_breakpoint: set breakpoint at main
...
This happens with gcc 7 and 8, but not with gcc 9 and later.
We're using dwarf5, so the .debug_str_offsets section is supposed to have a
header, but there's none:
...
.section .debug_str_offsets.dwo,"e",@progbits
.long 0 # indexed string 0x0: do_wait
.long 0x8 # indexed string 0x1: unsigned int
.long 0x15 # indexed string 0x2: wait
...
In other words, we have a v4-style .debug_str_offsets section.
Workaround this by detecting that it's not a valid v5 header by comparing the
initial length to the the section size, and handling it as a v4 section.
IWBN to enable this workaround only for gcc version < 9, but unfortunately the
workaround is required to correctly read the producer string, so that's not
possible.
Tested on x86_64-linux.
PR symtab/32861
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32861
---
gdb/dwarf2/read.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
base-commit: 6fe4e5bd10b996428a557e036c07c5839a8e0a49
@@ -15361,18 +15361,33 @@ cutu_reader::read_dwo_str_index (ULONGEST str_index)
{
unsigned offset_size;
ULONGEST str_offsets_base;
+
+ unsigned int bytes_read = 0;
+ bfd *abfd = m_dwo_file->sections.str_offsets.get_bfd_owner ();
+ const gdb_byte *p = m_dwo_file->sections.str_offsets.buffer;
+
+ bool valid_header = false;
if (m_cu->header.version >= 5)
{
/* We have a DWARF5 CU with a reference to a .debug_str_offsets section,
so assume the .debug_str_offsets section is DWARF5 as well, and
parse the header. FIXME: Parse the header only once. */
- unsigned int bytes_read = 0;
- bfd *abfd = m_dwo_file->sections.str_offsets.get_bfd_owner ();
- const gdb_byte *p = m_dwo_file->sections.str_offsets.buffer;
/* Header: Initial length. */
- read_initial_length (abfd, p + bytes_read, &bytes_read);
+ LONGEST initial_length
+ = read_initial_length (abfd, p + bytes_read, &bytes_read);
+ /* GCC 8 and earlier have a bug that for dwarf5 it produces a
+ pre-dwarf5 .debug_str_offsets section. We'd wish we could make
+ this work-around more precise by checking that producer is gcc and
+ gcc version <= 8, but that doesn't work if we need this workaround
+ to read the producer string. */
+ valid_header
+ = initial_length + bytes_read == m_dwo_file->sections.str_offsets.size;
+ }
+
+ if (m_cu->header.version >= 5 && valid_header)
+ {
/* Determine offset_size based on the .debug_str_offsets header. */
const bool dwarf5_is_dwarf64 = bytes_read != 4;
offset_size = dwarf5_is_dwarf64 ? 8 : 4;