1 //===-- DWARFFormValue.cpp --------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include <assert.h>
11
12 #include "lldb/Core/dwarf.h"
13 #include "lldb/Utility/Stream.h"
14
15 #include "DWARFUnit.h"
16 #include "DWARFFormValue.h"
17
18 class DWARFUnit;
19
20 using namespace lldb_private;
21
22 static uint8_t g_form_sizes_addr4[] = {
23 0, // 0x00 unused
24 4, // 0x01 DW_FORM_addr
25 0, // 0x02 unused
26 0, // 0x03 DW_FORM_block2
27 0, // 0x04 DW_FORM_block4
28 2, // 0x05 DW_FORM_data2
29 4, // 0x06 DW_FORM_data4
30 8, // 0x07 DW_FORM_data8
31 0, // 0x08 DW_FORM_string
32 0, // 0x09 DW_FORM_block
33 0, // 0x0a DW_FORM_block1
34 1, // 0x0b DW_FORM_data1
35 1, // 0x0c DW_FORM_flag
36 0, // 0x0d DW_FORM_sdata
37 4, // 0x0e DW_FORM_strp
38 0, // 0x0f DW_FORM_udata
39 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
40 // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
41 1, // 0x11 DW_FORM_ref1
42 2, // 0x12 DW_FORM_ref2
43 4, // 0x13 DW_FORM_ref4
44 8, // 0x14 DW_FORM_ref8
45 0, // 0x15 DW_FORM_ref_udata
46 0, // 0x16 DW_FORM_indirect
47 4, // 0x17 DW_FORM_sec_offset
48 0, // 0x18 DW_FORM_exprloc
49 0, // 0x19 DW_FORM_flag_present
50 0, // 0x1a
51 0, // 0x1b
52 0, // 0x1c
53 0, // 0x1d
54 0, // 0x1e
55 0, // 0x1f
56 8, // 0x20 DW_FORM_ref_sig8
57
58 };
59
60 static uint8_t g_form_sizes_addr8[] = {
61 0, // 0x00 unused
62 8, // 0x01 DW_FORM_addr
63 0, // 0x02 unused
64 0, // 0x03 DW_FORM_block2
65 0, // 0x04 DW_FORM_block4
66 2, // 0x05 DW_FORM_data2
67 4, // 0x06 DW_FORM_data4
68 8, // 0x07 DW_FORM_data8
69 0, // 0x08 DW_FORM_string
70 0, // 0x09 DW_FORM_block
71 0, // 0x0a DW_FORM_block1
72 1, // 0x0b DW_FORM_data1
73 1, // 0x0c DW_FORM_flag
74 0, // 0x0d DW_FORM_sdata
75 4, // 0x0e DW_FORM_strp
76 0, // 0x0f DW_FORM_udata
77 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
78 // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
79 1, // 0x11 DW_FORM_ref1
80 2, // 0x12 DW_FORM_ref2
81 4, // 0x13 DW_FORM_ref4
82 8, // 0x14 DW_FORM_ref8
83 0, // 0x15 DW_FORM_ref_udata
84 0, // 0x16 DW_FORM_indirect
85 4, // 0x17 DW_FORM_sec_offset
86 0, // 0x18 DW_FORM_exprloc
87 0, // 0x19 DW_FORM_flag_present
88 0, // 0x1a
89 0, // 0x1b
90 0, // 0x1c
91 0, // 0x1d
92 0, // 0x1e
93 0, // 0x1f
94 8, // 0x20 DW_FORM_ref_sig8
95 };
96
97 // Difference with g_form_sizes_addr8:
98 // DW_FORM_strp and DW_FORM_sec_offset are 8 instead of 4
99 static uint8_t g_form_sizes_addr8_dwarf64[] = {
100 0, // 0x00 unused
101 8, // 0x01 DW_FORM_addr
102 0, // 0x02 unused
103 0, // 0x03 DW_FORM_block2
104 0, // 0x04 DW_FORM_block4
105 2, // 0x05 DW_FORM_data2
106 4, // 0x06 DW_FORM_data4
107 8, // 0x07 DW_FORM_data8
108 0, // 0x08 DW_FORM_string
109 0, // 0x09 DW_FORM_block
110 0, // 0x0a DW_FORM_block1
111 1, // 0x0b DW_FORM_data1
112 1, // 0x0c DW_FORM_flag
113 0, // 0x0d DW_FORM_sdata
114 8, // 0x0e DW_FORM_strp
115 0, // 0x0f DW_FORM_udata
116 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
117 // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
118 1, // 0x11 DW_FORM_ref1
119 2, // 0x12 DW_FORM_ref2
120 4, // 0x13 DW_FORM_ref4
121 8, // 0x14 DW_FORM_ref8
122 0, // 0x15 DW_FORM_ref_udata
123 0, // 0x16 DW_FORM_indirect
124 8, // 0x17 DW_FORM_sec_offset
125 0, // 0x18 DW_FORM_exprloc
126 0, // 0x19 DW_FORM_flag_present
127 0, // 0x1a
128 0, // 0x1b
129 0, // 0x1c
130 0, // 0x1d
131 0, // 0x1e
132 0, // 0x1f
133 8, // 0x20 DW_FORM_ref_sig8
134 };
135
136 DWARFFormValue::FixedFormSizes
GetFixedFormSizesForAddressSize(uint8_t addr_size,bool is_dwarf64)137 DWARFFormValue::GetFixedFormSizesForAddressSize(uint8_t addr_size,
138 bool is_dwarf64) {
139 if (!is_dwarf64) {
140 switch (addr_size) {
141 case 4:
142 return FixedFormSizes(g_form_sizes_addr4, sizeof(g_form_sizes_addr4));
143 case 8:
144 return FixedFormSizes(g_form_sizes_addr8, sizeof(g_form_sizes_addr8));
145 }
146 } else {
147 if (addr_size == 8)
148 return FixedFormSizes(g_form_sizes_addr8_dwarf64,
149 sizeof(g_form_sizes_addr8_dwarf64));
150 // is_dwarf64 && addr_size == 4 : no provider does this.
151 }
152 return FixedFormSizes();
153 }
154
DWARFFormValue()155 DWARFFormValue::DWARFFormValue() : m_cu(NULL), m_form(0), m_value() {}
156
DWARFFormValue(const DWARFUnit * cu)157 DWARFFormValue::DWARFFormValue(const DWARFUnit *cu)
158 : m_cu(cu), m_form(0), m_value() {}
159
DWARFFormValue(const DWARFUnit * cu,dw_form_t form)160 DWARFFormValue::DWARFFormValue(const DWARFUnit *cu, dw_form_t form)
161 : m_cu(cu), m_form(form), m_value() {}
162
Clear()163 void DWARFFormValue::Clear() {
164 m_cu = nullptr;
165 m_form = 0;
166 memset(&m_value, 0, sizeof(m_value));
167 }
168
ExtractValue(const DWARFDataExtractor & data,lldb::offset_t * offset_ptr)169 bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
170 lldb::offset_t *offset_ptr) {
171 if (m_form == DW_FORM_implicit_const)
172 return true;
173
174 bool indirect = false;
175 bool is_block = false;
176 m_value.data = NULL;
177 uint8_t ref_addr_size;
178 // Read the value for the form into value and follow and DW_FORM_indirect
179 // instances we run into
180 do {
181 indirect = false;
182 switch (m_form) {
183 case DW_FORM_addr:
184 assert(m_cu);
185 m_value.value.uval =
186 data.GetMaxU64(offset_ptr, DWARFUnit::GetAddressByteSize(m_cu));
187 break;
188 case DW_FORM_block1:
189 m_value.value.uval = data.GetU8(offset_ptr);
190 is_block = true;
191 break;
192 case DW_FORM_block2:
193 m_value.value.uval = data.GetU16(offset_ptr);
194 is_block = true;
195 break;
196 case DW_FORM_block4:
197 m_value.value.uval = data.GetU32(offset_ptr);
198 is_block = true;
199 break;
200 case DW_FORM_data16:
201 m_value.value.uval = 16;
202 is_block = true;
203 break;
204 case DW_FORM_exprloc:
205 case DW_FORM_block:
206 m_value.value.uval = data.GetULEB128(offset_ptr);
207 is_block = true;
208 break;
209 case DW_FORM_string:
210 m_value.value.cstr = data.GetCStr(offset_ptr);
211 break;
212 case DW_FORM_sdata:
213 m_value.value.sval = data.GetSLEB128(offset_ptr);
214 break;
215 case DW_FORM_strp:
216 case DW_FORM_line_strp:
217 case DW_FORM_sec_offset:
218 assert(m_cu);
219 m_value.value.uval =
220 data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4);
221 break;
222 case DW_FORM_addrx1:
223 case DW_FORM_strx1:
224 case DW_FORM_ref1:
225 case DW_FORM_data1:
226 case DW_FORM_flag:
227 m_value.value.uval = data.GetU8(offset_ptr);
228 break;
229 case DW_FORM_addrx2:
230 case DW_FORM_strx2:
231 case DW_FORM_ref2:
232 case DW_FORM_data2:
233 m_value.value.uval = data.GetU16(offset_ptr);
234 break;
235 case DW_FORM_addrx3:
236 case DW_FORM_strx3:
237 m_value.value.uval = data.GetMaxU64(offset_ptr, 3);
238 break;
239 case DW_FORM_addrx4:
240 case DW_FORM_strx4:
241 case DW_FORM_ref4:
242 case DW_FORM_data4:
243 m_value.value.uval = data.GetU32(offset_ptr);
244 break;
245 case DW_FORM_data8:
246 case DW_FORM_ref8:
247 case DW_FORM_ref_sig8:
248 m_value.value.uval = data.GetU64(offset_ptr);
249 break;
250 case DW_FORM_addrx:
251 case DW_FORM_rnglistx:
252 case DW_FORM_strx:
253 case DW_FORM_udata:
254 case DW_FORM_ref_udata:
255 case DW_FORM_GNU_str_index:
256 case DW_FORM_GNU_addr_index:
257 m_value.value.uval = data.GetULEB128(offset_ptr);
258 break;
259 case DW_FORM_ref_addr:
260 assert(m_cu);
261 if (m_cu->GetVersion() <= 2)
262 ref_addr_size = m_cu->GetAddressByteSize();
263 else
264 ref_addr_size = m_cu->IsDWARF64() ? 8 : 4;
265 m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size);
266 break;
267 case DW_FORM_indirect:
268 m_form = data.GetULEB128(offset_ptr);
269 indirect = true;
270 break;
271 case DW_FORM_flag_present:
272 m_value.value.uval = 1;
273 break;
274 default:
275 return false;
276 }
277 } while (indirect);
278
279 if (is_block) {
280 m_value.data = data.PeekData(*offset_ptr, m_value.value.uval);
281 if (m_value.data != NULL) {
282 *offset_ptr += m_value.value.uval;
283 }
284 }
285
286 return true;
287 }
288
SkipValue(const DWARFDataExtractor & debug_info_data,lldb::offset_t * offset_ptr) const289 bool DWARFFormValue::SkipValue(const DWARFDataExtractor &debug_info_data,
290 lldb::offset_t *offset_ptr) const {
291 return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu);
292 }
293
SkipValue(dw_form_t form,const DWARFDataExtractor & debug_info_data,lldb::offset_t * offset_ptr,const DWARFUnit * cu)294 bool DWARFFormValue::SkipValue(dw_form_t form,
295 const DWARFDataExtractor &debug_info_data,
296 lldb::offset_t *offset_ptr,
297 const DWARFUnit *cu) {
298 uint8_t ref_addr_size;
299 switch (form) {
300 // Blocks if inlined data that have a length field and the data bytes inlined
301 // in the .debug_info
302 case DW_FORM_exprloc:
303 case DW_FORM_block: {
304 dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr);
305 *offset_ptr += size;
306 }
307 return true;
308 case DW_FORM_block1: {
309 dw_uleb128_t size = debug_info_data.GetU8(offset_ptr);
310 *offset_ptr += size;
311 }
312 return true;
313 case DW_FORM_block2: {
314 dw_uleb128_t size = debug_info_data.GetU16(offset_ptr);
315 *offset_ptr += size;
316 }
317 return true;
318 case DW_FORM_block4: {
319 dw_uleb128_t size = debug_info_data.GetU32(offset_ptr);
320 *offset_ptr += size;
321 }
322 return true;
323
324 // Inlined NULL terminated C-strings
325 case DW_FORM_string:
326 debug_info_data.GetCStr(offset_ptr);
327 return true;
328
329 // Compile unit address sized values
330 case DW_FORM_addr:
331 *offset_ptr += DWARFUnit::GetAddressByteSize(cu);
332 return true;
333
334 case DW_FORM_ref_addr:
335 ref_addr_size = 4;
336 assert(cu); // CU must be valid for DW_FORM_ref_addr objects or we will get
337 // this wrong
338 if (cu->GetVersion() <= 2)
339 ref_addr_size = cu->GetAddressByteSize();
340 else
341 ref_addr_size = cu->IsDWARF64() ? 8 : 4;
342 *offset_ptr += ref_addr_size;
343 return true;
344
345 // 0 bytes values (implied from DW_FORM)
346 case DW_FORM_flag_present:
347 case DW_FORM_implicit_const:
348 return true;
349
350 // 1 byte values
351 case DW_FORM_addrx1:
352 case DW_FORM_data1:
353 case DW_FORM_flag:
354 case DW_FORM_ref1:
355 case DW_FORM_strx1:
356 *offset_ptr += 1;
357 return true;
358
359 // 2 byte values
360 case DW_FORM_addrx2:
361 case DW_FORM_data2:
362 case DW_FORM_ref2:
363 case DW_FORM_strx2:
364 *offset_ptr += 2;
365 return true;
366
367 // 3 byte values
368 case DW_FORM_addrx3:
369 case DW_FORM_strx3:
370 *offset_ptr += 3;
371 return true;
372
373 // 32 bit for DWARF 32, 64 for DWARF 64
374 case DW_FORM_sec_offset:
375 case DW_FORM_strp:
376 assert(cu);
377 *offset_ptr += (cu->IsDWARF64() ? 8 : 4);
378 return true;
379
380 // 4 byte values
381 case DW_FORM_addrx4:
382 case DW_FORM_data4:
383 case DW_FORM_ref4:
384 case DW_FORM_strx4:
385 *offset_ptr += 4;
386 return true;
387
388 // 8 byte values
389 case DW_FORM_data8:
390 case DW_FORM_ref8:
391 case DW_FORM_ref_sig8:
392 *offset_ptr += 8;
393 return true;
394
395 // signed or unsigned LEB 128 values
396 case DW_FORM_addrx:
397 case DW_FORM_rnglistx:
398 case DW_FORM_sdata:
399 case DW_FORM_udata:
400 case DW_FORM_ref_udata:
401 case DW_FORM_GNU_addr_index:
402 case DW_FORM_GNU_str_index:
403 case DW_FORM_strx:
404 debug_info_data.Skip_LEB128(offset_ptr);
405 return true;
406
407 case DW_FORM_indirect: {
408 dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr);
409 return DWARFFormValue::SkipValue(indirect_form, debug_info_data, offset_ptr,
410 cu);
411 }
412
413 default:
414 break;
415 }
416 return false;
417 }
418
Dump(Stream & s) const419 void DWARFFormValue::Dump(Stream &s) const {
420 uint64_t uvalue = Unsigned();
421 bool cu_relative_offset = false;
422
423 switch (m_form) {
424 case DW_FORM_addr:
425 s.Address(uvalue, sizeof(uint64_t));
426 break;
427 case DW_FORM_flag:
428 case DW_FORM_data1:
429 s.PutHex8(uvalue);
430 break;
431 case DW_FORM_data2:
432 s.PutHex16(uvalue);
433 break;
434 case DW_FORM_sec_offset:
435 case DW_FORM_data4:
436 s.PutHex32(uvalue);
437 break;
438 case DW_FORM_ref_sig8:
439 case DW_FORM_data8:
440 s.PutHex64(uvalue);
441 break;
442 case DW_FORM_string:
443 s.QuotedCString(AsCString());
444 break;
445 case DW_FORM_exprloc:
446 case DW_FORM_block:
447 case DW_FORM_block1:
448 case DW_FORM_block2:
449 case DW_FORM_block4:
450 if (uvalue > 0) {
451 switch (m_form) {
452 case DW_FORM_exprloc:
453 case DW_FORM_block:
454 s.Printf("<0x%" PRIx64 "> ", uvalue);
455 break;
456 case DW_FORM_block1:
457 s.Printf("<0x%2.2x> ", (uint8_t)uvalue);
458 break;
459 case DW_FORM_block2:
460 s.Printf("<0x%4.4x> ", (uint16_t)uvalue);
461 break;
462 case DW_FORM_block4:
463 s.Printf("<0x%8.8x> ", (uint32_t)uvalue);
464 break;
465 default:
466 break;
467 }
468
469 const uint8_t *data_ptr = m_value.data;
470 if (data_ptr) {
471 const uint8_t *end_data_ptr =
472 data_ptr + uvalue; // uvalue contains size of block
473 while (data_ptr < end_data_ptr) {
474 s.Printf("%2.2x ", *data_ptr);
475 ++data_ptr;
476 }
477 } else
478 s.PutCString("NULL");
479 }
480 break;
481
482 case DW_FORM_sdata:
483 s.PutSLEB128(uvalue);
484 break;
485 case DW_FORM_udata:
486 s.PutULEB128(uvalue);
487 break;
488 case DW_FORM_strp: {
489 const char *dbg_str = AsCString();
490 if (dbg_str) {
491 s.QuotedCString(dbg_str);
492 } else {
493 s.PutHex32(uvalue);
494 }
495 } break;
496
497 case DW_FORM_ref_addr: {
498 assert(m_cu); // CU must be valid for DW_FORM_ref_addr objects or we will
499 // get this wrong
500 if (m_cu->GetVersion() <= 2)
501 s.Address(uvalue, sizeof(uint64_t) * 2);
502 else
503 s.Address(uvalue, 4 * 2); // 4 for DWARF32, 8 for DWARF64, but we don't
504 // support DWARF64 yet
505 break;
506 }
507 case DW_FORM_ref1:
508 cu_relative_offset = true;
509 break;
510 case DW_FORM_ref2:
511 cu_relative_offset = true;
512 break;
513 case DW_FORM_ref4:
514 cu_relative_offset = true;
515 break;
516 case DW_FORM_ref8:
517 cu_relative_offset = true;
518 break;
519 case DW_FORM_ref_udata:
520 cu_relative_offset = true;
521 break;
522
523 // All DW_FORM_indirect attributes should be resolved prior to calling this
524 // function
525 case DW_FORM_indirect:
526 s.PutCString("DW_FORM_indirect");
527 break;
528 case DW_FORM_flag_present:
529 break;
530 default:
531 s.Printf("DW_FORM(0x%4.4x)", m_form);
532 break;
533 }
534
535 if (cu_relative_offset) {
536 assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile
537 // unit relative or we will get this wrong
538 s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_cu->GetOffset());
539 }
540 }
541
AsCString() const542 const char *DWARFFormValue::AsCString() const {
543 SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
544
545 if (m_form == DW_FORM_string) {
546 return m_value.value.cstr;
547 } else if (m_form == DW_FORM_strp) {
548 if (!symbol_file)
549 return nullptr;
550
551 return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval);
552 } else if (m_form == DW_FORM_GNU_str_index) {
553 if (!symbol_file)
554 return nullptr;
555
556 uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4;
557 lldb::offset_t offset = m_value.value.uval * index_size;
558 dw_offset_t str_offset =
559 symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset,
560 index_size);
561 return symbol_file->get_debug_str_data().PeekCStr(str_offset);
562 }
563
564 if (m_form == DW_FORM_strx || m_form == DW_FORM_strx1 ||
565 m_form == DW_FORM_strx2 || m_form == DW_FORM_strx3 ||
566 m_form == DW_FORM_strx4) {
567
568 // The same code as above.
569 if (!symbol_file)
570 return nullptr;
571
572 uint32_t indexSize = m_cu->IsDWARF64() ? 8 : 4;
573 lldb::offset_t offset =
574 m_cu->GetStrOffsetsBase() + m_value.value.uval * indexSize;
575 dw_offset_t strOffset =
576 symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, indexSize);
577 return symbol_file->get_debug_str_data().PeekCStr(strOffset);
578 }
579
580 if (m_form == DW_FORM_line_strp)
581 return symbol_file->get_debug_line_str_data().PeekCStr(m_value.value.uval);
582
583 return nullptr;
584 }
585
Address() const586 dw_addr_t DWARFFormValue::Address() const {
587 SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
588
589 if (m_form == DW_FORM_addr)
590 return Unsigned();
591
592 assert(m_cu);
593 assert(m_form == DW_FORM_GNU_addr_index || m_form == DW_FORM_addrx ||
594 m_form == DW_FORM_addrx1 || m_form == DW_FORM_addrx2 ||
595 m_form == DW_FORM_addrx3 || m_form == DW_FORM_addrx4);
596
597 if (!symbol_file)
598 return 0;
599
600 uint32_t index_size = m_cu->GetAddressByteSize();
601 dw_offset_t addr_base = m_cu->GetAddrBase();
602 lldb::offset_t offset = addr_base + m_value.value.uval * index_size;
603 return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size);
604 }
605
Reference() const606 uint64_t DWARFFormValue::Reference() const {
607 uint64_t value = m_value.value.uval;
608 switch (m_form) {
609 case DW_FORM_ref1:
610 case DW_FORM_ref2:
611 case DW_FORM_ref4:
612 case DW_FORM_ref8:
613 case DW_FORM_ref_udata:
614 assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile
615 // unit relative or we will get this wrong
616 return value + m_cu->GetOffset();
617
618 case DW_FORM_ref_addr:
619 case DW_FORM_ref_sig8:
620 case DW_FORM_GNU_ref_alt:
621 return value;
622
623 default:
624 return DW_INVALID_OFFSET;
625 }
626 }
627
Reference(dw_offset_t base_offset) const628 uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const {
629 uint64_t value = m_value.value.uval;
630 switch (m_form) {
631 case DW_FORM_ref1:
632 case DW_FORM_ref2:
633 case DW_FORM_ref4:
634 case DW_FORM_ref8:
635 case DW_FORM_ref_udata:
636 return value + base_offset;
637
638 case DW_FORM_ref_addr:
639 case DW_FORM_ref_sig8:
640 case DW_FORM_GNU_ref_alt:
641 return value;
642
643 default:
644 return DW_INVALID_OFFSET;
645 }
646 }
647
BlockData() const648 const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; }
649
IsBlockForm(const dw_form_t form)650 bool DWARFFormValue::IsBlockForm(const dw_form_t form) {
651 switch (form) {
652 case DW_FORM_exprloc:
653 case DW_FORM_block:
654 case DW_FORM_block1:
655 case DW_FORM_block2:
656 case DW_FORM_block4:
657 return true;
658 }
659 return false;
660 }
661
IsDataForm(const dw_form_t form)662 bool DWARFFormValue::IsDataForm(const dw_form_t form) {
663 switch (form) {
664 case DW_FORM_sdata:
665 case DW_FORM_udata:
666 case DW_FORM_data1:
667 case DW_FORM_data2:
668 case DW_FORM_data4:
669 case DW_FORM_data8:
670 return true;
671 }
672 return false;
673 }
674
Compare(const DWARFFormValue & a_value,const DWARFFormValue & b_value)675 int DWARFFormValue::Compare(const DWARFFormValue &a_value,
676 const DWARFFormValue &b_value) {
677 dw_form_t a_form = a_value.Form();
678 dw_form_t b_form = b_value.Form();
679 if (a_form < b_form)
680 return -1;
681 if (a_form > b_form)
682 return 1;
683 switch (a_form) {
684 case DW_FORM_addr:
685 case DW_FORM_flag:
686 case DW_FORM_data1:
687 case DW_FORM_data2:
688 case DW_FORM_data4:
689 case DW_FORM_data8:
690 case DW_FORM_udata:
691 case DW_FORM_ref_addr:
692 case DW_FORM_sec_offset:
693 case DW_FORM_flag_present:
694 case DW_FORM_ref_sig8:
695 case DW_FORM_GNU_addr_index: {
696 uint64_t a = a_value.Unsigned();
697 uint64_t b = b_value.Unsigned();
698 if (a < b)
699 return -1;
700 if (a > b)
701 return 1;
702 return 0;
703 }
704
705 case DW_FORM_sdata: {
706 int64_t a = a_value.Signed();
707 int64_t b = b_value.Signed();
708 if (a < b)
709 return -1;
710 if (a > b)
711 return 1;
712 return 0;
713 }
714
715 case DW_FORM_string:
716 case DW_FORM_strp:
717 case DW_FORM_GNU_str_index: {
718 const char *a_string = a_value.AsCString();
719 const char *b_string = b_value.AsCString();
720 if (a_string == b_string)
721 return 0;
722 else if (a_string && b_string)
723 return strcmp(a_string, b_string);
724 else if (a_string == NULL)
725 return -1; // A string is NULL, and B is valid
726 else
727 return 1; // A string valid, and B is NULL
728 }
729
730 case DW_FORM_block:
731 case DW_FORM_block1:
732 case DW_FORM_block2:
733 case DW_FORM_block4:
734 case DW_FORM_exprloc: {
735 uint64_t a_len = a_value.Unsigned();
736 uint64_t b_len = b_value.Unsigned();
737 if (a_len < b_len)
738 return -1;
739 if (a_len > b_len)
740 return 1;
741 // The block lengths are the same
742 return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned());
743 } break;
744
745 case DW_FORM_ref1:
746 case DW_FORM_ref2:
747 case DW_FORM_ref4:
748 case DW_FORM_ref8:
749 case DW_FORM_ref_udata: {
750 uint64_t a = a_value.Reference();
751 uint64_t b = b_value.Reference();
752 if (a < b)
753 return -1;
754 if (a > b)
755 return 1;
756 return 0;
757 }
758
759 case DW_FORM_indirect:
760 llvm_unreachable(
761 "This shouldn't happen after the form has been extracted...");
762
763 default:
764 llvm_unreachable("Unhandled DW_FORM");
765 }
766 return -1;
767 }
768
FormIsSupported(dw_form_t form)769 bool DWARFFormValue::FormIsSupported(dw_form_t form) {
770 switch (form) {
771 case DW_FORM_addr:
772 case DW_FORM_addrx:
773 case DW_FORM_rnglistx:
774 case DW_FORM_block2:
775 case DW_FORM_block4:
776 case DW_FORM_data2:
777 case DW_FORM_data4:
778 case DW_FORM_data8:
779 case DW_FORM_string:
780 case DW_FORM_block:
781 case DW_FORM_block1:
782 case DW_FORM_data1:
783 case DW_FORM_flag:
784 case DW_FORM_sdata:
785 case DW_FORM_strp:
786 case DW_FORM_strx:
787 case DW_FORM_strx1:
788 case DW_FORM_strx2:
789 case DW_FORM_strx3:
790 case DW_FORM_strx4:
791 case DW_FORM_udata:
792 case DW_FORM_ref_addr:
793 case DW_FORM_ref1:
794 case DW_FORM_ref2:
795 case DW_FORM_ref4:
796 case DW_FORM_ref8:
797 case DW_FORM_ref_udata:
798 case DW_FORM_indirect:
799 case DW_FORM_sec_offset:
800 case DW_FORM_exprloc:
801 case DW_FORM_flag_present:
802 case DW_FORM_ref_sig8:
803 case DW_FORM_GNU_str_index:
804 case DW_FORM_GNU_addr_index:
805 case DW_FORM_implicit_const:
806 return true;
807 default:
808 break;
809 }
810 return false;
811 }
812