This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] LVU: dump loclists with locviews
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: Alan Modra <amodra at gmail dot com>
- Cc: binutils at sourceware dot org
- Date: Mon, 04 Sep 2017 21:50:39 -0300
- Subject: Re: [PATCH] LVU: dump loclists with locviews
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=aoliva at redhat dot com
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 244E73DBC0
- References: <oro9rd57c6.fsf@lxoliva.fsfla.org> <20170829223758.GH3368@bubble.grove.modra.org>
On Aug 29, 2017, Alan Modra <amodra@gmail.com> wrote:
> On Fri, Aug 18, 2017 at 10:33:13AM -0300, Alexandre Oliva wrote:
>> Tested on x86_64-linux-gnu. Ok to install?
> Patches like this need testing on a larger set of targets.
Ugh, yes indeed, my apologies. As much as I thought I had adjusted the
GCC output to look like the other dwarf dumping test, so as to make it
portable, evidently I missed a few details that made it not as
portable. "I only proved the code ought to work, but I didn't test it" :-D
Sorry, I shall learn eventually ;-)
The problems I found out by proper(er?) testing were:
- using '#' for comments; turned into /**/
- using .section directives with more than just the section name;
dropped flags and @type
This patch was tested on x86_64-linux-gnu (again), sh-elf, arm-eabi,
mips64-elf, and sh-pe. Does that seem like enough coverage, or would
you suggest any further targets? (I hope by listing the failures in all
those targets you were not suggesting me to test on all of them, but if
that's the case, I guess I could make arrangements to do so :-)
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.
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.
---
binutils/dwarf.c | 333 +++++++++++++++++++--
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 | 33 ++
binutils/testsuite/binutils-all/readelf.locview-1 | 35 ++
binutils/testsuite/binutils-all/readelf.locview-2 | 46 +++
include/dwarf2.def | 2
include/dwarf2.h | 8 +
9 files changed, 1030 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/dwarf.c b/binutils/dwarf.c
index d2fc799..1b5b27c 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 (_("<End of list>\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,16 @@ 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 +5774,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 +5790,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 +5800,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 +5849,7 @@ display_debug_loc (struct dwarf_section *section, void *file)
(unsigned long) offset);
}
start = next;
+ vstart = vnext;
if (offset >= bytes)
{
@@ -5617,14 +5858,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 +5880,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 4d3330c..15719ee 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 0000000..bde98bd
--- /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 .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 0000000..141e30e
--- /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 .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 .LVL0-.LVL0 /* Location list begin address (*.LLST0) */
+ .uleb128 .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 .LVL0-.LVL0 /* Location list begin address (*.LLST0) */
+ .uleb128 .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 .LVL0-.LVL0 /* Location list begin address (*.LLST1) */
+ .uleb128 .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 .LVL0-.LVL0 /* Location list begin address (*.LLST1) */
+ .uleb128 .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 .LVL0-.LVL0 /* Location list begin address (*.LLST2) */
+ .uleb128 .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 .LVL0-.LVL0 /* Location list begin address (*.LLST2) */
+ .uleb128 .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 .LVL0-.LVL0 /* Location list begin address (*.LLST2) */
+ .uleb128 .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 .LVL0-.LVL0 /* Location list begin address (*.LLST3) */
+ .uleb128 .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 .LVL0-.LVL0 /* Location list begin address (*.LLST3) */
+ .uleb128 .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 .LVL0-.LVL0 /* Location list begin address (*.LLST3) */
+ .uleb128 .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 d9e437d..5fbe839 100644
--- a/binutils/testsuite/binutils-all/readelf.exp
+++ b/binutils/testsuite/binutils-all/readelf.exp
@@ -366,7 +366,7 @@ if {![binutils_assemble $srcdir/$subdir/version.s tmpdir/version.o]} then {
if {![binutils_assemble $srcdir/$subdir/pr18374.s tmpdir/pr18374.o]} then {
perror "could not assemble PR18374 test file"
unresolved "readelf - failed to assemble"
- fail "readelf --debug-loc"
+ fail "readelf --debug-dump=loc"
} else {
if ![is_remote host] {
@@ -379,6 +379,37 @@ 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 {
+ perror "could not assemble locview-1 test file"
+ unresolved "readelf - failed to assemble"
+ fail "readelf --debug-dump=loc"
+} 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 {
+ perror "could not assemble locview-2 test file"
+ unresolved "readelf - failed to assemble"
+ fail "readelf --debug-dump=loc"
+} 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 {
perror "could not assemble decompress dump test file"
diff --git a/binutils/testsuite/binutils-all/readelf.locview-1 b/binutils/testsuite/binutils-all/readelf.locview-1
new file mode 100644
index 0000000..6148520
--- /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 <End of list>
+ 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 <End of list>
+
+ 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 <End of list>
+
+#pass
diff --git a/binutils/testsuite/binutils-all/readelf.locview-2 b/binutils/testsuite/binutils-all/readelf.locview-2
new file mode 100644
index 0000000..20437f2
--- /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 <End of list>
+ 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 <End of list>
+
+ 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 <End of list>
+ 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 <End of list>
+
+#pass
diff --git a/include/dwarf2.def b/include/dwarf2.def
index a91e943..1d6d13b 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 14b6f22e..c6d410e3 100644
--- a/include/dwarf2.h
+++ b/include/dwarf2.h
@@ -296,6 +296,14 @@ enum dwarf_location_list_entry_type
DW_LLE_start_end = 0x07,
DW_LLE_start_length = 0x08,
+ /* <http://lists.dwarfstd.org/private.cgi/dwarf-discuss-dwarfstd.org/2017-April/004347.html>
+ has the proposal for now; only available to list members.
+
+ A (possibly updated) copy of the proposal is available at
+ <http://people.redhat.com/aoliva/papers/sfn/dwarf6-sfn-lvu.txt>. */
+ 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,
--
Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/ FSF Latin America board member
Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer