readelf assumed each .debug_addr and .debug_str_offsets was associated
with precisely one CU DIE. But CU DIEs can have the same
DW_AT_addr_base or DW_AT_str_offsets_base. Change the code to find the
first CU associated with the offset.
* src/readelf.c (print_debug_addr_section): Skip CUs that
have an addr_base already handled.
(print_debug_str_offsets_section): Likewise for
str_offsets_base.
Signed-off-by: Mark Wielaard <[email protected]>
---
src/readelf.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/src/readelf.c b/src/readelf.c
index 5db86f0a84bc..3eab60c14b57 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -6053,7 +6053,13 @@ print_debug_addr_section (Dwfl_Module *dwflmod
__attribute__ ((unused)),
fprintf (out, "Table at offset %" PRIx64 " ", off);
- struct listptr *listptr = get_listptr (&known_addrbases, idx++);
+ /* Find the first CU that could plausibly be associated with
+ this address base offset. Skip CUs that point their addr_base
+ before this table. */
+ struct listptr *listptr = get_listptr (&known_addrbases, idx);
+ while (listptr != NULL && listptr->offset < off)
+ listptr = get_listptr (&known_addrbases, ++idx);
+
const unsigned char *next_unitp;
uint64_t unit_length;
@@ -6087,7 +6093,7 @@ print_debug_addr_section (Dwfl_Module *dwflmod
__attribute__ ((unused)),
version = 4;
/* The addresses start here, but where do they end? */
- listptr = get_listptr (&known_addrbases, idx);
+ listptr = get_listptr (&known_addrbases, idx + 1);
if (listptr == NULL)
next_unitp = readendp;
else if (listptr->cu->version < 5)
@@ -11402,7 +11408,13 @@ print_debug_str_offsets_section (Dwfl_Module *dwflmod
__attribute__ ((unused)),
fprintf (out, "Table at offset %" PRIx64 " ", off);
- struct listptr *listptr = get_listptr (&known_stroffbases, idx++);
+ /* Find the first CU that could plausibly be associated with
+ this string offsets index. Skip CUs that point
+ str_offsets_base before this table. */
+ struct listptr *listptr = get_listptr (&known_stroffbases, idx);
+ while (listptr != NULL && listptr->offset < off)
+ listptr = get_listptr (&known_stroffbases, ++idx);
+
const unsigned char *next_unitp = readendp;
uint8_t offset_size;
bool has_header;
--
2.52.0