public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Fix range lists issues (dwarf-5)
@ 2022-06-27 20:56 Kumar N, Bhuvanendra
  2022-06-29 11:17 ` Nick Clifton
  0 siblings, 1 reply; 5+ messages in thread
From: Kumar N, Bhuvanendra @ 2022-06-27 20:56 UTC (permalink / raw)
  To: binutils; +Cc: George, Jini Susan, Natarajan, Kavitha

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

[Public]

Hi,

As part of few dwarf-5 fixes planned to be sent one by one, I am requesting review for the next patch in this series. Patch is inlined below, also attached here.

For GCC and/or clang compiled objects with dwarf-5, following issues related to range lists dump are fixed.


  1.  range lists offset address dump under DW_AT_ranges is corrected, where DW_FORM_rnglistx form is used. While dumping the range lists offset, the address dumped is wrong where it was referring to .debug_addr instead of .debug_rnglists (fix applicable to clang only).



Test scenario:

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

. . .



  1.  .debug_rnglists section dump for multiple CU is fixed. For each CU, range lists header followed by range lists is dumped now (fix applicable to both GCC and clang).

Before fix (for GCC compiled object) :
Contents of the .debug_rnglists section:

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

    Offset   Begin    End
    0000000c 00000000004006ff 000000000040073e
    00000016 00000000004009b2 00000000004009b9
    00000020 <End of list>
    0000002d 000000000040073e 000000000040077d
    00000037 00000000004009b9 00000000004009c0
    00000041 <End of list>
    0000004e 000000000040077d 00000000004007bc
    00000058 00000000004009c0 00000000004009c7
    00000062 <End of list>
. . .

After fix (for GCC compiled object) :
Contents of the .debug_rnglists section:

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

    Offset   Begin    End
    0000000c 00000000004006ff 000000000040073e
    00000016 00000000004009b2 00000000004009b9
    00000020 <End of list>

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

    Offset   Begin    End
    0000002d 000000000040073e 000000000040077d
    00000037 00000000004009b9 00000000004009c0
    00000041 <End of list>

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

    Offset   Begin    End
    0000004e 000000000040077d 00000000004007bc
    00000058 00000000004009c0 00000000004009c7
    00000062 <End of list>
. . .

PATCH inlined:

From 0ffceff80252797a8d7619b19a3b1418954dac4b 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, 28 Jun 2022 00:50:14 +0530
Subject: [PATCH] [PATCH] Fix range lists issues (dwarf-5)

For GCC and/or clang compiled objects with dwarf-5, following issues
related to range lists dump are fixed.
1. range lists offset address dump under DW_AT_ranges is corrected,
where DW_FORM_rnglistx is used. While dumping the range lists offset,
the address dumped is wrong where it was referring to .debug_addr
instead of .debug_rnglists
2. .debug_rnglists section dump for multiple CU is fixed.
For each CU, range lists header followed by range lists is dumped now.

      * dwarf.c (fetch_indexed_value): Use base_address to access the
      section offset for rnglists also.
      (read_and_display_attr_value): Fix support for DW_FORM_rnglistx form.
      Read attribute DW_AT_rnglists_base which can come before or after
      DW_AT_ranges attribute.
      Update range_lists array for forms DW_FORM_rnglistx(clang) or
      DW_FORM_sec_offset(GCC).
      (display_debug_rnglists_list): Add new parameter called start_header
      and pass on the starting address of the next CU's range lists header.
      (display_debug_rnglists_header): New function to dump range lists
      header for each CU.
      (display_debug_ranges): Dump the range lists header before printing
      the range list entries for each CU.
      Capture the starting address of the next CU's range lists header.
---
binutils/dwarf.c | 132 ++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 124 insertions(+), 8 deletions(-)

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index bcabb61b871..2dab3ee3d96 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -811,7 +811,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;
@@ -877,6 +877,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
@@ -2407,6 +2408,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))
     {
@@ -2762,6 +2764,10 @@ read_and_display_attr_value (unsigned long           attribute,
           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", debug_info_p->range_lists [uvalue]));
         else
           printf (_("%c(index: 0x%s): %s"), delimiter,
                   dwarf_vmatoa ("x", uvalue),
@@ -2771,6 +2777,10 @@ read_and_display_attr_value (unsigned long           attribute,
           printf (_("%c(addr_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(addr_index: 0x%s): %s"), delimiter,
+                   dwarf_vmatoa ("x", uvalue),
+                   dwarf_vmatoa ("x", debug_info_p->range_lists [uvalue]));
         else
           printf (_("%c(addr_index: 0x%s): %s"), delimiter,
                   dwarf_vmatoa ("x", uvalue),
@@ -2909,6 +2919,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
@@ -2917,6 +2945,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)
          {
@@ -2927,10 +2956,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;
@@ -4043,6 +4077,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,
@@ -7947,7 +7983,8 @@ display_debug_rnglists_list (unsigned char * start,
                     unsigned int    pointer_size,
                     dwarf_vma       offset,
                     dwarf_vma       base_address,
-                     unsigned int    offset_size)
+                     unsigned int    offset_size,
+                     unsigned char ** start_header)
{
   unsigned char *next = start;
   unsigned int debug_addr_section_hdr_len;
@@ -8029,8 +8066,11 @@ display_debug_rnglists_list (unsigned char * start,
       break;
     }
-      if (rlet == DW_RLE_end_of_list)
+      if (rlet == DW_RLE_end_of_list) {
+     /* Pass on the starting address of the next CU's range lists header.  */
+     *start_header = start;
     break;
+      }
       if (rlet == DW_RLE_base_address || rlet == DW_RLE_base_addressx)
     continue;
@@ -8053,6 +8093,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)
@@ -8070,6 +8173,7 @@ display_debug_ranges (struct dwarf_section *section,
   unsigned char         address_size = 0;
   dwarf_vma             last_offset = 0;
   unsigned int          offset_size = 0;
+  unsigned char *       start_header = NULL;
   if (bytes == 0)
     {
@@ -8230,7 +8334,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;
@@ -8243,6 +8348,15 @@ display_debug_ranges (struct dwarf_section *section,
       offset = range_entry->ranges_offset;
       base_address = debug_info_p->base_address;
+      /* Print the range lists header before printing the range list entries for
+         each CU.  */
+      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)
     {
@@ -8258,7 +8372,7 @@ display_debug_ranges (struct dwarf_section *section,
       continue;
     }
-      next = section_begin + offset + debug_info_p->rnglists_base;
+      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
@@ -8289,8 +8403,10 @@ display_debug_ranges (struct dwarf_section *section,
       last_start = next;
       if (is_rnglists)
+        /* Print the current CU's range lists, also capture the starting address
+           of the next CU's range lists header.  */
     display_debug_rnglists_list
-       (start, finish, pointer_size, offset, base_address, offset_size);
+       (start, finish, pointer_size, offset, base_address, offset_size, &start_header);
       else
     display_debug_ranges_list
       (start, finish, pointer_size, offset, base_address);
--
2.17.1




[-- Attachment #2: 0001-PATCH-Fix-range-lists-issues-dwarf-5.patch --]
[-- Type: application/octet-stream, Size: 11795 bytes --]

From 0ffceff80252797a8d7619b19a3b1418954dac4b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Tue, 28 Jun 2022 00:50:14 +0530
Subject: [PATCH] [PATCH] Fix range lists issues (dwarf-5)

For GCC and/or clang compiled objects with dwarf-5, following issues
related to range lists dump are fixed.
1. range lists offset address dump under DW_AT_ranges is corrected,
where DW_FORM_rnglistx is used. While dumping the range lists offset,
the address dumped is wrong where it was referring to .debug_addr
instead of .debug_rnglists
2. .debug_rnglists section dump for multiple CU is fixed.
For each CU, range lists header followed by range lists is dumped now.

	* dwarf.c (fetch_indexed_value): Use base_address to access the
	section offset for rnglists also.
	(read_and_display_attr_value): Fix support for DW_FORM_rnglistx form.
	Read attribute DW_AT_rnglists_base which can come before or after
	DW_AT_ranges attribute.
	Update range_lists array for forms DW_FORM_rnglistx(clang) or
	DW_FORM_sec_offset(GCC).
	(display_debug_rnglists_list): Add new parameter called start_header
	and pass on the starting address of the next CU's range lists header.
	(display_debug_rnglists_header): New function to dump range lists
	header for each CU.
	(display_debug_ranges): Dump the range lists header before printing
	the range list entries for each CU.
	Capture the starting address of the next CU's range lists header.
---
 binutils/dwarf.c | 132 ++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 124 insertions(+), 8 deletions(-)

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index bcabb61b871..2dab3ee3d96 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -811,7 +811,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;
@@ -877,6 +877,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
@@ -2407,6 +2408,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))
     {
@@ -2762,6 +2764,10 @@ read_and_display_attr_value (unsigned long           attribute,
 	      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", debug_info_p->range_lists [uvalue]));
 	    else
 	      printf (_("%c(index: 0x%s): %s"), delimiter,
 	              dwarf_vmatoa ("x", uvalue),
@@ -2771,6 +2777,10 @@ read_and_display_attr_value (unsigned long           attribute,
 	      printf (_("%c(addr_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(addr_index: 0x%s): %s"), delimiter,
+	              dwarf_vmatoa ("x", uvalue),
+	              dwarf_vmatoa ("x", debug_info_p->range_lists [uvalue]));
 	    else
 	      printf (_("%c(addr_index: 0x%s): %s"), delimiter,
 	              dwarf_vmatoa ("x", uvalue),
@@ -2909,6 +2919,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
@@ -2917,6 +2945,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)
 		{
@@ -2927,10 +2956,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;
@@ -4043,6 +4077,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,
@@ -7947,7 +7983,8 @@ display_debug_rnglists_list (unsigned char * start,
 			     unsigned int    pointer_size,
 			     dwarf_vma       offset,
 			     dwarf_vma       base_address,
-			     unsigned int    offset_size)
+			     unsigned int    offset_size,
+			     unsigned char ** start_header)
 {
   unsigned char *next = start;
   unsigned int debug_addr_section_hdr_len;
@@ -8029,8 +8066,11 @@ display_debug_rnglists_list (unsigned char * start,
 	  break;
 	}
 
-      if (rlet == DW_RLE_end_of_list)
+      if (rlet == DW_RLE_end_of_list) {
+	/* Pass on the starting address of the next CU's range lists header.  */
+	*start_header = start;
 	break;
+      }
       if (rlet == DW_RLE_base_address || rlet == DW_RLE_base_addressx)
 	continue;
 
@@ -8053,6 +8093,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)
@@ -8070,6 +8173,7 @@ display_debug_ranges (struct dwarf_section *section,
   unsigned char         address_size = 0;
   dwarf_vma             last_offset = 0;
   unsigned int          offset_size = 0;
+  unsigned char *       start_header = NULL;
 
   if (bytes == 0)
     {
@@ -8230,7 +8334,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;
@@ -8243,6 +8348,15 @@ display_debug_ranges (struct dwarf_section *section,
       offset = range_entry->ranges_offset;
       base_address = debug_info_p->base_address;
 
+      /* Print the range lists header before printing the range list entries for
+         each CU.  */
+      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)
 	{
@@ -8258,7 +8372,7 @@ display_debug_ranges (struct dwarf_section *section,
 	  continue;
 	}
 
-      next = section_begin + offset + debug_info_p->rnglists_base;
+      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
@@ -8289,8 +8403,10 @@ display_debug_ranges (struct dwarf_section *section,
       last_start = next;
 
       if (is_rnglists)
+        /* Print the current CU's range lists, also capture the starting address
+           of the next CU's range lists header.  */
 	display_debug_rnglists_list
-	  (start, finish, pointer_size, offset, base_address, offset_size);
+	  (start, finish, pointer_size, offset, base_address, offset_size, &start_header);
       else
 	display_debug_ranges_list
 	  (start, finish, pointer_size, offset, base_address);
-- 
2.17.1


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

* Re: [PATCH] Fix range lists issues (dwarf-5)
  2022-06-27 20:56 [PATCH] Fix range lists issues (dwarf-5) Kumar N, Bhuvanendra
@ 2022-06-29 11:17 ` Nick Clifton
  2022-06-30 12:50   ` Kumar N, Bhuvanendra
  0 siblings, 1 reply; 5+ messages in thread
From: Nick Clifton @ 2022-06-29 11:17 UTC (permalink / raw)
  To: Kumar N, Bhuvanendra, binutils; +Cc: George, Jini Susan, Natarajan, Kavitha

Hi Kumar,

> As part of few dwarf-5 fixes planned to be sent one by one, I am requesting review for the next patch in this series. Patch is inlined below, also attached here.

Sorry - my own changes in this space overlap yours.  Would you
mind refactoring your patch and then resubmitting it ?

Cheers
   Nick


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

* RE: [PATCH] Fix range lists issues (dwarf-5)
  2022-06-29 11:17 ` Nick Clifton
