1 //===-- DWARFFormValue.cpp --------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 #include "lldb/Core/dwarf.h"
13 #include "lldb/Utility/Stream.h"
15 #include "DWARFCompileUnit.h"
16 #include "DWARFFormValue.h"
18 class DWARFCompileUnit;
20 using namespace lldb_private;
22 static uint8_t g_form_sizes_addr4[] = {
24 4, // 0x01 DW_FORM_addr
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
56 8, // 0x20 DW_FORM_ref_sig8
60 static uint8_t g_form_sizes_addr8[] = {
62 8, // 0x01 DW_FORM_addr
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
94 8, // 0x20 DW_FORM_ref_sig8
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[] = {
101 8, // 0x01 DW_FORM_addr
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
133 8, // 0x20 DW_FORM_ref_sig8
136 DWARFFormValue::FixedFormSizes
137 DWARFFormValue::GetFixedFormSizesForAddressSize(uint8_t addr_size,
142 return FixedFormSizes(g_form_sizes_addr4, sizeof(g_form_sizes_addr4));
144 return FixedFormSizes(g_form_sizes_addr8, sizeof(g_form_sizes_addr8));
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.
152 return FixedFormSizes();
155 DWARFFormValue::DWARFFormValue() : m_cu(NULL), m_form(0), m_value() {}
157 DWARFFormValue::DWARFFormValue(const DWARFCompileUnit *cu, dw_form_t form)
158 : m_cu(cu), m_form(form), m_value() {}
160 void DWARFFormValue::Clear() {
163 memset(&m_value, 0, sizeof(m_value));
166 bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
167 lldb::offset_t *offset_ptr) {
168 bool indirect = false;
169 bool is_block = false;
171 uint8_t ref_addr_size;
172 // Read the value for the form into value and follow and DW_FORM_indirect
173 // instances we run into
179 m_value.value.uval = data.GetMaxU64(
180 offset_ptr, DWARFCompileUnit::GetAddressByteSize(m_cu));
183 m_value.value.uval = data.GetU16(offset_ptr);
187 m_value.value.uval = data.GetU32(offset_ptr);
191 m_value.value.uval = data.GetU16(offset_ptr);
194 m_value.value.uval = data.GetU32(offset_ptr);
197 m_value.value.uval = data.GetU64(offset_ptr);
200 m_value.value.cstr = data.GetCStr(offset_ptr);
202 case DW_FORM_exprloc:
204 m_value.value.uval = data.GetULEB128(offset_ptr);
208 m_value.value.uval = data.GetU8(offset_ptr);
212 m_value.value.uval = data.GetU8(offset_ptr);
215 m_value.value.uval = data.GetU8(offset_ptr);
218 m_value.value.sval = data.GetSLEB128(offset_ptr);
223 data.GetMaxU64(offset_ptr, DWARFCompileUnit::IsDWARF64(m_cu) ? 8 : 4);
225 // case DW_FORM_APPLE_db_str:
227 m_value.value.uval = data.GetULEB128(offset_ptr);
229 case DW_FORM_ref_addr:
232 if (m_cu->GetVersion() <= 2)
233 ref_addr_size = m_cu->GetAddressByteSize();
235 ref_addr_size = m_cu->IsDWARF64() ? 8 : 4;
236 m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size);
239 m_value.value.uval = data.GetU8(offset_ptr);
242 m_value.value.uval = data.GetU16(offset_ptr);
245 m_value.value.uval = data.GetU32(offset_ptr);
248 m_value.value.uval = data.GetU64(offset_ptr);
250 case DW_FORM_ref_udata:
251 m_value.value.uval = data.GetULEB128(offset_ptr);
253 case DW_FORM_indirect:
254 m_form = data.GetULEB128(offset_ptr);
258 case DW_FORM_sec_offset:
261 data.GetMaxU64(offset_ptr, DWARFCompileUnit::IsDWARF64(m_cu) ? 8 : 4);
263 case DW_FORM_flag_present:
264 m_value.value.uval = 1;
266 case DW_FORM_ref_sig8:
267 m_value.value.uval = data.GetU64(offset_ptr);
269 case DW_FORM_GNU_str_index:
270 m_value.value.uval = data.GetULEB128(offset_ptr);
272 case DW_FORM_GNU_addr_index:
273 m_value.value.uval = data.GetULEB128(offset_ptr);
282 m_value.data = data.PeekData(*offset_ptr, m_value.value.uval);
283 if (m_value.data != NULL) {
284 *offset_ptr += m_value.value.uval;
291 bool DWARFFormValue::SkipValue(const DWARFDataExtractor &debug_info_data,
292 lldb::offset_t *offset_ptr) const {
293 return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu);
296 bool DWARFFormValue::SkipValue(dw_form_t form,
297 const DWARFDataExtractor &debug_info_data,
298 lldb::offset_t *offset_ptr,
299 const DWARFCompileUnit *cu) {
300 uint8_t ref_addr_size;
302 // Blocks if inlined data that have a length field and the data bytes
303 // inlined in the .debug_info
304 case DW_FORM_exprloc:
305 case DW_FORM_block: {
306 dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr);
310 case DW_FORM_block1: {
311 dw_uleb128_t size = debug_info_data.GetU8(offset_ptr);
315 case DW_FORM_block2: {
316 dw_uleb128_t size = debug_info_data.GetU16(offset_ptr);
320 case DW_FORM_block4: {
321 dw_uleb128_t size = debug_info_data.GetU32(offset_ptr);
326 // Inlined NULL terminated C-strings
328 debug_info_data.GetCStr(offset_ptr);
331 // Compile unit address sized values
333 *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu);
336 case DW_FORM_ref_addr:
338 assert(cu); // CU must be valid for DW_FORM_ref_addr objects or we will get
340 if (cu->GetVersion() <= 2)
341 ref_addr_size = cu->GetAddressByteSize();
343 ref_addr_size = cu->IsDWARF64() ? 8 : 4;
344 *offset_ptr += ref_addr_size;
347 // 0 bytes values (implied from DW_FORM)
348 case DW_FORM_flag_present:
364 // 32 bit for DWARF 32, 64 for DWARF 64
365 case DW_FORM_sec_offset:
368 *offset_ptr += (cu->IsDWARF64() ? 8 : 4);
380 case DW_FORM_ref_sig8:
384 // signed or unsigned LEB 128 values
387 case DW_FORM_ref_udata:
388 case DW_FORM_GNU_addr_index:
389 case DW_FORM_GNU_str_index:
390 debug_info_data.Skip_LEB128(offset_ptr);
393 case DW_FORM_indirect: {
394 dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr);
395 return DWARFFormValue::SkipValue(indirect_form, debug_info_data, offset_ptr,
405 void DWARFFormValue::Dump(Stream &s) const {
406 uint64_t uvalue = Unsigned();
407 bool cu_relative_offset = false;
411 s.Address(uvalue, sizeof(uint64_t));
420 case DW_FORM_sec_offset:
424 case DW_FORM_ref_sig8:
429 s.QuotedCString(AsCString());
431 case DW_FORM_exprloc:
438 case DW_FORM_exprloc:
440 s.Printf("<0x%" PRIx64 "> ", uvalue);
443 s.Printf("<0x%2.2x> ", (uint8_t)uvalue);
446 s.Printf("<0x%4.4x> ", (uint16_t)uvalue);
449 s.Printf("<0x%8.8x> ", (uint32_t)uvalue);
455 const uint8_t *data_ptr = m_value.data;
457 const uint8_t *end_data_ptr =
458 data_ptr + uvalue; // uvalue contains size of block
459 while (data_ptr < end_data_ptr) {
460 s.Printf("%2.2x ", *data_ptr);
464 s.PutCString("NULL");
469 s.PutSLEB128(uvalue);
472 s.PutULEB128(uvalue);
475 const char *dbg_str = AsCString();
477 s.QuotedCString(dbg_str);
483 case DW_FORM_ref_addr: {
484 assert(m_cu); // CU must be valid for DW_FORM_ref_addr objects or we will
486 if (m_cu->GetVersion() <= 2)
487 s.Address(uvalue, sizeof(uint64_t) * 2);
489 s.Address(uvalue, 4 * 2); // 4 for DWARF32, 8 for DWARF64, but we don't
490 // support DWARF64 yet
494 cu_relative_offset = true;
497 cu_relative_offset = true;
500 cu_relative_offset = true;
503 cu_relative_offset = true;
505 case DW_FORM_ref_udata:
506 cu_relative_offset = true;
509 // All DW_FORM_indirect attributes should be resolved prior to calling this
511 case DW_FORM_indirect:
512 s.PutCString("DW_FORM_indirect");
514 case DW_FORM_flag_present:
517 s.Printf("DW_FORM(0x%4.4x)", m_form);
521 if (cu_relative_offset) {
522 assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile
523 // unit relative or we will get this wrong
524 s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_cu->GetOffset());
528 const char *DWARFFormValue::AsCString() const {
529 SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
531 if (m_form == DW_FORM_string) {
532 return m_value.value.cstr;
533 } else if (m_form == DW_FORM_strp) {
537 return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval);
538 } else if (m_form == DW_FORM_GNU_str_index) {
542 uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4;
543 lldb::offset_t offset = m_value.value.uval * index_size;
544 dw_offset_t str_offset =
545 symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset,
547 return symbol_file->get_debug_str_data().PeekCStr(str_offset);
552 dw_addr_t DWARFFormValue::Address() const {
553 SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
555 if (m_form == DW_FORM_addr)
559 assert(m_form == DW_FORM_GNU_addr_index);
564 uint32_t index_size = m_cu->GetAddressByteSize();
565 dw_offset_t addr_base = m_cu->GetAddrBase();
566 lldb::offset_t offset = addr_base + m_value.value.uval * index_size;
567 return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size);
570 uint64_t DWARFFormValue::Reference() const {
571 uint64_t die_offset = m_value.value.uval;
577 case DW_FORM_ref_udata:
578 assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile
579 // unit relative or we will get this wrong
580 die_offset += m_cu->GetOffset();
590 uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const {
591 uint64_t die_offset = m_value.value.uval;
597 case DW_FORM_ref_udata:
598 die_offset += base_offset;
608 const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; }
610 bool DWARFFormValue::IsBlockForm(const dw_form_t form) {
612 case DW_FORM_exprloc:
622 bool DWARFFormValue::IsDataForm(const dw_form_t form) {
635 int DWARFFormValue::Compare(const DWARFFormValue &a_value,
636 const DWARFFormValue &b_value) {
637 dw_form_t a_form = a_value.Form();
638 dw_form_t b_form = b_value.Form();
651 case DW_FORM_ref_addr:
652 case DW_FORM_sec_offset:
653 case DW_FORM_flag_present:
654 case DW_FORM_ref_sig8:
655 case DW_FORM_GNU_addr_index: {
656 uint64_t a = a_value.Unsigned();
657 uint64_t b = b_value.Unsigned();
665 case DW_FORM_sdata: {
666 int64_t a = a_value.Signed();
667 int64_t b = b_value.Signed();
677 case DW_FORM_GNU_str_index: {
678 const char *a_string = a_value.AsCString();
679 const char *b_string = b_value.AsCString();
680 if (a_string == b_string)
682 else if (a_string && b_string)
683 return strcmp(a_string, b_string);
684 else if (a_string == NULL)
685 return -1; // A string is NULL, and B is valid
687 return 1; // A string valid, and B is NULL
694 case DW_FORM_exprloc: {
695 uint64_t a_len = a_value.Unsigned();
696 uint64_t b_len = b_value.Unsigned();
701 // The block lengths are the same
702 return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned());
709 case DW_FORM_ref_udata: {
710 uint64_t a = a_value.Reference();
711 uint64_t b = b_value.Reference();
719 case DW_FORM_indirect:
721 "This shouldn't happen after the form has been extracted...");
724 llvm_unreachable("Unhandled DW_FORM");
729 bool DWARFFormValue::FormIsSupported(dw_form_t form) {
745 case DW_FORM_ref_addr:
750 case DW_FORM_ref_udata:
751 case DW_FORM_indirect:
752 case DW_FORM_sec_offset:
753 case DW_FORM_exprloc:
754 case DW_FORM_flag_present:
755 case DW_FORM_ref_sig8:
756 case DW_FORM_GNU_str_index:
757 case DW_FORM_GNU_addr_index: