public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Binutils support for dwarf-5 (location and range lists related)
@ 2022-05-31 11:06 Kumar N, Bhuvanendra
  2022-06-03 10:46 ` Jan Beulich
  0 siblings, 1 reply; 3+ messages in thread
From: Kumar N, Bhuvanendra @ 2022-05-31 11:06 UTC (permalink / raw)
  To: binutils; +Cc: Nick Clifton, George, Jini Susan, Natarajan, Kavitha

[-- Attachment #1: Type: text/plain, Size: 52925 bytes --]

[Public]

Hi,

As part of dwarf-5 many new things are added for location and range lists support and clang and GCC compiler supports these features.
For clang compiler compiled objects with dwarf-5, multiple issues are fixed in Binutils(readelf/objdump) which are related to .debug_rnglists and .debug_loclists sections and their offset address dump comprising single and multiple CU. Binutils(readelf/objdump) emits error/warning/incorrect output in these cases which are fixed now.

There are 2 patches uploaded/inlined below. Fixes are divided into 2 patches(instead of making into one big patch), so that fix for each issues can be addressed separately, hence might be easy to review these changes. Patch 2/2 is continuation of patch 1/2. Even though many of these fixes are applicable to clang compiler generated objects, they are also applicable to GCC compiled objects as well. These fixes caters both clang and GCC.

Issues fixed in patch 1/2 are:
Issue 1: .debug_rnglists section dump for single CU. Incorrect section dump or error while dumping .debug_rnglists section is fixed.
Issue 2: location list offset address dump under DW_AT_location is corrected. while dumping the location list offset either the address dumped is wrong(refers to .debug_addr instead of .debug_loclists) or the below warning was emitted by readelf/objdump when used with objects having single CU and multiple CU.
<49>   DW_AT_location    :readelf: Warning: Offset into section .debug_addr too big: 0x18

Issue 3: range list offset address dump under DW_AT_ranges is corrected. Before fix, the range list offset displayed is wrong, its pointing to .debug_addr section. After fix, this offset is actually points to .debug_rnglists section.
Before fix: <3bdf>   DW_AT_ranges      : (addr_index: 0x0): 9008
After fix:    <3bdf>   DW_AT_ranges      : (addr_index: 0x0): 2c

Contents of the .debug_rnglists section:
. . .
Offsets starting at 0xc:
    [     0] 0x2c

Issues fixed in patch 2/2 are:
Issue 4: .debug_rnglists section dump for multiple CU. For each CU, range list header is dumped now. Fix caters both clang and gcc.

NOTE: I will be sending the Binutils patch for split-dwarf with dwarf-5 for clang and gcc compiler.

regards,
bhuvan

PATCH 1/2 inlined :

From 96ce32f762803a7d74ca30c3930f1679afc0100c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
Date: Tue, 31 May 2022 14:07:17 +0530
Subject: [PATCH] [PATCH 1/2] Binutils support for dwarf-5.

For clang compiled with dwarf-5, multiple issues are fixed which are
related to .debug_rnglists and .debug_loclists sections and their offset
address dump comprising single and multiple CU. There are 2 patches
and this is patch 1/2.

Issues fixed in patch 1/2 are:
Issue 1: .debug_rnglists section dump for single CU.
Issue 2: location list offset address dump under DW_AT_location is corrected.
Issue 3: range list offset address dump under DW_AT_ranges is corrected.

      * dwarf.c (fetch_indexed_value): Add base_address as parameter and
      use it to access the section offset.
      (read_and_display_attr_value): Handle DW_FORM_loclistx and
      DW_FORM_rnglistx forms separately.
      (display_debug_rnglists_list): Fix support for DW_RLE_base_addressx,
      DW_RLE_startx_length.
      (display_debug_ranges): Correct the range list entries starting address.
---
binutils/dwarf.c | 32 +++++++++++++++++++++-----------
1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index caa3ce48d00..566104762d1 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -118,6 +118,7 @@ int dwarf_cutoff_level = -1;
unsigned long dwarf_start_die;
 int dwarf_check = 0;
+#define DEBUG_LOCLISTS_RNGLISTS_SECTION_HEADER_LEN 12
 /* Convenient constant, to avoid having to cast -1 to dwarf_vma when
    testing whether e.g. a locview list is present.  */
@@ -826,7 +827,8 @@ fetch_indexed_addr (dwarf_vma offset, uint32_t num_bytes)
 static dwarf_vma
fetch_indexed_value (dwarf_vma idx,
-               enum dwarf_section_display_enum sec_enum)
+               enum dwarf_section_display_enum sec_enum,
+               dwarf_vma base_address)
{
   struct dwarf_section *section = &debug_displays [sec_enum].section;
@@ -851,8 +853,12 @@ fetch_indexed_value (dwarf_vma idx,

   dwarf_vma offset = idx * pointer_size;
-  /* Offsets are biased by the size of the section header.  */
-  offset += bias;
+  /* Offsets are biased by the size of the section header
+     or base address.  */
+  if (sec_enum == loclists)
+    offset += base_address;
+  else
+    offset += bias;
   if (offset + pointer_size > section->size)
     {
@@ -2788,7 +2794,15 @@ read_and_display_attr_value (unsigned long           attribute,
        offset = base + uvalue * pointer_size;
-       if (do_wide)
+       if (form == DW_FORM_loclistx)
+         printf (_("%c(index: 0x%s): %s"), delimiter,
+                 dwarf_vmatoa ("x", uvalue),
+                 dwarf_vmatoa ("x", debug_info_p->loc_offsets [uvalue]));
+       else if (form == DW_FORM_rnglistx)
+         printf (_("%c(index: 0x%s): %s"), delimiter,
+                 dwarf_vmatoa ("x", uvalue),
+                 dwarf_vmatoa ("x", fetch_indexed_value (uvalue, rnglists, 0)));
+       else if (do_wide)
         /* We have already displayed the form name.  */
         printf (_("%c(index: 0x%s): %s"), delimiter,
              dwarf_vmatoa ("x", uvalue),
@@ -2870,7 +2884,7 @@ read_and_display_attr_value (unsigned long           attribute,
          }
            if (form == DW_FORM_loclistx)
-          uvalue = fetch_indexed_value (uvalue, loclists);
+          uvalue = fetch_indexed_value (num, loclists, debug_info_p->loclists_base);
           else if (this_set != NULL)
          uvalue += this_set->section_offsets [DW_SECT_LOC];
@@ -2939,7 +2953,7 @@ read_and_display_attr_value (unsigned long           attribute,
          }
            if (form == DW_FORM_rnglistx)
-          uvalue = fetch_indexed_value (uvalue, rnglists);
+          uvalue = fetch_indexed_value (uvalue, rnglists, 0);
            debug_info_p->range_lists [num] = uvalue;
           debug_info_p->num_range_lists++;
@@ -7976,9 +7990,6 @@ display_debug_rnglists_list (unsigned char * start,
     case DW_RLE_base_addressx:
       READ_ULEB (base_address, start, finish);
       print_dwarf_vma (base_address, pointer_size);
-       printf (_("(base address index) "));
-       base_address = fetch_indexed_addr (base_address, pointer_size);
-       print_dwarf_vma (base_address, pointer_size);
       printf (_("(base address)\n"));
       break;
     case DW_RLE_startx_endx:
@@ -7990,7 +8001,6 @@ display_debug_rnglists_list (unsigned char * start,
     case DW_RLE_startx_length:
       READ_ULEB (begin, start, finish);
       READ_ULEB (length, start, finish);
-       begin = fetch_indexed_addr (begin, pointer_size);
       end = begin + length;
       break;
     case DW_RLE_offset_pair:
@@ -8243,7 +8253,7 @@ display_debug_ranges (struct dwarf_section *section,
          (unsigned long) offset, i);
       continue;
     }
-      next = section_begin + offset;
+      next = section_begin + offset + DEBUG_LOCLISTS_RNGLISTS_SECTION_HEADER_LEN;
       /* If multiple DWARF entities reference the same range then we will
          have multiple entries in the `range_entries' list for the same
--
2.17.1




PATCH 2/2 inlined:

From 882829b72716d43a7f4b3ce2c82e58d3fa6d4573 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
Date: Tue, 31 May 2022 15:03:16 +0530
Subject: [PATCH] [PATCH 2/2] Binutils support for dwarf-5.

For clang compiled with dwarf-5, multiple issues are fixed which are
related to .debug_rnglists and .debug_loclists sections and their offset
address dump comprising single and multiple CU. There are 2 patches
and this is patch 2/2 and it has dependency on patch 1/2 and its
continuation of patch 1/2.

Issues fixed in patch 2/2 are:
Issue 4: .debug_rnglists section dump for multiple CU.

      * dwarf.c (fetch_indexed_value): Use base_address parameter to
      access the section offset.
      (read_and_display_attr_value): Fix support for DW_FORM_rnglistx form.
      Add support for DW_AT_rnglists_base attribute.
      Read attribute DW_AT_rnglists_base which can come before or after
      DW_AT_ranges attribute.
      (display_offset_entry_loclists): Fix support for DW_LLE_base_addressx.
      (display_debug_rnglists_list): Add start_header as parameter and
      return the start of the range list header of next compilation unit.
      (display_debug_rnglists_header): New function to dump range lists header
      for each compilation unit.
      (display_debug_ranges): For each compilation unit call
      display_debug_rnglists_header accordingly.
      * dwarf.h (struct debug_info): Add rnglists_base field.
      * testsuite/binutils-all/dw5-loclist.S: New file, .debug_loclists section
      content is updated.
      * testsuite/binutils-all/dw5-loclist.W: New file, expected output.
      * testsuite/binutils-all/readelf.exp: Added new test point dw5-loclist.
---
binutils/dwarf.c                              | 143 +++-
binutils/dwarf.h                              |   1 +
binutils/testsuite/binutils-all/dw5-loclist.S | 691 ++++++++++++++++++
binutils/testsuite/binutils-all/dw5-loclist.W |  27 +
binutils/testsuite/binutils-all/readelf.exp   |  19 +
5 files changed, 865 insertions(+), 16 deletions(-)
create mode 100644 binutils/testsuite/binutils-all/dw5-loclist.S
create mode 100644 binutils/testsuite/binutils-all/dw5-loclist.W

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 566104762d1..58675b4088d 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -118,7 +118,6 @@ int dwarf_cutoff_level = -1;
unsigned long dwarf_start_die;
 int dwarf_check = 0;
-#define DEBUG_LOCLISTS_RNGLISTS_SECTION_HEADER_LEN 12
 /* Convenient constant, to avoid having to cast -1 to dwarf_vma when
    testing whether e.g. a locview list is present.  */