@ 2022-06-30 12:50   ` Kumar N, Bhuvanendra
  2022-07-01 13:23     ` Nick Clifton
  0 siblings, 1 reply; 5+ messages in thread
From: Kumar N, Bhuvanendra @ 2022-06-30 12:50 UTC (permalink / raw)
  To: Nick Clifton, binutils; +Cc: George, Jini Susan, Natarajan, Kavitha

[Public]

Hi,

I went thru your latest changes and they are fine and handle the cases I was trying to push, i.e.

1. proper and correct rangelist offset address dump against DW_AT_ranges
2. in case of multiple CU's, emitting rangelist header for each CU

I was trying to use range_lists array(for DW_FORM_rnglistx) just like loc_offsets(for DW_FORM_loclistx), but fetching it from fetch_indexed_value() is the right thing while printing its value for DW_FORM_rnglistx case, because we would have read DW_AT_rnglists_base already irrespective of DW_AT_rnglists_base comes after or before DW_AT_ranges. All the code changes are fine.

I have 2 minor things to say,

1. in the cases where we fetch values from fetch_indexed_addr(), should we use "addr_index" or "index" itself is fine? because we are fetching it from .debug_addr and emitting. I meant for DW_FORM_loclistx and DW_FORM_rnglistx using index is fine, for else part should we use addr_index or index? 

