]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
LVU: dump loclists with locviews
authorAlexandre Oliva <aoliva@redhat.com>
Fri, 18 Aug 2017 11:37:29 +0000 (08:37 -0300)
committerAlexandre Oliva <aoliva@redhat.com>
Fri, 18 Aug 2017 12:33:52 +0000 (09:33 -0300)
binutils/dwarf.c
binutils/dwarf.h
binutils/testsuite/binutils-all/locview-1.s [new file with mode: 0644]
binutils/testsuite/binutils-all/locview-2.s [new file with mode: 0644]
binutils/testsuite/binutils-all/readelf.exp
binutils/testsuite/binutils-all/readelf.locview-1 [new file with mode: 0644]
binutils/testsuite/binutils-all/readelf.locview-2 [new file with mode: 0644]
include/dwarf2.def
include/dwarf2.h

index 297f426ed567784efb9d17932f6bb4402383e587..1e215d17a032375f262eef62934f2271ef8d0a4b 100644 (file)
@@ -77,6 +77,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;
        }
@@ -5028,6 +5096,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
@@ -5036,9 +5150,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;
@@ -5072,6 +5187,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)
        {
@@ -5112,6 +5228,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"),
@@ -5143,9 +5277,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');
@@ -5154,6 +5288,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.  */
@@ -5164,9 +5299,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;
@@ -5175,8 +5311,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;
 
@@ -5216,6 +5352,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:
@@ -5233,6 +5385,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;
@@ -5267,17 +5434,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,
@@ -5300,9 +5472,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;
@@ -5345,17 +5518,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.  */
@@ -5382,6 +5585,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;
        }
 
@@ -5418,11 +5622,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)
@@ -5430,23 +5636,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;
@@ -5534,6 +5750,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;
@@ -5544,12 +5761,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];
            }
        }
     }
@@ -5558,7 +5779,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]));
@@ -5573,7 +5795,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;
@@ -5583,24 +5805,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
            {
@@ -5614,6 +5854,7 @@ display_debug_loc (struct dwarf_section *section, void *file)
                      (unsigned long) offset);
            }
          start = next;
+         vstart = vnext;
 
          if (offset >= bytes)
            {
@@ -5622,14 +5863,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
            {
@@ -5637,8 +5885,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);
        }
     }
 
index 4d3330c2b9e4a900b4ba53445b1762283842f071..15719eef85c78ffb54db3f7b67dad89ff4bdcdf8 100644 (file)
@@ -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 (file)
index 0000000..dffda42
--- /dev/null
@@ -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,"",@progbits
+.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,"",@progbits
+.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,"",@progbits
+.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 (file)
index 0000000..13ac21b
--- /dev/null
@@ -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,"",@progbits
+.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,"",@progbits
+.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,"",@progbits
+       .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:
index d9e437d967756c4f891fcdec5c6ee6c6337bed64..5fbe8396a30fd911ec1bb9d4637e7527b789b52e 100644 (file)
@@ -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 (file)
index 0000000..6148520
--- /dev/null
@@ -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 (file)
index 0000000..20437f2
--- /dev/null
@@ -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
index a91e9439cd82f3bb9fdddc14904114e5490c1af6..1d6d13bc45fa633a77e08967f0f11a659145c7e4 100644 (file)
@@ -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.  */
index 14b6f22e39e2f2f8cadb05009bfd10fafa9ea07c..c6d410e32e40e8b37cda7d0c91003588cd82bd3d 100644 (file)
@@ -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,