From 589d38af0de46f3325747a9e29e008c79e41e664 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Wed, 23 Aug 2023 11:36:25 +0100 Subject: [PATCH] readelf/objdump: Handle DWARF info with mixed types of range section. PR 30791 * dwarf.h (debug_info): Add range_versions field. * dwarf.c (read_and_display_attr_value): When recording a range arribute also ecord the dwarf version number. (is_range_list_for_this_section): New function. (display_debug_ranges): Only show debug ranges whose version is suitable for the secction being displayed. --- binutils/ChangeLog | 10 ++++++++++ binutils/dwarf.c | 30 +++++++++++++++++++++++++----- binutils/dwarf.h | 1 + 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 65cff807bec..9e6db82d0ab 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,13 @@ +2023-08-23 Nick Clifton + + PR 30791 + * dwarf.h (debug_info): Add range_versions field. + * dwarf.c (read_and_display_attr_value): When recording a range + arribute also ecord the dwarf version number. + (is_range_list_for_this_section): New function. + (display_debug_ranges): Only show debug ranges whose version is + suitable for the secction being displayed. + 2023-07-30 Jose E. Marchesi * readelf.c (get_machine_flags): Recognize and pretty print BPF diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 3ebc45ae373..7ce5d8efb2b 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -2970,6 +2970,9 @@ read_and_display_attr_value (unsigned long attribute, debug_info_p->range_lists = (uint64_t *) xcrealloc (debug_info_p->range_lists, lmax, sizeof (*debug_info_p->range_lists)); + debug_info_p->range_versions = (unsigned int *) + xcrealloc (debug_info_p->range_versions, + lmax, sizeof (*debug_info_p->range_versions)); debug_info_p->max_range_lists = lmax; } @@ -2977,6 +2980,7 @@ read_and_display_attr_value (unsigned long attribute, uvalue = fetch_indexed_value (uvalue, rnglists, 0); debug_info_p->range_lists [num] = uvalue; + debug_info_p->range_versions [num] = dwarf_version; debug_info_p->num_range_lists++; } break; @@ -8256,6 +8260,18 @@ display_debug_rnglists (struct dwarf_section *section) return 1; } +static bool +is_range_list_for_this_section (bool is_rnglists, unsigned int version) +{ + if (is_rnglists && version > 4) + return true; + + if (! is_rnglists && version < 5) + return true; + + return false; +} + static int display_debug_ranges (struct dwarf_section *section, void *file ATTRIBUTE_UNUSED) @@ -8268,7 +8284,7 @@ display_debug_ranges (struct dwarf_section *section, unsigned int num_range_list, i; struct range_entry *range_entries; struct range_entry *range_entry_fill; - int is_rnglists = strstr (section->name, "debug_rnglists") != NULL; + bool is_rnglists = strstr (section->name, "debug_rnglists") != NULL; /* Initialize it due to a false compiler warning. */ unsigned char address_size = 0; uint64_t last_offset = 0; @@ -8299,7 +8315,7 @@ display_debug_ranges (struct dwarf_section *section, { /* This can happen when the file was compiled with -gsplit-debug which removes references to range lists from the primary .o file. */ - printf (_("No range lists in .debug_info section.\n")); + printf (_("No range lists referenced by .debug_info section.\n")); return 1; } @@ -8314,12 +8330,16 @@ display_debug_ranges (struct dwarf_section *section, for (j = 0; j < debug_info_p->num_range_lists; j++) { - range_entry_fill->ranges_offset = debug_info_p->range_lists[j]; - range_entry_fill->debug_info_p = debug_info_p; - range_entry_fill++; + if (is_range_list_for_this_section (is_rnglists, debug_info_p->range_versions[j])) + { + range_entry_fill->ranges_offset = debug_info_p->range_lists[j]; + range_entry_fill->debug_info_p = debug_info_p; + range_entry_fill++; + } } } + num_range_list = range_entry_fill - range_entries; qsort (range_entries, num_range_list, sizeof (*range_entries), range_entry_compar); diff --git a/binutils/dwarf.h b/binutils/dwarf.h index d2f95235584..61c4158027b 100644 --- a/binutils/dwarf.h +++ b/binutils/dwarf.h @@ -189,6 +189,7 @@ typedef struct /* List of .debug_ranges offsets seen in this .debug_info. */ uint64_t * range_lists; + unsigned int * range_versions; unsigned int num_range_lists; unsigned int max_range_lists; uint64_t rnglists_base; -- 2.11.4.GIT