summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOmar Sandoval <[email protected]>2023-09-27 11:20:55 -0700
committerMark Wielaard <[email protected]>2023-10-03 23:36:05 +0200
commitefedcaa3415cf1305bb4d20a42aae3b60d341122 (patch)
treec1c7682e3643d4443380d62825dae7118f2231d3
parent4bddabc1e7f3020b83a5abd98901146c58da403e (diff)
libdw: Handle split DWARF in dwarf_macro_getsrcfiles
Macro information references file names from the line number information table, which is tricky in split DWARF for a couple of reasons. First, the line number information for a macro unit comes from the .debug_line.dwo section in the split file, not the .debug_line section in the skeleton file. This was not specified in the GNU DebugFission design document [1] or the DWARF 5 standard, but it is how GCC and Clang behave in practice and was clarified in DWARF standard issue 200602.1 [2] for the upcoming DWARF 6 standard. dwarf_macro_getsrcfiles uses the line number information from whichever Dwarf handle it was passed. This is error-prone, since the most natural thing to do is to pass the skeleton Dwarf handle. Fix this by storing the appropriate Dwarf handle in Dwarf_Macro_Op_Table and using that one. Second, for .debug_macinfo.dwo in GNU DebugFission (generated by gcc -gdwarf-4 -gstrict-dwarf -gsplit-dwarf), the offset into .debug_line.dwo is implicitly 0. Again, this isn't in any specification, but it's how GCC behaves in practice (Clang never generates macro information for DWARF 4 split DWARF). Make get_macinfo_table default to 0 for split DWARF when it can't find DW_AT_stmt_list. 1: https://gcc.gnu.org/wiki/DebugFission 2: https://dwarfstd.org/issues/200602.1.html Signed-off-by: Omar Sandoval <[email protected]>
-rw-r--r--libdw/ChangeLog8
-rw-r--r--libdw/dwarf_getmacros.c11
-rw-r--r--libdw/dwarf_macro_getsrcfiles.c5
-rw-r--r--libdw/libdwP.h2
4 files changed, 20 insertions, 6 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index d3f36cc8..be1e40bc 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -9,15 +9,17 @@
DW_FORM_strx, and DW_FORM_strx[1-4].
* dwarf_getmacros.c (get_macinfo_table): Replace assignment of
table->is_64bit with assignments of table->address_size and
- table->offset_size.
+ table->offset_size. Assume default DW_AT_stmt_list of 0 for split
+ DWARF. Set table->dbg.
(get_table_for_offset): Ditto.
(read_macros): Get fake CU offset_size from table->offset_size instead
of table->is_64bit.
* dwarf_macro_getsrcfiles.c (dwarf_macro_getsrcfiles): Get
address_size for __libdw_getsrclines from table->address_size instead
- of table->is_64bit.
+ of table->is_64bit. Get dbg for __libdw_getsrclines from table->dbg
+ instead of dbg parameter, which is now unused.
* libdwP.h (Dwarf_Macro_Op_Table): Replace is_64bit with address_size
- and offset_size.
+ and offset_size. Add dbg.
2023-02-22 Mark Wielaard <[email protected]>
diff --git a/libdw/dwarf_getmacros.c b/libdw/dwarf_getmacros.c
index b7d98af4..a3a78884 100644
--- a/libdw/dwarf_getmacros.c
+++ b/libdw/dwarf_getmacros.c
@@ -124,13 +124,19 @@ get_macinfo_table (Dwarf *dbg, Dwarf_Word macoff, Dwarf_Die *cudie)
= INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list, &attr_mem);
Dwarf_Off line_offset = (Dwarf_Off) -1;
if (attr != NULL)
- if (unlikely (INTUSE(dwarf_formudata) (attr, &line_offset) != 0))
- return NULL;
+ {
+ if (unlikely (INTUSE(dwarf_formudata) (attr, &line_offset) != 0))
+ return NULL;
+ }
+ else if (cudie->cu->unit_type == DW_UT_split_compile
+ && dbg->sectiondata[IDX_debug_line] != NULL)
+ line_offset = 0;
Dwarf_Macro_Op_Table *table = libdw_alloc (dbg, Dwarf_Macro_Op_Table,
macinfo_data_size, 1);
memcpy (table, macinfo_data, macinfo_data_size);
+ table->dbg = dbg;
table->offset = macoff;
table->sec_index = IDX_debug_macinfo;
table->line_offset = line_offset;
@@ -263,6 +269,7 @@ get_table_for_offset (Dwarf *dbg, Dwarf_Word macoff,
macop_table_size, 1);
*table = (Dwarf_Macro_Op_Table) {
+ .dbg = dbg,
.offset = macoff,
.sec_index = IDX_debug_macro,
.line_offset = line_offset,
diff --git a/libdw/dwarf_macro_getsrcfiles.c b/libdw/dwarf_macro_getsrcfiles.c
index 4e8deeeb..11c587af 100644
--- a/libdw/dwarf_macro_getsrcfiles.c
+++ b/libdw/dwarf_macro_getsrcfiles.c
@@ -36,6 +36,9 @@ int
dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro,
Dwarf_Files **files, size_t *nfiles)
{
+ /* This was needed before Dwarf_Macro_Op_Table stored the Dwarf handle. */
+ (void)dbg;
+
/* macro is declared NN */
Dwarf_Macro_Op_Table *const table = macro->table;
if (table->files == NULL)
@@ -71,7 +74,7 @@ dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro,
the same unit through dwarf_getsrcfiles, and the file names
will be broken. */
- if (__libdw_getsrclines (dbg, line_offset, table->comp_dir,
+ if (__libdw_getsrclines (table->dbg, line_offset, table->comp_dir,
table->address_size, NULL, &table->files) < 0)
table->files = (void *) -1;
}
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index c3fe9f93..77959b3b 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -508,6 +508,8 @@ typedef struct
/* Prototype table. */
typedef struct
{
+ Dwarf *dbg;
+
/* Offset of .debug_macro section. */
Dwarf_Off offset;