From 9f272209118972864b2c3799ddf2b39683c1a7b7 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Fri, 22 Sep 2017 17:05:51 -0300 Subject: [PATCH] LVU: dump loclists with locviews When dumping location lists, also dump locview lists that may be interspersed with them, and bring view pairs next to the corresponding location list entries. This patch supports DW_AT_GNU_locviews as a separate attribute for DWARF4- loc_lists and split (dwo) loclists, as well as DWARF5 loclists. It also supports, in DWARF5 loclists, the proposed DW_LLE_GNU_view_pair loclist entry type proposed for DWARF6. The tests use 32-bit DWARF, even on 64-bit targets, resolving offsets to constants so as to reduce the risk that relocations be created for them, or that the offsets be rejected as nonconstants. The patch also adds an xfail to an unrelated test, namely dw5, so that no unexpected fails remain on nds32*-elf, one of the tested targets. Reviewed-by: Alan Modra for include/ChangeLog * dwarf2.def (DW_AT_GNU_locviews): New. * dwarf2.h (enum dwarf_location_list_entry_type): Add DW_LLE_GNU_view_pair. (DW_LLE_view_pair): Define. for binutils/ChangeLog * dwarf.h (debug_info): Add loc_views and num_loc_views. * dwarf.c (vm1): New constant. (print_dwarf_view): New function. (read_and_display_attr_value): Support DW_AT_GNU_locviews. (process_debug_info): Keep num_loc_offsets and num_loc_views in sync. (display_view_pair_list): New function. (display_loc_list_dwo): Take vstart_ptr; update it. Dump location view pairs before the range they apply to, when a viewlist augments the loc list. (display_loc_list): Likewise. Check view numbers in range tests. (display_loclists_list): Likewise. Handle view pair entries, and warn on trailing ones. (loc_views): New variable. (loc_offsets_compar): Compare loc_views if loc_offsets are the same. (display_debug_loc): Check and sort loc_views too. Accept loc_view as expected_start. Skip if lists and views are the same. Dump locview list separately in order, and pass the locview list base to each list dump function. Warn and skip overlap and hole checking if we find loclists and locviews to not be adjacent. * testsuite/binutils-all/locview-1.s: New. * testsuite/binutils-all/readelf.locview-1: New. * testsuite/binutils-all/locview-2.s: New. * testsuite/binutils-all/readelf.locview-2: New. * testsuite/binutils-all/readelf.exp: Run new tests. Fix option spelling in pr18374 fail message. XFAIL dw5 test on nds32*-elf. --- binutils/ChangeLog | 33 ++ binutils/dwarf.c | 332 +++++++++++++++-- binutils/dwarf.h | 3 + binutils/testsuite/binutils-all/locview-1.s | 270 ++++++++++++++ binutils/testsuite/binutils-all/locview-2.s | 335 ++++++++++++++++++ binutils/testsuite/binutils-all/readelf.exp | 29 +- .../testsuite/binutils-all/readelf.locview-1 | 35 ++ .../testsuite/binutils-all/readelf.locview-2 | 46 +++ include/ChangeLog | 7 + include/dwarf2.def | 2 + include/dwarf2.h | 8 + 11 files changed, 1065 insertions(+), 35 deletions(-) create mode 100644 binutils/testsuite/binutils-all/locview-1.s create mode 100644 binutils/testsuite/binutils-all/locview-2.s create mode 100644 binutils/testsuite/binutils-all/readelf.locview-1 create mode 100644 binutils/testsuite/binutils-all/readelf.locview-2 diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 87ee8a4eaee..037408440be 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,36 @@ +2017-09-22 Alexandre Oliva + + * dwarf.h (debug_info): Add loc_views and num_loc_views. + * dwarf.c (vm1): New constant. + (print_dwarf_view): New function. + (read_and_display_attr_value): Support DW_AT_GNU_locviews. + (process_debug_info): Keep num_loc_offsets and num_loc_views + in sync. + (display_view_pair_list): New function. + (display_loc_list_dwo): Take vstart_ptr; update it. Dump + location view pairs before the range they apply to, when a + viewlist augments the loc list. + (display_loc_list): Likewise. Check view numbers in range + tests. + (display_loclists_list): Likewise. Handle view pair entries, + and warn on trailing ones. + (loc_views): New variable. + (loc_offsets_compar): Compare loc_views if loc_offsets are the + same. + (display_debug_loc): Check and sort loc_views too. Accept + loc_view as expected_start. Skip if lists and views are the + same. Dump locview list separately in order, and pass the + locview list base to each list dump function. Warn and skip + overlap and hole checking if we find loclists and locviews to + not be adjacent. + * testsuite/binutils-all/locview-1.s: New. + * testsuite/binutils-all/readelf.locview-1: New. + * testsuite/binutils-all/locview-2.s: New. + * testsuite/binutils-all/readelf.locview-2: New. + * testsuite/binutils-all/readelf.exp: Run new tests. Fix + option spelling in pr18374 fail message. XFAIL dw5 test on + nds32*-elf. + 2017-09-22 Alan Modra * testsuite/binutils-all/readelf.exp: Don't perror and exit on diff --git a/binutils/dwarf.c b/binutils/dwarf.c index d2fc7993cc8..af8732bb804 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -74,6 +74,10 @@ unsigned long dwarf_start_die; int dwarf_check = 0; +/* Convenient constant, to avoid having to cast -1 to dwarf_vma when + testing whether e.g. a locview list is present. */ +static const dwarf_vma vm1 = -1; + /* Collection of CU/TU section sets from .debug_cu_index and .debug_tu_index sections. For version 1 package files, each set is stored in SHNDX_POOL as a zero-terminated list of section indexes comprising one set of debug @@ -239,6 +243,26 @@ print_dwarf_vma (dwarf_vma value, unsigned num_bytes) printf ("%s ", dwarf_vmatoa_1 (NULL, value, num_bytes)); } +/* Print a view number in hexadecimal value, with the same width + print_dwarf_vma would have printed it with the same num_bytes. + Print blanks for zero view, unless force is nonzero. */ + +static void +print_dwarf_view (dwarf_vma value, unsigned num_bytes, int force) +{ + int len; + if (!num_bytes) + len = 4; + else + len = num_bytes * 2; + + assert (value == (unsigned long) value); + if (value || force) + printf ("v%0*lx ", len - 1, (unsigned long) value); + else + printf ("%*s", len + 1, ""); +} + /* Format a 64-bit value, given as two 32-bit values, in hex. For reentrancy, this uses a buffer provided by the caller. */ @@ -2012,6 +2036,7 @@ read_and_display_attr_value (unsigned long attribute, have_frame_base = 1; /* Fall through. */ case DW_AT_location: + case DW_AT_GNU_locviews: case DW_AT_string_length: case DW_AT_return_addr: case DW_AT_data_member_location: @@ -2041,6 +2066,9 @@ read_and_display_attr_value (unsigned long attribute, debug_info_p->loc_offsets = (dwarf_vma *) xcrealloc (debug_info_p->loc_offsets, lmax, sizeof (*debug_info_p->loc_offsets)); + debug_info_p->loc_views = (dwarf_vma *) + xcrealloc (debug_info_p->loc_views, + lmax, sizeof (*debug_info_p->loc_views)); debug_info_p->have_frame_base = (int *) xcrealloc (debug_info_p->have_frame_base, lmax, sizeof (*debug_info_p->have_frame_base)); @@ -2048,9 +2076,23 @@ read_and_display_attr_value (unsigned long attribute, } if (this_set != NULL) uvalue += this_set->section_offsets [DW_SECT_LOC]; - debug_info_p->loc_offsets [num] = uvalue; debug_info_p->have_frame_base [num] = have_frame_base; - debug_info_p->num_loc_offsets++; + if (attribute != DW_AT_GNU_locviews) + { + debug_info_p->loc_offsets [num] = uvalue; + debug_info_p->num_loc_offsets++; + assert (debug_info_p->num_loc_offsets + - debug_info_p->num_loc_views <= 1); + } + else + { + assert (debug_info_p->num_loc_views <= num); + num = debug_info_p->num_loc_views; + debug_info_p->loc_views [num] = uvalue; + debug_info_p->num_loc_views++; + assert (debug_info_p->num_loc_views + - debug_info_p->num_loc_offsets <= 1); + } } break; @@ -2858,21 +2900,22 @@ process_debug_info (struct dwarf_section *section, break; } + debug_info *debug_info_p = + (debug_information && unit < alloc_num_debug_info_entries) + ? debug_information + unit : NULL; + + assert (!debug_info_p + || (debug_info_p->num_loc_offsets + == debug_info_p->num_loc_views)); + for (attr = entry->first_attr; attr && attr->attribute; attr = attr->next) { - debug_info *arg; - if (! do_loc && do_printing) /* Show the offset from where the tag was extracted. */ printf (" <%lx>", (unsigned long)(tags - section_begin)); - if (debug_information && unit < alloc_num_debug_info_entries) - arg = debug_information + unit; - else - arg = NULL; - tags = read_and_display_attr (attr->attribute, attr->form, attr->implicit_const, @@ -2882,12 +2925,37 @@ process_debug_info (struct dwarf_section *section, compunit.cu_pointer_size, offset_size, compunit.cu_version, - arg, + debug_info_p, do_loc || ! do_printing, section, this_set); } + /* If a locview attribute appears before a location one, + make sure we don't associate it with an earlier + loclist. */ + if (debug_info_p) + switch (debug_info_p->num_loc_offsets - debug_info_p->num_loc_views) + { + case 1: + debug_info_p->loc_views [debug_info_p->num_loc_views] = vm1; + debug_info_p->num_loc_views++; + assert (debug_info_p->num_loc_views + == debug_info_p->num_loc_offsets); + break; + + case 0: + break; + + case -1: + warn(_("DIE has locviews without loclist\n")); + debug_info_p->num_loc_views--; + break; + + default: + assert (0); + } + if (entry->children) ++level; } @@ -5023,6 +5091,52 @@ is_max_address (dwarf_vma addr, unsigned int pointer_size) return ((addr & mask) == mask); } +/* Display a view pair list starting at *VSTART_PTR and ending at + VLISTEND within SECTION. */ + +static void +display_view_pair_list (struct dwarf_section *section, + unsigned char **vstart_ptr, + unsigned int debug_info_entry, + unsigned char *vlistend) +{ + unsigned char *vstart = *vstart_ptr; + unsigned char *section_end = section->start + section->size; + unsigned int pointer_size = debug_information [debug_info_entry].pointer_size; + + if (vlistend < section_end) + section_end = vlistend; + + putchar ('\n'); + + while (vstart < section_end) + { + dwarf_vma off = vstart - section->start; + dwarf_vma vbegin, vend; + + unsigned int bytes_read; + vbegin = read_uleb128 (vstart, &bytes_read, section_end); + vstart += bytes_read; + if (vstart == section_end) + { + vstart -= bytes_read; + break; + } + + vend = read_uleb128 (vstart, &bytes_read, section_end); + vstart += bytes_read; + + printf (" %8.8lx ", (unsigned long) off); + + print_dwarf_view (vbegin, pointer_size, 1); + print_dwarf_view (vend, pointer_size, 1); + printf (_("location view pair\n")); + } + + putchar ('\n'); + *vstart_ptr = vstart; +} + /* Display a location list from a normal (ie, non-dwo) .debug_loc section. */ static void @@ -5031,9 +5145,10 @@ display_loc_list (struct dwarf_section *section, 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 *start = *start_ptr, *vstart = *vstart_ptr; unsigned char *section_end = section->start + section->size; unsigned long cu_offset; unsigned int pointer_size; @@ -5067,6 +5182,7 @@ display_loc_list (struct dwarf_section *section, while (1) { dwarf_vma off = offset + (start - *start_ptr); + dwarf_vma vbegin = vm1, vend = vm1; if (start + 2 * pointer_size > section_end) { @@ -5107,6 +5223,24 @@ display_loc_list (struct dwarf_section *section, continue; } + if (vstart) + { + unsigned int bytes_read; + + off = offset + (vstart - *start_ptr); + + vbegin = read_uleb128 (vstart, &bytes_read, section_end); + vstart += bytes_read; + print_dwarf_view (vbegin, pointer_size, 1); + + vend = read_uleb128 (vstart, &bytes_read, section_end); + vstart += bytes_read; + print_dwarf_view (vend, pointer_size, 1); + + printf (_("views at %8.8lx for:\n %*s "), + (unsigned long) off, 8, ""); + } + if (start + 2 > section_end) { warn (_("Location list starting at offset 0x%lx is not terminated.\n"), @@ -5138,9 +5272,9 @@ display_loc_list (struct dwarf_section *section, if (need_frame_base && !has_frame_base) printf (_(" [without DW_AT_frame_base]")); - if (begin == end) + if (begin == end && vbegin == vend) fputs (_(" (start == end)"), stdout); - else if (begin > end) + else if (begin > end || (begin == end && vbegin > vend)) fputs (_(" (start > end)"), stdout); putchar ('\n'); @@ -5149,6 +5283,7 @@ display_loc_list (struct dwarf_section *section, } *start_ptr = start; + *vstart_ptr = vstart; } /* Display a location list from a normal (ie, non-dwo) .debug_loclists section. */ @@ -5159,9 +5294,10 @@ display_loclists_list (struct dwarf_section *section, 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 *start = *start_ptr, *vstart = *vstart_ptr; unsigned char *section_end = section->start + section->size; unsigned long cu_offset; unsigned int pointer_size; @@ -5170,8 +5306,8 @@ display_loclists_list (struct dwarf_section *section, unsigned int bytes_read; /* Initialize it due to a false compiler warning. */ - dwarf_vma begin = -1; - dwarf_vma end = -1; + dwarf_vma begin = -1, vbegin = -1; + dwarf_vma end = -1, vend = -1; dwarf_vma length; int need_frame_base; @@ -5211,6 +5347,22 @@ display_loclists_list (struct dwarf_section *section, SAFE_BYTE_GET_AND_INC (llet, start, 1, section_end); + if (vstart && llet == DW_LLE_offset_pair) + { + off = offset + (vstart - *start_ptr); + + vbegin = read_uleb128 (vstart, &bytes_read, section_end); + vstart += bytes_read; + print_dwarf_view (vbegin, pointer_size, 1); + + vend = read_uleb128 (vstart, &bytes_read, section_end); + vstart += bytes_read; + print_dwarf_view (vend, pointer_size, 1); + + printf (_("views at %8.8lx for:\n %*s "), + (unsigned long) off, 8, ""); + } + switch (llet) { case DW_LLE_end_of_list: @@ -5228,6 +5380,21 @@ display_loclists_list (struct dwarf_section *section, print_dwarf_vma (base_address, pointer_size); printf (_("(base address)\n")); break; +#ifdef DW_LLE_view_pair + case DW_LLE_view_pair: + if (vstart) + printf (_("View pair entry in loclist with locviews attribute\n")); + vbegin = read_uleb128 (start, &bytes_read, section_end); + start += bytes_read; + print_dwarf_view (vbegin, pointer_size, 1); + + vend = read_uleb128 (start, &bytes_read, section_end); + start += bytes_read; + print_dwarf_view (vend, pointer_size, 1); + + printf (_("views for:\n")); + continue; +#endif default: error (_("Invalid location list entry type %d\n"), llet); return; @@ -5262,17 +5429,22 @@ display_loclists_list (struct dwarf_section *section, if (need_frame_base && !has_frame_base) printf (_(" [without DW_AT_frame_base]")); - if (begin == end) + if (begin == end && vbegin == vend) fputs (_(" (start == end)"), stdout); - else if (begin > end) + else if (begin > end || (begin == end && vbegin > vend)) fputs (_(" (start > end)"), stdout); putchar ('\n'); start += length; + vbegin = vend = -1; } + if (vbegin != vm1 || vend != vm1) + printf (_("Trailing view pair not used in a range")); + *start_ptr = start; + *vstart_ptr = vstart; } /* Print a .debug_addr table index in decimal, surrounded by square brackets, @@ -5295,9 +5467,10 @@ display_loc_list_dwo (struct dwarf_section *section, unsigned char **start_ptr, unsigned int debug_info_entry, dwarf_vma offset, + unsigned char **vstart_ptr, int has_frame_base) { - unsigned char *start = *start_ptr; + unsigned char *start = *start_ptr, *vstart = *vstart_ptr; unsigned char *section_end = section->start + section->size; unsigned long cu_offset; unsigned int pointer_size; @@ -5340,17 +5513,47 @@ display_loc_list_dwo (struct dwarf_section *section, } SAFE_BYTE_GET_AND_INC (entry_type, start, 1, section_end); + + if (vstart) + switch (entry_type) + { + default: + break; + + case 2: + case 3: + case 4: + { + dwarf_vma view; + dwarf_vma off = offset + (vstart - *start_ptr); + + view = read_uleb128 (vstart, &bytes_read, section_end); + vstart += bytes_read; + print_dwarf_view (view, 8, 1); + + view = read_uleb128 (vstart, &bytes_read, section_end); + vstart += bytes_read; + print_dwarf_view (view, 8, 1); + + printf (_("views at %8.8lx for:\n %*s "), + (unsigned long) off, 8, ""); + + } + break; + } + switch (entry_type) { case 0: /* A terminating entry. */ *start_ptr = start; + *vstart_ptr = vstart; printf (_("\n")); return; case 1: /* A base-address entry. */ idx = read_uleb128 (start, &bytes_read, section_end); start += bytes_read; print_addr_index (idx, 8); - printf (" "); + printf ("%*s", 9 + (vstart ? 2 * 6 : 0), ""); printf (_("(base address selection entry)\n")); continue; case 2: /* A start/end entry. */ @@ -5377,6 +5580,7 @@ display_loc_list_dwo (struct dwarf_section *section, default: warn (_("Unknown location list entry type 0x%x.\n"), entry_type); *start_ptr = start; + *vstart_ptr = vstart; return; } @@ -5413,11 +5617,13 @@ display_loc_list_dwo (struct dwarf_section *section, } *start_ptr = start; + *vstart_ptr = vstart; } -/* Sort array of indexes in ascending order of loc_offsets[idx]. */ +/* Sort array of indexes in ascending order of loc_offsets[idx] and + loc_views. */ -static dwarf_vma *loc_offsets; +static dwarf_vma *loc_offsets, *loc_views; static int loc_offsets_compar (const void *ap, const void *bp) @@ -5425,23 +5631,33 @@ loc_offsets_compar (const void *ap, const void *bp) dwarf_vma a = loc_offsets[*(const unsigned int *) ap]; dwarf_vma b = loc_offsets[*(const unsigned int *) bp]; - return (a > b) - (b > a); + int ret = (a > b) - (b > a); + if (ret) + return ret; + + a = loc_views[*(const unsigned int *) ap]; + b = loc_views[*(const unsigned int *) bp]; + + ret = (a > b) - (b > a); + + return ret; } static int display_debug_loc (struct dwarf_section *section, void *file) { - unsigned char *start = section->start; + unsigned char *start = section->start, *vstart = NULL; unsigned long bytes; unsigned char *section_begin = start; unsigned int num_loc_list = 0; unsigned long last_offset = 0; + unsigned long last_view = 0; unsigned int first = 0; unsigned int i; unsigned int j; int seen_first_offset = 0; int locs_sorted = 1; - unsigned char *next; + unsigned char *next = start, *vnext = vstart; unsigned int *array = NULL; const char *suffix = strrchr (section->name, '.'); int is_dwo = 0; @@ -5529,6 +5745,7 @@ display_debug_loc (struct dwarf_section *section, void *file) { /* This is the first location list. */ last_offset = debug_information [i].loc_offsets [0]; + last_view = debug_information [i].loc_views [0]; first = i; seen_first_offset = 1; j = 1; @@ -5539,12 +5756,15 @@ display_debug_loc (struct dwarf_section *section, void *file) for (; j < num; j++) { if (last_offset > - debug_information [i].loc_offsets [j]) + debug_information [i].loc_offsets [j] + || (last_offset == debug_information [i].loc_offsets [j] + && last_view > debug_information [i].loc_views [j])) { locs_sorted = 0; break; } last_offset = debug_information [i].loc_offsets [j]; + last_view = debug_information [i].loc_views [j]; } } } @@ -5553,7 +5773,8 @@ display_debug_loc (struct dwarf_section *section, void *file) error (_("No location lists in .debug_info section!\n")); if (debug_information [first].num_loc_offsets > 0 - && debug_information [first].loc_offsets [0] != expected_start) + && 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"), section->name, dwarf_vmatoa ("x", debug_information [first].loc_offsets [0])); @@ -5568,7 +5789,7 @@ display_debug_loc (struct dwarf_section *section, void *file) seen_first_offset = 0; for (i = first; i < num_debug_info_entries; i++) { - dwarf_vma offset; + dwarf_vma offset, voffset; dwarf_vma base_address; unsigned int k; int has_frame_base; @@ -5578,24 +5799,42 @@ display_debug_loc (struct dwarf_section *section, void *file) for (k = 0; k < debug_information [i].num_loc_offsets; k++) array[k] = k; loc_offsets = debug_information [i].loc_offsets; + loc_views = debug_information [i].loc_views; qsort (array, debug_information [i].num_loc_offsets, sizeof (*array), loc_offsets_compar); } + int adjacent_view_loclists = 1; for (k = 0; k < debug_information [i].num_loc_offsets; k++) { j = locs_sorted ? k : array[k]; if (k - && debug_information [i].loc_offsets [locs_sorted + && (debug_information [i].loc_offsets [locs_sorted ? k - 1 : array [k - 1]] - == debug_information [i].loc_offsets [j]) + == debug_information [i].loc_offsets [j]) + && (debug_information [i].loc_views [locs_sorted + ? k - 1 : array [k - 1]] + == debug_information [i].loc_views [j])) continue; has_frame_base = debug_information [i].have_frame_base [j]; offset = debug_information [i].loc_offsets [j]; next = section_begin + offset; + voffset = debug_information [i].loc_views [j]; + if (voffset != vm1) + vnext = section_begin + voffset; + else + vnext = NULL; base_address = debug_information [i].base_address; - if (!seen_first_offset) + if (vnext && vnext < next) + { + vstart = vnext; + display_view_pair_list (section, &vstart, i, next); + if (start == vnext) + start = vstart; + } + + if (!seen_first_offset || !adjacent_view_loclists) seen_first_offset = 1; else { @@ -5609,6 +5848,7 @@ display_debug_loc (struct dwarf_section *section, void *file) (unsigned long) offset); } start = next; + vstart = vnext; if (offset >= bytes) { @@ -5617,14 +5857,21 @@ display_debug_loc (struct dwarf_section *section, void *file) continue; } + if (vnext && voffset >= bytes) + { + warn (_("View Offset 0x%lx is bigger than .debug_loc section size.\n"), + (unsigned long) voffset); + continue; + } + if (!is_loclists) { if (is_dwo) display_loc_list_dwo (section, &start, i, offset, - has_frame_base); + &vstart, has_frame_base); else display_loc_list (section, &start, i, offset, base_address, - has_frame_base); + &vstart, has_frame_base); } else { @@ -5632,8 +5879,25 @@ display_debug_loc (struct dwarf_section *section, void *file) warn (_("DWO is not yet supported.\n")); else display_loclists_list (section, &start, i, offset, base_address, - has_frame_base); + &vstart, has_frame_base); + } + + /* FIXME: this arrangement is quite simplistic. Nothing + requires locview lists to be adjacent to corresponding + loclists, and a single loclist could be augmented by + different locview lists, and vice-versa, unlikely as it + is that it would make sense to do so. Hopefully we'll + have view pair support built into loclists before we ever + need to address all these possibilities. */ + if (adjacent_view_loclists && vnext + && vnext != start && vstart != next) + { + adjacent_view_loclists = 0; + warn (_("Hole and overlap detection requires adjacent view lists and loclists.\n")); } + + if (vnext && vnext == start) + display_view_pair_list (section, &start, i, vstart); } } diff --git a/binutils/dwarf.h b/binutils/dwarf.h index 4d3330c2b9e..15719eef85c 100644 --- a/binutils/dwarf.h +++ b/binutils/dwarf.h @@ -170,9 +170,12 @@ typedef struct dwarf_vma ranges_base; /* This is an array of offsets to the location list table. */ dwarf_vma * loc_offsets; + /* This is an array of offsets to the location view table. */ + dwarf_vma * loc_views; int * have_frame_base; unsigned int num_loc_offsets; unsigned int max_loc_offsets; + unsigned int num_loc_views; /* 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/locview-1.s b/binutils/testsuite/binutils-all/locview-1.s new file mode 100644 index 00000000000..d9d9b5b77a2 --- /dev/null +++ b/binutils/testsuite/binutils-all/locview-1.s @@ -0,0 +1,270 @@ + .text +.Ltext0: +.LFB0: + /* locview.c:1 */ +.LM1: + /* view -0 */ + /* locview.c:2 */ +.LM2: + /* view 1 */ +.LVL0: + /* DEBUG i => 0 */ + /* locview.c:3 */ +.LM3: + /* view 2 */ + /* DEBUG j => 0x1 */ + /* locview.c:4 */ +.LM4: + /* view 3 */ + /* DEBUG i => 0x2 */ + /* locview.c:5 */ +.LM5: + /* view 4 */ + /* DEBUG j => 0x3 */ + /* locview.c:6 */ +.LM6: + /* view 5 */ + /* DEBUG k => 0x4 */ + /* DEBUG l => 0x4 */ + /* locview.c:7 */ +.LM7: + /* view 6 */ + /* DEBUG k => 0x5 */ + /* DEBUG l => 0x5 */ + /* locview.c:8 */ +.LM8: + /* view 7 */ + /* DEBUG k => 0x6 */ + /* DEBUG l => 0x6 */ + /* locview.c:9 */ +.LM9: + /* view 8 */ + .byte 0 +.LFE0: +.Letext0: + + .section .debug_info +.Ldebug_info0: +.LIbase: + .4byte .LIend - .LIstart /* Length of Compilation Unit Info */ +.LIstart: + .2byte 0x4 /* DWARF version number */ + .4byte .Ldebug_abbrev0 /* Offset Into Abbrev. Section */ + .byte 0x4 /* Pointer Size (in bytes) */ +.LIcu: + .uleb128 0x1 /* (DIE (cu) DW_TAG_compile_unit) */ + .ascii "hand-crafted based on GCC output\0" + .byte 0xc /* DW_AT_language */ + .ascii "locview.c\0" + .ascii "/tmp\0" + .4byte 0 /* DW_AT_low_pc */ +.LIsubf: + .uleb128 0x2 /* (DIE (subf) DW_TAG_subprogram) */ + .ascii "f\0" /* DW_AT_name */ + .byte 0x1 /* DW_AT_decl_file (locview.c) */ + .byte 0x1 /* DW_AT_decl_line */ + .4byte .LIint-.LIbase /* DW_AT_type */ + .4byte .LFB0 /* DW_AT_low_pc */ + .4byte 1 /* .LFE0-.LFB0 */ /* DW_AT_high_pc */ + .uleb128 0x1 /* DW_AT_frame_base */ + .byte 0x9c /* DW_OP_call_frame_cfa */ + /* DW_AT_GNU_all_call_sites */ + .4byte .LIint - .LIbase /* DW_AT_sibling */ +.LIvari: + .uleb128 0x3 /* (DIE (vari) DW_TAG_variable) */ + .ascii "i\0" /* DW_AT_name */ + .byte 0x1 /* DW_AT_decl_file (locview.c) */ + .byte 0x2 /* DW_AT_decl_line */ + .4byte .LIint-.LIbase /* DW_AT_type */ + .4byte .LLST0 /* DW_AT_location */ + .4byte .LVUS0 /* DW_AT_GNU_locviews */ +.LIvarj: + .uleb128 0x3 /* (DIE (varf) DW_TAG_variable) */ + .ascii "j\0" /* DW_AT_name */ + .byte 0x1 /* DW_AT_decl_file (locview.c) */ + .byte 0x3 /* DW_AT_decl_line */ + .4byte .LIint - .LIbase /* DW_AT_type */ + .4byte .LLST1 /* DW_AT_location */ + .4byte .LVUS1 /* DW_AT_GNU_locviews */ +.LIvark: + .uleb128 0x5 /* (DIE (vark) DW_TAG_variable) */ + .ascii "k\0" /* DW_AT_name */ + .byte 0x1 /* DW_AT_decl_file (locview.c) */ + .byte 0x6 /* DW_AT_decl_line */ + .4byte .LIint - .LIbase /* DW_AT_type */ + .4byte .LVUS2 /* DW_AT_GNU_locviews */ + .4byte .LLST2 /* DW_AT_location */ + .byte 0 /* end of children of subf */ +.LIvarl: + .uleb128 0x5 /* (DIE (varl) DW_TAG_variable) */ + .ascii "l\0" /* DW_AT_name */ + .byte 0x1 /* DW_AT_decl_file (locview.c) */ + .byte 0x6 /* DW_AT_decl_line */ + .4byte .LIint - .LIbase /* DW_AT_type */ + .4byte .LVUS2 /* DW_AT_GNU_locviews */ + .4byte .LLST2 /* DW_AT_location */ + .byte 0 /* end of children of subf */ + +.LIint: + .uleb128 0x4 /* (DIE (int) DW_TAG_base_type) */ + .byte 0x4 /* DW_AT_byte_size */ + .byte 0x5 /* DW_AT_encoding */ + .ascii "int\0" /* DW_AT_name */ + .byte 0 /* end of children of cu */ +.LIend: + + .section .debug_abbrev +.Ldebug_abbrev0: +.LAbrv1: + .uleb128 0x1 /* (abbrev code) */ + .uleb128 0x11 /* (TAG: DW_TAG_compile_unit) */ + .byte 0x1 /* DW_children_yes */ + .uleb128 0x25 /* (DW_AT_producer) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .uleb128 0x13 /* (DW_AT_language) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x3 /* (DW_AT_name) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .uleb128 0x1b /* (DW_AT_comp_dir) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .uleb128 0x11 /* (DW_AT_low_pc) */ + .uleb128 0x1 /* (DW_FORM_addr) */ + .byte 0 + .byte 0 +.LAbrv2: + .uleb128 0x2 /* (abbrev code) */ + .uleb128 0x2e /* (TAG: DW_TAG_subprogram) */ + .byte 0x1 /* DW_children_yes */ + .uleb128 0x3 /* (DW_AT_name) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .uleb128 0x3a /* (DW_AT_decl_file) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x3b /* (DW_AT_decl_line) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x49 /* (DW_AT_type) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .uleb128 0x11 /* (DW_AT_low_pc) */ + .uleb128 0x1 /* (DW_FORM_addr) */ + .uleb128 0x12 /* (DW_AT_high_pc) */ + .uleb128 0x6 /* (DW_FORM_data4) */ + .uleb128 0x40 /* (DW_AT_frame_base) */ + .uleb128 0x18 /* (DW_FORM_exprloc) */ + .uleb128 0x2117 /* (DW_AT_GNU_all_call_sites) */ + .uleb128 0x19 /* (DW_FORM_flag_present) */ + .uleb128 0x1 /* (DW_AT_sibling) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .byte 0 + .byte 0 +.LAbrv3: + .uleb128 0x3 /* (abbrev code) */ + .uleb128 0x34 /* (TAG: DW_TAG_variable) */ + .byte 0 /* DW_children_no */ + .uleb128 0x3 /* (DW_AT_name) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .uleb128 0x3a /* (DW_AT_decl_file) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x3b /* (DW_AT_decl_line) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x49 /* (DW_AT_type) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .uleb128 0x2 /* (DW_AT_location) */ + .uleb128 0x17 /* (DW_FORM_sec_offset) */ + .uleb128 0x2137 /* (DW_AT_GNU_locviews) */ + .uleb128 0x17 /* (DW_FORM_sec_offset) */ + .byte 0 + .byte 0 +.LAbrv4: + .uleb128 0x4 /* (abbrev code) */ + .uleb128 0x24 /* (TAG: DW_TAG_base_type) */ + .byte 0 /* DW_children_no */ + .uleb128 0xb /* (DW_AT_byte_size) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x3e /* (DW_AT_encoding) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x3 /* (DW_AT_name) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .byte 0 + .byte 0 +.LAbrv5: + .uleb128 0x5 /* (abbrev code) */ + .uleb128 0x34 /* (TAG: DW_TAG_variable) */ + .byte 0 /* DW_children_no */ + .uleb128 0x3 /* (DW_AT_name) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .uleb128 0x3a /* (DW_AT_decl_file) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x3b /* (DW_AT_decl_line) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x49 /* (DW_AT_type) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .uleb128 0x2137 /* (DW_AT_GNU_locviews) */ + .uleb128 0x17 /* (DW_FORM_sec_offset) */ + .uleb128 0x2 /* (DW_AT_location) */ + .uleb128 0x17 /* (DW_FORM_sec_offset) */ + .byte 0 + .byte 0 + .byte 0 + + .section .debug_loc +.Ldebug_loc0: +.LVUS0: + .uleb128 0x2 /* View list begin (*.LVUS0) */ + .uleb128 0x4 /* View list end (*.LVUS0) */ + .uleb128 0x4 /* View list begin (*.LVUS0) */ + .uleb128 0 /* View list end (*.LVUS0) */ +.LLST0: + .4byte .LVL0 /* Location list begin address (*.LLST0) */ + .4byte .LVL0 /* Location list end address (*.LLST0) */ + .2byte 0x2 /* Location expression size */ + .byte 0x30 /* DW_OP_lit0 */ + .byte 0x9f /* DW_OP_stack_value */ + .4byte .LVL0 /* Location list begin address (*.LLST0) */ + .4byte .LFE0 /* Location list end address (*.LLST0) */ + .2byte 0x2 /* Location expression size */ + .byte 0x32 /* DW_OP_lit2 */ + .byte 0x9f /* DW_OP_stack_value */ + .4byte 0 /* Location list terminator begin (*.LLST0) */ + .4byte 0 /* Location list terminator end (*.LLST0) */ +.LLST1: + .4byte .LVL0 /* Location list begin address (*.LLST1) */ + .4byte .LVL0 /* Location list end address (*.LLST1) */ + .2byte 0x2 /* Location expression size */ + .byte 0x31 /* DW_OP_lit1 */ + .byte 0x9f /* DW_OP_stack_value */ + .4byte .LVL0 /* Location list begin address (*.LLST1) */ + .4byte .LFE0 /* Location list end address (*.LLST1) */ + .2byte 0x2 /* Location expression size */ + .byte 0x33 /* DW_OP_lit3 */ + .byte 0x9f /* DW_OP_stack_value */ + .4byte 0 /* Location list terminator begin (*.LLST1) */ + .4byte 0 /* Location list terminator end (*.LLST1) */ +.LVUS1: + .uleb128 0x3 /* View list begin (*.LVUS1) */ + .uleb128 0x5 /* View list end (*.LVUS1) */ + .uleb128 0x5 /* View list begin (*.LVUS1) */ + .uleb128 0 /* View list end (*.LVUS1) */ +.LVUS2: + .uleb128 0x6 /* View list begin (*.LVUS2) */ + .uleb128 0x7 /* View list end (*.LVUS2) */ + .uleb128 0x7 /* View list begin (*.LVUS2) */ + .uleb128 0x8 /* View list end (*.LVUS2) */ + .uleb128 0x8 /* View list begin (*.LVUS2) */ + .uleb128 0 /* View list end (*.LVUS2) */ +.LLST2: + .4byte .LVL0 /* Location list begin address (*.LLST2) */ + .4byte .LVL0 /* Location list end address (*.LLST2) */ + .2byte 0x2 /* Location expression size */ + .byte 0x34 /* DW_OP_lit4 */ + .byte 0x9f /* DW_OP_stack_value */ + .4byte .LVL0 /* Location list begin address (*.LLST2) */ + .4byte .LVL0 /* Location list end address (*.LLST2) */ + .2byte 0x2 /* Location expression size */ + .byte 0x35 /* DW_OP_lit5 */ + .byte 0x9f /* DW_OP_stack_value */ + .4byte .LVL0 /* Location list begin address (*.LLST2) */ + .4byte .LFE0 /* Location list end address (*.LLST2) */ + .2byte 0x2 /* Location expression size */ + .byte 0x36 /* DW_OP_lit6 */ + .byte 0x9f /* DW_OP_stack_value */ + .4byte 0 /* Location list terminator begin (*.LLST2) */ + .4byte 0 /* Location list terminator end (*.LLST2) */ diff --git a/binutils/testsuite/binutils-all/locview-2.s b/binutils/testsuite/binutils-all/locview-2.s new file mode 100644 index 00000000000..d9b1d587595 --- /dev/null +++ b/binutils/testsuite/binutils-all/locview-2.s @@ -0,0 +1,335 @@ + .text +.Ltext0: +.LFB0: + /* locview.c:1 */ +.LM1: + /* view -0 */ + /* locview.c:2 */ +.LM2: + /* view 1 */ +.LVL0: + /* DEBUG i => 0 */ + /* locview.c:3 */ +.LM3: + /* view 2 */ + /* DEBUG j => 0x1 */ + /* locview.c:4 */ +.LM4: + /* view 3 */ + /* DEBUG i => 0x2 */ + /* locview.c:5 */ +.LM5: + /* view 4 */ + /* DEBUG j => 0x3 */ + /* locview.c:6 */ +.LM6: + /* view 5 */ + /* DEBUG k => 0x4 */ + /* DEBUG l => 0x4 */ + /* locview.c:7 */ +.LM7: + /* view 6 */ + /* DEBUG k => 0x5 */ + /* DEBUG l => 0x5 */ + /* locview.c:8 */ +.LM8: + /* view 7 */ + /* DEBUG k => 0x6 */ + /* DEBUG l => 0x6 */ + /* locview.c:9 */ +.LM9: + /* view 8 */ + .byte 0 +.LFE0: +.Letext0: + + .section .debug_info +.Ldebug_info0: +.LIbase: + .4byte .LIend - .LIstart /* Length of Compilation Unit Info */ +.LIstart: + .2byte 0x5 /* DWARF version number */ + .byte 0x1 /* DW_UT_compile */ + .byte 0x4 /* Pointer Size (in bytes) */ + .4byte .Ldebug_abbrev0 /* Offset Into Abbrev. Section */ +.LIcu: + .uleb128 0x2 /* (DIE (cu) DW_TAG_compile_unit) */ + .ascii "hand-crafted based on GCC output\0" + .byte 0x1d /* DW_AT_language */ + .ascii "locview.c\0" + .ascii "/tmp\0" + .4byte 0 /* DW_AT_low_pc */ +.LIsubf: + .uleb128 0x3 /* (DIE (subf) DW_TAG_subprogram) */ + .ascii "f\0" /* DW_AT_name */ + .byte 0x1 /* DW_AT_decl_file (locview.c) */ + .byte 0x1 /* DW_AT_decl_line */ + .4byte .LIint-.LIbase /* DW_AT_type */ + .4byte .LFB0 /* DW_AT_low_pc */ + .4byte 1 /* .LFE0-.LFB0 */ /* DW_AT_high_pc */ + .uleb128 0x1 /* DW_AT_frame_base */ + .byte 0x9c /* DW_OP_call_frame_cfa */ + /* DW_AT_call_all_calls */ + .4byte .LIint - .LIbase /* DW_AT_sibling */ +.LIvari: + .uleb128 0x1 /* (DIE (vari) DW_TAG_variable) */ + .ascii "i\0" /* DW_AT_name */ + /* DW_AT_decl_file (1, locview.c) */ + .byte 0x2 /* DW_AT_decl_line */ + .4byte .LIint - .LIbase /* DW_AT_type */ + .4byte .LLST0 /* DW_AT_location */ + .4byte .LVUS0 /* DW_AT_GNU_locviews */ +.LIvarj: + .uleb128 0x1 /* (DIE (varj) DW_TAG_variable) */ + .ascii "j\0" /* DW_AT_name */ + /* DW_AT_decl_file (1, locview.c) */ + .byte 0x3 /* DW_AT_decl_line */ + .4byte .LIint - .LIbase /* DW_AT_type */ + .4byte .LLST1 /* DW_AT_location */ + .4byte .LVUS1 /* DW_AT_GNU_locviews */ +.LIvark: + .uleb128 0x5 /* (DIE (vark) DW_TAG_variable) */ + .ascii "k\0" /* DW_AT_name */ + /* DW_AT_decl_file (1, locview.c) */ + .byte 0x6 /* DW_AT_decl_line */ + .4byte .LIint - .LIbase /* DW_AT_type */ + .4byte .LVUS2 /* DW_AT_GNU_locviews */ + .4byte .LLST2 /* DW_AT_location */ +.LIvarl: + .uleb128 0x6 /* (DIE (varl) DW_TAG_variable) */ + .ascii "l\0" /* DW_AT_name */ + /* DW_AT_decl_file (1, locview.c) */ + .byte 0x6 /* DW_AT_decl_line */ + .4byte .LIint - .LIbase /* DW_AT_type */ + .4byte .LLST3 /* DW_AT_location */ + .byte 0 /* end of children of DIE subf */ + +.LIint: + .uleb128 0x4 /* (DIE (int) DW_TAG_base_type) */ + .byte 0x4 /* DW_AT_byte_size */ + .byte 0x5 /* DW_AT_encoding */ + .ascii "int\0" /* DW_AT_name */ + .byte 0 /* end of children of DIE cu */ +.LIend: + .section .debug_abbrev +.Ldebug_abbrev0: +.LAbrv1: + .uleb128 0x1 /* (abbrev code) */ + .uleb128 0x34 /* (TAG: DW_TAG_variable) */ + .byte 0 /* DW_children_no */ + .uleb128 0x3 /* (DW_AT_name) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .uleb128 0x3a /* (DW_AT_decl_file) */ + .uleb128 0x21 /* (DW_FORM_implicit_const) */ + .sleb128 1 /* (locview.c) */ + .uleb128 0x3b /* (DW_AT_decl_line) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x49 /* (DW_AT_type) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .uleb128 0x2 /* (DW_AT_location) */ + .uleb128 0x17 /* (DW_FORM_sec_offset) */ + .uleb128 0x2137 /* (DW_AT_GNU_locviews) */ + .uleb128 0x17 /* (DW_FORM_sec_offset) */ + .byte 0 + .byte 0 +.LAbrv2: + .uleb128 0x2 /* (abbrev code) */ + .uleb128 0x11 /* (TAG: DW_TAG_compile_unit) */ + .byte 0x1 /* DW_children_yes */ + .uleb128 0x25 /* (DW_AT_producer) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .uleb128 0x13 /* (DW_AT_language) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x3 /* (DW_AT_name) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .uleb128 0x1b /* (DW_AT_comp_dir) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .uleb128 0x11 /* (DW_AT_low_pc) */ + .uleb128 0x1 /* (DW_FORM_addr) */ + .byte 0 + .byte 0 +.LAbrv3: + .uleb128 0x3 /* (abbrev code) */ + .uleb128 0x2e /* (TAG: DW_TAG_subprogram) */ + .byte 0x1 /* DW_children_yes */ + .uleb128 0x3 /* (DW_AT_name) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .uleb128 0x3a /* (DW_AT_decl_file) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x3b /* (DW_AT_decl_line) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x49 /* (DW_AT_type) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .uleb128 0x11 /* (DW_AT_low_pc) */ + .uleb128 0x1 /* (DW_FORM_addr) */ + .uleb128 0x12 /* (DW_AT_high_pc) */ + .uleb128 0x6 /* (DW_FORM_data4) */ + .uleb128 0x40 /* (DW_AT_frame_base) */ + .uleb128 0x18 /* (DW_FORM_exprloc) */ + .uleb128 0x7a /* (DW_AT_call_all_calls) */ + .uleb128 0x19 /* (DW_FORM_flag_present) */ + .uleb128 0x1 /* (DW_AT_sibling) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .byte 0 + .byte 0 +.LAbrv4: + .uleb128 0x4 /* (abbrev code) */ + .uleb128 0x24 /* (TAG: DW_TAG_base_type) */ + .byte 0 /* DW_children_no */ + .uleb128 0xb /* (DW_AT_byte_size) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x3e /* (DW_AT_encoding) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x3 /* (DW_AT_name) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .byte 0 + .byte 0 +.LAbrv5: + .uleb128 0x5 /* (abbrev code) */ + .uleb128 0x34 /* (TAG: DW_TAG_variable) */ + .byte 0 /* DW_children_no */ + .uleb128 0x3 /* (DW_AT_name) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .uleb128 0x3a /* (DW_AT_decl_file) */ + .uleb128 0x21 /* (DW_FORM_implicit_const) */ + .sleb128 1 /* (locview.c) */ + .uleb128 0x3b /* (DW_AT_decl_line) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x49 /* (DW_AT_type) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .uleb128 0x2137 /* (DW_AT_GNU_locviews) */ + .uleb128 0x17 /* (DW_FORM_sec_offset) */ + .uleb128 0x2 /* (DW_AT_location) */ + .uleb128 0x17 /* (DW_FORM_sec_offset) */ + .byte 0 + .byte 0 +.LAbrv6: + .uleb128 0x6 /* (abbrev code) */ + .uleb128 0x34 /* (TAG: DW_TAG_variable) */ + .byte 0 /* DW_children_no */ + .uleb128 0x3 /* (DW_AT_name) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .uleb128 0x3a /* (DW_AT_decl_file) */ + .uleb128 0x21 /* (DW_FORM_implicit_const) */ + .sleb128 1 /* (locview.c) */ + .uleb128 0x3b /* (DW_AT_decl_line) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x49 /* (DW_AT_type) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .uleb128 0x2 /* (DW_AT_location) */ + .uleb128 0x17 /* (DW_FORM_sec_offset) */ + .byte 0 + .byte 0 + .byte 0 + + .section .debug_loclists + .4byte .Ldebug_loc2-.Ldebug_loc1 /* Length of Location Lists */ +.Ldebug_loc1: + .2byte 0x5 /* DWARF version number */ + .byte 0x4 /* Address Size */ + .byte 0 /* Segment Size */ + .4byte 0 /* Offset Entry Count */ +.Ldebug_loc0: +.LVUS0: + .uleb128 0x2 /* View list begin (*.LVUS0) */ + .uleb128 0x4 /* View list end (*.LVUS0) */ + .uleb128 0x4 /* View list begin (*.LVUS0) */ + .uleb128 0 /* View list end (*.LVUS0) */ +.LLST0: + .byte 0x6 /* DW_LLE_base_address (*.LLST0) */ + .4byte .LVL0 /* Base address (*.LLST0) */ + .byte 0x4 /* DW_LLE_offset_pair (*.LLST0) */ + .uleb128 0 /* .LVL0-.LVL0 */ /* Location list begin address (*.LLST0) */ + .uleb128 0 /* .LVL0-.LVL0 */ /* Location list end address (*.LLST0) */ + .uleb128 0x2 /* Location expression size */ + .byte 0x30 /* DW_OP_lit0 */ + .byte 0x9f /* DW_OP_stack_value */ + .byte 0x4 /* DW_LLE_offset_pair (*.LLST0) */ + .uleb128 0 /* .LVL0-.LVL0 */ /* Location list begin address (*.LLST0) */ + .uleb128 1 /* .LFE0-.LVL0 */ /* Location list end address (*.LLST0) */ + .uleb128 0x2 /* Location expression size */ + .byte 0x32 /* DW_OP_lit2 */ + .byte 0x9f /* DW_OP_stack_value */ + .byte 0 /* DW_LLE_end_of_list (*.LLST0) */ +.LLST1: + .byte 0x6 /* DW_LLE_base_address (*.LLST1) */ + .4byte .LVL0 /* Base address (*.LLST1) */ + .byte 0x4 /* DW_LLE_offset_pair (*.LLST1) */ + .uleb128 0 /* .LVL0-.LVL0 */ /* Location list begin address (*.LLST1) */ + .uleb128 0 /* .LVL0-.LVL0 */ /* Location list end address (*.LLST1) */ + .uleb128 0x2 /* Location expression size */ + .byte 0x31 /* DW_OP_lit1 */ + .byte 0x9f /* DW_OP_stack_value */ + .byte 0x4 /* DW_LLE_offset_pair (*.LLST1) */ + .uleb128 0 /* .LVL0-.LVL0 */ /* Location list begin address (*.LLST1) */ + .uleb128 1 /* .LFE0-.LVL0 */ /* Location list end address (*.LLST1) */ + .uleb128 0x2 /* Location expression size */ + .byte 0x33 /* DW_OP_lit3 */ + .byte 0x9f /* DW_OP_stack_value */ + .byte 0 /* DW_LLE_end_of_list (*.LLST1) */ +.LVUS1: + .uleb128 0x3 /* View list begin (*.LVUS1) */ + .uleb128 0x5 /* View list end (*.LVUS1) */ + .uleb128 0x5 /* View list begin (*.LVUS1) */ + .uleb128 0 /* View list end (*.LVUS1) */ +.LVUS2: + .uleb128 0x6 /* View list begin (*.LVUS2) */ + .uleb128 0x7 /* View list end (*.LVUS2) */ + .uleb128 0x7 /* View list begin (*.LVUS2) */ + .uleb128 0x8 /* View list end (*.LVUS2) */ + .uleb128 0x8 /* View list begin (*.LVUS2) */ + .uleb128 0 /* View list end (*.LVUS2) */ +.LLST2: + .byte 0x6 /* DW_LLE_base_address (*.LLST2) */ + .4byte .LVL0 /* Base address (*.LLST2) */ + .byte 0x4 /* DW_LLE_offset_pair (*.LLST2) */ + .uleb128 0 /* .LVL0-.LVL0 */ /* Location list begin address (*.LLST2) */ + .uleb128 0 /* .LVL0-.LVL0 */ /* Location list end address (*.LLST2) */ + .uleb128 0x2 /* Location expression size */ + .byte 0x34 /* DW_OP_lit4 */ + .byte 0x9f /* DW_OP_stack_value */ + .byte 0x4 /* DW_LLE_offset_pair (*.LLST2) */ + .uleb128 0 /* .LVL0-.LVL0 */ /* Location list begin address (*.LLST2) */ + .uleb128 0 /* .LVL0-.LVL0 */ /* Location list end address (*.LLST2) */ + .uleb128 0x2 /* Location expression size */ + .byte 0x35 /* DW_OP_lit5 */ + .byte 0x9f /* DW_OP_stack_value */ + .byte 0x4 /* DW_LLE_offset_pair (*.LLST2) */ + .uleb128 0 /* .LVL0-.LVL0 */ /* Location list begin address (*.LLST2) */ + .uleb128 1 /* .LFE0-.LVL0 */ /* Location list end address (*.LLST2) */ + .uleb128 0x2 /* Location expression size */ + .byte 0x36 /* DW_OP_lit6 */ + .byte 0x9f /* DW_OP_stack_value */ + .byte 0 /* DW_LLE_end_of_list (*.LLST2) */ +.LLST3: + .byte 0x6 /* DW_LLE_base_address (*.LLST3) */ + .4byte .LVL0 /* Base address (*.LLST3) */ + .byte 0x9 /* DW_LLE_view_pair (extension proposed for DWARF6) */ + .uleb128 0x6 /* View list begin (*.LLST3) */ + .uleb128 0x7 /* View list end (*.LVUS3) */ + .byte 0x4 /* DW_LLE_offset_pair (*.LLST3) */ + .uleb128 0 /* .LVL0-.LVL0 */ /* Location list begin address (*.LLST3) */ + .uleb128 0 /* .LVL0-.LVL0 */ /* Location list end address (*.LLST3) */ + .uleb128 0x2 /* Location expression size */ + .byte 0x34 /* DW_OP_lit4 */ + .byte 0x9f /* DW_OP_stack_value */ + .byte 0x9 /* DW_LLE_view_pair */ + .uleb128 0x7 /* View list begin (*.LLST3) */ + .uleb128 0x8 /* View list end (*.LVUS3) */ + .byte 0x4 /* DW_LLE_offset_pair (*.LLST3) */ + .uleb128 0 /* .LVL0-.LVL0 */ /* Location list begin address (*.LLST3) */ + .uleb128 0 /* .LVL0-.LVL0 */ /* Location list end address (*.LLST3) */ + .uleb128 0x2 /* Location expression size */ + .byte 0x35 /* DW_OP_lit5 */ + .byte 0x9f /* DW_OP_stack_value */ + .byte 0x9 /* DW_LLE_view_pair */ + .uleb128 0x8 /* View list begin (*.LLST3) */ + .uleb128 0x0 /* View list end (*.LVUS3) */ + .byte 0x4 /* DW_LLE_offset_pair (*.LLST3) */ + .uleb128 0 /* .LVL0-.LVL0 */ /* Location list begin address (*.LLST3) */ + .uleb128 1 /* .LFE0-.LVL0 */ /* Location list end address (*.LLST3) */ + .uleb128 0x2 /* Location expression size */ + .byte 0x36 /* DW_OP_lit6 */ + .byte 0x9f /* DW_OP_stack_value */ + .byte 0 /* DW_LLE_end_of_list (*.LLST3) */ +.Ldebug_loc2: diff --git a/binutils/testsuite/binutils-all/readelf.exp b/binutils/testsuite/binutils-all/readelf.exp index 6a7b5621dd0..81d18092253 100644 --- a/binutils/testsuite/binutils-all/readelf.exp +++ b/binutils/testsuite/binutils-all/readelf.exp @@ -379,6 +379,33 @@ if {![binutils_assemble $srcdir/$subdir/pr18374.s tmpdir/pr18374.o]} then { } +# locview - Check dumping of location lists with location views. +if {![binutils_assemble $srcdir/$subdir/locview-1.s tmpdir/locview-1.o]} then { + unresolved "readelf --debug-dump=loc locview-1 (failed to assemble)" +} else { + + if ![is_remote host] { + set tempfile tmpdir/locview-1.o + } else { + set tempfile [remote_download host tmpdir/locview-1.o] + } + + readelf_test --debug-dump=loc $tempfile readelf.locview-1 {} +} +if {![binutils_assemble $srcdir/$subdir/locview-2.s tmpdir/locview-2.o]} then { + unresolved "readelf --debug-dump=loc locview-2 (failed to assemble)" +} else { + + if ![is_remote host] { + set tempfile tmpdir/locview-2.o + } else { + set tempfile [remote_download host tmpdir/locview-2.o] + } + + readelf_test --debug-dump=loc $tempfile readelf.locview-2 {} +} + + # Check that decompressed dumps work. if {![binutils_assemble $srcdir/$subdir/z.s tmpdir/z.o]} then { unresolved "readelf --decompress --hex-dump .debug_loc z (failed to assemble)" @@ -417,6 +444,6 @@ if ![istarget "riscv*-*-*"] then { readelf_find_size $tempfile # Make sure that readelf can decode the contents. - readelf_test -wiaoRlL $tempfile dw5.W {} + readelf_test -wiaoRlL $tempfile dw5.W { nds32*-elf } } } diff --git a/binutils/testsuite/binutils-all/readelf.locview-1 b/binutils/testsuite/binutils-all/readelf.locview-1 new file mode 100644 index 00000000000..614852015e7 --- /dev/null +++ b/binutils/testsuite/binutils-all/readelf.locview-1 @@ -0,0 +1,35 @@ +Contents of the .*ebug_loc section: + + Offset Begin End Expression + + 00000000 v0000002 v0000004 location view pair + 00000002 v0000004 v0000000 location view pair + + 00000004 v0000002 v0000004 views at 00000000 for: + 00000000 00000000 \(DW_OP_lit0; DW_OP_stack_value\) + 00000010 v0000004 v0000000 views at 00000002 for: + 00000000 00000001 \(DW_OP_lit2; DW_OP_stack_value\) + 0000001c + 00000024 v0000003 v0000005 views at 00000044 for: + 00000000 00000000 \(DW_OP_lit1; DW_OP_stack_value\) + 00000030 v0000005 v0000000 views at 00000046 for: + 00000000 00000001 \(DW_OP_lit3; DW_OP_stack_value\) + 0000003c + + 00000044 v0000003 v0000005 location view pair + 00000046 v0000005 v0000000 location view pair + + + 00000048 v0000006 v0000007 location view pair + 0000004a v0000007 v0000008 location view pair + 0000004c v0000008 v0000000 location view pair + + 0000004e v0000006 v0000007 views at 00000048 for: + 00000000 00000000 \(DW_OP_lit4; DW_OP_stack_value\) + 0000005a v0000007 v0000008 views at 0000004a for: + 00000000 00000000 \(DW_OP_lit5; DW_OP_stack_value\) + 00000066 v0000008 v0000000 views at 0000004c for: + 00000000 00000001 \(DW_OP_lit6; DW_OP_stack_value\) + 00000072 + +#pass diff --git a/binutils/testsuite/binutils-all/readelf.locview-2 b/binutils/testsuite/binutils-all/readelf.locview-2 new file mode 100644 index 00000000000..f064ad78bae --- /dev/null +++ b/binutils/testsuite/binutils-all/readelf.locview-2 @@ -0,0 +1,46 @@ +Contents of the .*ebug_loclists section: +#... + Offset Begin End Expression + + 0000000c v0000002 v0000004 location view pair + 0000000e v0000004 v0000000 location view pair + + 00000010 00000000 \(base address\) + 00000015 v0000002 v0000004 views at 0000000c for: + 00000000 00000000 \(DW_OP_lit0; DW_OP_stack_value\) + 0000001b v0000004 v0000000 views at 0000000e for: + 00000000 00000001 \(DW_OP_lit2; DW_OP_stack_value\) + 00000021 + 00000022 00000000 \(base address\) + 00000027 v0000003 v0000005 views at 00000034 for: + 00000000 00000000 \(DW_OP_lit1; DW_OP_stack_value\) + 0000002d v0000005 v0000000 views at 00000036 for: + 00000000 00000001 \(DW_OP_lit3; DW_OP_stack_value\) + 00000033 + + 00000034 v0000003 v0000005 location view pair + 00000036 v0000005 v0000000 location view pair + + + 00000038 v0000006 v0000007 location view pair + 0000003a v0000007 v0000008 location view pair + 0000003c v0000008 v0000000 location view pair + + 0000003e 00000000 \(base address\) + 00000043 v0000006 v0000007 views at 00000038 for: + 00000000 00000000 \(DW_OP_lit4; DW_OP_stack_value\) + 00000049 v0000007 v0000008 views at 0000003a for: + 00000000 00000000 \(DW_OP_lit5; DW_OP_stack_value\) + 0000004f v0000008 v0000000 views at 0000003c for: + 00000000 00000001 \(DW_OP_lit6; DW_OP_stack_value\) + 00000055 + 00000056 00000000 \(base address\) + 0000005b v0000006 v0000007 views for: + 0000005e 00000000 00000000 \(DW_OP_lit4; DW_OP_stack_value\) + 00000064 v0000007 v0000008 views for: + 00000067 00000000 00000000 \(DW_OP_lit5; DW_OP_stack_value\) + 0000006d v0000008 v0000000 views for: + 00000070 00000000 00000001 \(DW_OP_lit6; DW_OP_stack_value\) + 00000076 + +#pass diff --git a/include/ChangeLog b/include/ChangeLog index 1ba7de3c6a5..0ece8de3f7e 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,10 @@ +2017-09-22 Alexandre Oliva + + * dwarf2.def (DW_AT_GNU_locviews): New. + * dwarf2.h (enum dwarf_location_list_entry_type): Add + DW_LLE_GNU_view_pair. + (DW_LLE_view_pair): Define. + 2017-09-15 Pedro Alves Sync with mainline gcc sources (r252823) diff --git a/include/dwarf2.def b/include/dwarf2.def index 2a3b23fef87..8e731a3b87a 100644 --- a/include/dwarf2.def +++ b/include/dwarf2.def @@ -443,6 +443,8 @@ DW_AT (DW_AT_GNU_pubtypes, 0x2135) /* Attribute for discriminator. See http://gcc.gnu.org/wiki/Discriminator */ DW_AT (DW_AT_GNU_discriminator, 0x2136) +DW_AT (DW_AT_GNU_locviews, 0x2137) +DW_AT (DW_AT_GNU_entry_view, 0x2138) /* VMS extensions. */ DW_AT (DW_AT_VMS_rtnbeg_pd_address, 0x2201) /* GNAT extensions. */ diff --git a/include/dwarf2.h b/include/dwarf2.h index a2e022dbdb3..fd76d82e6eb 100644 --- a/include/dwarf2.h +++ b/include/dwarf2.h @@ -298,6 +298,14 @@ enum dwarf_location_list_entry_type DW_LLE_start_end = 0x07, DW_LLE_start_length = 0x08, + /* + has the proposal for now; only available to list members. + + A (possibly updated) copy of the proposal is available at + . */ + DW_LLE_GNU_view_pair = 0x09, +#define DW_LLE_view_pair DW_LLE_GNU_view_pair + /* Former extension for Fission. See http://gcc.gnu.org/wiki/DebugFission. */ DW_LLE_GNU_end_of_list_entry = 0x00, -- 2.30.2