Before fix:     <24>   DW_AT_low_pc      : (addr_index: 0x0): 201e40
After fix:     <24>   DW_AT_low_pc      : (index: 0x0): 201e40

2. in the new function(display_debug_rnglists) added, newline character printing is missing

$ git diff
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index b6746a21274..ec6c3ea9900 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -8203,6 +8203,7 @@ display_debug_rnglists (struct dwarf_section *section)
        putchar ('\n');
     }

+  putchar ('\n');
   return 1;
 }

-----Original Message-----
From: Nick Clifton <nickc@redhat.com> 
Sent: Wednesday, June 29, 2022 4:48 PM
To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>; binutils@sourceware.org
Cc: George, Jini Susan <JiniSusan.George@amd.com>; Natarajan, Kavitha <Kavitha.Natarajan@amd.com>
Subject: Re: [PATCH] Fix range lists issues (dwarf-5)

[CAUTION: External Email]

Hi Kumar,

> As part of few dwarf-5 fixes planned to be sent one by one, I am requesting review for the next patch in this series. Patch is inlined below, also attached here.

Sorry - my own changes in this space overlap yours.  Would you mind refactoring your patch and then resubmitting it ?

Cheers
   Nick

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

* Re: [PATCH] Fix range lists issues (dwarf-5)
  2022-06-30 12:50   ` Kumar N, Bhuvanendra
@ 2022-07-01 13:23     ` Nick Clifton
  2022-07-01 14:29       ` Kumar N, Bhuvanendra
  0 siblings, 1 reply; 5+ messages in thread
From: Nick Clifton @ 2022-07-01 13:23 UTC (permalink / raw)
  To: Kumar N, Bhuvanendra, binutils; +Cc: George, Jini Susan, Natarajan, Kavitha

Hi Kumar,

> 1. in the cases where we fetch values from fetch_indexed_addr(), should we use "addr_index" or "index" itself is fine? because we are fetching it from .debug_addr and emitting. I meant for DW_FORM_loclistx and DW_FORM_rnglistx using index is fine, for else part should we use addr_index or index?
> 
> Before fix:     <24>   DW_AT_low_pc      : (addr_index: 0x0): 201e40
> After fix:     <24>   DW_AT_low_pc      : (index: 0x0): 201e40

This is debatable.  All of the forms are indices (indexes ?) of some kind
so using the generic term "index" seems appropriate to me.  If we instead
use "addr_index" for address indices then shouldn't we use "loclist_index"
and "rnglist_index" for the others ?

Also in the current 2.38 binutils release (and earlier releases) we use
"addr_index" by default, but in wide mode we use just "index", which made
no sense to me.

So unless you have a strong objection I would like to leave the code in
its current state.


> 2. in the new function(display_debug_rnglists) added, newline character printing is missing

Thanks - added.

Cheers
   Nick


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

* RE: [PATCH] Fix range lists issues (dwarf-5)
  2022-07-01 13:23     ` Nick Clifton
