1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
From ec41dd75c866599fc03c390c6afb5736c159c0ff Mon Sep 17 00:00:00 2001
From: Nick Clifton <nickc@redhat.com>
Date: Tue, 21 Jun 2022 16:37:27 +0100
Subject: [PATCH] Binutils support for dwarf-5 (location and range lists
related)
* 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.
Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=ec41dd75c866599fc03c390c6afb5736c159c0ff]
Signed-off-by: Pgowda <pgowda.cve@gmail.com>
---
binutils/ChangeLog | 10 +++++++++
binutils/dwarf.c | 53 ++++++++++++++++++++++++++++++++++------------
binutils/dwarf.h | 1 +
3 files changed, 51 insertions(+), 13 deletions(-)
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index cb2523af1f3..30b64ac68a8 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -2812,7 +2812,12 @@ read_and_display_attr_value (unsigned lo
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. */
@@ -3303,6 +3308,7 @@ read_and_display_attr_value (unsigned lo
/* 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:
@@ -3322,7 +3328,10 @@ read_and_display_attr_value (unsigned lo
&& (form == DW_FORM_data4 || form == DW_FORM_data8))
|| form == DW_FORM_sec_offset
|| form == DW_FORM_loclistx)
- printf (_(" (location list)"));
+ {
+ if (attribute != DW_AT_rnglists_base)
+ printf (_(" (location list)"));
+ }
/* Fall through. */
case DW_AT_allocated:
case DW_AT_associated:
@@ -3809,6 +3818,7 @@ process_debug_info (struct dwarf_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)
@@ -7932,9 +7942,16 @@ display_debug_rnglists_list (unsigned ch
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)
{
@@ -7964,20 +7981,24 @@ display_debug_rnglists_list (unsigned ch
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:
@@ -8003,6 +8024,7 @@ display_debug_rnglists_list (unsigned ch
rlet = DW_RLE_end_of_list;
break;
}
+
if (rlet == DW_RLE_end_of_list)
break;
if (rlet == DW_RLE_base_address || rlet == DW_RLE_base_addressx)
@@ -8043,6 +8065,7 @@ display_debug_ranges (struct dwarf_secti
/* 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)
{
@@ -8054,10 +8077,10 @@ display_debug_ranges (struct dwarf_secti
if (is_rnglists)
{
- dwarf_vma initial_length;
- unsigned char segment_selector_size;
- unsigned int offset_size, offset_entry_count;
- unsigned short version;
+ dwarf_vma initial_length;
+ unsigned char segment_selector_size;
+ unsigned int offset_entry_count;
+ unsigned short version;
/* Get and check the length of the block. */
SAFE_BYTE_GET_AND_INC (initial_length, start, 4, finish);
@@ -8230,7 +8253,8 @@ display_debug_ranges (struct dwarf_secti
(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
@@ -8262,7 +8286,7 @@ display_debug_ranges (struct dwarf_secti
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);
@@ -11911,6 +11935,9 @@ load_separate_debug_files (void * file,
&& load_debug_section (abbrev, file)
&& load_debug_section (info, file))
{
+ /* Load the .debug_addr section, if it 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;
|