19
19
#include " Plugins/SymbolFile/DWARF/DWARFDataExtractor.h"
20
20
#include " Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h"
21
21
#include " Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h"
22
+ #include " Plugins/SymbolFile/DWARF/DWARFDebugAranges.h"
22
23
#include " Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
23
24
#include " Plugins/SymbolFile/PDB/SymbolFilePDB.h"
24
25
#include " Plugins/TypeSystem/Clang/TypeSystemClang.h"
@@ -70,7 +71,7 @@ TEST_F(SymbolFileDWARFTests, TestAbilitiesForDWARF) {
70
71
TEST_F (SymbolFileDWARFTests, TestAbbrevOrder1Start1) {
71
72
// Test that if we have a .debug_abbrev that contains ordered abbreviation
72
73
// codes that start at 1, that we get O(1) access.
73
-
74
+
74
75
const auto byte_order = eByteOrderLittle;
75
76
const uint8_t addr_size = 4 ;
76
77
StreamString encoder (Stream::eBinary, addr_size, byte_order);
@@ -81,17 +82,17 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevOrder1Start1) {
81
82
encoder.PutULEB128 (DW_FORM_strp);
82
83
encoder.PutULEB128 (0 );
83
84
encoder.PutULEB128 (0 );
84
-
85
+
85
86
encoder.PutULEB128 (2 ); // Abbrev code 2
86
87
encoder.PutULEB128 (DW_TAG_subprogram);
87
88
encoder.PutHex8 (DW_CHILDREN_no);
88
89
encoder.PutULEB128 (DW_AT_name);
89
90
encoder.PutULEB128 (DW_FORM_strp);
90
91
encoder.PutULEB128 (0 );
91
92
encoder.PutULEB128 (0 );
92
-
93
+
93
94
encoder.PutULEB128 (0 ); // Abbrev code 0 (termination)
94
-
95
+
95
96
DWARFDataExtractor data;
96
97
data.SetData (encoder.GetData (), encoder.GetSize (), byte_order);
97
98
DWARFAbbreviationDeclarationSet abbrev_set;
@@ -101,7 +102,7 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevOrder1Start1) {
101
102
// Make sure we have O(1) access to each abbreviation by making sure the
102
103
// index offset is 1 and not UINT32_MAX
103
104
EXPECT_EQ (abbrev_set.GetIndexOffset (), 1u );
104
-
105
+
105
106
auto abbrev1 = abbrev_set.GetAbbreviationDeclaration (1 );
106
107
EXPECT_EQ (abbrev1->Tag (), DW_TAG_compile_unit);
107
108
EXPECT_TRUE (abbrev1->HasChildren ());
@@ -115,7 +116,7 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevOrder1Start1) {
115
116
TEST_F (SymbolFileDWARFTests, TestAbbrevOrder1Start5) {
116
117
// Test that if we have a .debug_abbrev that contains ordered abbreviation
117
118
// codes that start at 5, that we get O(1) access.
118
-
119
+
119
120
const auto byte_order = eByteOrderLittle;
120
121
const uint8_t addr_size = 4 ;
121
122
StreamString encoder (Stream::eBinary, addr_size, byte_order);
@@ -126,17 +127,17 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevOrder1Start5) {
126
127
encoder.PutULEB128 (DW_FORM_strp);
127
128
encoder.PutULEB128 (0 );
128
129
encoder.PutULEB128 (0 );
129
-
130
+
130
131
encoder.PutULEB128 (6 ); // Abbrev code 6
131
132
encoder.PutULEB128 (DW_TAG_subprogram);
132
133
encoder.PutHex8 (DW_CHILDREN_no);
133
134
encoder.PutULEB128 (DW_AT_name);
134
135
encoder.PutULEB128 (DW_FORM_strp);
135
136
encoder.PutULEB128 (0 );
136
137
encoder.PutULEB128 (0 );
137
-
138
+
138
139
encoder.PutULEB128 (0 ); // Abbrev code 0 (termination)
139
-
140
+
140
141
DWARFDataExtractor data;
141
142
data.SetData (encoder.GetData (), encoder.GetSize (), byte_order);
142
143
DWARFAbbreviationDeclarationSet abbrev_set;
@@ -146,7 +147,7 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevOrder1Start5) {
146
147
// Make sure we have O(1) access to each abbreviation by making sure the
147
148
// index offset is 5 and not UINT32_MAX
148
149
EXPECT_EQ (abbrev_set.GetIndexOffset (), 5u );
149
-
150
+
150
151
auto abbrev1 = abbrev_set.GetAbbreviationDeclaration (5 );
151
152
EXPECT_EQ (abbrev1->Tag (), DW_TAG_compile_unit);
152
153
EXPECT_TRUE (abbrev1->HasChildren ());
@@ -160,7 +161,7 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevOrder1Start5) {
160
161
TEST_F (SymbolFileDWARFTests, TestAbbrevOutOfOrder) {
161
162
// Test that if we have a .debug_abbrev that contains unordered abbreviation
162
163
// codes, that we can access the information correctly.
163
-
164
+
164
165
const auto byte_order = eByteOrderLittle;
165
166
const uint8_t addr_size = 4 ;
166
167
StreamString encoder (Stream::eBinary, addr_size, byte_order);
@@ -171,17 +172,17 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevOutOfOrder) {
171
172
encoder.PutULEB128 (DW_FORM_strp);
172
173
encoder.PutULEB128 (0 );
173
174
encoder.PutULEB128 (0 );
174
-
175
+
175
176
encoder.PutULEB128 (1 ); // Abbrev code 1
176
177
encoder.PutULEB128 (DW_TAG_subprogram);
177
178
encoder.PutHex8 (DW_CHILDREN_no);
178
179
encoder.PutULEB128 (DW_AT_name);
179
180
encoder.PutULEB128 (DW_FORM_strp);
180
181
encoder.PutULEB128 (0 );
181
182
encoder.PutULEB128 (0 );
182
-
183
+
183
184
encoder.PutULEB128 (0 ); // Abbrev code 0 (termination)
184
-
185
+
185
186
DWARFDataExtractor data;
186
187
data.SetData (encoder.GetData (), encoder.GetSize (), byte_order);
187
188
DWARFAbbreviationDeclarationSet abbrev_set;
@@ -191,7 +192,7 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevOutOfOrder) {
191
192
// Make sure we don't have O(1) access to each abbreviation by making sure
192
193
// the index offset is UINT32_MAX
193
194
EXPECT_EQ (abbrev_set.GetIndexOffset (), UINT32_MAX);
194
-
195
+
195
196
auto abbrev1 = abbrev_set.GetAbbreviationDeclaration (2 );
196
197
EXPECT_EQ (abbrev1->Tag (), DW_TAG_compile_unit);
197
198
EXPECT_TRUE (abbrev1->HasChildren ());
@@ -205,7 +206,7 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevOutOfOrder) {
205
206
TEST_F (SymbolFileDWARFTests, TestAbbrevInvalidNULLTag) {
206
207
// Test that we detect when an abbreviation has a NULL tag and that we get
207
208
// an error when decoding.
208
-
209
+
209
210
const auto byte_order = eByteOrderLittle;
210
211
const uint8_t addr_size = 4 ;
211
212
StreamString encoder (Stream::eBinary, addr_size, byte_order);
@@ -214,9 +215,9 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevInvalidNULLTag) {
214
215
encoder.PutHex8 (DW_CHILDREN_no);
215
216
encoder.PutULEB128 (0 );
216
217
encoder.PutULEB128 (0 );
217
-
218
+
218
219
encoder.PutULEB128 (0 ); // Abbrev code 0 (termination)
219
-
220
+
220
221
DWARFDataExtractor data;
221
222
data.SetData (encoder.GetData (), encoder.GetSize (), byte_order);
222
223
DWARFAbbreviationDeclarationSet abbrev_set;
@@ -232,7 +233,7 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevInvalidNULLTag) {
232
233
TEST_F (SymbolFileDWARFTests, TestAbbrevNullAttrValidForm) {
233
234
// Test that we detect when an abbreviation has a NULL attribute and a non
234
235
// NULL form and that we get an error when decoding.
235
-
236
+
236
237
const auto byte_order = eByteOrderLittle;
237
238
const uint8_t addr_size = 4 ;
238
239
StreamString encoder (Stream::eBinary, addr_size, byte_order);
@@ -245,7 +246,7 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevNullAttrValidForm) {
245
246
encoder.PutULEB128 (0 );
246
247
247
248
encoder.PutULEB128 (0 ); // Abbrev code 0 (termination)
248
-
249
+
249
250
DWARFDataExtractor data;
250
251
data.SetData (encoder.GetData (), encoder.GetSize (), byte_order);
251
252
DWARFAbbreviationDeclarationSet abbrev_set;
@@ -255,13 +256,12 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevNullAttrValidForm) {
255
256
EXPECT_TRUE (bool (error));
256
257
EXPECT_EQ (" malformed abbreviation declaration attribute" ,
257
258
llvm::toString (std::move (error)));
258
-
259
259
}
260
260
261
261
TEST_F (SymbolFileDWARFTests, TestAbbrevValidAttrNullForm) {
262
262
// Test that we detect when an abbreviation has a valid attribute and a
263
263
// NULL form and that we get an error when decoding.
264
-
264
+
265
265
const auto byte_order = eByteOrderLittle;
266
266
const uint8_t addr_size = 4 ;
267
267
StreamString encoder (Stream::eBinary, addr_size, byte_order);
@@ -272,9 +272,9 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevValidAttrNullForm) {
272
272
encoder.PutULEB128 (0 ); // NULL form
273
273
encoder.PutULEB128 (0 );
274
274
encoder.PutULEB128 (0 );
275
-
275
+
276
276
encoder.PutULEB128 (0 ); // Abbrev code 0 (termination)
277
-
277
+
278
278
DWARFDataExtractor data;
279
279
data.SetData (encoder.GetData (), encoder.GetSize (), byte_order);
280
280
DWARFAbbreviationDeclarationSet abbrev_set;
@@ -290,7 +290,7 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevMissingTerminator) {
290
290
// Test that we detect when an abbreviation has a valid attribute and a
291
291
// form, but is missing the NULL attribute and form that terminates an
292
292
// abbreviation
293
-
293
+
294
294
const auto byte_order = eByteOrderLittle;
295
295
const uint8_t addr_size = 4 ;
296
296
StreamString encoder (Stream::eBinary, addr_size, byte_order);
@@ -300,7 +300,7 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevMissingTerminator) {
300
300
encoder.PutULEB128 (DW_AT_name);
301
301
encoder.PutULEB128 (DW_FORM_strp);
302
302
// Don't add the NULL DW_AT and NULL DW_FORM terminator
303
-
303
+
304
304
DWARFDataExtractor data;
305
305
data.SetData (encoder.GetData (), encoder.GetSize (), byte_order);
306
306
DWARFAbbreviationDeclarationSet abbrev_set;
@@ -346,3 +346,42 @@ TEST_F(SymbolFileDWARFTests, ParseArangesNonzeroSegmentSize) {
346
346
llvm::toString (std::move (error)));
347
347
EXPECT_EQ (off, 12U ); // Parser should read no further than the segment size
348
348
}
349
+
350
+ TEST_F (SymbolFileDWARFTests, ParseAranges) {
351
+ // Test we can successfully parse a DWARFDebugAranges. The initial error
352
+ // checking code had a bug where it would always return an empty address
353
+ // ranges for everything in .debug_aranges and no error.
354
+ const unsigned char binary_data[] = {
355
+ 60 , 0 , 0 , 0 , // unit_length
356
+ 2 , 0 , // DWARF version number
357
+ 255 , 0 , 0 , 0 , // offset into the .debug_info_table
358
+ 8 , // address size
359
+ 0 , // segment size
360
+ 0 , 0 , 0 , 0 , // pad bytes
361
+ // BEGIN TUPLES
362
+ // First tuple: [0x1000-0x1100)
363
+ 0x00 , 0x10 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , // Address 0x1000
364
+ 0x00 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , // Size 0x0100
365
+ // Second tuple: [0x2000-0x2100)
366
+ 0x00 , 0x20 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , // Address 0x2000
367
+ 0x00 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , // Size 0x0100
368
+ // Terminating tuple
369
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , // Terminator
370
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 // Terminator
371
+ };
372
+ DWARFDataExtractor data;
373
+ data.SetData (static_cast <const void *>(binary_data), sizeof binary_data,
374
+ lldb::ByteOrder::eByteOrderLittle);
375
+ DWARFDebugAranges debug_aranges;
376
+ llvm::Error error = debug_aranges.extract (data);
377
+ ASSERT_FALSE (bool (error));
378
+ EXPECT_EQ (debug_aranges.GetNumRanges (), 2u );
379
+ EXPECT_EQ (debug_aranges.FindAddress (0x0fff ), DW_INVALID_OFFSET);
380
+ EXPECT_EQ (debug_aranges.FindAddress (0x1000 ), 255u );
381
+ EXPECT_EQ (debug_aranges.FindAddress (0x1100 - 1 ), 255u );
382
+ EXPECT_EQ (debug_aranges.FindAddress (0x1100 ), DW_INVALID_OFFSET);
383
+ EXPECT_EQ (debug_aranges.FindAddress (0x1fff ), DW_INVALID_OFFSET);
384
+ EXPECT_EQ (debug_aranges.FindAddress (0x2000 ), 255u );
385
+ EXPECT_EQ (debug_aranges.FindAddress (0x2100 - 1 ), 255u );
386
+ EXPECT_EQ (debug_aranges.FindAddress (0x2100 ), DW_INVALID_OFFSET);
387
+ }
0 commit comments