mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-19 09:14:14 +08:00
Fix the display of the idnex values for DW_FORM_loclistx and DW_FORM_rnglistx. Correct the display of .debug.loclists sections.
PR 29267 * dwarf.c (display_debug_rnglists): New function, broken out of.. (display_debug_ranges): ... here. (read_and_display_attr_value): Correct calculation of index displayed for DW_FORM_loclistx and DW_FORM_rnglistx. * testsuite/binutils-all/x86-64/pr26808.dump: Update expected output.
This commit is contained in:
218
binutils/dwarf.c
218
binutils/dwarf.c
@ -763,7 +763,7 @@ fetch_indexed_addr (dwarf_vma offset, uint32_t num_bytes)
|
||||
|
||||
if (section->start == NULL)
|
||||
{
|
||||
warn (_("<no .debug_addr section>"));
|
||||
warn (_("Cannot fetch indexed address: the .debug_addr section is missing\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -778,7 +778,7 @@ fetch_indexed_addr (dwarf_vma offset, uint32_t num_bytes)
|
||||
}
|
||||
|
||||
/* Fetch a value from a debug section that has been indexed by
|
||||
something in another section (eg DW_FORM_loclistx).
|
||||
something in another section (eg DW_FORM_loclistx or DW_FORM_rnglistx).
|
||||
Returns 0 if the value could not be found. */
|
||||
|
||||
static dwarf_vma
|
||||
@ -811,7 +811,7 @@ fetch_indexed_value (dwarf_vma idx,
|
||||
|
||||
/* Offsets are biased by the size of the section header
|
||||
or base address. */
|
||||
if (sec_enum == loclists)
|
||||
if (base_address)
|
||||
offset += base_address;
|
||||
else
|
||||
offset += bias;
|
||||
@ -2743,37 +2743,52 @@ read_and_display_attr_value (unsigned long attribute,
|
||||
case DW_FORM_rnglistx:
|
||||
if (!do_loc)
|
||||
{
|
||||
dwarf_vma base;
|
||||
dwarf_vma offset;
|
||||
dwarf_vma base, index;
|
||||
|
||||
if (debug_info_p == NULL)
|
||||
base = 0;
|
||||
else if (debug_info_p->addr_base == DEBUG_INFO_UNAVAILABLE)
|
||||
base = 0;
|
||||
if (form == DW_FORM_loclistx)
|
||||
{
|
||||
if (debug_info_p == NULL)
|
||||
{
|
||||
index = fetch_indexed_value (uvalue, loclists, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We want to compute:
|
||||
index = fetch_indexed_value (uvalue, loclists, debug_info_p->loclists_base);
|
||||
index += debug_info_p->loclists_base;
|
||||
Fortunately we already have that sum cached in the
|
||||
loc_offsets array. */
|
||||
index = debug_info_p->loc_offsets [uvalue];
|
||||
}
|
||||
}
|
||||
else if (form == DW_FORM_rnglistx)
|
||||
{
|
||||
if (debug_info_p == NULL)
|
||||
base = 0;
|
||||
else
|
||||
base = debug_info_p->rnglists_base;
|
||||
/* We do not have a cached value this time, so we perform the
|
||||
computation manually. */
|
||||
index = fetch_indexed_value (uvalue, rnglists, base);
|
||||
index += base;
|
||||
}
|
||||
else
|
||||
base = debug_info_p->addr_base;
|
||||
{
|
||||
if (debug_info_p == NULL)
|
||||
base = 0;
|
||||
else if (debug_info_p->addr_base == DEBUG_INFO_UNAVAILABLE)
|
||||
base = 0;
|
||||
else
|
||||
base = debug_info_p->addr_base;
|
||||
|
||||
offset = base + uvalue * pointer_size;
|
||||
base += uvalue * pointer_size;
|
||||
index = fetch_indexed_addr (base, pointer_size);
|
||||
}
|
||||
|
||||
if (do_wide)
|
||||
/* We have already displayed the form name. */
|
||||
if (form == DW_FORM_loclistx)
|
||||
printf (_("%c(index: 0x%s): %s"), delimiter,
|
||||
dwarf_vmatoa ("x", uvalue),
|
||||
dwarf_vmatoa ("x", debug_info_p->loc_offsets [uvalue]));
|
||||
else
|
||||
printf (_("%c(index: 0x%s): %s"), delimiter,
|
||||
dwarf_vmatoa ("x", uvalue),
|
||||
dwarf_vmatoa ("x", fetch_indexed_addr (offset, pointer_size)));
|
||||
else
|
||||
if (form == DW_FORM_loclistx)
|
||||
printf (_("%c(addr_index: 0x%s): %s"), delimiter,
|
||||
dwarf_vmatoa ("x", uvalue),
|
||||
dwarf_vmatoa ("x", debug_info_p->loc_offsets [uvalue]));
|
||||
else
|
||||
printf (_("%c(addr_index: 0x%s): %s"), delimiter,
|
||||
dwarf_vmatoa ("x", uvalue),
|
||||
dwarf_vmatoa ("x", fetch_indexed_addr (offset, pointer_size)));
|
||||
/* We have already displayed the form name. */
|
||||
printf (_("%c(index: 0x%s): %s"), delimiter,
|
||||
dwarf_vmatoa ("x", uvalue),
|
||||
dwarf_vmatoa ("x", index));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2797,20 +2812,26 @@ read_and_display_attr_value (unsigned long attribute,
|
||||
{
|
||||
case DW_AT_loclists_base:
|
||||
if (debug_info_p->loclists_base)
|
||||
warn (_("CU @ 0x%s has multiple loclists_base values"),
|
||||
dwarf_vmatoa ("x", debug_info_p->cu_offset));
|
||||
warn (_("CU @ 0x%s has multiple loclists_base values (0x%s and 0x%s)"),
|
||||
dwarf_vmatoa ("x", debug_info_p->cu_offset),
|
||||
dwarf_vmatoa ("x", debug_info_p->loclists_base),
|
||||
dwarf_vmatoa ("x", uvalue));
|
||||
debug_info_p->loclists_base = uvalue;
|
||||
break;
|
||||
case DW_AT_rnglists_base:
|
||||
if (debug_info_p->rnglists_base)
|
||||
warn (_("CU @ 0x%s has multiple rnglists_base values"),
|
||||
dwarf_vmatoa ("x", debug_info_p->cu_offset));
|
||||
warn (_("CU @ 0x%s has multiple rnglists_base values (0x%s and 0x%s)"),
|
||||
dwarf_vmatoa ("x", debug_info_p->cu_offset),
|
||||
dwarf_vmatoa ("x", debug_info_p->rnglists_base),
|
||||
dwarf_vmatoa ("x", uvalue));
|
||||
debug_info_p->rnglists_base = uvalue;
|
||||
break;
|
||||
case DW_AT_str_offsets_base:
|
||||
if (debug_info_p->str_offsets_base)
|
||||
warn (_("CU @ 0x%s has multiple str_offsets_base values"),
|
||||
dwarf_vmatoa ("x", debug_info_p->cu_offset));
|
||||
warn (_("CU @ 0x%s has multiple str_offsets_base values (0x%s and 0x%s)"),
|
||||
dwarf_vmatoa ("x", debug_info_p->cu_offset),
|
||||
dwarf_vmatoa ("x", debug_info_p->str_offsets_base),
|
||||
dwarf_vmatoa ("x", uvalue));
|
||||
debug_info_p->str_offsets_base = uvalue;
|
||||
break;
|
||||
|
||||
@ -3811,6 +3832,7 @@ process_debug_info (struct dwarf_section * section,
|
||||
debug_information [unit].base_address = 0;
|
||||
debug_information [unit].addr_base = DEBUG_INFO_UNAVAILABLE;
|
||||
debug_information [unit].ranges_base = DEBUG_INFO_UNAVAILABLE;
|
||||
debug_information [unit].rnglists_base = 0;
|
||||
debug_information [unit].loc_offsets = NULL;
|
||||
debug_information [unit].have_frame_base = NULL;
|
||||
debug_information [unit].max_loc_offsets = 0;
|
||||
@ -7940,7 +7962,7 @@ display_debug_ranges_list (unsigned char * start,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static unsigned char *
|
||||
display_debug_rnglists_list (unsigned char * start,
|
||||
unsigned char * finish,
|
||||
unsigned int pointer_size,
|
||||
@ -8050,40 +8072,28 @@ display_debug_rnglists_list (unsigned char * start,
|
||||
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
static int
|
||||
display_debug_ranges (struct dwarf_section *section,
|
||||
void *file ATTRIBUTE_UNUSED)
|
||||
display_debug_rnglists (struct dwarf_section *section)
|
||||
{
|
||||
unsigned char * start = section->start;
|
||||
unsigned char * last_start = start;
|
||||
dwarf_vma bytes = section->size;
|
||||
unsigned char * section_begin = start;
|
||||
unsigned char * finish = start + bytes;
|
||||
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;
|
||||
/* Initialize it due to a false compiler warning. */
|
||||
unsigned char address_size = 0;
|
||||
dwarf_vma last_offset = 0;
|
||||
unsigned int offset_size = 0;
|
||||
unsigned char * finish = start + section->size;
|
||||
|
||||
if (bytes == 0)
|
||||
{
|
||||
printf (_("\nThe %s section is empty.\n"), section->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
introduce (section, false);
|
||||
|
||||
if (is_rnglists)
|
||||
while (start < finish)
|
||||
{
|
||||
unsigned char * table_start;
|
||||
dwarf_vma offset = start - section->start;
|
||||
unsigned char * end;
|
||||
dwarf_vma initial_length;
|
||||
unsigned char segment_selector_size;
|
||||
unsigned int offset_entry_count;
|
||||
unsigned int i;
|
||||
unsigned short version;
|
||||
unsigned char address_size = 0;
|
||||
unsigned char offset_size;
|
||||
|
||||
/* Get and check the length of the block. */
|
||||
SAFE_BYTE_GET_AND_INC (initial_length, start, 4, finish);
|
||||
@ -8103,9 +8113,7 @@ display_debug_ranges (struct dwarf_section *section,
|
||||
not complain if it is inaccurate (and probably negative).
|
||||
It is copied from .debug_line handling code. */
|
||||
if (reloc_at (section, (start - section->start) - offset_size))
|
||||
{
|
||||
initial_length = finish - start;
|
||||
}
|
||||
initial_length = finish - start;
|
||||
else
|
||||
{
|
||||
warn (_("The length field (0x%lx) in the debug_rnglists header is wrong - the section is too small\n"),
|
||||
@ -8114,12 +8122,15 @@ display_debug_ranges (struct dwarf_section *section,
|
||||
}
|
||||
}
|
||||
|
||||
end = start + initial_length;
|
||||
|
||||
/* Get the other fields in the header. */
|
||||
SAFE_BYTE_GET_AND_INC (version, start, 2, finish);
|
||||
SAFE_BYTE_GET_AND_INC (address_size, start, 1, finish);
|
||||
SAFE_BYTE_GET_AND_INC (segment_selector_size, start, 1, finish);
|
||||
SAFE_BYTE_GET_AND_INC (offset_entry_count, start, 4, finish);
|
||||
|
||||
printf (_(" Table at Offset: 0x%s:\n"), dwarf_vmatoa ("x", offset));
|
||||
printf (_(" Length: 0x%s\n"), dwarf_vmatoa ("x", initial_length));
|
||||
printf (_(" DWARF version: %u\n"), version);
|
||||
printf (_(" Address size: %u\n"), address_size);
|
||||
@ -8142,6 +8153,8 @@ display_debug_ranges (struct dwarf_section *section,
|
||||
return 0;
|
||||
}
|
||||
|
||||
table_start = start;
|
||||
|
||||
if (offset_entry_count != 0)
|
||||
{
|
||||
printf (_("\n Offsets starting at 0x%lx:\n"), (long)(start - section->start));
|
||||
@ -8166,8 +8179,60 @@ display_debug_ranges (struct dwarf_section *section,
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
offset_entry_count = 1;
|
||||
|
||||
for (i = 0; i < offset_entry_count; i++)
|
||||
{
|
||||
dwarf_vma indx = start - table_start;
|
||||
|
||||
offset = start - section->start;
|
||||
printf (_("\n Offset: %lx, Index: 0x%s\n"),
|
||||
(long) offset, dwarf_vmatoa ("x", indx));
|
||||
printf (_(" Offset Begin End\n"));
|
||||
start = display_debug_rnglists_list
|
||||
(start, end, address_size, offset, 0, offset_size);
|
||||
if (start >= end)
|
||||
break;
|
||||
}
|
||||
|
||||
start = end;
|
||||
|
||||
if (start < finish)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
display_debug_ranges (struct dwarf_section *section,
|
||||
void *file ATTRIBUTE_UNUSED)
|
||||
{
|
||||
unsigned char * start = section->start;
|
||||
unsigned char * last_start = start;
|
||||
dwarf_vma bytes = section->size;
|
||||
unsigned char * section_begin = start;
|
||||
unsigned char * finish = start + bytes;
|
||||
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;
|
||||
/* Initialize it due to a false compiler warning. */
|
||||
unsigned char address_size = 0;
|
||||
dwarf_vma last_offset = 0;
|
||||
|
||||
if (bytes == 0)
|
||||
{
|
||||
printf (_("\nThe %s section is empty.\n"), section->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
introduce (section, false);
|
||||
|
||||
if (is_rnglists)
|
||||
return display_debug_rnglists (section);
|
||||
|
||||
if (load_debug_info (file) == 0)
|
||||
{
|
||||
warn (_("Unable to load/parse the .debug_info section, so cannot interpret the %s section.\n"),
|
||||
@ -8177,15 +8242,7 @@ display_debug_ranges (struct dwarf_section *section,
|
||||
|
||||
num_range_list = 0;
|
||||
for (i = 0; i < num_debug_info_entries; i++)
|
||||
{
|
||||
if (debug_information [i].dwarf_version < 5 && is_rnglists)
|
||||
/* Skip .debug_rnglists reference. */
|
||||
continue;
|
||||
if (debug_information [i].dwarf_version >= 5 && !is_rnglists)
|
||||
/* Skip .debug_range reference. */
|
||||
continue;
|
||||
num_range_list += debug_information [i].num_range_lists;
|
||||
}
|
||||
num_range_list += debug_information [i].num_range_lists;
|
||||
|
||||
if (num_range_list == 0)
|
||||
{
|
||||
@ -8204,13 +8261,6 @@ display_debug_ranges (struct dwarf_section *section,
|
||||
debug_info *debug_info_p = &debug_information[i];
|
||||
unsigned int j;
|
||||
|
||||
if (debug_information [i].dwarf_version < 5 && is_rnglists)
|
||||
/* Skip .debug_rnglists reference. */
|
||||
continue;
|
||||
if (debug_information [i].dwarf_version >= 5 && !is_rnglists)
|
||||
/* Skip .debug_range reference. */
|
||||
continue;
|
||||
|
||||
for (j = 0; j < debug_info_p->num_range_lists; j++)
|
||||
{
|
||||
range_entry_fill->ranges_offset = debug_info_p->range_lists[j];
|
||||
@ -8287,12 +8337,8 @@ display_debug_ranges (struct dwarf_section *section,
|
||||
start = next;
|
||||
last_start = next;
|
||||
|
||||
if (is_rnglists)
|
||||
display_debug_rnglists_list
|
||||
(start, finish, pointer_size, offset, base_address, offset_size);
|
||||
else
|
||||
display_debug_ranges_list
|
||||
(start, finish, pointer_size, offset, base_address);
|
||||
display_debug_ranges_list
|
||||
(start, finish, pointer_size, offset, base_address);
|
||||
}
|
||||
putchar ('\n');
|
||||
|
||||
|
Reference in New Issue
Block a user