@ 2022-07-01 14:29       ` Kumar N, Bhuvanendra
  0 siblings, 0 replies; 5+ messages in thread
From: Kumar N, Bhuvanendra @ 2022-07-01 14:29 UTC (permalink / raw)
  To: Nick Clifton, binutils; +Cc: George, Jini Susan, Natarajan, Kavitha

[AMD Official Use Only - General]

> So unless you have a strong objection I would like to leave the code in its current state.

Sure, its fine for me as well. thanks

Regards,
bhuvan

-----Original Message-----
From: Nick Clifton <nickc@redhat.com> 
Sent: Friday, July 1, 2022 6:53 PM
To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>; binutils@sourceware.org
Cc: George, Jini Susan <JiniSusan.George@amd.com>; Natarajan, Kavitha <Kavitha.Natarajan@amd.com>
Subject: Re: [PATCH] Fix range lists issues (dwarf-5)

[CAUTION: External Email]

Hi Kumar,

> 1. in the cases where we fetch values from fetch_indexed_addr(), should we use "addr_index" or "index" itself is fine? because we are fetching it from .debug_addr and emitting. I meant for DW_FORM_loclistx and DW_FORM_rnglistx using index is fine, for else part should we use addr_index or index?
>
> Before fix:     <24>   DW_AT_low_pc      : (addr_index: 0x0): 201e40
> After fix:     <24>   DW_AT_low_pc      : (index: 0x0): 201e40

This is debatable.  All of the forms are indices (indexes ?) of some kind so using the generic term "index" seems appropriate to me.  If we instead use "addr_index" for address indices then shouldn't we use "loclist_index"
and "rnglist_index" for the others ?

Also in the current 2.38 binutils release (and earlier releases) we use "addr_index" by default, but in wide mode we use just "index", which made no sense to me.

So unless you have a strong objection I would like to leave the code in its current state.


> 2. in the new function(display_debug_rnglists) added, newline 
> character printing is missing

Thanks - added.

Cheers
   Nick

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

end of thread, other threads:[~2022-07-01 14:29 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-27 20:56 [PATCH] Fix range lists issues (dwarf-5) Kumar N, Bhuvanendra
2022-06-29 11:17 ` Nick Clifton
2022-06-30 12:50   ` Kumar N, Bhuvanendra
2022-07-01 13:23     ` Nick Clifton
2022-07-01 14:29       ` 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).