dwarf: Properly check holes in .debug_ranges/debug_rnglists

Don't warn if the offset of the first entry in .debug_rnglists starts
right after the header.  Warn holes in .debug_ranges and debug_rnglists
sections only if the last end pointer isn't the same as the current
start pointer.

	PR binutils/32927
	* dwarf.c (display_debug_ranges_list): Return the pointer to the
	end.
	(display_debug_ranges): Don't warn if the offset of the first
	entry in .debug_rnglists starts right after the header.  Warn a
	hole only if the last end pointer is the same as the next pointer.
	* testsuite/binutils-all/x86-64/dwarf4.s: New file.
	* testsuite/binutils-all/x86-64/dwarf5.s: Likewise.
	* testsuite/binutils-all/x86-64/pr32927-1.d: Likewise.
	* testsuite/binutils-all/x86-64/pr32927-2.d: Likewise.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Co-Authored-By: Alan Modra <amodra@gmail.com>
This commit is contained in:
H.J. Lu
2025-04-30 08:37:08 +08:00
committed by Alan Modra
parent 4aa66c7645
commit f72c4fa3d5
5 changed files with 52394 additions and 12 deletions

View File

@@ -8090,7 +8090,7 @@ range_entry_compar (const void *ap, const void *bp)
return (a > b) - (b > a);
}
static void
static unsigned char *
display_debug_ranges_list (unsigned char * start,
unsigned char * finish,
unsigned int pointer_size,
@@ -8137,6 +8137,8 @@ display_debug_ranges_list (unsigned char * start,
putchar ('\n');
}
return start;
}
static unsigned char *
@@ -8358,6 +8360,7 @@ display_debug_ranges (struct dwarf_section *section,
{
unsigned char *start = section->start;
unsigned char *last_start = start;
unsigned char *last_end;
uint64_t bytes = section->size;
unsigned char *section_begin = start;
unsigned char *finish = start + bytes;
@@ -8421,14 +8424,11 @@ display_debug_ranges (struct dwarf_section *section,
qsort (range_entries, num_range_list, sizeof (*range_entries),
range_entry_compar);
if (dwarf_check != 0 && range_entries[0].ranges_offset != 0)
warn (_("Range lists in %s section start at %#" PRIx64 "\n"),
section->name, range_entries[0].ranges_offset);
putchar ('\n');
if (!is_rnglists)
printf (_(" Offset Begin End\n"));
last_end = NULL;
for (i = 0; i < num_range_list; i++)
{
struct range_entry *range_entry = &range_entries[i];
@@ -8467,6 +8467,12 @@ display_debug_ranges (struct dwarf_section *section,
next = section_begin + offset; /* Offset is from the section start, the base has already been added. */
if (i == 0)
{
last_end = section_begin;
if (is_rnglists)
last_end += 2 * offset_size - 4 + 2 + 1 + 1 + 4;
}
/* If multiple DWARF entities reference the same range then we will
have multiple entries in the `range_entries' list for the same
offset. Thanks to the sort above these will all be consecutive in
@@ -8476,11 +8482,15 @@ display_debug_ranges (struct dwarf_section *section,
continue;
last_offset = offset;
if (dwarf_check != 0 && i > 0)
if (dwarf_check != 0)
{
if (start < next)
warn (_("There is a hole [%#tx - %#tx] in %s section.\n"),
start - section_begin, next - section_begin, section->name);
{
if (last_end != next)
warn (_("There is a hole [%#tx - %#tx] in %s section.\n"),
last_end - section_begin, next - section_begin,
section->name);
}
else if (start > next)
{
if (next == last_start)
@@ -8494,11 +8504,14 @@ display_debug_ranges (struct dwarf_section *section,
last_start = next;
if (is_rnglists)
display_debug_rnglists_list
(start, finish, pointer_size, offset, base_address, debug_info_p->addr_base);
last_end
= display_debug_rnglists_list
(start, finish, pointer_size, offset, base_address,
debug_info_p->addr_base);
else
display_debug_ranges_list
(start, finish, pointer_size, offset, base_address);
last_end
= display_debug_ranges_list
(start, finish, pointer_size, offset, base_address);
}
/* Display trailing empty (or unreferenced) compile units, if any. */