* [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).