@@ -855,7 +854,7 @@ fetch_indexed_value (dwarf_vma idx,
   /* Offsets are biased by the size of the section header
      or base address.  */
-  if (sec_enum == loclists)
+  if ((sec_enum == loclists) || (sec_enum == rnglists))
     offset += base_address;
   else
     offset += bias;
@@ -921,6 +920,7 @@ typedef struct abbrev_map
static abbrev_map *   cu_abbrev_map = NULL;
static unsigned long  num_abbrev_map_entries = 0;
static unsigned long  next_free_abbrev_map_entry = 0;
+static abbrev_attr *ranges_attr = NULL;
 #define INITIAL_NUM_ABBREV_MAP_ENTRIES 8
#define ABBREV_MAP_ENTRIES_INCREMENT   8
@@ -2451,6 +2451,7 @@ read_and_display_attr_value (unsigned long           attribute,
   dwarf_vma uvalue_hi = 0;
   unsigned char *block_start = NULL;
   unsigned char *orig_data = data;
+  dwarf_vma uvalue_rnglists_base;
   if (data > end || (data == end && form != DW_FORM_flag_present))
     {
@@ -2801,7 +2802,7 @@ read_and_display_attr_value (unsigned long           attribute,
       else if (form == DW_FORM_rnglistx)
         printf (_("%c(index: 0x%s): %s"), delimiter,
                 dwarf_vmatoa ("x", uvalue),
-                 dwarf_vmatoa ("x", fetch_indexed_value (uvalue, rnglists, 0)));
+                 dwarf_vmatoa ("x", debug_info_p->range_lists [uvalue]));
       else if (do_wide)
         /* We have already displayed the form name.  */
         printf (_("%c(index: 0x%s): %s"), delimiter,
@@ -2839,6 +2840,13 @@ read_and_display_attr_value (unsigned long           attribute,
       debug_info_p->loclists_base = uvalue;
       break;
+     case DW_AT_rnglists_base:
+       if (debug_info_p->rnglists_base)
+         warn (_("CU @ 0x%s has multiple rnglists_base values"),
+               dwarf_vmatoa ("x", debug_info_p->cu_offset));
+       debug_info_p->rnglists_base = uvalue;
+       break;
+
     case DW_AT_frame_base:
       have_frame_base = 1;
       /* Fall through.  */
@@ -2934,6 +2942,24 @@ read_and_display_attr_value (unsigned long           attribute,
       break;
      case DW_AT_ranges:
+       uvalue_rnglists_base = 0;
+       /* DW_AT_rnglists_base can appear before or after DW_AT_ranges attribute.
+          If its found before, DW_AT_rnglists_base is used directly,
+          otherwise its looked ahead from DW_AT_ranges and read.  */
+       if (!debug_info_p->rnglists_base) {
+         if (ranges_attr && ranges_attr->next && ranges_attr->next->next &&
+             (ranges_attr->next->next->attribute == DW_AT_rnglists_base)) {
+           unsigned char *data_dupl = data;
+           dwarf_vma uvalue_skip;
+           data_dupl = skip_attr_bytes (ranges_attr->next->form, data_dupl, end,
+                                        pointer_size, offset_size,
+                                        dwarf_version, &uvalue_skip);
+           SAFE_BYTE_GET_AND_INC (uvalue_rnglists_base, data_dupl, offset_size, end);
+         }
+       }
+       else
+         uvalue_rnglists_base = debug_info_p->rnglists_base;
+
       if ((dwarf_version < 4
            && (form == DW_FORM_data4 || form == DW_FORM_data8))
           || form == DW_FORM_sec_offset
@@ -2942,6 +2968,7 @@ read_and_display_attr_value (unsigned long           attribute,
           /* Process range list.  */
           unsigned int lmax = debug_info_p->max_range_lists;
           unsigned int num = debug_info_p->num_range_lists;
+           dwarf_vma uvalue_index;
            if (lmax == 0 || num >= lmax)
          {
@@ -2952,10 +2979,15 @@ read_and_display_attr_value (unsigned long           attribute,
            debug_info_p->max_range_lists = lmax;
          }
+           uvalue_index = uvalue;
           if (form == DW_FORM_rnglistx)
-          uvalue = fetch_indexed_value (uvalue, rnglists, 0);
+          uvalue = fetch_indexed_value (uvalue, rnglists, uvalue_rnglists_base);
-           debug_info_p->range_lists [num] = uvalue;
+           uvalue += uvalue_rnglists_base;
+           if (form == DW_FORM_rnglistx)
+             debug_info_p->range_lists [uvalue_index] = uvalue;
+           else
+             debug_info_p->range_lists [num] = uvalue;
           debug_info_p->num_range_lists++;
         }
       break;
@@ -3329,6 +3361,7 @@ read_and_display_attr_value (unsigned long           attribute,
       /* Fall through.  */
     case DW_AT_location:
     case DW_AT_loclists_base:
+    case DW_AT_rnglists_base:
     case DW_AT_string_length:
     case DW_AT_return_addr:
     case DW_AT_data_member_location:
@@ -3347,8 +3380,12 @@ read_and_display_attr_value (unsigned long           attribute,
       if ((dwarf_version < 4
        && (form == DW_FORM_data4 || form == DW_FORM_data8))
       || form == DW_FORM_sec_offset
-       || form == DW_FORM_loclistx)
-     printf (_(" (location list)"));
+       || form == DW_FORM_loclistx) {
+     if (attribute == DW_AT_rnglists_base)
+       printf (_(" (range list)"));
+     else
+       printf (_(" (location list)"));
+      }
       /* Fall through.  */
     case DW_AT_allocated:
     case DW_AT_associated:
@@ -3835,6 +3872,7 @@ process_debug_info (struct dwarf_section * section,
       debug_information [unit].range_lists = NULL;
       debug_information [unit].max_range_lists= 0;
       debug_information [unit].num_range_lists = 0;
+       debug_information [unit].rnglists_base = 0;
     }
       if (!do_loc && dwarf_start_die == 0)
@@ -4056,6 +4094,8 @@ process_debug_info (struct dwarf_section * section,
           if (! do_loc && do_printing)
          /* Show the offset from where the tag was extracted.  */
          printf ("    <%lx>", (unsigned long)(tags - section_begin));
+           if (attr->attribute == DW_AT_ranges)
+             ranges_attr = attr;
           tags = read_and_display_attr (attr->attribute,
                               attr->form,
                               attr->implicit_const,
@@ -7086,9 +7126,6 @@ display_offset_entry_loclists (struct dwarf_section *section)
         case DW_LLE_base_addressx:
           READ_ULEB (base_address, start, end);
           print_dwarf_vma (base_address, address_size);
-           printf (_("(index into .debug_addr) "));
-           base_address = fetch_indexed_addr (base_address, address_size);
-           print_dwarf_vma (base_address, address_size);
           printf (_("(base address)\n"));
           continue;
@@ -7959,7 +7996,8 @@ display_debug_rnglists_list (unsigned char * start,
                     unsigned char * finish,
                     unsigned int    pointer_size,
                     dwarf_vma       offset,
-                     dwarf_vma       base_address)
+                     dwarf_vma       base_address,
+                     unsigned char ** start_header)
{
   unsigned char *next = start;
@@ -8026,8 +8064,10 @@ display_debug_rnglists_list (unsigned char * start,
       rlet = DW_RLE_end_of_list;
       break;
     }
-      if (rlet == DW_RLE_end_of_list)
-     break;
+      if (rlet == DW_RLE_end_of_list) {
+        *start_header = start;
+        break;
+      }
       if (rlet == DW_RLE_base_address || rlet == DW_RLE_base_addressx)
     continue;
@@ -8050,6 +8090,69 @@ display_debug_rnglists_list (unsigned char * start,
     }
}
+static void display_debug_rnglists_header (unsigned char * start,
+                                           unsigned char * finish)
+{
+      dwarf_vma initial_length;
+      unsigned char segment_selector_size;
+      unsigned int offset_size, offset_entry_count, i;
+      unsigned short version;
+      unsigned char  address_size = 0;
+
+      /* Get and check the length of the block.  */
+      SAFE_BYTE_GET_AND_INC (initial_length, start, 4, finish);
+
+      if (initial_length == 0xffffffff)
+        {
+          /* This section is 64-bit DWARF 3.  */
+          SAFE_BYTE_GET_AND_INC (initial_length, start, 8, finish);
+          offset_size = 8;
+        }
+      else
+        offset_size = 4;
+
+      /* Get the other fields in the header.  */
+      SAFE_BYTE_GET_AND_INC (version, start, 2, finish);
+      SAFE_BYTE_GET_AND_INC (address_size, start, 1, finish);
+      SAFE_BYTE_GET_AND_INC (segment_selector_size, start, 1, finish);
+      SAFE_BYTE_GET_AND_INC (offset_entry_count, start, 4, finish);
+
+      putchar ('\n');
+      printf (_("  Length:          0x%s\n"), dwarf_vmatoa ("x", initial_length));
+      printf (_("  DWARF version:   %u\n"), version);
+      printf (_("  Address size:    %u\n"), address_size);
+      printf (_("  Segment size:    %u\n"), segment_selector_size);
+      printf (_("  Offset entries:  %u\n"), offset_entry_count);
+
+      if (offset_entry_count != 0)
+        {
+          printf (_("\n   Offsets starting at 0x%lx:\n"),
+                  (long)(start - debug_displays [rnglists].section.start));
+          if (offset_size == 8)
+            {
+              for (i = 0; i < offset_entry_count; i++)
+                {
+                  dwarf_vma entry;
+
+                  SAFE_BYTE_GET_AND_INC (entry, start, 8, finish);
+                  printf (_("    [%6u] 0x%s\n"), i, dwarf_vmatoa ("x", entry));
+                }
+            }
+          else
+            {
+              for (i = 0; i < offset_entry_count; i++)
+                {
+                  uint32_t entry;
+
+                  SAFE_BYTE_GET_AND_INC (entry, start, 4, finish);
+                  printf (_("    [%6u] 0x%x\n"), i, entry);
+                }
+            }
+        }
+      putchar ('\n');
+      printf (_("    Offset   Begin    End\n"));
+}
+
static int
display_debug_ranges (struct dwarf_section *section,
                void *file ATTRIBUTE_UNUSED)
@@ -8066,6 +8169,7 @@ display_debug_ranges (struct dwarf_section *section,
   /* Initialize it due to a false compiler warning.  */
   unsigned char         address_size = 0;
   dwarf_vma             last_offset = 0;
+  unsigned char *       start_header = NULL;
   if (bytes == 0)
     {
@@ -8226,7 +8330,8 @@ display_debug_ranges (struct dwarf_section *section,
   putchar ('\n');
   printf (_("    Offset   Begin    End\n"));
-  for (i = 0; i < num_range_list; i++)
+  unsigned int range_lists_count = 0;
+  for (i = 0; i < num_range_list; i++, range_lists_count++)
     {
       struct range_entry *range_entry = &range_entries[i];
       debug_info *debug_info_p = range_entry->debug_info_p;
@@ -8239,6 +8344,12 @@ display_debug_ranges (struct dwarf_section *section,
       offset = range_entry->ranges_offset;
       base_address = debug_info_p->base_address;
+      if ((i > 0) &&
+          (start_header != NULL) &&
+          (range_lists_count == range_entries[i-1].debug_info_p->num_range_lists)) {
+        range_lists_count = 0;
+        display_debug_rnglists_header (start_header, finish);
+      }
       /* PR 17512: file: 001-101485-0.001:0.1.  */
       if (pointer_size < 2 || pointer_size > 8)
     {
@@ -8253,7 +8364,7 @@ display_debug_ranges (struct dwarf_section *section,
          (unsigned long) offset, i);
       continue;
     }
-      next = section_begin + offset + DEBUG_LOCLISTS_RNGLISTS_SECTION_HEADER_LEN;
+      next = section_begin + offset;
       /* If multiple DWARF entities reference the same range then we will
          have multiple entries in the `range_entries' list for the same
@@ -8285,7 +8396,7 @@ display_debug_ranges (struct dwarf_section *section,
       if (is_rnglists)
     display_debug_rnglists_list
-       (start, finish, pointer_size, offset, base_address);
+       (start, finish, pointer_size, offset, base_address, &start_header);
       else
     display_debug_ranges_list
       (start, finish, pointer_size, offset, base_address);
diff --git a/binutils/dwarf.h b/binutils/dwarf.h
index 040e674c6ce..8a89c08e7c2 100644
--- a/binutils/dwarf.h
+++ b/binutils/dwarf.h
@@ -192,6 +192,7 @@ typedef struct
   dwarf_vma *    range_lists;
   unsigned int   num_range_lists;
   unsigned int   max_range_lists;
+  dwarf_vma      rnglists_base;
}
debug_info;
diff --git a/binutils/testsuite/binutils-all/dw5-loclist.S b/binutils/testsuite/binutils-all/dw5-loclist.S
new file mode 100644
index 00000000000..5adf66c66c0
--- /dev/null
+++ b/binutils/testsuite/binutils-all/dw5-loclist.S
@@ -0,0 +1,691 @@
+/* Copyright (C) 2017-2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see http://www.gnu.org/licenses/.  */
+
+     .file "main.c"
+     .text
+.Ltext0:
+     .p2align 4,,15
+     .globl     func
+     .type func, %function
+func:
+.LFB0:
+     /* main.c:5 */
+.LM1:
+/* BLOCK 2 freq:10000 seq:0 */
+/* PRED: ENTRY [100.0%]  (FALLTHRU) */
+     /* main.c:5 */
+.LM2:
+     .dc.b 0
+/* SUCC: */
+     .dc.b 0
+.LFE0:
+     .size func, .-func
+     .section   .text.startup,"ax",%progbits
+     .p2align 4,,15
+     .globl     main
+     .type main, %function
+main:
+.LFB1:
+     /* main.c:6 */
+.LM3:
+.LVL0:
+/* BLOCK 2 freq:10000 seq:0 */
+/* PRED: ENTRY [100.0%]  (FALLTHRU) */
+     .dc.b 0
+     /* main.c:6 */
+.LM4:
+     .dc.b 0
+.LVL1:
+     .dc.b 0
+.LVL2:
+     .dc.b 0
+/* SUCC: EXIT [100.0%]  */
+     .dc.b 0
+.LFE1:
+     .size main, .-main
+ .ifdef HPUX
+pvar .comm 8
+yvar .comm 4
+ .else
+     .comm pvar,8,8
+     .comm yvar,4,4
+ .endif
+     .globl     xvar
+     .data
+     .align 4
+     .type xvar, %object
+     .size xvar, 4
+xvar:
+     .4byte     42
+     .text
+.Letext0:
+     .section   .debug_info,"",%progbits
+.Ldebug_info0:
+     .4byte     0x160 /* Length of Compilation Unit Info */
+     .2byte     0x5  /* DWARF version number */
+     .byte 0x1  /* DW_UT_compile */
+     .byte 0x8  /* Pointer Size (in bytes) */
+     .4byte     .Ldebug_abbrev0 /* Offset Into Abbrev. Section */
+     .uleb128 0x6    /* (DIE (0xc) DW_TAG_compile_unit) */
+     .4byte     .LASF21    /* DW_AT_producer: "GNU C11 7.0.1 20170218 (experimental) -mtune=generic -march=x86-64 -gdwarf-5 -O2" */
+     .byte 0x1d /* DW_AT_language */
+     .4byte     .LASF0     /* DW_AT_name: "main.c" */
+     .4byte     .LASF1     /* DW_AT_comp_dir: "" */
+     .4byte     .LLRL2     /* DW_AT_ranges */
+     .8byte     0     /* DW_AT_low_pc */
+     .4byte     .Ldebug_line0   /* DW_AT_stmt_list */
+     .uleb128 0x1    /* (DIE (0x2a) DW_TAG_base_type) */
+     .byte 0x1  /* DW_AT_byte_size */
+     .byte 0x8  /* DW_AT_encoding */
+     .4byte     .LASF2     /* DW_AT_name: "unsigned char" */
+     .uleb128 0x1    /* (DIE (0x31) DW_TAG_base_type) */
+     .byte 0x2  /* DW_AT_byte_size */
+     .byte 0x7  /* DW_AT_encoding */
+     .4byte     .LASF3     /* DW_AT_name: "short unsigned int" */
+     .uleb128 0x1    /* (DIE (0x38) DW_TAG_base_type) */
+     .byte 0x4  /* DW_AT_byte_size */
+     .byte 0x7  /* DW_AT_encoding */
+     .4byte     .LASF4     /* DW_AT_name: "unsigned int" */
+     .uleb128 0x1    /* (DIE (0x3f) DW_TAG_base_type) */
+     .byte 0x8  /* DW_AT_byte_size */
+     .byte 0x7  /* DW_AT_encoding */
+     .4byte     .LASF5     /* DW_AT_name: "long unsigned int" */
+     .uleb128 0x1    /* (DIE (0x46) DW_TAG_base_type) */
+     .byte 0x1  /* DW_AT_byte_size */
+     .byte 0x6  /* DW_AT_encoding */
+     .4byte     .LASF6     /* DW_AT_name: "signed char" */
+     .uleb128 0x1    /* (DIE (0x4d) DW_TAG_base_type) */
+     .byte 0x2  /* DW_AT_byte_size */
+     .byte 0x5  /* DW_AT_encoding */
+     .4byte     .LASF7     /* DW_AT_name: "short int" */
+     .uleb128 0x7    /* (DIE (0x54) DW_TAG_base_type) */
+     .byte 0x4  /* DW_AT_byte_size */
+     .byte 0x5  /* DW_AT_encoding */
+     .ascii "int\0"  /* DW_AT_name */
+     .uleb128 0x1    /* (DIE (0x5b) DW_TAG_base_type) */
+     .byte 0x8  /* DW_AT_byte_size */
+     .byte 0x5  /* DW_AT_encoding */
+     .4byte     .LASF8     /* DW_AT_name: "long int" */
+     .uleb128 0x1    /* (DIE (0x62) DW_TAG_base_type) */
+     .byte 0x8  /* DW_AT_byte_size */
+     .byte 0x7  /* DW_AT_encoding */
+     .4byte     .LASF9     /* DW_AT_name: "sizetype" */
+     .uleb128 0x3    /* (DIE (0x69) DW_TAG_pointer_type) */
+                /* DW_AT_byte_size (0x8) */
+     .4byte     0x6e /* DW_AT_type */
+     .uleb128 0x1    /* (DIE (0x6e) DW_TAG_base_type) */
+     .byte 0x1  /* DW_AT_byte_size */
+     .byte 0x6  /* DW_AT_encoding */
+     .4byte     .LASF10    /* DW_AT_name: "char" */
+     .uleb128 0x8    /* (DIE (0x75) DW_TAG_variable) */
+     .4byte     .LASF11    /* DW_AT_name: "__environ" */
+     .byte 0x2  /* DW_AT_decl_file (/usr/include/unistd.h) */
+     .2byte     0x222 /* DW_AT_decl_line */
+     .4byte     0x81 /* DW_AT_type */
+                /* DW_AT_external */
+                /* DW_AT_declaration */
+     .uleb128 0x3    /* (DIE (0x81) DW_TAG_pointer_type) */
+                /* DW_AT_byte_size (0x8) */
+     .4byte     0x69 /* DW_AT_type */
+     .uleb128 0x2    /* (DIE (0x86) DW_TAG_variable) */
+     .4byte     .LASF12    /* DW_AT_name: "optarg" */
+                /* DW_AT_decl_file (3, /usr/include/getopt.h) */
+     .byte 0x39 /* DW_AT_decl_line */
+     .4byte     0x69 /* DW_AT_type */
+                /* DW_AT_external */
+                /* DW_AT_declaration */
+     .uleb128 0x2    /* (DIE (0x90) DW_TAG_variable) */
+     .4byte     .LASF13    /* DW_AT_name: "optind" */
+                /* DW_AT_decl_file (3, /usr/include/getopt.h) */
+     .byte 0x47 /* DW_AT_decl_line */
+     .4byte     0x54 /* DW_AT_type */
+                /* DW_AT_external */
+                /* DW_AT_declaration */
+     .uleb128 0x2    /* (DIE (0x9a) DW_TAG_variable) */
+     .4byte     .LASF14    /* DW_AT_name: "opterr" */
+                /* DW_AT_decl_file (3, /usr/include/getopt.h) */
+     .byte 0x4c /* DW_AT_decl_line */
+     .4byte     0x54 /* DW_AT_type */
+                /* DW_AT_external */
+                /* DW_AT_declaration */
+     .uleb128 0x2    /* (DIE (0xa4) DW_TAG_variable) */
+     .4byte     .LASF15    /* DW_AT_name: "optopt" */
+                /* DW_AT_decl_file (3, /usr/include/getopt.h) */
+     .byte 0x50 /* DW_AT_decl_line */
+     .4byte     0x54 /* DW_AT_type */
+                /* DW_AT_external */
+                /* DW_AT_declaration */
+     .uleb128 0x4    /* (DIE (0xae) DW_TAG_variable) */
+     .4byte     .LASF16    /* DW_AT_name: "xvar" */
+                /* DW_AT_decl_file (1, main.c) */
+     .byte 0x2  /* DW_AT_decl_line */
+     .4byte     0x54 /* DW_AT_type */
+                /* DW_AT_external */
+     .uleb128 0x9    /* DW_AT_location */
+     .byte 0x3  /* DW_OP_addr */
+     .8byte     0x1234
+     .uleb128 0x4    /* (DIE (0xc2) DW_TAG_variable) */
+     .4byte     .LASF17    /* DW_AT_name: "yvar" */
+                /* DW_AT_decl_file (1, main.c) */
+     .byte 0x3  /* DW_AT_decl_line */
+     .4byte     0x54 /* DW_AT_type */
+                /* DW_AT_external */
+     .uleb128 0x9    /* DW_AT_location */
+     .byte 0x3  /* DW_OP_addr */
+     .8byte     0x1234
+     .uleb128 0x4    /* (DIE (0xd6) DW_TAG_variable) */
+     .4byte     .LASF18    /* DW_AT_name: "pvar" */
+                /* DW_AT_decl_file (1, main.c) */
+     .byte 0x4  /* DW_AT_decl_line */
+     .4byte     0xea /* DW_AT_type */
+                /* DW_AT_external */
+     .uleb128 0x9    /* DW_AT_location */
+     .byte 0x3  /* DW_OP_addr */
+     .8byte     0x1234
+     .uleb128 0x3    /* (DIE (0xea) DW_TAG_pointer_type) */
+                /* DW_AT_byte_size (0x8) */
+     .4byte     0x54 /* DW_AT_type */
+     .uleb128 0x9    /* (DIE (0xef) DW_TAG_subprogram) */
+                /* DW_AT_external */
+     .4byte     .LASF22    /* DW_AT_name: "main" */
+     .byte 0x1  /* DW_AT_decl_file (main.c) */
+     .byte 0x6  /* DW_AT_decl_line */
+                /* DW_AT_prototyped */
+     .4byte     0x54 /* DW_AT_type */
+     .8byte     0x1234     /* DW_AT_low_pc */
+     .8byte     0x5678     /* DW_AT_high_pc */
+     .uleb128 0x1    /* DW_AT_frame_base */
+     .byte 0x9c /* DW_OP_call_frame_cfa */
+                /* DW_AT_call_all_calls */
+     .4byte     0x13e /* DW_AT_sibling */
+     .uleb128 0x5    /* (DIE (0x110) DW_TAG_formal_parameter) */
+     .4byte     .LASF19    /* DW_AT_name: "argc" */
+                /* DW_AT_decl_file (1, main.c) */
+                /* DW_AT_decl_line (0x6) */
+     .4byte     0x54 /* DW_AT_type */
+     .4byte     .LLST0     /* DW_AT_location */
+     .uleb128 0x5    /* (DIE (0x11d) DW_TAG_formal_parameter) */
+     .4byte     .LASF20    /* DW_AT_name: "argv" */
+                /* DW_AT_decl_file (1, main.c) */
+                /* DW_AT_decl_line (0x6) */
+     .4byte     0x81 /* DW_AT_type */
+     .4byte     .LLST1     /* DW_AT_location */
+     .uleb128 0xa    /* (DIE (0x12a) DW_TAG_call_site) */
+     .8byte     0x12345    /* DW_AT_call_return_pc */
+     .4byte     0x157 /* DW_AT_call_origin */
+     .uleb128 0xb    /* (DIE (0x137) DW_TAG_call_site_parameter) */
+     .uleb128 0x1    /* DW_AT_location */
+     .byte 0x55 /* DW_OP_reg5 */
+     .uleb128 0x1    /* DW_AT_call_value */
+     .byte 0x30 /* DW_OP_lit0 */
+     .byte 0     /* end of children of DIE 0x12a */
+     .byte 0     /* end of children of DIE 0xef */
+     .uleb128 0xc    /* (DIE (0x13e) DW_TAG_subprogram) */
+                /* DW_AT_external */
+     .4byte     .LASF23    /* DW_AT_name: "func" */
+     .byte 0x1  /* DW_AT_decl_file (main.c) */
+     .byte 0x5  /* DW_AT_decl_line */
+                /* DW_AT_prototyped */
+     .8byte     0x1234     /* DW_AT_low_pc */
+     .8byte     0x5678     /* DW_AT_high_pc */
+     .uleb128 0x1    /* DW_AT_frame_base */
+     .byte 0x9c /* DW_OP_call_frame_cfa */
+                /* DW_AT_call_all_calls */
+     .uleb128 0xd    /* (DIE (0x157) DW_TAG_subprogram) */
+                /* DW_AT_external */
+                /* DW_AT_declaration */
+     .4byte     .LASF24    /* DW_AT_linkage_name: "alarm" */
+     .4byte     .LASF24    /* DW_AT_name: "alarm" */
+     .byte 0x2  /* DW_AT_decl_file (/usr/include/unistd.h) */
+     .2byte     0x1b3 /* DW_AT_decl_line */
+     .byte 0     /* end of children of DIE 0xc */
+     .section   .debug_abbrev,"",%progbits
+.Ldebug_abbrev0:
+.Lfunc_begin0:
+     .uleb128 0x1    /* (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) */
+.Lfunc_end0:
+     .uleb128 0x3    /* (DW_AT_name) */
+     .uleb128 0xe    /* (DW_FORM_strp) */
+     .byte 0
+     .byte 0
+     .uleb128 0x2    /* (abbrev code) */
+     .uleb128 0x34   /* (TAG: DW_TAG_variable) */
+     .byte 0     /* DW_children_no */
+     .uleb128 0x3    /* (DW_AT_name) */
+     .uleb128 0xe    /* (DW_FORM_strp) */
+     .uleb128 0x3a   /* (DW_AT_decl_file) */
+     .uleb128 0x21   /* (DW_FORM_implicit_const) */
+     .sleb128 3 /* (/usr/include/getopt.h) */
+     .uleb128 0x3b   /* (DW_AT_decl_line) */
+     .uleb128 0xb    /* (DW_FORM_data1) */
+     .uleb128 0x49   /* (DW_AT_type) */
+     .uleb128 0x13   /* (DW_FORM_ref4) */
+     .uleb128 0x3f   /* (DW_AT_external) */
+     .uleb128 0x19   /* (DW_FORM_flag_present) */
+     .uleb128 0x3c   /* (DW_AT_declaration) */
+     .uleb128 0x19   /* (DW_FORM_flag_present) */
+     .byte 0
+     .byte 0
+     .uleb128 0x3    /* (abbrev code) */
+     .uleb128 0xf    /* (TAG: DW_TAG_pointer_type) */
+     .byte 0     /* DW_children_no */
+     .uleb128 0xb    /* (DW_AT_byte_size) */
+     .uleb128 0x21   /* (DW_FORM_implicit_const) */
+     .sleb128 8
+     .uleb128 0x49   /* (DW_AT_type) */
+     .uleb128 0x13   /* (DW_FORM_ref4) */
+     .byte 0
+     .byte 0
+     .uleb128 0x4    /* (abbrev code) */
+     .uleb128 0x34   /* (TAG: DW_TAG_variable) */
+     .byte 0     /* DW_children_no */
+     .uleb128 0x3    /* (DW_AT_name) */
+     .uleb128 0xe    /* (DW_FORM_strp) */
+     .uleb128 0x3a   /* (DW_AT_decl_file) */
+     .uleb128 0x21   /* (DW_FORM_implicit_const) */
+     .sleb128 1 /* (main.c) */
+     .uleb128 0x3b   /* (DW_AT_decl_line) */
+     .uleb128 0xb    /* (DW_FORM_data1) */
+     .uleb128 0x49   /* (DW_AT_type) */
+     .uleb128 0x13   /* (DW_FORM_ref4) */
+     .uleb128 0x3f   /* (DW_AT_external) */
+     .uleb128 0x19   /* (DW_FORM_flag_present) */
+     .uleb128 0x2    /* (DW_AT_location) */
+     .uleb128 0x18   /* (DW_FORM_exprloc) */
+     .byte 0
+     .byte 0
+     .uleb128 0x5    /* (abbrev code) */
+     .uleb128 0x5    /* (TAG: DW_TAG_formal_parameter) */
+     .byte 0     /* DW_children_no */
+     .uleb128 0x3    /* (DW_AT_name) */
+     .uleb128 0xe    /* (DW_FORM_strp) */
+     .uleb128 0x3a   /* (DW_AT_decl_file) */
+     .uleb128 0x21   /* (DW_FORM_implicit_const) */
+     .sleb128 1 /* (main.c) */
+     .uleb128 0x3b   /* (DW_AT_decl_line) */
+     .uleb128 0x21   /* (DW_FORM_implicit_const) */
+     .sleb128 6
+     .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
+     .uleb128 0x6    /* (abbrev code) */
+     .uleb128 0x11   /* (TAG: DW_TAG_compile_unit) */
+     .byte 0x1  /* DW_children_yes */
+     .uleb128 0x25   /* (DW_AT_producer) */
+     .uleb128 0xe    /* (DW_FORM_strp) */
+     .uleb128 0x13   /* (DW_AT_language) */
+     .uleb128 0xb    /* (DW_FORM_data1) */
+     .uleb128 0x3    /* (DW_AT_name) */
+     .uleb128 0x1f   /* (DW_FORM_line_strp) */
+     .uleb128 0x1b   /* (DW_AT_comp_dir) */
+     .uleb128 0x1f   /* (DW_FORM_line_strp) */
+     .uleb128 0x55   /* (DW_AT_ranges) */
+     .uleb128 0x17   /* (DW_FORM_sec_offset) */
+     .uleb128 0x11   /* (DW_AT_low_pc) */
+     .uleb128 0x1    /* (DW_FORM_addr) */
+     .uleb128 0x10   /* (DW_AT_stmt_list) */
+     .uleb128 0x17   /* (DW_FORM_sec_offset) */
+     .byte 0
+     .byte 0
+     .uleb128 0x7    /* (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
+     .uleb128 0x8    /* (abbrev code) */
+     .uleb128 0x34   /* (TAG: DW_TAG_variable) */
+     .byte 0     /* DW_children_no */
+     .uleb128 0x3    /* (DW_AT_name) */
+     .uleb128 0xe    /* (DW_FORM_strp) */
+     .uleb128 0x3a   /* (DW_AT_decl_file) */
+     .uleb128 0xb    /* (DW_FORM_data1) */
+     .uleb128 0x3b   /* (DW_AT_decl_line) */
+     .uleb128 0x5    /* (DW_FORM_data2) */
+     .uleb128 0x49   /* (DW_AT_type) */
+     .uleb128 0x13   /* (DW_FORM_ref4) */
+     .uleb128 0x3f   /* (DW_AT_external) */
+     .uleb128 0x19   /* (DW_FORM_flag_present) */
+     .uleb128 0x3c   /* (DW_AT_declaration) */
+     .uleb128 0x19   /* (DW_FORM_flag_present) */
+     .byte 0
+     .byte 0
+     .uleb128 0x9    /* (abbrev code) */
+     .uleb128 0x2e   /* (TAG: DW_TAG_subprogram) */
+     .byte 0x1  /* DW_children_yes */
+     .uleb128 0x3f   /* (DW_AT_external) */
+     .uleb128 0x19   /* (DW_FORM_flag_present) */
+     .uleb128 0x3    /* (DW_AT_name) */
+     .uleb128 0xe    /* (DW_FORM_strp) */
+     .uleb128 0x3a   /* (DW_AT_decl_file) */
+     .uleb128 0xb    /* (DW_FORM_data1) */
+     .uleb128 0x3b   /* (DW_AT_decl_line) */
+     .uleb128 0xb    /* (DW_FORM_data1) */
+     .uleb128 0x27   /* (DW_AT_prototyped) */
+     .uleb128 0x19   /* (DW_FORM_flag_present) */
+     .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 0x7    /* (DW_FORM_data8) */
+     .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
+     .uleb128 0xa    /* (abbrev code) */
+     .uleb128 0x48   /* (TAG: DW_TAG_call_site) */
+     .byte 0x1  /* DW_children_yes */
+     .uleb128 0x7d   /* (DW_AT_call_return_pc) */
+     .uleb128 0x1    /* (DW_FORM_addr) */
+     .uleb128 0x7f   /* (DW_AT_call_origin) */
+     .uleb128 0x13   /* (DW_FORM_ref4) */
+     .byte 0
+     .byte 0
+     .uleb128 0xb    /* (abbrev code) */
+     .uleb128 0x49   /* (TAG: DW_TAG_call_site_parameter) */
+     .byte 0     /* DW_children_no */
+     .uleb128 0x2    /* (DW_AT_location) */
+     .uleb128 0x18   /* (DW_FORM_exprloc) */
+     .uleb128 0x7e   /* (DW_AT_call_value) */
+     .uleb128 0x18   /* (DW_FORM_exprloc) */
+     .byte 0
+     .byte 0
+     .uleb128 0xc    /* (abbrev code) */
+     .uleb128 0x2e   /* (TAG: DW_TAG_subprogram) */
+     .byte 0     /* DW_children_no */
+     .uleb128 0x3f   /* (DW_AT_external) */
+     .uleb128 0x19   /* (DW_FORM_flag_present) */
+     .uleb128 0x3    /* (DW_AT_name) */
+     .uleb128 0xe    /* (DW_FORM_strp) */
+     .uleb128 0x3a   /* (DW_AT_decl_file) */
+     .uleb128 0xb    /* (DW_FORM_data1) */
+     .uleb128 0x3b   /* (DW_AT_decl_line) */
+     .uleb128 0xb    /* (DW_FORM_data1) */
+     .uleb128 0x27   /* (DW_AT_prototyped) */
+     .uleb128 0x19   /* (DW_FORM_flag_present) */
+     .uleb128 0x11   /* (DW_AT_low_pc) */
+     .uleb128 0x1    /* (DW_FORM_addr) */
+     .uleb128 0x12   /* (DW_AT_high_pc) */
+     .uleb128 0x7    /* (DW_FORM_data8) */
+     .uleb128 0x40   /* (DW_AT_frame_base) */
+     .uleb128 0x18   /* (DW_FORM_exprloc) */
+     .uleb128 0x7a   /* (DW_AT_call_all_calls) */
+     .uleb128 0x19   /* (DW_FORM_flag_present) */
+     .byte 0
+     .byte 0
+     .uleb128 0xd    /* (abbrev code) */
+     .uleb128 0x2e   /* (TAG: DW_TAG_subprogram) */
+     .byte 0     /* DW_children_no */
+     .uleb128 0x3f   /* (DW_AT_external) */
+     .uleb128 0x19   /* (DW_FORM_flag_present) */
+     .uleb128 0x3c   /* (DW_AT_declaration) */
+     .uleb128 0x19   /* (DW_FORM_flag_present) */
+     .uleb128 0x6e   /* (DW_AT_linkage_name) */
+     .uleb128 0xe    /* (DW_FORM_strp) */
+     .uleb128 0x3    /* (DW_AT_name) */
+     .uleb128 0xe    /* (DW_FORM_strp) */
+     .uleb128 0x3a   /* (DW_AT_decl_file) */
+     .uleb128 0xb    /* (DW_FORM_data1) */
+     .uleb128 0x3b   /* (DW_AT_decl_line) */
+     .uleb128 0x5    /* (DW_FORM_data2) */
+     .byte 0
+     .byte 0
+     .byte 0
+     .section   .debug_loclists,"",%progbits
+        .long   .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
+.Ldebug_list_header_start0:
+        .short  5                               # Version
+        .byte   8                               # Address size
+        .byte   0                               # Segment selector size
+        .long   3                               # Offset entry count
+.Lloclists_table_base0:
+        .long   .Ldebug_loc0-.Lloclists_table_base0
+        .long   .Ldebug_loc1-.Lloclists_table_base0
+        .long   .Ldebug_loc2-.Lloclists_table_base0
+.Ldebug_loc0:
+        .byte   4                               # DW_LLE_offset_pair
+        .uleb128 .Lfunc_begin0-.Lfunc_begin0    #   starting offset
+        .uleb128 .Lfunc_end0-.Lfunc_begin0      #   ending offset
+        .byte   6                               # Loc expr size
+        .byte   85                              # DW_OP_reg5
+        .byte   147                             # DW_OP_piece
+        .byte   8                               # 8
+        .byte   84                              # super-register DW_OP_reg4
+        .byte   147                             # DW_OP_piece
+        .byte   4                               # 4
+        .byte   0                               # DW_LLE_end_of_list
+.Ldebug_loc1:
+        .byte   4                               # DW_LLE_offset_pair
+        .uleb128 .Lfunc_begin0-.Lfunc_begin0    #   starting offset
+        .uleb128 .Lfunc_end0-.Lfunc_begin0      #   ending offset
+        .byte   6                               # Loc expr size
+        .byte   81                              # DW_OP_reg1
+        .byte   147                             # DW_OP_piece
+        .byte   8                               # 8
+        .byte   82                              # super-register DW_OP_reg2
+        .byte   147                             # DW_OP_piece
+        .byte   4                               # 4
+        .byte   0                               # DW_LLE_end_of_list
+.Ldebug_loc2:
+        .byte   4                               # DW_LLE_offset_pair
+        .uleb128 .Lfunc_begin0-.Lfunc_begin0    #   starting offset
+        .uleb128 .Lfunc_end0-.Lfunc_begin0      #   ending offset
+        .byte   6                               # Loc expr size
+        .byte   88                              # DW_OP_reg8
+        .byte   147                             # DW_OP_piece
+        .byte   8                               # 8
+        .byte   89                              # super-register DW_OP_reg9
+        .byte   147                             # DW_OP_piece
+        .byte   4                               # 4
+        .byte   0                               # DW_LLE_end_of_list
+.Ldebug_list_header_end0:
+     .section   .debug_aranges,"",%progbits
+     .4byte     0x3c /* Length of Address Ranges Info */
+     .2byte     0x2  /* DWARF Version */
+     .4byte     .Ldebug_info0   /* Offset of Compilation Unit Info */
+     .byte 0x8  /* Size of Address */
+     .byte 0     /* Size of Segment Descriptor */
+     .2byte     0     /* Pad to 16 byte boundary */
+     .2byte     0
+     .8byte     0x1234     /* Address */
+     .8byte     0x4567     /* Length */
+     .8byte     0x1234     /* Address */
+     .8byte     0x5678     /* Length */
+     .8byte     0
+     .8byte     0
+     .section   .debug_rnglists,"",%progbits
+.Ldebug_ranges0:
+     .4byte     .Ldebug_ranges3-.Ldebug_ranges2  /* Length of Range Lists */
+.Ldebug_ranges2:
+     .2byte     0x5  /* DWARF Version */
+     .byte 0x8  /* Address Size */
+     .byte 0     /* Segment Size */
+     .4byte     0     /* Offset Entry Count */
+.LLRL2:
+     .byte 0x7  /* DW_RLE_start_length (*.LLRL2) */
+     .8byte     0x1234     /* Range begin address (*.LLRL2) */
+     .uleb128 .Letext0-.Ltext0  /* Range length (*.LLRL2) */
+     .byte 0x7  /* DW_RLE_start_length (*.LLRL2) */
+     .8byte     0x1234     /* Range begin address (*.LLRL2) */
+     .uleb128 .LFE1-.LFB1  /* Range length (*.LLRL2) */
+     .byte 0     /* DW_RLE_end_of_list (*.LLRL2) */
+.Ldebug_ranges3:
+     .section   .debug_line,"",%progbits
+.Ldebug_line0:
+     .4byte     .LELT0-.LSLT0   /* Length of Source Line Info */
+.LSLT0:
+     .2byte     0x5  /* DWARF Version */
+     .byte 0x8  /* Address Size */
+     .byte 0     /* Segment Size */
+     .4byte     .LELTP0-.LASLTP0 /* Prolog Length */
+.LASLTP0:
+     .byte 0x1  /* Minimum Instruction Length */
+     .byte 0x1  /* Maximum Operations Per Instruction */
+     .byte 0x1  /* Default is_stmt_start flag */
+     .byte 0xf6 /* Line Base Value (Special Opcodes) */
+     .byte 0xf2 /* Line Range Value (Special Opcodes) */
+     .byte 0xd  /* Special Opcode Base */
+     .byte 0     /* opcode: 0x1 has 0 args */
+     .byte 0x1  /* opcode: 0x2 has 1 arg */
+     .byte 0x1  /* opcode: 0x3 has 1 arg */
+     .byte 0x1  /* opcode: 0x4 has 1 arg */
+     .byte 0x1  /* opcode: 0x5 has 1 arg */
+     .byte 0     /* opcode: 0x6 has 0 args */
+     .byte 0     /* opcode: 0x7 has 0 args */
+     .byte 0     /* opcode: 0x8 has 0 args */
+     .byte 0x1  /* opcode: 0x9 has 1 arg */
+     .byte 0     /* opcode: 0xa has 0 args */
+     .byte 0     /* opcode: 0xb has 0 args */
+     .byte 0x1  /* opcode: 0xc has 1 arg */
+     .byte 0x1  /* Directory entry format count */
+     .uleb128 0x1    /* DW_LNCT_path */
+     .uleb128 0x1f   /* DW_FORM_line_strp */
+     .uleb128 0x3    /* Directories count */
+     .4byte     .LASF1     /* Directory Entry: 0: "" */
+     .4byte     .LASF25    /* Directory Entry: 0: "" */
+     .4byte     .LASF26    /* Directory Entry: 0: "/usr/include" */
+     .byte 0x2  /* File name entry format count */
+     .uleb128 0x1    /* DW_LNCT_path */
+     .uleb128 0x1f   /* DW_FORM_line_strp */
+     .uleb128 0x2    /* DW_LNCT_directory_index */
+     .uleb128 0xb    /* DW_FORM_data1 */
+     .uleb128 0x4    /* File names count */
+     .4byte     .LASF0     /* File Entry: 0: "main.c" */
+     .byte 0
+     .4byte     .LASF27    /* File Entry: 0: "main.c" */
+     .byte 0x1
+     .4byte     .LASF28    /* File Entry: 0: "unistd.h" */
+     .byte 0x2
+     .4byte     .LASF29    /* File Entry: 0: "getopt.h" */
+     .byte 0x2
+.LELTP0:
+     .byte 0     /* set address *.LM3 */
+     .uleb128 0x9
+     .byte 0x2
+     .8byte     0x1234
+     .byte 0x1c /* line 6 */
+     .byte 0     /* set address *.LM4 */
+     .uleb128 0x9
+     .byte 0x2
+     .8byte     0x12346
+     .byte 0x1  /* copy line 6 */
+     .byte 0     /* set address *.LFE1 */
+     .uleb128 0x9
+     .byte 0x2
+     .8byte     0x1234
+     .byte 0     /* end sequence */
+     .uleb128 0x1
+     .byte 0x1
+     .byte 0     /* set address *.LM1 */
+     .uleb128 0x9
+     .byte 0x2
+     .8byte     0x1234
+     .byte 0x1b /* line 5 */
+     .byte 0     /* set address *.LM2 */
+     .uleb128 0x9
+     .byte 0x2
+     .8byte     0x1234
+     .byte 0x1  /* copy line 5 */
+     .byte 0     /* set address *.Letext0 */
+     .uleb128 0x9
+     .byte 0x2
+     .8byte     0x1234
+     .byte 0     /* end sequence */
+     .uleb128 0x1
+     .byte 0x1
+.LELT0:
+     .section   .debug_str,"MS",%progbits,1
+.LASF4:
+     .asciz     "unsigned int"
+.LASF15:
+     .asciz     "optopt"
+.LASF22:
+     .asciz     "main"
+.LASF6:
+     .asciz     "signed char"
+.LASF16:
+     .asciz     "xvar"
+.LASF5:
+     .asciz     "long unsigned int"
+.LASF14:
+     .asciz     "opterr"
+.LASF21:
+     .asciz     "GNU C11 7.0.1 20170218 (experimental) -mtune=generic -march=x86-64 -gdwarf-5 -O2"
+.LASF2:
+     .asciz     "unsigned char"
+.LASF10:
+     .asciz     "char"
+.LASF13:
+     .asciz     "optind"
+.LASF8:
+     .asciz     "long int"
+.LASF19:
+     .asciz     "argc"
+.LASF3:
+     .asciz     "short unsigned int"
+.LASF17:
+     .asciz     "yvar"
+.LASF18:
+     .asciz     "pvar"
+.LASF11:
+     .asciz     "__environ"
+.LASF23:
+     .asciz     "func"
+.LASF12:
+     .asciz     "optarg"
+.LASF7:
+     .asciz     "short int"
+.LASF24:
+     .asciz     "alarm"
+.LASF9:
+     .asciz     "sizetype"
+.LASF20:
+     .asciz     "argv"
+     .section   .debug_line_str,"MS",%progbits,1
+.LASF1:
+     .asciz     ""
+.LASF25:
+     .asciz     ""
+.LASF29:
+     .asciz     "getopt.h"
+.LASF28:
+     .asciz     "unistd.h"
+.LASF0:
+     .asciz     "main.c"
+.LASF27:
+     .asciz     "main.c"
+.LASF26:
+     .asciz     "/usr/include"
+     .ident     "GCC: (GNU) 7.0.1 20170218 (experimental)"
+     .section   .note.GNU-stack,"",%progbits
diff --git a/binutils/testsuite/binutils-all/dw5-loclist.W b/binutils/testsuite/binutils-all/dw5-loclist.W
new file mode 100644
index 00000000000..79c220aa658
--- /dev/null
+++ b/binutils/testsuite/binutils-all/dw5-loclist.W
@@ -0,0 +1,27 @@
+Contents of the .debug_loclists section:
+
+Table at Offset 0x0
+  Length:          0x35
+  DWARF version:   5
+  Address size:    8
+  Segment size:    0
+  Offset entries:  3
+
+   Offset Entries starting at 0xc:
+    \[     0\] 0xc
+    \[     1\] 0x17
+    \[     2\] 0x22
+
+   Offset Entry 0
+    00000018 0000000000000000 0000000000000007  DW_OP_reg5 \(rdi\); DW_OP_piece: 8; DW_OP_reg4 \(rsi\); DW_OP_piece: 4
+    00000022 <End of list>
+
+   Offset Entry 1
+    00000023 0000000000000000 0000000000000007  DW_OP_reg1 \(rdx\); DW_OP_piece: 8; DW_OP_reg2 \(rcx\); DW_OP_piece: 4
+    0000002d <End of list>
+
+   Offset Entry 2
+    0000002e 0000000000000000 0000000000000007  DW_OP_reg8 \(r8\); DW_OP_piece: 8; DW_OP_reg9 \(r9\); DW_OP_piece: 4
+    00000038 <End of list>
+
+
diff --git a/binutils/testsuite/binutils-all/readelf.exp b/binutils/testsuite/binutils-all/readelf.exp
index 0f7a1f3b5a0..aaa50cf6c12 100644
--- a/binutils/testsuite/binutils-all/readelf.exp
+++ b/binutils/testsuite/binutils-all/readelf.exp
@@ -616,3 +616,22 @@ readelf_find_size $tempfile 2
# Make sure that readelf can decode the contents.
readelf_test -wi $tempfile dw5-op.W
}
+
+# Check dwarf-5 support for .debug_loclists section dump.
+if {![binutils_assemble_flags $srcdir/$subdir/dw5-loclist.S tmpdir/dw5-loclist.o $hpux]} then {
+    unsupported "readelf -wo dw5-loclist (failed to assemble)"
+} else {
+
+# Download it.
+if ![is_remote host] {
+    set tempfile tmpdir/dw5-loclist.o
+} else {
+    set tempfile [remote_download host tmpdir/dw5-loclist.o]
+}
+
+# First, determine the size, so specific output matchers can be used.
+readelf_find_size $tempfile 2
+
+# Make sure that readelf can decode the contents.
+readelf_test -wo $tempfile dw5-loclist.W
+}
--
2.17.1




[-- Attachment #2: 0001-PATCH-1-2-Binutils-support-for-dwarf-5.patch --]
[-- Type: application/octet-stream, Size: 4913 bytes --]

From 96ce32f762803a7d74ca30c3930f1679afc0100c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Tue, 31 May 2022 14:07:17 +0530
Subject: [PATCH] [PATCH 1/2] Binutils support for dwarf-5.

For clang compiled with dwarf-5, multiple issues are fixed which are
related to .debug_rnglists and .debug_loclists sections and their offset
address dump comprising single and multiple CU. There are 2 patches
and this is patch 1/2.

Issues fixed in patch 1/2 are:
Issue 1: .debug_rnglists section dump for single CU.
Issue 2: location list offset address dump under DW_AT_location is corrected.
Issue 3: range list offset address dump under DW_AT_ranges is corrected.

	* dwarf.c (fetch_indexed_value): Add base_address as parameter and
	use it to access the section offset.
	(read_and_display_attr_value): Handle DW_FORM_loclistx and
	DW_FORM_rnglistx forms separately.
	(display_debug_rnglists_list): Fix support for DW_RLE_base_addressx,
	DW_RLE_startx_length.
	(display_debug_ranges): Correct the range list entries starting address.
---
 binutils/dwarf.c | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index caa3ce48d00..566104762d1 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -118,6 +118,7 @@ int dwarf_cutoff_level = -1;
 unsigned long dwarf_start_die;
 
 int dwarf_check = 0;
+#define DEBUG_LOCLISTS_RNGLISTS_SECTION_HEADER_LEN 12
 
 /* Convenient constant, to avoid having to cast -1 to dwarf_vma when
    testing whether e.g. a locview list is present.  */
@@ -826,7 +827,8 @@ fetch_indexed_addr (dwarf_vma offset, uint32_t num_bytes)
 
 static dwarf_vma
 fetch_indexed_value (dwarf_vma idx,
-		     enum dwarf_section_display_enum sec_enum)
+		     enum dwarf_section_display_enum sec_enum,
+		     dwarf_vma base_address)
 {
   struct dwarf_section *section = &debug_displays [sec_enum].section;
 
@@ -851,8 +853,12 @@ fetch_indexed_value (dwarf_vma idx,
  
   dwarf_vma offset = idx * pointer_size;
 
-  /* Offsets are biased by the size of the section header.  */
-  offset += bias;
+  /* Offsets are biased by the size of the section header
+     or base address.  */
+  if (sec_enum == loclists)
+    offset += base_address;
+  else
+    offset += bias;
 
   if (offset + pointer_size > section->size)
     {
@@ -2788,7 +2794,15 @@ read_and_display_attr_value (unsigned long           attribute,
 
 	  offset = base + uvalue * pointer_size;
 
-	  if (do_wide)
+	  if (form == DW_FORM_loclistx)
+	    printf (_("%c(index: 0x%s): %s"), delimiter,
+	            dwarf_vmatoa ("x", uvalue),
+	            dwarf_vmatoa ("x", debug_info_p->loc_offsets [uvalue]));
+	  else if (form == DW_FORM_rnglistx)
+	    printf (_("%c(index: 0x%s): %s"), delimiter,
+	            dwarf_vmatoa ("x", uvalue),
+	            dwarf_vmatoa ("x", fetch_indexed_value (uvalue, rnglists, 0)));
+	  else if (do_wide)
 	    /* We have already displayed the form name.  */
 	    printf (_("%c(index: 0x%s): %s"), delimiter,
 		    dwarf_vmatoa ("x", uvalue),
@@ -2870,7 +2884,7 @@ read_and_display_attr_value (unsigned long           attribute,
 		}
 
 	      if (form == DW_FORM_loclistx)
-		uvalue = fetch_indexed_value (uvalue, loclists);
+		uvalue = fetch_indexed_value (num, loclists, debug_info_p->loclists_base);
 	      else if (this_set != NULL)
 		uvalue += this_set->section_offsets [DW_SECT_LOC];
 
@@ -2939,7 +2953,7 @@ read_and_display_attr_value (unsigned long           attribute,
 		}
 
 	      if (form == DW_FORM_rnglistx)
-		uvalue = fetch_indexed_value (uvalue, rnglists);
+		uvalue = fetch_indexed_value (uvalue, rnglists, 0);
 
 	      debug_info_p->range_lists [num] = uvalue;
 	      debug_info_p->num_range_lists++;
@@ -7976,9 +7990,6 @@ display_debug_rnglists_list (unsigned char * start,
 	case DW_RLE_base_addressx:
 	  READ_ULEB (base_address, start, finish);
 	  print_dwarf_vma (base_address, pointer_size);
-	  printf (_("(base address index) "));
-	  base_address = fetch_indexed_addr (base_address, pointer_size);
-	  print_dwarf_vma (base_address, pointer_size);
 	  printf (_("(base address)\n"));
 	  break;
 	case DW_RLE_startx_endx:
@@ -7990,7 +8001,6 @@ display_debug_rnglists_list (unsigned char * start,
 	case DW_RLE_startx_length:
 	  READ_ULEB (begin, start, finish);
 	  READ_ULEB (length, start, finish);
-	  begin = fetch_indexed_addr (begin, pointer_size);
 	  end = begin + length;
 	  break;
 	case DW_RLE_offset_pair:
@@ -8243,7 +8253,7 @@ display_debug_ranges (struct dwarf_section *section,
 		(unsigned long) offset, i);
 	  continue;
 	}
-      next = section_begin + offset;
+      next = section_begin + offset + DEBUG_LOCLISTS_RNGLISTS_SECTION_HEADER_LEN;
 
       /* If multiple DWARF entities reference the same range then we will
          have multiple entries in the `range_entries' list for the same
-- 
2.17.1


[-- Attachment #3: 0001-PATCH-2-2-Binutils-support-for-dwarf-5.patch --]
[-- Type: application/octet-stream, Size: 39689 bytes --]

From 882829b72716d43a7f4b3ce2c82e58d3fa6d4573 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Tue, 31 May 2022 15:03:16 +0530
Subject: [PATCH] [PATCH 2/2] Binutils support for dwarf-5.

For clang compiled with dwarf-5, multiple issues are fixed which are
related to .debug_rnglists and .debug_loclists sections and their offset
address dump comprising single and multiple CU. There are 2 patches
and this is patch 2/2 and it has dependency on patch 1/2 and its
continuation of patch 1/2.

Issues fixed in patch 2/2 are:
Issue 4: .debug_rnglists section dump for multiple CU.

	* dwarf.c (fetch_indexed_value): Use base_address parameter to
	access the section offset.
	(read_and_display_attr_value): Fix support for DW_FORM_rnglistx form.
	Add support for DW_AT_rnglists_base attribute.
	Read attribute DW_AT_rnglists_base which can come before or after
	DW_AT_ranges attribute.
	(display_offset_entry_loclists): Fix support for DW_LLE_base_addressx.
	(display_debug_rnglists_list): Add start_header as parameter and
	return the start of the range list header of next compilation unit.
	(display_debug_rnglists_header): New function to dump range lists header
	for each compilation unit.
	(display_debug_ranges): For each compilation unit call
	display_debug_rnglists_header accordingly.
	* dwarf.h (struct debug_info): Add rnglists_base field.
	* testsuite/binutils-all/dw5-loclist.S: New file, .debug_loclists section
	content is updated.
	* testsuite/binutils-all/dw5-loclist.W: New file, expected output.
	* testsuite/binutils-all/readelf.exp: Added new test point dw5-loclist.
---
 binutils/dwarf.c                              | 143 +++-
 binutils/dwarf.h                              |   1 +
 binutils/testsuite/binutils-all/dw5-loclist.S | 691 ++++++++++++++++++
 binutils/testsuite/binutils-all/dw5-loclist.W |  27 +
 binutils/testsuite/binutils-all/readelf.exp   |  19 +
 5 files changed, 865 insertions(+), 16 deletions(-)
 create mode 100644 binutils/testsuite/binutils-all/dw5-loclist.S
 create mode 100644 binutils/testsuite/binutils-all/dw5-loclist.W

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 566104762d1..58675b4088d 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -118,7 +118,6 @@ int dwarf_cutoff_level = -1;
 unsigned long dwarf_start_die;
 
 int dwarf_check = 0;
-#define DEBUG_LOCLISTS_RNGLISTS_SECTION_HEADER_LEN 12
 
 /* Convenient constant, to avoid having to cast -1 to dwarf_vma when
    testing whether e.g. a locview list is present.  */
@@ -855,7 +854,7 @@ fetch_indexed_value (dwarf_vma idx,
 
   /* Offsets are biased by the size of the section header
      or base address.  */
-  if (sec_enum == loclists)
+  if ((sec_enum == loclists) || (sec_enum == rnglists))
     offset += base_address;
   else
     offset += bias;
@@ -921,6 +920,7 @@ typedef struct abbrev_map
 static abbrev_map *   cu_abbrev_map = NULL;
 static unsigned long  num_abbrev_map_entries = 0;
 static unsigned long  next_free_abbrev_map_entry = 0;
+static abbrev_attr *ranges_attr = NULL;
 
 #define INITIAL_NUM_ABBREV_MAP_ENTRIES 8
 #define ABBREV_MAP_ENTRIES_INCREMENT   8
@@ -2451,6 +2451,7 @@ read_and_display_attr_value (unsigned long           attribute,
   dwarf_vma uvalue_hi = 0;
   unsigned char *block_start = NULL;
   unsigned char *orig_data = data;
+  dwarf_vma uvalue_rnglists_base;
 
   if (data > end || (data == end && form != DW_FORM_flag_present))
     {
@@ -2801,7 +2802,7 @@ read_and_display_attr_value (unsigned long           attribute,
 	  else if (form == DW_FORM_rnglistx)
 	    printf (_("%c(index: 0x%s): %s"), delimiter,
 	            dwarf_vmatoa ("x", uvalue),
-	            dwarf_vmatoa ("x", fetch_indexed_value (uvalue, rnglists, 0)));
+	            dwarf_vmatoa ("x", debug_info_p->range_lists [uvalue]));
 	  else if (do_wide)
 	    /* We have already displayed the form name.  */
 	    printf (_("%c(index: 0x%s): %s"), delimiter,
@@ -2839,6 +2840,13 @@ read_and_display_attr_value (unsigned long           attribute,
 	  debug_info_p->loclists_base = uvalue;
 	  break;
 
+	case DW_AT_rnglists_base:
+	  if (debug_info_p->rnglists_base)
+	    warn (_("CU @ 0x%s has multiple rnglists_base values"),
+	          dwarf_vmatoa ("x", debug_info_p->cu_offset));
+	  debug_info_p->rnglists_base = uvalue;
+	  break;
+
 	case DW_AT_frame_base:
 	  have_frame_base = 1;
 	  /* Fall through.  */
@@ -2934,6 +2942,24 @@ read_and_display_attr_value (unsigned long           attribute,
 	  break;
 
 	case DW_AT_ranges:
+	  uvalue_rnglists_base = 0;
+	  /* DW_AT_rnglists_base can appear before or after DW_AT_ranges attribute.
+	     If its found before, DW_AT_rnglists_base is used directly,
+	     otherwise its looked ahead from DW_AT_ranges and read.  */
+	  if (!debug_info_p->rnglists_base) {
+	    if (ranges_attr && ranges_attr->next && ranges_attr->next->next &&
+	        (ranges_attr->next->next->attribute == DW_AT_rnglists_base)) {
+	      unsigned char *data_dupl = data;
+	      dwarf_vma uvalue_skip;
+	      data_dupl = skip_attr_bytes (ranges_attr->next->form, data_dupl, end,
+	                                   pointer_size, offset_size,
+	                                   dwarf_version, &uvalue_skip);
+	      SAFE_BYTE_GET_AND_INC (uvalue_rnglists_base, data_dupl, offset_size, end);
+	    }
+	  }
+	  else
+	    uvalue_rnglists_base = debug_info_p->rnglists_base;
+
 	  if ((dwarf_version < 4
 	       && (form == DW_FORM_data4 || form == DW_FORM_data8))
 	      || form == DW_FORM_sec_offset
@@ -2942,6 +2968,7 @@ read_and_display_attr_value (unsigned long           attribute,
 	      /* Process range list.  */
 	      unsigned int lmax = debug_info_p->max_range_lists;
 	      unsigned int num = debug_info_p->num_range_lists;
+	      dwarf_vma uvalue_index;
 
 	      if (lmax == 0 || num >= lmax)
 		{
@@ -2952,10 +2979,15 @@ read_and_display_attr_value (unsigned long           attribute,
 		  debug_info_p->max_range_lists = lmax;
 		}
 
+	      uvalue_index = uvalue;
 	      if (form == DW_FORM_rnglistx)
-		uvalue = fetch_indexed_value (uvalue, rnglists, 0);
+		uvalue = fetch_indexed_value (uvalue, rnglists, uvalue_rnglists_base);
 
-	      debug_info_p->range_lists [num] = uvalue;
+	      uvalue += uvalue_rnglists_base;
+	      if (form == DW_FORM_rnglistx)
+	        debug_info_p->range_lists [uvalue_index] = uvalue;
+	      else
+	        debug_info_p->range_lists [num] = uvalue;
 	      debug_info_p->num_range_lists++;
 	    }
 	  break;
@@ -3329,6 +3361,7 @@ read_and_display_attr_value (unsigned long           attribute,
       /* Fall through.  */
     case DW_AT_location:
     case DW_AT_loclists_base:
+    case DW_AT_rnglists_base:
     case DW_AT_string_length:
     case DW_AT_return_addr:
     case DW_AT_data_member_location:
@@ -3347,8 +3380,12 @@ read_and_display_attr_value (unsigned long           attribute,
       if ((dwarf_version < 4
 	   && (form == DW_FORM_data4 || form == DW_FORM_data8))
 	  || form == DW_FORM_sec_offset
-	  || form == DW_FORM_loclistx)
-	printf (_(" (location list)"));
+	  || form == DW_FORM_loclistx) {
+	if (attribute == DW_AT_rnglists_base)
+	  printf (_(" (range list)"));
+	else
+	  printf (_(" (location list)"));
+      }
       /* Fall through.  */
     case DW_AT_allocated:
     case DW_AT_associated:
@@ -3835,6 +3872,7 @@ process_debug_info (struct dwarf_section * section,
 	  debug_information [unit].range_lists = NULL;
 	  debug_information [unit].max_range_lists= 0;
 	  debug_information [unit].num_range_lists = 0;
+	  debug_information [unit].rnglists_base = 0;
 	}
 
       if (!do_loc && dwarf_start_die == 0)
@@ -4056,6 +4094,8 @@ process_debug_info (struct dwarf_section * section,
 	      if (! do_loc && do_printing)
 		/* Show the offset from where the tag was extracted.  */
 		printf ("    <%lx>", (unsigned long)(tags - section_begin));
+	      if (attr->attribute == DW_AT_ranges)
+	        ranges_attr = attr;
 	      tags = read_and_display_attr (attr->attribute,
 					    attr->form,
 					    attr->implicit_const,
@@ -7086,9 +7126,6 @@ display_offset_entry_loclists (struct dwarf_section *section)
 	    case DW_LLE_base_addressx:
 	      READ_ULEB (base_address, start, end);
 	      print_dwarf_vma (base_address, address_size);
-	      printf (_("(index into .debug_addr) "));
-	      base_address = fetch_indexed_addr (base_address, address_size);
-	      print_dwarf_vma (base_address, address_size);
 	      printf (_("(base address)\n"));
 	      continue;
 
@@ -7959,7 +7996,8 @@ display_debug_rnglists_list (unsigned char * start,
 			     unsigned char * finish,
 			     unsigned int    pointer_size,
 			     dwarf_vma       offset,
-			     dwarf_vma       base_address)
+			     dwarf_vma       base_address,
+			     unsigned char ** start_header)
 {
   unsigned char *next = start;
 
@@ -8026,8 +8064,10 @@ display_debug_rnglists_list (unsigned char * start,
 	  rlet = DW_RLE_end_of_list;
 	  break;
 	}
-      if (rlet == DW_RLE_end_of_list)
-	break;
+      if (rlet == DW_RLE_end_of_list) {
+        *start_header = start;
+        break;
+      }
       if (rlet == DW_RLE_base_address || rlet == DW_RLE_base_addressx)
 	continue;
 
@@ -8050,6 +8090,69 @@ display_debug_rnglists_list (unsigned char * start,
     }
 }
 
+static void display_debug_rnglists_header (unsigned char * start,
+                                           unsigned char * finish)
+{
+      dwarf_vma initial_length;
+      unsigned char segment_selector_size;
+      unsigned int offset_size, offset_entry_count, i;
+      unsigned short version;
+      unsigned char  address_size = 0;
+
+      /* Get and check the length of the block.  */
+      SAFE_BYTE_GET_AND_INC (initial_length, start, 4, finish);
+
+      if (initial_length == 0xffffffff)
+        {
+          /* This section is 64-bit DWARF 3.  */
+          SAFE_BYTE_GET_AND_INC (initial_length, start, 8, finish);
+          offset_size = 8;
+        }
+      else
+        offset_size = 4;
+
+      /* Get the other fields in the header.  */
+      SAFE_BYTE_GET_AND_INC (version, start, 2, finish);
+      SAFE_BYTE_GET_AND_INC (address_size, start, 1, finish);
+      SAFE_BYTE_GET_AND_INC (segment_selector_size, start, 1, finish);
+      SAFE_BYTE_GET_AND_INC (offset_entry_count, start, 4, finish);
+
+      putchar ('\n');
+      printf (_("  Length:          0x%s\n"), dwarf_vmatoa ("x", initial_length));
+      printf (_("  DWARF version:   %u\n"), version);
+      printf (_("  Address size:    %u\n"), address_size);
+      printf (_("  Segment size:    %u\n"), segment_selector_size);
+      printf (_("  Offset entries:  %u\n"), offset_entry_count);
+
+      if (offset_entry_count != 0)
+        {
+          printf (_("\n   Offsets starting at 0x%lx:\n"),
+                  (long)(start - debug_displays [rnglists].section.start));
+          if (offset_size == 8)
+            {
+              for (i = 0; i < offset_entry_count; i++)
+                {
+                  dwarf_vma entry;
+
+                  SAFE_BYTE_GET_AND_INC (entry, start, 8, finish);
+                  printf (_("    [%6u] 0x%s\n"), i, dwarf_vmatoa ("x", entry));
+                }
+            }
+          else
+            {
+              for (i = 0; i < offset_entry_count; i++)
+                {
+                  uint32_t entry;
+
+                  SAFE_BYTE_GET_AND_INC (entry, start, 4, finish);
+                  printf (_("    [%6u] 0x%x\n"), i, entry);
+                }
+            }
+        }
+      putchar ('\n');
+      printf (_("    Offset   Begin    End\n"));
+}
+
 static int
 display_debug_ranges (struct dwarf_section *section,
 		      void *file ATTRIBUTE_UNUSED)
@@ -8066,6 +8169,7 @@ display_debug_ranges (struct dwarf_section *section,
   /* Initialize it due to a false compiler warning.  */
   unsigned char         address_size = 0;
   dwarf_vma             last_offset = 0;
+  unsigned char *       start_header = NULL;
 
   if (bytes == 0)
     {
@@ -8226,7 +8330,8 @@ display_debug_ranges (struct dwarf_section *section,
   putchar ('\n');
   printf (_("    Offset   Begin    End\n"));
 
-  for (i = 0; i < num_range_list; i++)
+  unsigned int range_lists_count = 0;
+  for (i = 0; i < num_range_list; i++, range_lists_count++)
     {
       struct range_entry *range_entry = &range_entries[i];
       debug_info *debug_info_p = range_entry->debug_info_p;
@@ -8239,6 +8344,12 @@ display_debug_ranges (struct dwarf_section *section,
       offset = range_entry->ranges_offset;
       base_address = debug_info_p->base_address;
 
+      if ((i > 0) &&
+          (start_header != NULL) &&
+          (range_lists_count == range_entries[i-1].debug_info_p->num_range_lists)) {
+        range_lists_count = 0;
+        display_debug_rnglists_header (start_header, finish);
+      }
       /* PR 17512: file: 001-101485-0.001:0.1.  */
       if (pointer_size < 2 || pointer_size > 8)
 	{
@@ -8253,7 +8364,7 @@ display_debug_ranges (struct dwarf_section *section,
 		(unsigned long) offset, i);
 	  continue;
 	}
-      next = section_begin + offset + DEBUG_LOCLISTS_RNGLISTS_SECTION_HEADER_LEN;
+      next = section_begin + offset;
 
       /* If multiple DWARF entities reference the same range then we will
          have multiple entries in the `range_entries' list for the same
@@ -8285,7 +8396,7 @@ display_debug_ranges (struct dwarf_section *section,
 
       if (is_rnglists)
 	display_debug_rnglists_list
-	  (start, finish, pointer_size, offset, base_address);
+	  (start, finish, pointer_size, offset, base_address, &start_header);
       else
 	display_debug_ranges_list
 	  (start, finish, pointer_size, offset, base_address);
diff --git a/binutils/dwarf.h b/binutils/dwarf.h
index 040e674c6ce..8a89c08e7c2 100644
--- a/binutils/dwarf.h
+++ b/binutils/dwarf.h
@@ -192,6 +192,7 @@ typedef struct
   dwarf_vma *    range_lists;
   unsigned int   num_range_lists;
   unsigned int   max_range_lists;
+  dwarf_vma      rnglists_base;
 }
 debug_info;
 
diff --git a/binutils/testsuite/binutils-all/dw5-loclist.S b/binutils/testsuite/binutils-all/dw5-loclist.S
new file mode 100644
index 00000000000..5adf66c66c0
--- /dev/null
+++ b/binutils/testsuite/binutils-all/dw5-loclist.S
@@ -0,0 +1,691 @@
+/* Copyright (C) 2017-2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+	.file	"main.c"
+	.text
+.Ltext0:
+	.p2align 4,,15
+	.globl	func
+	.type	func, %function
+func:
+.LFB0:
+	/* main.c:5 */
+.LM1:
+/* BLOCK 2 freq:10000 seq:0 */
+/* PRED: ENTRY [100.0%]  (FALLTHRU) */
+	/* main.c:5 */
+.LM2:
+	.dc.b 0
+/* SUCC: */
+	.dc.b 0
+.LFE0:
+	.size	func, .-func
+	.section	.text.startup,"ax",%progbits
+	.p2align 4,,15
+	.globl	main
+	.type	main, %function
+main:
+.LFB1:
+	/* main.c:6 */
+.LM3:
+.LVL0:
+/* BLOCK 2 freq:10000 seq:0 */
+/* PRED: ENTRY [100.0%]  (FALLTHRU) */
+	.dc.b 0
+	/* main.c:6 */
+.LM4:
+	.dc.b 0
+.LVL1:
+	.dc.b 0
+.LVL2:
+	.dc.b 0
+/* SUCC: EXIT [100.0%]  */
+	.dc.b 0
+.LFE1:
+	.size	main, .-main
+ .ifdef HPUX
+pvar	.comm	8
+yvar	.comm	4
+ .else
+	.comm	pvar,8,8
+	.comm	yvar,4,4
+ .endif
+	.globl	xvar
+	.data
+	.align 4
+	.type	xvar, %object
+	.size	xvar, 4
+xvar:
+	.4byte	42
+	.text
+.Letext0:
+	.section	.debug_info,"",%progbits
+.Ldebug_info0:
+	.4byte	0x160	/* Length of Compilation Unit Info */
+	.2byte	0x5	/* DWARF version number */
+	.byte	0x1	/* DW_UT_compile */
+	.byte	0x8	/* Pointer Size (in bytes) */
+	.4byte	.Ldebug_abbrev0	/* Offset Into Abbrev. Section */
+	.uleb128 0x6	/* (DIE (0xc) DW_TAG_compile_unit) */
+	.4byte	.LASF21	/* DW_AT_producer: "GNU C11 7.0.1 20170218 (experimental) -mtune=generic -march=x86-64 -gdwarf-5 -O2" */
+	.byte	0x1d	/* DW_AT_language */
+	.4byte	.LASF0	/* DW_AT_name: "main.c" */
+	.4byte	.LASF1	/* DW_AT_comp_dir: "" */
+	.4byte	.LLRL2	/* DW_AT_ranges */
+	.8byte	0	/* DW_AT_low_pc */
+	.4byte	.Ldebug_line0	/* DW_AT_stmt_list */
+	.uleb128 0x1	/* (DIE (0x2a) DW_TAG_base_type) */
+	.byte	0x1	/* DW_AT_byte_size */
+	.byte	0x8	/* DW_AT_encoding */
+	.4byte	.LASF2	/* DW_AT_name: "unsigned char" */
+	.uleb128 0x1	/* (DIE (0x31) DW_TAG_base_type) */
+	.byte	0x2	/* DW_AT_byte_size */
+	.byte	0x7	/* DW_AT_encoding */
+	.4byte	.LASF3	/* DW_AT_name: "short unsigned int" */
+	.uleb128 0x1	/* (DIE (0x38) DW_TAG_base_type) */
+	.byte	0x4	/* DW_AT_byte_size */
+	.byte	0x7	/* DW_AT_encoding */
+	.4byte	.LASF4	/* DW_AT_name: "unsigned int" */
+	.uleb128 0x1	/* (DIE (0x3f) DW_TAG_base_type) */
+	.byte	0x8	/* DW_AT_byte_size */
+	.byte	0x7	/* DW_AT_encoding */
+	.4byte	.LASF5	/* DW_AT_name: "long unsigned int" */
+	.uleb128 0x1	/* (DIE (0x46) DW_TAG_base_type) */
+	.byte	0x1	/* DW_AT_byte_size */
+	.byte	0x6	/* DW_AT_encoding */
+	.4byte	.LASF6	/* DW_AT_name: "signed char" */
+	.uleb128 0x1	/* (DIE (0x4d) DW_TAG_base_type) */
+	.byte	0x2	/* DW_AT_byte_size */
+	.byte	0x5	/* DW_AT_encoding */
+	.4byte	.LASF7	/* DW_AT_name: "short int" */
+	.uleb128 0x7	/* (DIE (0x54) DW_TAG_base_type) */
+	.byte	0x4	/* DW_AT_byte_size */
+	.byte	0x5	/* DW_AT_encoding */
+	.ascii "int\0"	/* DW_AT_name */
+	.uleb128 0x1	/* (DIE (0x5b) DW_TAG_base_type) */
+	.byte	0x8	/* DW_AT_byte_size */
+	.byte	0x5	/* DW_AT_encoding */
+	.4byte	.LASF8	/* DW_AT_name: "long int" */
+	.uleb128 0x1	/* (DIE (0x62) DW_TAG_base_type) */
+	.byte	0x8	/* DW_AT_byte_size */
+	.byte	0x7	/* DW_AT_encoding */
+	.4byte	.LASF9	/* DW_AT_name: "sizetype" */
+	.uleb128 0x3	/* (DIE (0x69) DW_TAG_pointer_type) */
+			/* DW_AT_byte_size (0x8) */
+	.4byte	0x6e	/* DW_AT_type */
+	.uleb128 0x1	/* (DIE (0x6e) DW_TAG_base_type) */
+	.byte	0x1	/* DW_AT_byte_size */
+	.byte	0x6	/* DW_AT_encoding */
+	.4byte	.LASF10	/* DW_AT_name: "char" */
+	.uleb128 0x8	/* (DIE (0x75) DW_TAG_variable) */
+	.4byte	.LASF11	/* DW_AT_name: "__environ" */
+	.byte	0x2	/* DW_AT_decl_file (/usr/include/unistd.h) */
+	.2byte	0x222	/* DW_AT_decl_line */
+	.4byte	0x81	/* DW_AT_type */
+			/* DW_AT_external */
+			/* DW_AT_declaration */
+	.uleb128 0x3	/* (DIE (0x81) DW_TAG_pointer_type) */
+			/* DW_AT_byte_size (0x8) */
+	.4byte	0x69	/* DW_AT_type */
+	.uleb128 0x2	/* (DIE (0x86) DW_TAG_variable) */
+	.4byte	.LASF12	/* DW_AT_name: "optarg" */
+			/* DW_AT_decl_file (3, /usr/include/getopt.h) */
+	.byte	0x39	/* DW_AT_decl_line */
+	.4byte	0x69	/* DW_AT_type */
+			/* DW_AT_external */
+			/* DW_AT_declaration */
+	.uleb128 0x2	/* (DIE (0x90) DW_TAG_variable) */
+	.4byte	.LASF13	/* DW_AT_name: "optind" */
+			/* DW_AT_decl_file (3, /usr/include/getopt.h) */
+	.byte	0x47	/* DW_AT_decl_line */
+	.4byte	0x54	/* DW_AT_type */
+			/* DW_AT_external */
+			/* DW_AT_declaration */
+	.uleb128 0x2	/* (DIE (0x9a) DW_TAG_variable) */
+	.4byte	.LASF14	/* DW_AT_name: "opterr" */
+			/* DW_AT_decl_file (3, /usr/include/getopt.h) */
+	.byte	0x4c	/* DW_AT_decl_line */
+	.4byte	0x54	/* DW_AT_type */
+			/* DW_AT_external */
+			/* DW_AT_declaration */
+	.uleb128 0x2	/* (DIE (0xa4) DW_TAG_variable) */
+	.4byte	.LASF15	/* DW_AT_name: "optopt" */
+			/* DW_AT_decl_file (3, /usr/include/getopt.h) */
+	.byte	0x50	/* DW_AT_decl_line */
+	.4byte	0x54	/* DW_AT_type */
+			/* DW_AT_external */
+			/* DW_AT_declaration */
+	.uleb128 0x4	/* (DIE (0xae) DW_TAG_variable) */
+	.4byte	.LASF16	/* DW_AT_name: "xvar" */
+			/* DW_AT_decl_file (1, main.c) */
+	.byte	0x2	/* DW_AT_decl_line */
+	.4byte	0x54	/* DW_AT_type */
+			/* DW_AT_external */
+	.uleb128 0x9	/* DW_AT_location */
+	.byte	0x3	/* DW_OP_addr */
+	.8byte	0x1234
+	.uleb128 0x4	/* (DIE (0xc2) DW_TAG_variable) */
+	.4byte	.LASF17	/* DW_AT_name: "yvar" */
+			/* DW_AT_decl_file (1, main.c) */
+	.byte	0x3	/* DW_AT_decl_line */
+	.4byte	0x54	/* DW_AT_type */
+			/* DW_AT_external */
+	.uleb128 0x9	/* DW_AT_location */
+	.byte	0x3	/* DW_OP_addr */
+	.8byte	0x1234
+	.uleb128 0x4	/* (DIE (0xd6) DW_TAG_variable) */
+	.4byte	.LASF18	/* DW_AT_name: "pvar" */
+			/* DW_AT_decl_file (1, main.c) */
+	.byte	0x4	/* DW_AT_decl_line */
+	.4byte	0xea	/* DW_AT_type */
+			/* DW_AT_external */
+	.uleb128 0x9	/* DW_AT_location */
+	.byte	0x3	/* DW_OP_addr */
+	.8byte	0x1234
+	.uleb128 0x3	/* (DIE (0xea) DW_TAG_pointer_type) */
+			/* DW_AT_byte_size (0x8) */
+	.4byte	0x54	/* DW_AT_type */
+	.uleb128 0x9	/* (DIE (0xef) DW_TAG_subprogram) */
+			/* DW_AT_external */
+	.4byte	.LASF22	/* DW_AT_name: "main" */
+	.byte	0x1	/* DW_AT_decl_file (main.c) */
+	.byte	0x6	/* DW_AT_decl_line */
+			/* DW_AT_prototyped */
+	.4byte	0x54	/* DW_AT_type */
+	.8byte	0x1234	/* DW_AT_low_pc */
+	.8byte	0x5678	/* DW_AT_high_pc */
+	.uleb128 0x1	/* DW_AT_frame_base */
+	.byte	0x9c	/* DW_OP_call_frame_cfa */
+			/* DW_AT_call_all_calls */
+	.4byte	0x13e	/* DW_AT_sibling */
+	.uleb128 0x5	/* (DIE (0x110) DW_TAG_formal_parameter) */
+	.4byte	.LASF19	/* DW_AT_name: "argc" */
+			/* DW_AT_decl_file (1, main.c) */
+			/* DW_AT_decl_line (0x6) */
+	.4byte	0x54	/* DW_AT_type */
+	.4byte	.LLST0	/* DW_AT_location */
+	.uleb128 0x5	/* (DIE (0x11d) DW_TAG_formal_parameter) */
+	.4byte	.LASF20	/* DW_AT_name: "argv" */
+			/* DW_AT_decl_file (1, main.c) */
+			/* DW_AT_decl_line (0x6) */
+	.4byte	0x81	/* DW_AT_type */
+	.4byte	.LLST1	/* DW_AT_location */
+	.uleb128 0xa	/* (DIE (0x12a) DW_TAG_call_site) */
+	.8byte	0x12345	/* DW_AT_call_return_pc */
+	.4byte	0x157	/* DW_AT_call_origin */
+	.uleb128 0xb	/* (DIE (0x137) DW_TAG_call_site_parameter) */
+	.uleb128 0x1	/* DW_AT_location */
+	.byte	0x55	/* DW_OP_reg5 */
+	.uleb128 0x1	/* DW_AT_call_value */
+	.byte	0x30	/* DW_OP_lit0 */
+	.byte	0	/* end of children of DIE 0x12a */
+	.byte	0	/* end of children of DIE 0xef */
+	.uleb128 0xc	/* (DIE (0x13e) DW_TAG_subprogram) */
+			/* DW_AT_external */
+	.4byte	.LASF23	/* DW_AT_name: "func" */
+	.byte	0x1	/* DW_AT_decl_file (main.c) */
+	.byte	0x5	/* DW_AT_decl_line */
+			/* DW_AT_prototyped */
+	.8byte	0x1234	/* DW_AT_low_pc */
+	.8byte	0x5678	/* DW_AT_high_pc */
+	.uleb128 0x1	/* DW_AT_frame_base */
+	.byte	0x9c	/* DW_OP_call_frame_cfa */
+			/* DW_AT_call_all_calls */
+	.uleb128 0xd	/* (DIE (0x157) DW_TAG_subprogram) */
+			/* DW_AT_external */
+			/* DW_AT_declaration */
+	.4byte	.LASF24	/* DW_AT_linkage_name: "alarm" */
+	.4byte	.LASF24	/* DW_AT_name: "alarm" */
+	.byte	0x2	/* DW_AT_decl_file (/usr/include/unistd.h) */
+	.2byte	0x1b3	/* DW_AT_decl_line */
+	.byte	0	/* end of children of DIE 0xc */
+	.section	.debug_abbrev,"",%progbits
+.Ldebug_abbrev0:
+.Lfunc_begin0:
+	.uleb128 0x1	/* (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) */
+.Lfunc_end0:
+	.uleb128 0x3	/* (DW_AT_name) */
+	.uleb128 0xe	/* (DW_FORM_strp) */
+	.byte	0
+	.byte	0
+	.uleb128 0x2	/* (abbrev code) */
+	.uleb128 0x34	/* (TAG: DW_TAG_variable) */
+	.byte	0	/* DW_children_no */
+	.uleb128 0x3	/* (DW_AT_name) */
+	.uleb128 0xe	/* (DW_FORM_strp) */
+	.uleb128 0x3a	/* (DW_AT_decl_file) */
+	.uleb128 0x21	/* (DW_FORM_implicit_const) */
+	.sleb128 3	/* (/usr/include/getopt.h) */
+	.uleb128 0x3b	/* (DW_AT_decl_line) */
+	.uleb128 0xb	/* (DW_FORM_data1) */
+	.uleb128 0x49	/* (DW_AT_type) */
+	.uleb128 0x13	/* (DW_FORM_ref4) */
+	.uleb128 0x3f	/* (DW_AT_external) */
+	.uleb128 0x19	/* (DW_FORM_flag_present) */
+	.uleb128 0x3c	/* (DW_AT_declaration) */
+	.uleb128 0x19	/* (DW_FORM_flag_present) */
+	.byte	0
+	.byte	0
+	.uleb128 0x3	/* (abbrev code) */
+	.uleb128 0xf	/* (TAG: DW_TAG_pointer_type) */
+	.byte	0	/* DW_children_no */
+	.uleb128 0xb	/* (DW_AT_byte_size) */
+	.uleb128 0x21	/* (DW_FORM_implicit_const) */
+	.sleb128 8
+	.uleb128 0x49	/* (DW_AT_type) */
+	.uleb128 0x13	/* (DW_FORM_ref4) */
+	.byte	0
+	.byte	0
+	.uleb128 0x4	/* (abbrev code) */
+	.uleb128 0x34	/* (TAG: DW_TAG_variable) */
+	.byte	0	/* DW_children_no */
+	.uleb128 0x3	/* (DW_AT_name) */
+	.uleb128 0xe	/* (DW_FORM_strp) */
+	.uleb128 0x3a	/* (DW_AT_decl_file) */
+	.uleb128 0x21	/* (DW_FORM_implicit_const) */
+	.sleb128 1	/* (main.c) */
+	.uleb128 0x3b	/* (DW_AT_decl_line) */
+	.uleb128 0xb	/* (DW_FORM_data1) */
+	.uleb128 0x49	/* (DW_AT_type) */
+	.uleb128 0x13	/* (DW_FORM_ref4) */
+	.uleb128 0x3f	/* (DW_AT_external) */
+	.uleb128 0x19	/* (DW_FORM_flag_present) */
+	.uleb128 0x2	/* (DW_AT_location) */
+	.uleb128 0x18	/* (DW_FORM_exprloc) */
+	.byte	0
+	.byte	0
+	.uleb128 0x5	/* (abbrev code) */
+	.uleb128 0x5	/* (TAG: DW_TAG_formal_parameter) */
+	.byte	0	/* DW_children_no */
+	.uleb128 0x3	/* (DW_AT_name) */
+	.uleb128 0xe	/* (DW_FORM_strp) */
+	.uleb128 0x3a	/* (DW_AT_decl_file) */
+	.uleb128 0x21	/* (DW_FORM_implicit_const) */
+	.sleb128 1	/* (main.c) */
+	.uleb128 0x3b	/* (DW_AT_decl_line) */
+	.uleb128 0x21	/* (DW_FORM_implicit_const) */
+	.sleb128 6
+	.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
+	.uleb128 0x6	/* (abbrev code) */
+	.uleb128 0x11	/* (TAG: DW_TAG_compile_unit) */
+	.byte	0x1	/* DW_children_yes */
+	.uleb128 0x25	/* (DW_AT_producer) */
+	.uleb128 0xe	/* (DW_FORM_strp) */
+	.uleb128 0x13	/* (DW_AT_language) */
+	.uleb128 0xb	/* (DW_FORM_data1) */
+	.uleb128 0x3	/* (DW_AT_name) */
+	.uleb128 0x1f	/* (DW_FORM_line_strp) */
+	.uleb128 0x1b	/* (DW_AT_comp_dir) */
+	.uleb128 0x1f	/* (DW_FORM_line_strp) */
+	.uleb128 0x55	/* (DW_AT_ranges) */
+	.uleb128 0x17	/* (DW_FORM_sec_offset) */
+	.uleb128 0x11	/* (DW_AT_low_pc) */
+	.uleb128 0x1	/* (DW_FORM_addr) */
+	.uleb128 0x10	/* (DW_AT_stmt_list) */
+	.uleb128 0x17	/* (DW_FORM_sec_offset) */
+	.byte	0
+	.byte	0
+	.uleb128 0x7	/* (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
+	.uleb128 0x8	/* (abbrev code) */
+	.uleb128 0x34	/* (TAG: DW_TAG_variable) */
+	.byte	0	/* DW_children_no */
+	.uleb128 0x3	/* (DW_AT_name) */
+	.uleb128 0xe	/* (DW_FORM_strp) */
+	.uleb128 0x3a	/* (DW_AT_decl_file) */
+	.uleb128 0xb	/* (DW_FORM_data1) */
+	.uleb128 0x3b	/* (DW_AT_decl_line) */
+	.uleb128 0x5	/* (DW_FORM_data2) */
+	.uleb128 0x49	/* (DW_AT_type) */
+	.uleb128 0x13	/* (DW_FORM_ref4) */
+	.uleb128 0x3f	/* (DW_AT_external) */
+	.uleb128 0x19	/* (DW_FORM_flag_present) */
+	.uleb128 0x3c	/* (DW_AT_declaration) */
+	.uleb128 0x19	/* (DW_FORM_flag_present) */
+	.byte	0
+	.byte	0
+	.uleb128 0x9	/* (abbrev code) */
+	.uleb128 0x2e	/* (TAG: DW_TAG_subprogram) */
+	.byte	0x1	/* DW_children_yes */
+	.uleb128 0x3f	/* (DW_AT_external) */
+	.uleb128 0x19	/* (DW_FORM_flag_present) */
+	.uleb128 0x3	/* (DW_AT_name) */
+	.uleb128 0xe	/* (DW_FORM_strp) */
+	.uleb128 0x3a	/* (DW_AT_decl_file) */
+	.uleb128 0xb	/* (DW_FORM_data1) */
+	.uleb128 0x3b	/* (DW_AT_decl_line) */
+	.uleb128 0xb	/* (DW_FORM_data1) */
+	.uleb128 0x27	/* (DW_AT_prototyped) */
+	.uleb128 0x19	/* (DW_FORM_flag_present) */
+	.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 0x7	/* (DW_FORM_data8) */
+	.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
+	.uleb128 0xa	/* (abbrev code) */
+	.uleb128 0x48	/* (TAG: DW_TAG_call_site) */
+	.byte	0x1	/* DW_children_yes */
+	.uleb128 0x7d	/* (DW_AT_call_return_pc) */
+	.uleb128 0x1	/* (DW_FORM_addr) */
+	.uleb128 0x7f	/* (DW_AT_call_origin) */
+	.uleb128 0x13	/* (DW_FORM_ref4) */
+	.byte	0
+	.byte	0
+	.uleb128 0xb	/* (abbrev code) */
+	.uleb128 0x49	/* (TAG: DW_TAG_call_site_parameter) */
+	.byte	0	/* DW_children_no */
+	.uleb128 0x2	/* (DW_AT_location) */
+	.uleb128 0x18	/* (DW_FORM_exprloc) */
+	.uleb128 0x7e	/* (DW_AT_call_value) */
+	.uleb128 0x18	/* (DW_FORM_exprloc) */
+	.byte	0
+	.byte	0
+	.uleb128 0xc	/* (abbrev code) */
+	.uleb128 0x2e	/* (TAG: DW_TAG_subprogram) */
+	.byte	0	/* DW_children_no */
+	.uleb128 0x3f	/* (DW_AT_external) */
+	.uleb128 0x19	/* (DW_FORM_flag_present) */
+	.uleb128 0x3	/* (DW_AT_name) */
+	.uleb128 0xe	/* (DW_FORM_strp) */
+	.uleb128 0x3a	/* (DW_AT_decl_file) */
+	.uleb128 0xb	/* (DW_FORM_data1) */
+	.uleb128 0x3b	/* (DW_AT_decl_line) */
+	.uleb128 0xb	/* (DW_FORM_data1) */
+	.uleb128 0x27	/* (DW_AT_prototyped) */
+	.uleb128 0x19	/* (DW_FORM_flag_present) */
+	.uleb128 0x11	/* (DW_AT_low_pc) */
+	.uleb128 0x1	/* (DW_FORM_addr) */
+	.uleb128 0x12	/* (DW_AT_high_pc) */
+	.uleb128 0x7	/* (DW_FORM_data8) */
+	.uleb128 0x40	/* (DW_AT_frame_base) */
+	.uleb128 0x18	/* (DW_FORM_exprloc) */
+	.uleb128 0x7a	/* (DW_AT_call_all_calls) */
+	.uleb128 0x19	/* (DW_FORM_flag_present) */
+	.byte	0
+	.byte	0
+	.uleb128 0xd	/* (abbrev code) */
+	.uleb128 0x2e	/* (TAG: DW_TAG_subprogram) */
+	.byte	0	/* DW_children_no */
+	.uleb128 0x3f	/* (DW_AT_external) */
+	.uleb128 0x19	/* (DW_FORM_flag_present) */
+	.uleb128 0x3c	/* (DW_AT_declaration) */
+	.uleb128 0x19	/* (DW_FORM_flag_present) */
+	.uleb128 0x6e	/* (DW_AT_linkage_name) */
+	.uleb128 0xe	/* (DW_FORM_strp) */
+	.uleb128 0x3	/* (DW_AT_name) */
+	.uleb128 0xe	/* (DW_FORM_strp) */
+	.uleb128 0x3a	/* (DW_AT_decl_file) */
+	.uleb128 0xb	/* (DW_FORM_data1) */
+	.uleb128 0x3b	/* (DW_AT_decl_line) */
+	.uleb128 0x5	/* (DW_FORM_data2) */
+	.byte	0
+	.byte	0
+	.byte	0
+	.section	.debug_loclists,"",%progbits
+        .long   .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
+.Ldebug_list_header_start0:
+        .short  5                               # Version
+        .byte   8                               # Address size
+        .byte   0                               # Segment selector size
+        .long   3                               # Offset entry count
+.Lloclists_table_base0:
+        .long   .Ldebug_loc0-.Lloclists_table_base0
+        .long   .Ldebug_loc1-.Lloclists_table_base0
+        .long   .Ldebug_loc2-.Lloclists_table_base0
+.Ldebug_loc0:
+        .byte   4                               # DW_LLE_offset_pair
+        .uleb128 .Lfunc_begin0-.Lfunc_begin0    #   starting offset
+        .uleb128 .Lfunc_end0-.Lfunc_begin0      #   ending offset
+        .byte   6                               # Loc expr size
+        .byte   85                              # DW_OP_reg5
+        .byte   147                             # DW_OP_piece
+        .byte   8                               # 8
+        .byte   84                              # super-register DW_OP_reg4
+        .byte   147                             # DW_OP_piece
+        .byte   4                               # 4
+        .byte   0                               # DW_LLE_end_of_list
+.Ldebug_loc1:
+        .byte   4                               # DW_LLE_offset_pair
+        .uleb128 .Lfunc_begin0-.Lfunc_begin0    #   starting offset
+        .uleb128 .Lfunc_end0-.Lfunc_begin0      #   ending offset
+        .byte   6                               # Loc expr size
+        .byte   81                              # DW_OP_reg1
+        .byte   147                             # DW_OP_piece
+        .byte   8                               # 8
+        .byte   82                              # super-register DW_OP_reg2
+        .byte   147                             # DW_OP_piece
+        .byte   4                               # 4
+        .byte   0                               # DW_LLE_end_of_list
+.Ldebug_loc2:
+        .byte   4                               # DW_LLE_offset_pair
+        .uleb128 .Lfunc_begin0-.Lfunc_begin0    #   starting offset
+        .uleb128 .Lfunc_end0-.Lfunc_begin0      #   ending offset
+        .byte   6                               # Loc expr size
+        .byte   88                              # DW_OP_reg8
+        .byte   147                             # DW_OP_piece
+        .byte   8                               # 8
+        .byte   89                              # super-register DW_OP_reg9
+        .byte   147                             # DW_OP_piece
+        .byte   4                               # 4
+        .byte   0                               # DW_LLE_end_of_list
+.Ldebug_list_header_end0:
+	.section	.debug_aranges,"",%progbits
+	.4byte	0x3c	/* Length of Address Ranges Info */
+	.2byte	0x2	/* DWARF Version */
+	.4byte	.Ldebug_info0	/* Offset of Compilation Unit Info */
+	.byte	0x8	/* Size of Address */
+	.byte	0	/* Size of Segment Descriptor */
+	.2byte	0	/* Pad to 16 byte boundary */
+	.2byte	0
+	.8byte	0x1234	/* Address */
+	.8byte	0x4567	/* Length */
+	.8byte	0x1234	/* Address */
+	.8byte	0x5678	/* Length */
+	.8byte	0
+	.8byte	0
+	.section	.debug_rnglists,"",%progbits
+.Ldebug_ranges0:
+	.4byte	.Ldebug_ranges3-.Ldebug_ranges2	/* Length of Range Lists */
+.Ldebug_ranges2:
+	.2byte	0x5	/* DWARF Version */
+	.byte	0x8	/* Address Size */
+	.byte	0	/* Segment Size */
+	.4byte	0	/* Offset Entry Count */
+.LLRL2:
+	.byte	0x7	/* DW_RLE_start_length (*.LLRL2) */
+	.8byte	0x1234	/* Range begin address (*.LLRL2) */
+	.uleb128 .Letext0-.Ltext0	/* Range length (*.LLRL2) */
+	.byte	0x7	/* DW_RLE_start_length (*.LLRL2) */
+	.8byte	0x1234	/* Range begin address (*.LLRL2) */
+	.uleb128 .LFE1-.LFB1	/* Range length (*.LLRL2) */
+	.byte	0	/* DW_RLE_end_of_list (*.LLRL2) */
+.Ldebug_ranges3:
+	.section	.debug_line,"",%progbits
+.Ldebug_line0:
+	.4byte	.LELT0-.LSLT0	/* Length of Source Line Info */
+.LSLT0:
+	.2byte	0x5	/* DWARF Version */
+	.byte	0x8	/* Address Size */
+	.byte	0	/* Segment Size */
+	.4byte	.LELTP0-.LASLTP0	/* Prolog Length */
+.LASLTP0:
+	.byte	0x1	/* Minimum Instruction Length */
+	.byte	0x1	/* Maximum Operations Per Instruction */
+	.byte	0x1	/* Default is_stmt_start flag */
+	.byte	0xf6	/* Line Base Value (Special Opcodes) */
+	.byte	0xf2	/* Line Range Value (Special Opcodes) */
+	.byte	0xd	/* Special Opcode Base */
+	.byte	0	/* opcode: 0x1 has 0 args */
+	.byte	0x1	/* opcode: 0x2 has 1 arg */
+	.byte	0x1	/* opcode: 0x3 has 1 arg */
+	.byte	0x1	/* opcode: 0x4 has 1 arg */
+	.byte	0x1	/* opcode: 0x5 has 1 arg */
+	.byte	0	/* opcode: 0x6 has 0 args */
+	.byte	0	/* opcode: 0x7 has 0 args */
+	.byte	0	/* opcode: 0x8 has 0 args */
+	.byte	0x1	/* opcode: 0x9 has 1 arg */
+	.byte	0	/* opcode: 0xa has 0 args */
+	.byte	0	/* opcode: 0xb has 0 args */
+	.byte	0x1	/* opcode: 0xc has 1 arg */
+	.byte	0x1	/* Directory entry format count */
+	.uleb128 0x1	/* DW_LNCT_path */
+	.uleb128 0x1f	/* DW_FORM_line_strp */
+	.uleb128 0x3	/* Directories count */
+	.4byte	.LASF1	/* Directory Entry: 0: "" */
+	.4byte	.LASF25	/* Directory Entry: 0: "" */
+	.4byte	.LASF26	/* Directory Entry: 0: "/usr/include" */
+	.byte	0x2	/* File name entry format count */
+	.uleb128 0x1	/* DW_LNCT_path */
+	.uleb128 0x1f	/* DW_FORM_line_strp */
+	.uleb128 0x2	/* DW_LNCT_directory_index */
+	.uleb128 0xb	/* DW_FORM_data1 */
+	.uleb128 0x4	/* File names count */
+	.4byte	.LASF0	/* File Entry: 0: "main.c" */
+	.byte	0
+	.4byte	.LASF27	/* File Entry: 0: "main.c" */
+	.byte	0x1
+	.4byte	.LASF28	/* File Entry: 0: "unistd.h" */
+	.byte	0x2
+	.4byte	.LASF29	/* File Entry: 0: "getopt.h" */
+	.byte	0x2
+.LELTP0:
+	.byte	0	/* set address *.LM3 */
+	.uleb128 0x9
+	.byte	0x2
+	.8byte	0x1234
+	.byte	0x1c	/* line 6 */
+	.byte	0	/* set address *.LM4 */
+	.uleb128 0x9
+	.byte	0x2
+	.8byte	0x12346
+	.byte	0x1	/* copy line 6 */
+	.byte	0	/* set address *.LFE1 */
+	.uleb128 0x9
+	.byte	0x2
+	.8byte	0x1234
+	.byte	0	/* end sequence */
+	.uleb128 0x1
+	.byte	0x1
+	.byte	0	/* set address *.LM1 */
+	.uleb128 0x9
+	.byte	0x2
+	.8byte	0x1234
+	.byte	0x1b	/* line 5 */
+	.byte	0	/* set address *.LM2 */
+	.uleb128 0x9
+	.byte	0x2
+	.8byte	0x1234
+	.byte	0x1	/* copy line 5 */
+	.byte	0	/* set address *.Letext0 */
+	.uleb128 0x9
+	.byte	0x2
+	.8byte	0x1234
+	.byte	0	/* end sequence */
+	.uleb128 0x1
+	.byte	0x1
+.LELT0:
+	.section	.debug_str,"MS",%progbits,1
+.LASF4:
+	.asciz	"unsigned int"
+.LASF15:
+	.asciz	"optopt"
+.LASF22:
+	.asciz	"main"
+.LASF6:
+	.asciz	"signed char"
+.LASF16:
+	.asciz	"xvar"
+.LASF5:
+	.asciz	"long unsigned int"
+.LASF14:
+	.asciz	"opterr"
+.LASF21:
+	.asciz	"GNU C11 7.0.1 20170218 (experimental) -mtune=generic -march=x86-64 -gdwarf-5 -O2"
+.LASF2:
+	.asciz	"unsigned char"
+.LASF10:
+	.asciz	"char"
+.LASF13:
+	.asciz	"optind"
+.LASF8:
+	.asciz	"long int"
+.LASF19:
+	.asciz	"argc"
+.LASF3:
+	.asciz	"short unsigned int"
+.LASF17:
+	.asciz	"yvar"
+.LASF18:
+	.asciz	"pvar"
+.LASF11:
+	.asciz	"__environ"
+.LASF23:
+	.asciz	"func"
+.LASF12:
+	.asciz	"optarg"
+.LASF7:
+	.asciz	"short int"
+.LASF24:
+	.asciz	"alarm"
+.LASF9:
+	.asciz	"sizetype"
+.LASF20:
+	.asciz	"argv"
+	.section	.debug_line_str,"MS",%progbits,1
+.LASF1:
+	.asciz	""
+.LASF25:
+	.asciz	""
+.LASF29:
+	.asciz	"getopt.h"
+.LASF28:
+	.asciz	"unistd.h"
+.LASF0:
+	.asciz	"main.c"
+.LASF27:
+	.asciz	"main.c"
+.LASF26:
+	.asciz	"/usr/include"
+	.ident	"GCC: (GNU) 7.0.1 20170218 (experimental)"
+	.section	.note.GNU-stack,"",%progbits
diff --git a/binutils/testsuite/binutils-all/dw5-loclist.W b/binutils/testsuite/binutils-all/dw5-loclist.W
new file mode 100644
index 00000000000..79c220aa658
--- /dev/null
+++ b/binutils/testsuite/binutils-all/dw5-loclist.W
@@ -0,0 +1,27 @@
+Contents of the .debug_loclists section:
+
+Table at Offset 0x0
+  Length:          0x35
+  DWARF version:   5
+  Address size:    8
+  Segment size:    0
+  Offset entries:  3
+
+   Offset Entries starting at 0xc:
+    \[     0\] 0xc
+    \[     1\] 0x17
+    \[     2\] 0x22
+
+   Offset Entry 0
+    00000018 0000000000000000 0000000000000007  DW_OP_reg5 \(rdi\); DW_OP_piece: 8; DW_OP_reg4 \(rsi\); DW_OP_piece: 4
+    00000022 <End of list>
+
+   Offset Entry 1
+    00000023 0000000000000000 0000000000000007  DW_OP_reg1 \(rdx\); DW_OP_piece: 8; DW_OP_reg2 \(rcx\); DW_OP_piece: 4
+    0000002d <End of list>
+
+   Offset Entry 2
+    0000002e 0000000000000000 0000000000000007  DW_OP_reg8 \(r8\); DW_OP_piece: 8; DW_OP_reg9 \(r9\); DW_OP_piece: 4
+    00000038 <End of list>
+
+
diff --git a/binutils/testsuite/binutils-all/readelf.exp b/binutils/testsuite/binutils-all/readelf.exp
index 0f7a1f3b5a0..aaa50cf6c12 100644
--- a/binutils/testsuite/binutils-all/readelf.exp
+++ b/binutils/testsuite/binutils-all/readelf.exp
@@ -616,3 +616,22 @@ readelf_find_size $tempfile 2
 # Make sure that readelf can decode the contents.
 readelf_test -wi $tempfile dw5-op.W
 }
+
+# Check dwarf-5 support for .debug_loclists section dump.
+if {![binutils_assemble_flags $srcdir/$subdir/dw5-loclist.S tmpdir/dw5-loclist.o $hpux]} then {
+    unsupported "readelf -wo dw5-loclist (failed to assemble)"
+} else {
+
+# Download it.
+if ![is_remote host] {
+    set tempfile tmpdir/dw5-loclist.o
+} else {
+    set tempfile [remote_download host tmpdir/dw5-loclist.o]
+}
+
+# First, determine the size, so specific output matchers can be used.
+readelf_find_size $tempfile 2
+
+# Make sure that readelf can decode the contents.
+readelf_test -wo $tempfile dw5-loclist.W
+}
-- 
2.17.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Binutils support for dwarf-5 (location and range lists related)
  2022-05-31 11:06 [PATCH] Binutils support for dwarf-5 (location and range lists related) Kumar N, Bhuvanendra
@ 2022-06-03 10:46 ` Jan Beulich
  2022-06-08  9:53   ` Kumar N, Bhuvanendra
  0 siblings, 1 reply; 3+ messages in thread
From: Jan Beulich @ 2022-06-03 10:46 UTC (permalink / raw)
  To: Kumar N, Bhuvanendra; +Cc: George, Jini Susan, Natarajan, Kavitha, binutils

On 31.05.2022 13:06, Kumar N, Bhuvanendra via Binutils wrote:
> PATCH 1/2 inlined :
> 
> From 96ce32f762803a7d74ca30c3930f1679afc0100c Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> Date: Tue, 31 May 2022 14:07:17 +0530
> Subject: [PATCH] [PATCH 1/2] Binutils support for dwarf-5.
> 
> For clang compiled with dwarf-5, multiple issues are fixed which are
> related to .debug_rnglists and .debug_loclists sections and their offset
> address dump comprising single and multiple CU. There are 2 patches
> and this is patch 1/2.
> 
> Issues fixed in patch 1/2 are:
> Issue 1: .debug_rnglists section dump for single CU.
> Issue 2: location list offset address dump under DW_AT_location is corrected.
> Issue 3: range list offset address dump under DW_AT_ranges is corrected.

To be honest I don't think it's helpful to put these all in a single
patch. They're not directly related, and if I'm getting it right the
code changes are also independent of one another. This would also
allow to approve one part while another still needs clarification or
refinement.

And then it would also help if you could send multiple patches
properly as a series, rather than all in a single email.

> @@ -2788,7 +2794,15 @@ read_and_display_attr_value (unsigned long           attribute,
>         offset = base + uvalue * pointer_size;
> -       if (do_wide)
> +       if (form == DW_FORM_loclistx)
> +         printf (_("%c(index: 0x%s): %s"), delimiter,
> +                 dwarf_vmatoa ("x", uvalue),
> +                 dwarf_vmatoa ("x", debug_info_p->loc_offsets [uvalue]));

Aren't you risking an oob array access here? And isn't the ordering of
elements in loc_offset[] an implementation detail, i.e. using a value
fetched from debug info is effectively meaningless when used as an
index into the array?

> +       else if (form == DW_FORM_rnglistx)
> +         printf (_("%c(index: 0x%s): %s"), delimiter,
> +                 dwarf_vmatoa ("x", uvalue),
> +                 dwarf_vmatoa ("x", fetch_indexed_value (uvalue, rnglists, 0)));
> +       else if (do_wide)
>          /* We have already displayed the form name.  */
>          printf (_("%c(index: 0x%s): %s"), delimiter,
>               dwarf_vmatoa ("x", uvalue),

For both special cases, how come they don't respect do_wide?

> @@ -7976,9 +7990,6 @@ display_debug_rnglists_list (unsigned char * start,
>      case DW_RLE_base_addressx:
>        READ_ULEB (base_address, start, finish);
>        print_dwarf_vma (base_address, pointer_size);
> -       printf (_("(base address index) "));
> -       base_address = fetch_indexed_addr (base_address, pointer_size);
> -       print_dwarf_vma (base_address, pointer_size);
>        printf (_("(base address)\n"));
>        break;
>      case DW_RLE_startx_endx:
> @@ -7990,7 +8001,6 @@ display_debug_rnglists_list (unsigned char * start,
>      case DW_RLE_startx_length:
>        READ_ULEB (begin, start, finish);
>        READ_ULEB (length, start, finish);
> -       begin = fetch_indexed_addr (begin, pointer_size);
>        end = begin + length;
>        break;
>      case DW_RLE_offset_pair:

I don't see how these two hunks can be correct: You're removing the
indirection through .debug_addr. And at the same time you're keeping
similar indirection for DW_RLE_startx_endx. Aiui all x-suffixed items
are to be dealt with identically.

> @@ -8243,7 +8253,7 @@ display_debug_ranges (struct dwarf_section *section,
>           (unsigned long) offset, i);
>        continue;
>      }
> -      next = section_begin + offset;
> +      next = section_begin + offset + DEBUG_LOCLISTS_RNGLISTS_SECTION_HEADER_LEN;

I'm afraid I can't figure what 12 bytes you're meaning to skip here.
I also think that _if_ an adjustment was needed here, the preceding
if() likely would also need adjustment, perhaps by way of actually
adjusting offset.

Jan


^ permalink raw reply	[flat|nested] 3+ messages in thread

* RE: [PATCH] Binutils support for dwarf-5 (location and range lists related)
  2022-06-03 10:46 ` Jan Beulich
@ 2022-06-08  9:53   ` Kumar N, Bhuvanendra
  0 siblings, 0 replies; 3+ messages in thread
From: Kumar N, Bhuvanendra @ 2022-06-08  9:53 UTC (permalink / raw)
  To: Jan Beulich; +Cc: George, Jini Susan, Natarajan, Kavitha, binutils

[-- Attachment #1: Type: text/plain, Size: 13570 bytes --]

[AMD Official Use Only - General]

Hi,

Thanks for the review.

>To be honest I don't think it's helpful to put these all in a single patch. They're not directly related, and if I'm getting it right the code changes are also independent of one another. This would also allow to approve one part while another still needs clarification or refinement.

I am now sharing these issues as separate patches as you suggested and this is the first one which fixes issues related to .debug_rnglists section dump involving DW_RLE_base_addressx, DW_RLE_startx_endx, DW_RLE_startx_length items. DW_AT_rnglists_base is read and used. I will share the future patches which may be depending on these fixes.

Patch is inlined below and also attached with this email.

Main thing was while referring to fetch_indexed_addr() for these range items, proper entry in .debug_addr section was not accessed and its fixed now.

Sample output (Also I compared the binutils output with llvm-dwarfdump as a cross verification):

i. readelf output without fix: 
Contents of the .debug_rnglists section:

  Length:          0x1b
  DWARF version:   5
  Address size:    8
  Segment size:    0
  Offset entries:  1

   Offsets starting at 0xc:
    [     0] 0x4

    Offset   Begin    End
    00000004 0400000001000800 (base address)
    0000000d <End of list>

ii. with fix:
Contents of the .debug_rnglists section:

  Length:          0x1b
  DWARF version:   5
  Address size:    8
  Segment size:    0
  Offset entries:  1

   Offsets starting at 0xc:
    [     0] 0x4

    Offset   Begin    End
    00000004 0000000000000000 (base address index) 0000000000000000 (base address)
    00000006 0000000000000000 000000000000001d
    00000009 0000000000000030 0000000000000031
    0000000c 0000000000000040 0000000000000051
    0000000f 0000000000000000 0000000000000001
    00000012 <End of list>

Patch inlined:

From 994744e7a2560b12a842d6c5112c0d935befce05 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Wed, 8 Jun 2022 14:31:53 +0530
Subject: [PATCH] [PATCH] .debug_rnglists section dump for single CU (dwraf-5).

For clang compiled objects with dwarf-5, few issues are fixed related to
.debug_rnglists section dump involving DW_RLE_base_addressx, DW_RLE_startx_endx,
DW_RLE_startx_length items and read DW_AT_rnglists_base.
These fixes are applicable for single CU.

	* dwarf.h (struct debug_info): Add rnglists_base field.
	* dwarf.c (read_and_display_attr_value): Read attribute DW_AT_rnglists_base.
	(display_debug_rnglists_list): While handling DW_RLE_base_addressx,
  	DW_RLE_startx_endx, DW_RLE_startx_length items, pass the proper parameter
	value to fetch_indexed_addr(), i.e. fetch the proper entry in .debug_addr section.
	(display_debug_ranges): Add rnglists_base to the .debug_rnglists base address.
	(load_separate_debug_files): Load .debug_addr section, if exists.
---
 binutils/dwarf.c | 45 +++++++++++++++++++++++++++++++++------------
 binutils/dwarf.h |  1 +
 2 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index caa3ce48d00..2fa3fc77468 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -2824,7 +2824,12 @@ read_and_display_attr_value (unsigned long           attribute,
 		  dwarf_vmatoa ("x", debug_info_p->cu_offset));
 	  debug_info_p->loclists_base = uvalue;
 	  break;
-
+	case DW_AT_rnglists_base:
+	  if (debug_info_p->rnglists_base)
+	    warn (_("CU @ 0x%s has multiple rnglists_base values"),
+	          dwarf_vmatoa ("x", debug_info_p->cu_offset));
+	  debug_info_p->rnglists_base = uvalue;
+	  break;
 	case DW_AT_frame_base:
 	  have_frame_base = 1;
 	  /* Fall through.  */
@@ -3315,6 +3320,7 @@ read_and_display_attr_value (unsigned long           attribute,
       /* Fall through.  */
     case DW_AT_location:
     case DW_AT_loclists_base:
+    case DW_AT_rnglists_base:
     case DW_AT_string_length:
     case DW_AT_return_addr:
     case DW_AT_data_member_location:
@@ -3333,8 +3339,10 @@ read_and_display_attr_value (unsigned long           attribute,
       if ((dwarf_version < 4
 	   && (form == DW_FORM_data4 || form == DW_FORM_data8))
 	  || form == DW_FORM_sec_offset
-	  || form == DW_FORM_loclistx)
-	printf (_(" (location list)"));
+	  || form == DW_FORM_loclistx) {
+        if (attribute != DW_AT_rnglists_base)
+          printf (_(" (location list)"));
+      }
       /* Fall through.  */
     case DW_AT_allocated:
     case DW_AT_associated:
@@ -3821,6 +3829,7 @@ process_debug_info (struct dwarf_section * section,
 	  debug_information [unit].range_lists = NULL;
 	  debug_information [unit].max_range_lists= 0;
 	  debug_information [unit].num_range_lists = 0;
+	  debug_information [unit].rnglists_base = 0;
 	}
 
       if (!do_loc && dwarf_start_die == 0)
@@ -7945,9 +7954,15 @@ display_debug_rnglists_list (unsigned char * start,
 			     unsigned char * finish,
 			     unsigned int    pointer_size,
 			     dwarf_vma       offset,
-			     dwarf_vma       base_address)
+			     dwarf_vma       base_address,
+			     unsigned int    offset_size)
 {
   unsigned char *next = start;
+  unsigned int debug_addr_section_hdr_len;
+  if (offset_size == 4)
+    debug_addr_section_hdr_len = 8;
+  else
+    debug_addr_section_hdr_len = 16;
 
   while (1)
     {
@@ -7967,7 +7982,6 @@ display_debug_rnglists_list (unsigned char * start,
       print_dwarf_vma (off, 4);
 
       SAFE_BYTE_GET_AND_INC (rlet, start, 1, finish);
-
       switch (rlet)
 	{
 	case DW_RLE_end_of_list:
@@ -7977,20 +7991,24 @@ display_debug_rnglists_list (unsigned char * start,
 	  READ_ULEB (base_address, start, finish);
 	  print_dwarf_vma (base_address, pointer_size);
 	  printf (_("(base address index) "));
-	  base_address = fetch_indexed_addr (base_address, pointer_size);
+	  base_address = fetch_indexed_addr (base_address * pointer_size
+			                     + debug_addr_section_hdr_len, pointer_size);
 	  print_dwarf_vma (base_address, pointer_size);
 	  printf (_("(base address)\n"));
 	  break;
 	case DW_RLE_startx_endx:
 	  READ_ULEB (begin, start, finish);
 	  READ_ULEB (end, start, finish);
-	  begin = fetch_indexed_addr (begin, pointer_size);
-	  end   = fetch_indexed_addr (begin, pointer_size);
+	  begin = fetch_indexed_addr (begin * pointer_size
+			              + debug_addr_section_hdr_len, pointer_size);
+	  end   = fetch_indexed_addr (begin * pointer_size
+			              + debug_addr_section_hdr_len, pointer_size);
 	  break;
 	case DW_RLE_startx_length:
 	  READ_ULEB (begin, start, finish);
 	  READ_ULEB (length, start, finish);
-	  begin = fetch_indexed_addr (begin, pointer_size);
+	  begin = fetch_indexed_addr (begin * pointer_size
+			              + debug_addr_section_hdr_len, pointer_size);
 	  end = begin + length;
 	  break;
 	case DW_RLE_offset_pair:
@@ -8056,6 +8074,7 @@ display_debug_ranges (struct dwarf_section *section,
   /* Initialize it due to a false compiler warning.  */
   unsigned char         address_size = 0;
   dwarf_vma             last_offset = 0;
+  unsigned int          offset_size = 0;
 
   if (bytes == 0)
     {
@@ -8069,7 +8088,7 @@ display_debug_ranges (struct dwarf_section *section,
     {
       dwarf_vma initial_length;
       unsigned char segment_selector_size;
-      unsigned int offset_size, offset_entry_count;
+      unsigned int offset_entry_count;
       unsigned short version;
 
       /* Get and check the length of the block.  */
@@ -8243,7 +8262,7 @@ display_debug_ranges (struct dwarf_section *section,
 		(unsigned long) offset, i);
 	  continue;
 	}
-      next = section_begin + offset;
+      next = section_begin + offset + debug_info_p->rnglists_base;
 
       /* If multiple DWARF entities reference the same range then we will
          have multiple entries in the `range_entries' list for the same
@@ -8275,7 +8294,7 @@ display_debug_ranges (struct dwarf_section *section,
 
       if (is_rnglists)
 	display_debug_rnglists_list
-	  (start, finish, pointer_size, offset, base_address);
+	  (start, finish, pointer_size, offset, base_address, offset_size);
       else
 	display_debug_ranges_list
 	  (start, finish, pointer_size, offset, base_address);
@@ -11889,6 +11908,8 @@ load_separate_debug_files (void * file, const char * filename)
       && load_debug_section (abbrev, file)
       && load_debug_section (info, file))
     {
+      /* Load .debug_addr section, if exists.  */
+      load_debug_section (debug_addr, file);
       free_dwo_info ();
 
       if (process_debug_info (& debug_displays[info].section, file, abbrev,
diff --git a/binutils/dwarf.h b/binutils/dwarf.h
index 040e674c6ce..8a89c08e7c2 100644
--- a/binutils/dwarf.h
+++ b/binutils/dwarf.h
@@ -192,6 +192,7 @@ typedef struct
   dwarf_vma *    range_lists;
   unsigned int   num_range_lists;
   unsigned int   max_range_lists;
+  dwarf_vma      rnglists_base;
 }
 debug_info;
 
-- 
2.17.1


-----Original Message-----
From: Jan Beulich <jbeulich@suse.com> 
Sent: Friday, June 3, 2022 4:16 PM
To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
Cc: George, Jini Susan <JiniSusan.George@amd.com>; Natarajan, Kavitha <Kavitha.Natarajan@amd.com>; binutils@sourceware.org
Subject: Re: [PATCH] Binutils support for dwarf-5 (location and range lists related)

[CAUTION: External Email]

On 31.05.2022 13:06, Kumar N, Bhuvanendra via Binutils wrote:
> PATCH 1/2 inlined :
>
> From 96ce32f762803a7d74ca30c3930f1679afc0100c Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= 
> Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> Date: Tue, 31 May 2022 14:07:17 +0530
> Subject: [PATCH] [PATCH 1/2] Binutils support for dwarf-5.
>
> For clang compiled with dwarf-5, multiple issues are fixed which are 
> related to .debug_rnglists and .debug_loclists sections and their 
> offset address dump comprising single and multiple CU. There are 2 
> patches and this is patch 1/2.
>
> Issues fixed in patch 1/2 are:
> Issue 1: .debug_rnglists section dump for single CU.
> Issue 2: location list offset address dump under DW_AT_location is corrected.
> Issue 3: range list offset address dump under DW_AT_ranges is corrected.

To be honest I don't think it's helpful to put these all in a single patch. They're not directly related, and if I'm getting it right the code changes are also independent of one another. This would also allow to approve one part while another still needs clarification or refinement.

And then it would also help if you could send multiple patches properly as a series, rather than all in a single email.

> @@ -2788,7 +2794,15 @@ read_and_display_attr_value (unsigned long           attribute,
>         offset = base + uvalue * pointer_size;
> -       if (do_wide)
> +       if (form == DW_FORM_loclistx)
> +         printf (_("%c(index: 0x%s): %s"), delimiter,
> +                 dwarf_vmatoa ("x", uvalue),
> +                 dwarf_vmatoa ("x", debug_info_p->loc_offsets 
> + [uvalue]));

Aren't you risking an oob array access here? And isn't the ordering of elements in loc_offset[] an implementation detail, i.e. using a value fetched from debug info is effectively meaningless when used as an index into the array?

> +       else if (form == DW_FORM_rnglistx)
> +         printf (_("%c(index: 0x%s): %s"), delimiter,
> +                 dwarf_vmatoa ("x", uvalue),
> +                 dwarf_vmatoa ("x", fetch_indexed_value (uvalue, rnglists, 0)));
> +       else if (do_wide)
>          /* We have already displayed the form name.  */
>          printf (_("%c(index: 0x%s): %s"), delimiter,
>               dwarf_vmatoa ("x", uvalue),

For both special cases, how come they don't respect do_wide?

> @@ -7976,9 +7990,6 @@ display_debug_rnglists_list (unsigned char * start,
>      case DW_RLE_base_addressx:
>        READ_ULEB (base_address, start, finish);
>        print_dwarf_vma (base_address, pointer_size);
> -       printf (_("(base address index) "));
> -       base_address = fetch_indexed_addr (base_address, pointer_size);
> -       print_dwarf_vma (base_address, pointer_size);
>        printf (_("(base address)\n"));
>        break;
>      case DW_RLE_startx_endx:
> @@ -7990,7 +8001,6 @@ display_debug_rnglists_list (unsigned char * start,
>      case DW_RLE_startx_length:
>        READ_ULEB (begin, start, finish);
>        READ_ULEB (length, start, finish);
> -       begin = fetch_indexed_addr (begin, pointer_size);
>        end = begin + length;
>        break;
>      case DW_RLE_offset_pair:

I don't see how these two hunks can be correct: You're removing the indirection through .debug_addr. And at the same time you're keeping similar indirection for DW_RLE_startx_endx. Aiui all x-suffixed items are to be dealt with identically.

> @@ -8243,7 +8253,7 @@ display_debug_ranges (struct dwarf_section *section,
>           (unsigned long) offset, i);
>        continue;
>      }
> -      next = section_begin + offset;
> +      next = section_begin + offset + 
> + DEBUG_LOCLISTS_RNGLISTS_SECTION_HEADER_LEN;

I'm afraid I can't figure what 12 bytes you're meaning to skip here.
I also think that _if_ an adjustment was needed here, the preceding
if() likely would also need adjustment, perhaps by way of actually adjusting offset.

Jan

[-- Attachment #2: 0001-PATCH-.debug_rnglists-section-dump-for-single-CU-dwr.patch --]
[-- Type: application/octet-stream, Size: 7034 bytes --]

From 994744e7a2560b12a842d6c5112c0d935befce05 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Wed, 8 Jun 2022 14:31:53 +0530
Subject: [PATCH] [PATCH] .debug_rnglists section dump for single CU (dwraf-5).

For clang compiled objects with dwarf-5, few issues are fixed related to
.debug_rnglists section dump involving DW_RLE_base_addressx, DW_RLE_startx_endx,
DW_RLE_startx_length items and read DW_AT_rnglists_base.
These fixes are applicable for single CU.

	* dwarf.h (struct debug_info): Add rnglists_base field.
	* dwarf.c (read_and_display_attr_value): Read attribute DW_AT_rnglists_base.
	(display_debug_rnglists_list): While handling DW_RLE_base_addressx,
  	DW_RLE_startx_endx, DW_RLE_startx_length items, pass the proper parameter
	value to fetch_indexed_addr(), i.e. fetch the proper entry in .debug_addr section.
	(display_debug_ranges): Add rnglists_base to the .debug_rnglists base address.
	(load_separate_debug_files): Load .debug_addr section, if exists.
---
 binutils/dwarf.c | 45 +++++++++++++++++++++++++++++++++------------
 binutils/dwarf.h |  1 +
 2 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index caa3ce48d00..2fa3fc77468 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -2824,7 +2824,12 @@ read_and_display_attr_value (unsigned long           attribute,
 		  dwarf_vmatoa ("x", debug_info_p->cu_offset));
 	  debug_info_p->loclists_base = uvalue;
 	  break;
-
+	case DW_AT_rnglists_base:
+	  if (debug_info_p->rnglists_base)
+	    warn (_("CU @ 0x%s has multiple rnglists_base values"),
+	          dwarf_vmatoa ("x", debug_info_p->cu_offset));
+	  debug_info_p->rnglists_base = uvalue;
+	  break;
 	case DW_AT_frame_base:
 	  have_frame_base = 1;
 	  /* Fall through.  */
@@ -3315,6 +3320,7 @@ read_and_display_attr_value (unsigned long           attribute,
       /* Fall through.  */
     case DW_AT_location:
     case DW_AT_loclists_base:
+    case DW_AT_rnglists_base:
     case DW_AT_string_length:
     case DW_AT_return_addr:
     case DW_AT_data_member_location:
@@ -3333,8 +3339,10 @@ read_and_display_attr_value (unsigned long           attribute,
       if ((dwarf_version < 4
 	   && (form == DW_FORM_data4 || form == DW_FORM_data8))
 	  || form == DW_FORM_sec_offset
-	  || form == DW_FORM_loclistx)
-	printf (_(" (location list)"));
+	  || form == DW_FORM_loclistx) {
+        if (attribute != DW_AT_rnglists_base)
+          printf (_(" (location list)"));
+      }
       /* Fall through.  */
     case DW_AT_allocated:
     case DW_AT_associated:
@@ -3821,6 +3829,7 @@ process_debug_info (struct dwarf_section * section,
 	  debug_information [unit].range_lists = NULL;
 	  debug_information [unit].max_range_lists= 0;
 	  debug_information [unit].num_range_lists = 0;
+	  debug_information [unit].rnglists_base = 0;
 	}
 
       if (!do_loc && dwarf_start_die == 0)
@@ -7945,9 +7954,15 @@ display_debug_rnglists_list (unsigned char * start,
 			     unsigned char * finish,
 			     unsigned int    pointer_size,
 			     dwarf_vma       offset,
-			     dwarf_vma       base_address)
+			     dwarf_vma       base_address,
+			     unsigned int    offset_size)
 {
   unsigned char *next = start;
+  unsigned int debug_addr_section_hdr_len;
+  if (offset_size == 4)
+    debug_addr_section_hdr_len = 8;
+  else
+    debug_addr_section_hdr_len = 16;
 
   while (1)
     {
@@ -7967,7 +7982,6 @@ display_debug_rnglists_list (unsigned char * start,
       print_dwarf_vma (off, 4);
 
       SAFE_BYTE_GET_AND_INC (rlet, start, 1, finish);
-
       switch (rlet)
 	{
 	case DW_RLE_end_of_list:
@@ -7977,20 +7991,24 @@ display_debug_rnglists_list (unsigned char * start,
 	  READ_ULEB (base_address, start, finish);
 	  print_dwarf_vma (base_address, pointer_size);
 	  printf (_("(base address index) "));
-	  base_address = fetch_indexed_addr (base_address, pointer_size);
+	  base_address = fetch_indexed_addr (base_address * pointer_size
+			                     + debug_addr_section_hdr_len, pointer_size);
 	  print_dwarf_vma (base_address, pointer_size);
 	  printf (_("(base address)\n"));
 	  break;
 	case DW_RLE_startx_endx:
 	  READ_ULEB (begin, start, finish);
 	  READ_ULEB (end, start, finish);
-	  begin = fetch_indexed_addr (begin, pointer_size);
-	  end   = fetch_indexed_addr (begin, pointer_size);
+	  begin = fetch_indexed_addr (begin * pointer_size
+			              + debug_addr_section_hdr_len, pointer_size);
+	  end   = fetch_indexed_addr (begin * pointer_size
+			              + debug_addr_section_hdr_len, pointer_size);
 	  break;
 	case DW_RLE_startx_length:
 	  READ_ULEB (begin, start, finish);
 	  READ_ULEB (length, start, finish);
-	  begin = fetch_indexed_addr (begin, pointer_size);
+	  begin = fetch_indexed_addr (begin * pointer_size
+			              + debug_addr_section_hdr_len, pointer_size);
 	  end = begin + length;
 	  break;
 	case DW_RLE_offset_pair:
@@ -8056,6 +8074,7 @@ display_debug_ranges (struct dwarf_section *section,
   /* Initialize it due to a false compiler warning.  */
   unsigned char         address_size = 0;
   dwarf_vma             last_offset = 0;
+  unsigned int          offset_size = 0;
 
   if (bytes == 0)
     {
@@ -8069,7 +8088,7 @@ display_debug_ranges (struct dwarf_section *section,
     {
       dwarf_vma initial_length;
       unsigned char segment_selector_size;
-      unsigned int offset_size, offset_entry_count;
+      unsigned int offset_entry_count;
       unsigned short version;
 
       /* Get and check the length of the block.  */
@@ -8243,7 +8262,7 @@ display_debug_ranges (struct dwarf_section *section,
 		(unsigned long) offset, i);
 	  continue;
 	}
-      next = section_begin + offset;
+      next = section_begin + offset + debug_info_p->rnglists_base;
 
       /* If multiple DWARF entities reference the same range then we will
          have multiple entries in the `range_entries' list for the same
@@ -8275,7 +8294,7 @@ display_debug_ranges (struct dwarf_section *section,
 
       if (is_rnglists)
 	display_debug_rnglists_list
-	  (start, finish, pointer_size, offset, base_address);
+	  (start, finish, pointer_size, offset, base_address, offset_size);
       else
 	display_debug_ranges_list
 	  (start, finish, pointer_size, offset, base_address);
@@ -11889,6 +11908,8 @@ load_separate_debug_files (void * file, const char * filename)
       && load_debug_section (abbrev, file)
       && load_debug_section (info, file))
     {
+      /* Load .debug_addr section, if exists.  */
+      load_debug_section (debug_addr, file);
       free_dwo_info ();
 
       if (process_debug_info (& debug_displays[info].section, file, abbrev,
diff --git a/binutils/dwarf.h b/binutils/dwarf.h
index 040e674c6ce..8a89c08e7c2 100644
--- a/binutils/dwarf.h
+++ b/binutils/dwarf.h
@@ -192,6 +192,7 @@ typedef struct
   dwarf_vma *    range_lists;
   unsigned int   num_range_lists;
   unsigned int   max_range_lists;
+  dwarf_vma      rnglists_base;
 }
 debug_info;
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-06-08  9:53 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-31 11:06 [PATCH] Binutils support for dwarf-5 (location and range lists related) Kumar N, Bhuvanendra
2022-06-03 10:46 ` Jan Beulich
2022-06-08  9:53   ` Kumar N, Bhuvanendra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).