From 19c26da69d68d5d863f37c06ad73ab6292d02ffa Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Wed, 6 Apr 2022 14:43:37 +0100 Subject: [PATCH] Add code to display the contents of .debug_loclists sections which contain offset entry tables. PR 28981 * dwarf.c (fetch_indexed_value): Rename to fecth_indexed_addr and return the address, rather than a string. (fetch_indexed_value): New function - returns a value indexed by a DW_FORM_loclistx or DW_FORM_rnglistx form. (read_and_display_attr_value): Add support for DW_FORM_loclistx and DW_FORM_rnglistx. (process_debug_info): Load the loclists and rnglists sections. (display_loclists_list): Add support for DW_LLE_base_addressx, DW_LLE_startx_endx, DW_LLE_startx_length and DW_LLE_default_location. (display_offset_entry_loclists): New function. Displays a .debug_loclists section that contains offset entry tables. (display_debug_loc): Call the new function. (display_debug_rnglists_list): Add support for DW_RLE_base_addressx, DW_RLE_startx_endx and DW_RLE_startx_length. (display_debug_ranges): Display the contents of the section's header. * dwarf.h (struct debug_info): Add loclists_base field. * testsuite/binutils-all/dw5.W: Update expected output. * testsuite/binutils-all/x86-64/pr26808.dump: Likewise. Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=19c26da69d68d5d863f37c06ad73ab6292d02ffa] Signed-off-by: Pgowda --- binutils/ChangeLog | 24 + binutils/dwarf.c | 513 +++++++++++++++--- binutils/dwarf.h | 4 + binutils/testsuite/binutils-all/dw5.W | 2 +- .../binutils-all/x86-64/pr26808.dump | 82 +-- gas/ChangeLog | 5 + gas/testsuite/gas/elf/dwarf-5-irp.d | 2 +- 7 files changed, 517 insertions(+), 115 deletions(-) diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 15b3c81a138..bc862f77c04 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -240,7 +240,7 @@ static const char * dwarf_vmatoa_1 (const char *fmtch, dwarf_vma value, unsigned num_bytes) { /* As dwarf_vmatoa is used more then once in a printf call - for output, we are cycling through an fixed array of pointers + for output, we are cycling through a fixed array of pointers for return address. */ static int buf_pos = 0; static struct dwarf_vmatoa_buf @@ -796,24 +796,70 @@ fetch_indexed_string (dwarf_vma idx, str return ret; } -static const char * -fetch_indexed_value (dwarf_vma offset, dwarf_vma bytes) +static dwarf_vma +fetch_indexed_addr (dwarf_vma offset, uint32_t num_bytes) { struct dwarf_section *section = &debug_displays [debug_addr].section; if (section->start == NULL) - return (_("")); + { + warn (_("")); + return 0; + } - if (offset + bytes > section->size) + if (offset + num_bytes > section->size) { warn (_("Offset into section %s too big: 0x%s\n"), section->name, dwarf_vmatoa ("x", offset)); - return ""; + return 0; } - return dwarf_vmatoa ("x", byte_get (section->start + offset, bytes)); + return byte_get (section->start + offset, num_bytes); } +/* Fetch a value from a debug section that has been indexed by + something in another section (eg DW_FORM_loclistx). + Returns 0 if the value could not be found. */ + +static dwarf_vma +fetch_indexed_value (dwarf_vma index, + enum dwarf_section_display_enum sec_enum) +{ + struct dwarf_section *section = &debug_displays [sec_enum].section; + + if (section->start == NULL) + { + warn (_("Unable to locate %s section\n"), section->uncompressed_name); + return 0; + } + + uint32_t pointer_size, bias; + + if (byte_get (section->start, 4) == 0xffffffff) + { + pointer_size = 8; + bias = 20; + } + else + { + pointer_size = 4; + bias = 12; + } + + dwarf_vma offset = index * pointer_size; + + /* Offsets are biased by the size of the section header. */ + offset += bias; + + if (offset + pointer_size > section->size) + { + warn (_("Offset into section %s too big: 0x%s\n"), + section->name, dwarf_vmatoa ("x", offset)); + return 0; + } + + return byte_get (section->start + offset, pointer_size); +} /* FIXME: There are better and more efficient ways to handle these structures. For now though, I just want something that @@ -1999,6 +2045,8 @@ skip_attr_bytes (unsigned long form, case DW_FORM_strx: case DW_FORM_GNU_addr_index: case DW_FORM_addrx: + case DW_FORM_loclistx: + case DW_FORM_rnglistx: READ_ULEB (uvalue, data, end); break; @@ -2410,9 +2458,6 @@ read_and_display_attr_value (unsigned lo switch (form) { - default: - break; - case DW_FORM_ref_addr: if (dwarf_version == 2) SAFE_BYTE_GET_AND_INC (uvalue, data, pointer_size, end); @@ -2496,6 +2541,8 @@ read_and_display_attr_value (unsigned lo case DW_FORM_udata: case DW_FORM_GNU_addr_index: case DW_FORM_addrx: + case DW_FORM_loclistx: + case DW_FORM_rnglistx: READ_ULEB (uvalue, data, end); break; @@ -2515,6 +2562,9 @@ read_and_display_attr_value (unsigned lo case DW_FORM_implicit_const: uvalue = implicit_const; break; + + default: + break; } switch (form) @@ -2710,6 +2760,8 @@ read_and_display_attr_value (unsigned lo case DW_FORM_addrx2: case DW_FORM_addrx3: case DW_FORM_addrx4: + case DW_FORM_loclistx: + case DW_FORM_rnglistx: if (!do_loc) { dwarf_vma base; @@ -2728,11 +2780,11 @@ read_and_display_attr_value (unsigned lo /* We have already displayed the form name. */ printf (_("%c(index: 0x%s): %s"), delimiter, dwarf_vmatoa ("x", uvalue), - fetch_indexed_value (offset, pointer_size)); + dwarf_vmatoa ("x", fetch_indexed_addr (offset, pointer_size))); else printf (_("%c(addr_index: 0x%s): %s"), delimiter, dwarf_vmatoa ("x", uvalue), - fetch_indexed_value (offset, pointer_size)); + dwarf_vmatoa ("x", fetch_indexed_addr (offset, pointer_size))); } break; @@ -2754,6 +2806,13 @@ read_and_display_attr_value (unsigned lo { switch (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)); + debug_info_p->loclists_base = uvalue; + break; + case DW_AT_frame_base: have_frame_base = 1; /* Fall through. */ @@ -2776,7 +2835,8 @@ read_and_display_attr_value (unsigned lo case DW_AT_GNU_call_site_target_clobbered: if ((dwarf_version < 4 && (form == DW_FORM_data4 || form == DW_FORM_data8)) - || form == DW_FORM_sec_offset) + || form == DW_FORM_sec_offset + || form == DW_FORM_loclistx) { /* Process location list. */ unsigned int lmax = debug_info_p->max_loc_offsets; @@ -2796,11 +2856,17 @@ read_and_display_attr_value (unsigned lo lmax, sizeof (*debug_info_p->have_frame_base)); debug_info_p->max_loc_offsets = lmax; } - if (this_set != NULL) + + if (form == DW_FORM_loclistx) + uvalue = fetch_indexed_value (uvalue, loclists); + else if (this_set != NULL) uvalue += this_set->section_offsets [DW_SECT_LOC]; + debug_info_p->have_frame_base [num] = have_frame_base; if (attribute != DW_AT_GNU_locviews) { + uvalue += debug_info_p->loclists_base; + /* Corrupt DWARF info can produce more offsets than views. See PR 23062 for an example. */ if (debug_info_p->num_loc_offsets @@ -2844,7 +2910,8 @@ read_and_display_attr_value (unsigned lo case DW_AT_ranges: if ((dwarf_version < 4 && (form == DW_FORM_data4 || form == DW_FORM_data8)) - || form == DW_FORM_sec_offset) + || form == DW_FORM_sec_offset + || form == DW_FORM_rnglistx) { /* Process range list. */ unsigned int lmax = debug_info_p->max_range_lists; @@ -2858,6 +2925,10 @@ read_and_display_attr_value (unsigned lo lmax, sizeof (*debug_info_p->range_lists)); debug_info_p->max_range_lists = lmax; } + + if (form == DW_FORM_rnglistx) + uvalue = fetch_indexed_value (uvalue, rnglists); + debug_info_p->range_lists [num] = uvalue; debug_info_p->num_range_lists++; } @@ -3231,6 +3302,7 @@ read_and_display_attr_value (unsigned lo have_frame_base = 1; /* Fall through. */ case DW_AT_location: + case DW_AT_loclists_base: case DW_AT_string_length: case DW_AT_return_addr: case DW_AT_data_member_location: @@ -3248,7 +3320,8 @@ read_and_display_attr_value (unsigned lo case DW_AT_GNU_call_site_target_clobbered: if ((dwarf_version < 4 && (form == DW_FORM_data4 || form == DW_FORM_data8)) - || form == DW_FORM_sec_offset) + || form == DW_FORM_sec_offset + || form == DW_FORM_loclistx) printf (_(" (location list)")); /* Fall through. */ case DW_AT_allocated: @@ -3517,6 +3590,9 @@ process_debug_info (struct dwarf_section } load_debug_section_with_follow (abbrev_sec, file); + load_debug_section_with_follow (loclists, file); + load_debug_section_with_follow (rnglists, file); + if (debug_displays [abbrev_sec].section.start == NULL) { warn (_("Unable to locate %s section!\n"), @@ -3729,6 +3805,7 @@ process_debug_info (struct dwarf_section debug_information [unit].have_frame_base = NULL; debug_information [unit].max_loc_offsets = 0; debug_information [unit].num_loc_offsets = 0; + debug_information [unit].loclists_base = 0; debug_information [unit].range_lists = NULL; debug_information [unit].max_range_lists= 0; debug_information [unit].num_range_lists = 0; @@ -6465,20 +6542,21 @@ display_loc_list (struct dwarf_section * /* Display a location list from a normal (ie, non-dwo) .debug_loclists section. */ static void -display_loclists_list (struct dwarf_section *section, - unsigned char **start_ptr, - unsigned int debug_info_entry, - dwarf_vma offset, - dwarf_vma base_address, - unsigned char **vstart_ptr, - int has_frame_base) -{ - unsigned char *start = *start_ptr, *vstart = *vstart_ptr; - unsigned char *section_end = section->start + section->size; - dwarf_vma cu_offset; - unsigned int pointer_size; - unsigned int offset_size; - int dwarf_version; +display_loclists_list (struct dwarf_section * section, + unsigned char ** start_ptr, + unsigned int debug_info_entry, + dwarf_vma offset, + dwarf_vma base_address, + unsigned char ** vstart_ptr, + int has_frame_base) +{ + unsigned char * start = *start_ptr; + unsigned char * vstart = *vstart_ptr; + unsigned char * section_end = section->start + section->size; + dwarf_vma cu_offset; + unsigned int pointer_size; + unsigned int offset_size; + unsigned int dwarf_version; /* Initialize it due to a false compiler warning. */ dwarf_vma begin = -1, vbegin = -1; @@ -6544,27 +6622,59 @@ display_loclists_list (struct dwarf_sect case DW_LLE_end_of_list: printf (_("\n")); break; + + case DW_LLE_base_addressx: + READ_ULEB (base_address, start, section_end); + print_dwarf_vma (base_address, pointer_size); + printf (_("(index into .debug_addr) ")); + base_address = fetch_indexed_addr (base_address, pointer_size); + print_dwarf_vma (base_address, pointer_size); + printf (_("(base address)\n")); + break; + + case DW_LLE_startx_endx: + READ_ULEB (begin, start, section_end); + begin = fetch_indexed_addr (begin, pointer_size); + READ_ULEB (end, start, section_end); + end = fetch_indexed_addr (end, pointer_size); + break; + + case DW_LLE_startx_length: + READ_ULEB (begin, start, section_end); + begin = fetch_indexed_addr (begin, pointer_size); + READ_ULEB (end, start, section_end); + end += begin; + break; + + case DW_LLE_default_location: + begin = end = 0; + break; + case DW_LLE_offset_pair: READ_ULEB (begin, start, section_end); begin += base_address; READ_ULEB (end, start, section_end); end += base_address; break; + + case DW_LLE_base_address: + SAFE_BYTE_GET_AND_INC (base_address, start, pointer_size, + section_end); + print_dwarf_vma (base_address, pointer_size); + printf (_("(base address)\n")); + break; + case DW_LLE_start_end: SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, section_end); SAFE_BYTE_GET_AND_INC (end, start, pointer_size, section_end); break; + case DW_LLE_start_length: SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, section_end); READ_ULEB (end, start, section_end); end += begin; break; - case DW_LLE_base_address: - SAFE_BYTE_GET_AND_INC (base_address, start, pointer_size, - section_end); - print_dwarf_vma (base_address, pointer_size); - printf (_("(base address)\n")); - break; + #ifdef DW_LLE_view_pair case DW_LLE_view_pair: if (vstart) @@ -6578,15 +6688,17 @@ display_loclists_list (struct dwarf_sect printf (_("views for:\n")); continue; #endif + default: error (_("Invalid location list entry type %d\n"), llet); return; } + if (llet == DW_LLE_end_of_list) break; - if (llet != DW_LLE_offset_pair - && llet != DW_LLE_start_end - && llet != DW_LLE_start_length) + + if (llet == DW_LLE_base_address + || llet == DW_LLE_base_addressx) continue; if (start == section_end) @@ -6828,6 +6940,218 @@ loc_offsets_compar (const void *ap, cons } static int +display_offset_entry_loclists (struct dwarf_section *section) +{ + unsigned char * start = section->start; + unsigned char * const end = start + section->size; + + introduce (section, false); + + do + { + dwarf_vma length; + unsigned short version; + unsigned char address_size; + unsigned char segment_selector_size; + uint32_t offset_entry_count; + uint32_t i; + bool is_64bit; + + printf (_("Table at Offset 0x%lx\n"), (long)(start - section->start)); + + SAFE_BYTE_GET_AND_INC (length, start, 4, end); + if (length == 0xffffffff) + { + is_64bit = true; + SAFE_BYTE_GET_AND_INC (length, start, 8, end); + } + else + is_64bit = false; + + SAFE_BYTE_GET_AND_INC (version, start, 2, end); + SAFE_BYTE_GET_AND_INC (address_size, start, 1, end); + SAFE_BYTE_GET_AND_INC (segment_selector_size, start, 1, end); + SAFE_BYTE_GET_AND_INC (offset_entry_count, start, 4, end); + + printf (_(" Length: 0x%s\n"), dwarf_vmatoa ("x", length)); + printf (_(" DWARF version: %u\n"), version); + printf (_(" Address size: %u\n"), address_size); + printf (_(" Segment size: %u\n"), segment_selector_size); + printf (_(" Offset entries: %u\n"), offset_entry_count); + + if (version < 5) + { + warn (_("The %s section contains a corrupt or " + "unsupported version number: %d.\n"), + section->name, version); + return 0; + } + + if (segment_selector_size != 0) + { + warn (_("The %s section contains an " + "unsupported segment selector size: %d.\n"), + section->name, segment_selector_size); + return 0; + } + + if (offset_entry_count == 0) + { + warn (_("The %s section contains a table without offset\n"), + section->name); + return 0; + } + + printf (_("\n Offset Entries starting at 0x%lx:\n"), + (long)(start - section->start)); + + if (is_64bit) + { + for (i = 0; i < offset_entry_count; i++) + { + dwarf_vma entry; + + SAFE_BYTE_GET_AND_INC (entry, start, 8, end); + printf (_(" [%6u] 0x%s\n"), i, dwarf_vmatoa ("x", entry)); + } + } + else + { + for (i = 0; i < offset_entry_count; i++) + { + uint32_t entry; + + SAFE_BYTE_GET_AND_INC (entry, start, 4, end); + printf (_(" [%6u] 0x%x\n"), i, entry); + } + } + + putchar ('\n'); + + uint32_t j; + + for (j = 1, i = 0; i < offset_entry_count;) + { + unsigned char lle; + dwarf_vma base_address = 0; + dwarf_vma begin; + dwarf_vma finish; + dwarf_vma off = start - section->start; + + if (j != i) + { + printf (_(" Offset Entry %u\n"), i); + j = i; + } + + printf (" "); + print_dwarf_vma (off, 4); + + SAFE_BYTE_GET_AND_INC (lle, start, 1, end); + + switch (lle) + { + case DW_LLE_end_of_list: + printf (_("\n\n")); + i ++; + continue; + + case DW_LLE_base_addressx: + READ_ULEB (base_address, start, end); + print_dwarf_vma (base_address, address_size); + printf (_("(index into .debug_addr) ")); + base_address = fetch_indexed_addr (base_address, address_size); + print_dwarf_vma (base_address, address_size); + printf (_("(base address)\n")); + continue; + + case DW_LLE_startx_endx: + READ_ULEB (begin, start, end); + begin = fetch_indexed_addr (begin, address_size); + READ_ULEB (finish, start, end); + finish = fetch_indexed_addr (finish, address_size); + break; + + case DW_LLE_startx_length: + READ_ULEB (begin, start, end); + begin = fetch_indexed_addr (begin, address_size); + READ_ULEB (finish, start, end); + finish += begin; + break; + + case DW_LLE_offset_pair: + READ_ULEB (begin, start, end); + begin += base_address; + READ_ULEB (finish, start, end); + finish += base_address; + break; + + case DW_LLE_default_location: + begin = finish = 0; + break; + + case DW_LLE_base_address: + SAFE_BYTE_GET_AND_INC (base_address, start, address_size, end); + print_dwarf_vma (base_address, address_size); + printf (_("(base address)\n")); + continue; + + case DW_LLE_start_end: + SAFE_BYTE_GET_AND_INC (begin, start, address_size, end); + SAFE_BYTE_GET_AND_INC (finish, start, address_size, end); + break; + + case DW_LLE_start_length: + SAFE_BYTE_GET_AND_INC (begin, start, address_size, end); + READ_ULEB (finish, start, end); + finish += begin; + break; + + default: + error (_("Invalid location list entry type %d\n"), lle); + return 0; + } + + if (start == end) + { + warn (_("Location list starting at offset 0x%lx is not terminated.\n"), + (unsigned long) off); + break; + } + + print_dwarf_vma (begin, address_size); + print_dwarf_vma (finish, address_size); + + if (begin == finish) + fputs (_(" (start == end)"), stdout); + else if (begin > finish) + fputs (_(" (start > end)"), stdout); + + /* Read the counted location descriptions. */ + READ_ULEB (length, start, end); + + if (length > (size_t) (end - start)) + { + warn (_("Location list starting at offset 0x%lx is not terminated.\n"), + (unsigned long) off); + break; + } + + putchar (' '); + (void) decode_location_expression (start, address_size, address_size, + version, length, 0, section); + start += length; + putchar ('\n'); + } + + putchar ('\n'); + } + while (start < end); + + return 1; +} + +static int display_debug_loc (struct dwarf_section *section, void *file) { unsigned char *start = section->start, *vstart = NULL; @@ -6893,13 +7217,9 @@ display_debug_loc (struct dwarf_section } SAFE_BYTE_GET_AND_INC (offset_entry_count, hdrptr, 4, end); + if (offset_entry_count != 0) - { - warn (_("The %s section contains " - "unsupported offset entry count: %d.\n"), - section->name, offset_entry_count); - return 0; - } + return display_offset_entry_loclists (section); expected_start = hdrptr - section_begin; } @@ -6959,9 +7279,10 @@ display_debug_loc (struct dwarf_section if (debug_information [first].num_loc_offsets > 0 && debug_information [first].loc_offsets [0] != expected_start && debug_information [first].loc_views [0] != expected_start) - warn (_("Location lists in %s section start at 0x%s\n"), + warn (_("Location lists in %s section start at 0x%s rather than 0x%s\n"), section->name, - dwarf_vmatoa ("x", debug_information [first].loc_offsets [0])); + dwarf_vmatoa ("x", debug_information [first].loc_offsets [0]), + dwarf_vmatoa ("x", expected_start)); if (!locs_sorted) array = (unsigned int *) xcmalloc (num_loc_list, sizeof (unsigned int)); @@ -7639,24 +7960,44 @@ display_debug_rnglists_list (unsigned ch case DW_RLE_end_of_list: printf (_("\n")); break; - case DW_RLE_base_address: - SAFE_BYTE_GET_AND_INC (base_address, start, pointer_size, finish); + case DW_RLE_base_addressx: + READ_ULEB (base_address, start, finish); + print_dwarf_vma (base_address, pointer_size); + printf (_("(base address index) ")); + base_address = fetch_indexed_addr (base_address, pointer_size); print_dwarf_vma (base_address, pointer_size); printf (_("(base address)\n")); break; - case DW_RLE_start_length: - SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, finish); + case DW_RLE_startx_endx: + READ_ULEB (begin, start, finish); + READ_ULEB (end, start, finish); + begin = fetch_indexed_addr (begin, pointer_size); + end = fetch_indexed_addr (begin, pointer_size); + break; + case DW_RLE_startx_length: + READ_ULEB (begin, start, finish); READ_ULEB (length, start, finish); + begin = fetch_indexed_addr (begin, pointer_size); end = begin + length; break; case DW_RLE_offset_pair: READ_ULEB (begin, start, finish); READ_ULEB (end, start, finish); break; + case DW_RLE_base_address: + SAFE_BYTE_GET_AND_INC (base_address, start, pointer_size, finish); + print_dwarf_vma (base_address, pointer_size); + printf (_("(base address)\n")); + break; case DW_RLE_start_end: SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, finish); SAFE_BYTE_GET_AND_INC (end, start, pointer_size, finish); break; + case DW_RLE_start_length: + SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, finish); + READ_ULEB (length, start, finish); + end = begin + length; + break; default: error (_("Invalid range list entry type %d\n"), rlet); rlet = DW_RLE_end_of_list; @@ -7664,7 +8005,7 @@ display_debug_rnglists_list (unsigned ch } if (rlet == DW_RLE_end_of_list) break; - if (rlet == DW_RLE_base_address) + if (rlet == DW_RLE_base_address || rlet == DW_RLE_base_addressx) continue; /* Only a DW_RLE_offset_pair needs the base address added. */ @@ -7709,6 +8050,8 @@ display_debug_ranges (struct dwarf_secti return 0; } + introduce (section, false); + if (is_rnglists) { dwarf_vma initial_length; @@ -7745,19 +8088,19 @@ display_debug_ranges (struct dwarf_secti } } - /* Get and check the version number. */ + /* Get the other fields in the header. */ SAFE_BYTE_GET_AND_INC (version, start, 2, finish); - - if (version != 5) - { - warn (_("Only DWARF version 5 debug_rnglists info " - "is currently supported.\n")); - return 0; - } - 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 (_(" Length: 0x%s\n"), dwarf_vmatoa ("x", initial_length)); + printf (_(" DWARF version: %u\n"), version); + printf (_(" Address size: %u\n"), address_size); + printf (_(" Segment size: %u\n"), segment_selector_size); + printf (_(" Offset entries: %u\n"), offset_entry_count); + + /* Check the fields. */ if (segment_selector_size != 0) { warn (_("The %s section contains " @@ -7766,16 +8109,39 @@ display_debug_ranges (struct dwarf_secti return 0; } - SAFE_BYTE_GET_AND_INC (offset_entry_count, start, 4, finish); - if (offset_entry_count != 0) + if (version < 5) { - warn (_("The %s section contains " - "unsupported offset entry count: %u.\n"), - section->name, offset_entry_count); + warn (_("Only DWARF version 5+ debug_rnglists info " + "is currently supported.\n")); return 0; } - } + if (offset_entry_count != 0) + { + printf (_("\n Offsets starting at 0x%lx:\n"), (long)(start - section->start)); + if (offset_size == 8) + { + for (i = 0; i < offset_entry_count; i++) + { + dwarf_vma entry; + + SAFE_BYTE_GET_AND_INC (entry, start, 8, finish); + printf (_(" [%6u] 0x%s\n"), i, dwarf_vmatoa ("x", entry)); + } + } + else + { + for (i = 0; i < offset_entry_count; i++) + { + uint32_t entry; + + SAFE_BYTE_GET_AND_INC (entry, start, 4, finish); + printf (_(" [%6u] 0x%x\n"), i, entry); + } + } + } + } + if (load_debug_info (file) == 0) { warn (_("Unable to load/parse the .debug_info section, so cannot interpret the %s section.\n"), @@ -7834,8 +8200,7 @@ display_debug_ranges (struct dwarf_secti warn (_("Range lists in %s section start at 0x%lx\n"), section->name, (unsigned long) range_entries[0].ranges_offset); - introduce (section, false); - + putchar ('\n'); printf (_(" Offset Begin End\n")); for (i = 0; i < num_range_list; i++) @@ -7895,8 +8260,12 @@ display_debug_ranges (struct dwarf_secti start = next; last_start = next; - (is_rnglists ? display_debug_rnglists_list : display_debug_ranges_list) - (start, finish, pointer_size, offset, base_address); + if (is_rnglists) + display_debug_rnglists_list + (start, finish, pointer_size, offset, base_address); + else + display_debug_ranges_list + (start, finish, pointer_size, offset, base_address); } putchar ('\n'); diff --git a/binutils/dwarf.h b/binutils/dwarf.h index 4fc62abfa4c..ccce2461c81 100644 --- a/binutils/dwarf.h +++ b/binutils/dwarf.h @@ -181,9 +181,13 @@ typedef struct /* This is an array of offsets to the location view table. */ dwarf_vma * loc_views; int * have_frame_base; + + /* Information for associating location lists with CUs. */ unsigned int num_loc_offsets; unsigned int max_loc_offsets; unsigned int num_loc_views; + dwarf_vma loclists_base; + /* List of .debug_ranges offsets seen in this .debug_info. */ dwarf_vma * range_lists; unsigned int num_range_lists; diff --git a/binutils/testsuite/binutils-all/dw5.W b/binutils/testsuite/binutils-all/dw5.W index ebab8b7d3b0..bfcdac175ba 100644 --- a/binutils/testsuite/binutils-all/dw5.W +++ b/binutils/testsuite/binutils-all/dw5.W @@ -281,7 +281,7 @@ Contents of the .debug_loclists section: 00000039 Contents of the .debug_rnglists section: - +#... Offset Begin End 0000000c 0000000000001234 0000000000001236 00000016 0000000000001234 0000000000001239 diff --git a/binutils/testsuite/binutils-all/x86-64/pr26808.dump b/binutils/testsuite/binutils-all/x86-64/pr26808.dump index f64f9d008f9..7ef73b24dc9 100644 --- a/binutils/testsuite/binutils-all/x86-64/pr26808.dump +++ b/binutils/testsuite/binutils-all/x86-64/pr26808.dump @@ -30,13 +30,13 @@ Contents of the .debug_info.dwo section: DW_AT_decl_file : 1 DW_AT_decl_line : 30 DW_AT_type : <0x90> - DW_AT_low_pc : (addr_index: 0x0): + DW_AT_low_pc : (addr_index: 0x0): 0 DW_AT_high_pc : 0x304 DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) DW_AT_GNU_all_tail_call_sites: 1 DW_AT_sibling : <0x11b> <2>: Abbrev Number: 14 (DW_TAG_lexical_block) - DW_AT_low_pc : (addr_index: 0x1): + DW_AT_low_pc : (addr_index: 0x1): 0 DW_AT_high_pc : 0x2fa <3>: Abbrev Number: 15 (DW_TAG_variable) DW_AT_name : c1 @@ -56,7 +56,7 @@ Contents of the .debug_info.dwo section: DW_AT_artificial : 1 DW_AT_location : 2 byte block: fb 2 (DW_OP_GNU_addr_index <0x2>) <3><102>: Abbrev Number: 14 (DW_TAG_lexical_block) - <103> DW_AT_low_pc : (addr_index: 0x3): + <103> DW_AT_low_pc : (addr_index: 0x3): 0 <104> DW_AT_high_pc : 0x2f <4><10c>: Abbrev Number: 17 (DW_TAG_variable) <10d> DW_AT_name : i @@ -274,7 +274,7 @@ Contents of the .debug_info.dwo section: <2dd> DW_AT_decl_file : 1 <2de> DW_AT_decl_line : 70 <2df> DW_AT_linkage_name: _Z4f13iv - <2e8> DW_AT_low_pc : (addr_index: 0x0): + <2e8> DW_AT_low_pc : (addr_index: 0x0): 0 <2e9> DW_AT_high_pc : 0x6 <2f1> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <2f3> DW_AT_GNU_all_call_sites: 1 @@ -282,7 +282,7 @@ Contents of the .debug_info.dwo section: <2f4> DW_AT_specification: <0x219> <2f8> DW_AT_decl_file : 2 <2f9> DW_AT_decl_line : 30 - <2fa> DW_AT_low_pc : (addr_index: 0x1): + <2fa> DW_AT_low_pc : (addr_index: 0x1): 0 <2fb> DW_AT_high_pc : 0x20 <303> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <305> DW_AT_object_pointer: <0x30d> @@ -300,7 +300,7 @@ Contents of the .debug_info.dwo section: <31d> DW_AT_specification: <0x223> <321> DW_AT_decl_file : 2 <322> DW_AT_decl_line : 38 - <323> DW_AT_low_pc : (addr_index: 0x2): + <323> DW_AT_low_pc : (addr_index: 0x2): 0 <324> DW_AT_high_pc : 0x18 <32c> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <32e> DW_AT_object_pointer: <0x336> @@ -316,7 +316,7 @@ Contents of the .debug_info.dwo section: <341> DW_AT_specification: <0x22d> <345> DW_AT_decl_file : 2 <346> DW_AT_decl_line : 46 - <347> DW_AT_low_pc : (addr_index: 0x3): + <347> DW_AT_low_pc : (addr_index: 0x3): 0 <348> DW_AT_high_pc : 0x18 <350> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <352> DW_AT_object_pointer: <0x35a> @@ -332,7 +332,7 @@ Contents of the .debug_info.dwo section: <365> DW_AT_specification: <0x237> <369> DW_AT_decl_file : 2 <36a> DW_AT_decl_line : 54 - <36b> DW_AT_low_pc : (addr_index: 0x4): + <36b> DW_AT_low_pc : (addr_index: 0x4): 0 <36c> DW_AT_high_pc : 0x16 <374> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <376> DW_AT_object_pointer: <0x37e> @@ -348,7 +348,7 @@ Contents of the .debug_info.dwo section: <389> DW_AT_specification: <0x26b> <38d> DW_AT_decl_file : 2 <38e> DW_AT_decl_line : 62 - <38f> DW_AT_low_pc : (addr_index: 0x5): + <38f> DW_AT_low_pc : (addr_index: 0x5): 0 <390> DW_AT_high_pc : 0x16 <398> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <39a> DW_AT_object_pointer: <0x3a2> @@ -366,7 +366,7 @@ Contents of the .debug_info.dwo section: <3b2> DW_AT_specification: <0x275> <3b6> DW_AT_decl_file : 2 <3b7> DW_AT_decl_line : 72 - <3b8> DW_AT_low_pc : (addr_index: 0x6): + <3b8> DW_AT_low_pc : (addr_index: 0x6): 0 <3b9> DW_AT_high_pc : 0x1b <3c1> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <3c3> DW_AT_object_pointer: <0x3cb> @@ -382,7 +382,7 @@ Contents of the .debug_info.dwo section: <3d6> DW_AT_specification: <0x27f> <3da> DW_AT_decl_file : 2 <3db> DW_AT_decl_line : 82 - <3dc> DW_AT_low_pc : (addr_index: 0x7): + <3dc> DW_AT_low_pc : (addr_index: 0x7): 0 <3dd> DW_AT_high_pc : 0x1b <3e5> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <3e7> DW_AT_object_pointer: <0x3ef> @@ -398,7 +398,7 @@ Contents of the .debug_info.dwo section: <3fa> DW_AT_specification: <0x289> <3fe> DW_AT_decl_file : 2 <3ff> DW_AT_decl_line : 92 - <400> DW_AT_low_pc : (addr_index: 0x8): + <400> DW_AT_low_pc : (addr_index: 0x8): 0 <401> DW_AT_high_pc : 0x19 <409> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <40b> DW_AT_object_pointer: <0x413> @@ -414,7 +414,7 @@ Contents of the .debug_info.dwo section: <41e> DW_AT_specification: <0x2ae> <422> DW_AT_decl_file : 2 <423> DW_AT_decl_line : 102 - <424> DW_AT_low_pc : (addr_index: 0x9): + <424> DW_AT_low_pc : (addr_index: 0x9): 0 <425> DW_AT_high_pc : 0x19 <42d> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <42f> DW_AT_object_pointer: <0x437> @@ -432,7 +432,7 @@ Contents of the .debug_info.dwo section: <447> DW_AT_specification: <0x2b8> <44b> DW_AT_decl_file : 2 <44c> DW_AT_decl_line : 112 - <44d> DW_AT_low_pc : (addr_index: 0xa): + <44d> DW_AT_low_pc : (addr_index: 0xa): 0 <44e> DW_AT_high_pc : 0x1f <456> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <458> DW_AT_object_pointer: <0x460> @@ -451,7 +451,7 @@ Contents of the .debug_info.dwo section: <471> DW_AT_decl_line : 120 <472> DW_AT_linkage_name: _Z4f11av <47b> DW_AT_type : <0x242> - <47f> DW_AT_low_pc : (addr_index: 0xb): + <47f> DW_AT_low_pc : (addr_index: 0xb): 0 <480> DW_AT_high_pc : 0xb <488> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <48a> DW_AT_GNU_all_call_sites: 1 @@ -459,7 +459,7 @@ Contents of the .debug_info.dwo section: <48b> DW_AT_specification: <0x2c2> <48f> DW_AT_decl_file : 2 <490> DW_AT_decl_line : 126 - <491> DW_AT_low_pc : (addr_index: 0xc): + <491> DW_AT_low_pc : (addr_index: 0xc): 0 <492> DW_AT_high_pc : 0x20 <49a> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <49c> DW_AT_object_pointer: <0x4a4> @@ -478,7 +478,7 @@ Contents of the .debug_info.dwo section: <4b4> DW_AT_decl_line : 134 <4b5> DW_AT_linkage_name: _Z3t12v <4bd> DW_AT_type : <0x249> - <4c1> DW_AT_low_pc : (addr_index: 0xd): + <4c1> DW_AT_low_pc : (addr_index: 0xd): 0 <4c2> DW_AT_high_pc : 0x19 <4ca> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <4cc> DW_AT_GNU_all_tail_call_sites: 1 @@ -489,7 +489,7 @@ Contents of the .debug_info.dwo section: <4d2> DW_AT_decl_line : 142 <4d3> DW_AT_linkage_name: _Z3t13v <4db> DW_AT_type : <0x249> - <4df> DW_AT_low_pc : (addr_index: 0xe): + <4df> DW_AT_low_pc : (addr_index: 0xe): 0 <4e0> DW_AT_high_pc : 0x14 <4e8> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <4ea> DW_AT_GNU_all_tail_call_sites: 1 @@ -500,13 +500,13 @@ Contents of the .debug_info.dwo section: <4f0> DW_AT_decl_line : 150 <4f1> DW_AT_linkage_name: _Z3t14v <4f9> DW_AT_type : <0x249> - <4fd> DW_AT_low_pc : (addr_index: 0xf): + <4fd> DW_AT_low_pc : (addr_index: 0xf): 0 <4fe> DW_AT_high_pc : 0x61 <506> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <508> DW_AT_GNU_all_tail_call_sites: 1 <508> DW_AT_sibling : <0x532> <2><50c>: Abbrev Number: 24 (DW_TAG_lexical_block) - <50d> DW_AT_low_pc : (addr_index: 0x10): + <50d> DW_AT_low_pc : (addr_index: 0x10): 0 <50e> DW_AT_high_pc : 0x57 <3><516>: Abbrev Number: 25 (DW_TAG_variable) <517> DW_AT_name : s1 @@ -538,13 +538,13 @@ Contents of the .debug_info.dwo section: <54b> DW_AT_decl_line : 163 <54c> DW_AT_linkage_name: _Z3t15v <554> DW_AT_type : <0x249> - <558> DW_AT_low_pc : (addr_index: 0x11): + <558> DW_AT_low_pc : (addr_index: 0x11): 0 <559> DW_AT_high_pc : 0x5d <561> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <563> DW_AT_GNU_all_tail_call_sites: 1 <563> DW_AT_sibling : <0x58d> <2><567>: Abbrev Number: 24 (DW_TAG_lexical_block) - <568> DW_AT_low_pc : (addr_index: 0x12): + <568> DW_AT_low_pc : (addr_index: 0x12): 0 <569> DW_AT_high_pc : 0x53 <3><571>: Abbrev Number: 25 (DW_TAG_variable) <572> DW_AT_name : s1 @@ -576,7 +576,7 @@ Contents of the .debug_info.dwo section: <5a9> DW_AT_decl_line : 176 <5aa> DW_AT_linkage_name: _Z3t16v <5b2> DW_AT_type : <0x249> - <5b6> DW_AT_low_pc : (addr_index: 0x13): + <5b6> DW_AT_low_pc : (addr_index: 0x13): 0 <5b7> DW_AT_high_pc : 0x13 <5bf> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <5c1> DW_AT_GNU_all_tail_call_sites: 1 @@ -587,13 +587,13 @@ Contents of the .debug_info.dwo section: <5c7> DW_AT_decl_line : 184 <5c8> DW_AT_linkage_name: _Z3t17v <5d0> DW_AT_type : <0x249> - <5d4> DW_AT_low_pc : (addr_index: 0x14): + <5d4> DW_AT_low_pc : (addr_index: 0x14): 0 <5d5> DW_AT_high_pc : 0x5f <5dd> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <5df> DW_AT_GNU_all_call_sites: 1 <5df> DW_AT_sibling : <0x612> <2><5e3>: Abbrev Number: 24 (DW_TAG_lexical_block) - <5e4> DW_AT_low_pc : (addr_index: 0x15): + <5e4> DW_AT_low_pc : (addr_index: 0x15): 0 <5e5> DW_AT_high_pc : 0x59 <3><5ed>: Abbrev Number: 25 (DW_TAG_variable) <5ee> DW_AT_name : c @@ -602,7 +602,7 @@ Contents of the .debug_info.dwo section: <5f2> DW_AT_type : <0x53d> <5f6> DW_AT_location : 2 byte block: 91 6f (DW_OP_fbreg: -17) <3><5f9>: Abbrev Number: 24 (DW_TAG_lexical_block) - <5fa> DW_AT_low_pc : (addr_index: 0x16): + <5fa> DW_AT_low_pc : (addr_index: 0x16): 0 <5fb> DW_AT_high_pc : 0x50 <4><603>: Abbrev Number: 25 (DW_TAG_variable) <604> DW_AT_name : i @@ -620,13 +620,13 @@ Contents of the .debug_info.dwo section: <618> DW_AT_decl_line : 199 <619> DW_AT_linkage_name: _Z3t18v <621> DW_AT_type : <0x249> - <625> DW_AT_low_pc : (addr_index: 0x17): + <625> DW_AT_ow_pc : (addr_index: 0x17): 0 <626> DW_AT_high_pc : 0x5f <62e> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <630> DW_AT_GNU_all_tail_call_sites: 1 <630> DW_AT_sibling : <0x67a> <2><634>: Abbrev Number: 24 (DW_TAG_lexical_block) - <635> DW_AT_low_pc : (addr_index: 0x18): + <635> DW_AT_low_pc : (addr_index: 0x18): 0 <636> DW_AT_high_pc : 0x55 <3><63e>: Abbrev Number: 25 (DW_TAG_variable) <63f> DW_AT_name : c @@ -635,7 +635,7 @@ Contents of the .debug_info.dwo section: <643> DW_AT_type : <0x53d> <647> DW_AT_location : 2 byte block: 91 6f (DW_OP_fbreg: -17) <3><64a>: Abbrev Number: 24 (DW_TAG_lexical_block) - <64b> DW_AT_low_pc : (addr_index: 0x19): + <64b> DW_AT_low_pc : (addr_index: 0x19): 0 <64c> DW_AT_high_pc : 0x4c <4><654>: Abbrev Number: 25 (DW_TAG_variable) <655> DW_AT_name : i @@ -644,7 +644,7 @@ Contents of the .debug_info.dwo section: <659> DW_AT_type : <0x242> <65d> DW_AT_location : 2 byte block: 91 68 (DW_OP_fbreg: -24) <4><660>: Abbrev Number: 24 (DW_TAG_lexical_block) - <661> DW_AT_low_pc : (addr_index: 0x1a): + <661> DW_AT_low_pc : (addr_index: 0x1a): 0 <662> DW_AT_high_pc : 0x34 <5><66a>: Abbrev Number: 25 (DW_TAG_variable) <66b> DW_AT_name : s @@ -786,7 +786,7 @@ Contents of the .debug_info.dwo section: <7d3> DW_AT_decl_line : 32 <7d4> DW_AT_linkage_name: _Z4t16av <7dd> DW_AT_type : <0x7c4> - <7e1> DW_AT_low_pc : (addr_index: 0x0): + <7e1> DW_AT_low_pc : (addr_index: 0x0): 0 <7e2> DW_AT_high_pc : 0x13 <7ea> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <7ec> DW_AT_GNU_all_tail_call_sites: 1 @@ -878,14 +878,14 @@ Contents of the .debug_info.dwo section: <908> DW_AT_decl_file : 1 <909> DW_AT_decl_line : 70 <90a> DW_AT_linkage_name: _Z4f13iv - <913> DW_AT_low_pc : (addr_index: 0x0): + <913> DW_AT_low_pc : (addr_index: 0x0): 0 <914> DW_AT_high_pc : 0x6 <91c> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <91e> DW_AT_GNU_all_call_sites: 1 <1><91e>: Abbrev Number: 17 (DW_TAG_subprogram) <91f> DW_AT_specification: <0x8a8> <923> DW_AT_decl_file : 2 - <924> DW_AT_low_pc : (addr_index: 0x1): + <924> DW_AT_low_pc : (addr_index: 0x1): 0 <925> DW_AT_high_pc : 0xf <92d> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <92f> DW_AT_object_pointer: <0x937> @@ -903,7 +903,7 @@ Contents of the .debug_info.dwo section: <94b> DW_AT_specification: <0x89b> <94f> DW_AT_decl_file : 2 <950> DW_AT_decl_line : 36 - <951> DW_AT_low_pc : (addr_index: 0x2): + <951> DW_AT_low_pc : (addr_index: 0x2): 0 <952> DW_AT_high_pc : 0x20 <95a> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <95c> DW_AT_object_pointer: <0x964> @@ -922,7 +922,7 @@ Contents of the .debug_info.dwo section: <978> DW_AT_decl_line : 72 <979> DW_AT_linkage_name: _Z3f10v <981> DW_AT_type : <0x8b7> - <985> DW_AT_low_pc : (addr_index: 0x3): + <985> DW_AT_low_pc : (addr_index: 0x3): 0 <986> DW_AT_high_pc : 0xb <98e> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <990> DW_AT_GNU_all_call_sites: 1 @@ -933,7 +933,7 @@ Contents of the .debug_info.dwo section: <997> DW_AT_decl_line : 80 <998> DW_AT_linkage_name: _Z4f11bPFivE <9a5> DW_AT_type : <0x8b7> - <9a9> DW_AT_low_pc : (addr_index: 0x4): + <9a9> DW_AT_low_pc : (addr_index: 0x4): 0 <9aa> DW_AT_high_pc : 0x14 <9b2> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <9b4> DW_AT_GNU_all_tail_call_sites: 1 @@ -954,7 +954,7 @@ Contents of the .debug_info.dwo section: <9d3> DW_AT_specification: <0x8e0> <9d7> DW_AT_decl_file : 2 <9d8> DW_AT_decl_line : 88 - <9d9> DW_AT_low_pc : (addr_index: 0x5): + <9d9> DW_AT_low_pc : (addr_index: 0x5): 0 <9da> DW_AT_high_pc : 0xf <9e2> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <9e4> DW_AT_object_pointer: <0x9ec> @@ -976,7 +976,7 @@ Contents of the .debug_info.dwo section: DW_AT_decl_line : 96 DW_AT_linkage_name: _Z3f13v DW_AT_type : <0xa1e> - DW_AT_low_pc : (addr_index: 0x6): + DW_AT_low_pc : (addr_index: 0x6): 0 DW_AT_high_pc : 0xb DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) DW_AT_GNU_all_call_sites: 1 @@ -990,7 +990,7 @@ Contents of the .debug_info.dwo section: DW_AT_decl_line : 104 DW_AT_linkage_name: _Z3f14v DW_AT_type : <0xa42> - DW_AT_low_pc : (addr_index: 0x7): + DW_AT_low_pc : (addr_index: 0x7): 0 DW_AT_high_pc : 0xb DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) DW_AT_GNU_all_call_sites: 1 @@ -1010,7 +1010,7 @@ Contents of the .debug_info.dwo section: DW_AT_decl_line : 112 DW_AT_linkage_name: _Z3f15v DW_AT_type : <0xa73> - DW_AT_low_pc : (addr_index: 0x8): + DW_AT_low_pc : (addr_index: 0x8): 0 DW_AT_high_pc : 0xb DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) DW_AT_GNU_all_call_sites: 1 @@ -1030,7 +1030,7 @@ Contents of the .debug_info.dwo section: DW_AT_decl_line : 127 DW_AT_linkage_name: _Z3f18i DW_AT_type : <0xa42> - DW_AT_low_pc : (addr_index: 0x9): + DW_AT_low_pc : (addr_index: 0x9): 0 DW_AT_high_pc : 0x44 DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) DW_AT_GNU_all_call_sites: 1