]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
readelf: Handle CUs that share an addr_base or str_offsets_base
authorMark Wielaard <mark@klomp.org>
Thu, 5 Feb 2026 18:58:05 +0000 (19:58 +0100)
committerMark Wielaard <mark@klomp.org>
Tue, 17 Feb 2026 12:37:43 +0000 (13:37 +0100)
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 <mark@klomp.org>
src/readelf.c

index 5db86f0a84bca3ec079bb8721891da1bc8ea6089..3eab60c14b57e2e7dbd6c77018a01e5506a9ca64 100644 (file)
@@ -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;