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/Stream.h"
13 #include "lldb/Core/dwarf.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;
409 bool verbose = s.GetVerbose();
413 s.Address(uvalue, sizeof(uint64_t));
422 case DW_FORM_sec_offset:
426 case DW_FORM_ref_sig8:
431 s.QuotedCString(AsCString());
433 case DW_FORM_exprloc:
440 case DW_FORM_exprloc:
442 s.Printf("<0x%" PRIx64 "> ", uvalue);
445 s.Printf("<0x%2.2x> ", (uint8_t)uvalue);
448 s.Printf("<0x%4.4x> ", (uint16_t)uvalue);
451 s.Printf("<0x%8.8x> ", (uint32_t)uvalue);
457 const uint8_t *data_ptr = m_value.data;
459 const uint8_t *end_data_ptr =
460 data_ptr + uvalue; // uvalue contains size of block
461 while (data_ptr < end_data_ptr) {
462 s.Printf("%2.2x ", *data_ptr);
466 s.PutCString("NULL");
471 s.PutSLEB128(uvalue);
474 s.PutULEB128(uvalue);
477 const char *dbg_str = AsCString();
480 s.Printf(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
481 s.QuotedCString(dbg_str);
487 case DW_FORM_ref_addr: {
488 assert(m_cu); // CU must be valid for DW_FORM_ref_addr objects or we will
490 if (m_cu->GetVersion() <= 2)
491 s.Address(uvalue, sizeof(uint64_t) * 2);
493 s.Address(uvalue, 4 * 2); // 4 for DWARF32, 8 for DWARF64, but we don't
494 // support DWARF64 yet
498 cu_relative_offset = true;
500 s.Printf("cu + 0x%2.2x", (uint8_t)uvalue);
503 cu_relative_offset = true;
505 s.Printf("cu + 0x%4.4x", (uint16_t)uvalue);
508 cu_relative_offset = true;
510 s.Printf("cu + 0x%4.4x", (uint32_t)uvalue);
513 cu_relative_offset = true;
515 s.Printf("cu + 0x%8.8" PRIx64, uvalue);
517 case DW_FORM_ref_udata:
518 cu_relative_offset = true;
520 s.Printf("cu + 0x%" PRIx64, uvalue);
523 // All DW_FORM_indirect attributes should be resolved prior to calling this
525 case DW_FORM_indirect:
526 s.PutCString("DW_FORM_indirect");
528 case DW_FORM_flag_present:
531 s.Printf("DW_FORM(0x%4.4x)", m_form);
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
539 s.PutCString(" => ");
541 s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_cu->GetOffset());
545 const char *DWARFFormValue::AsCString() const {
546 SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
548 if (m_form == DW_FORM_string) {
549 return m_value.value.cstr;
550 } else if (m_form == DW_FORM_strp) {
554 return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval);
555 } else if (m_form == DW_FORM_GNU_str_index) {
559 uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4;
560 lldb::offset_t offset = m_value.value.uval * index_size;
561 dw_offset_t str_offset =
562 symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset,
564 return symbol_file->get_debug_str_data().PeekCStr(str_offset);
569 dw_addr_t DWARFFormValue::Address() const {
570 SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
572 if (m_form == DW_FORM_addr)
576 assert(m_form == DW_FORM_GNU_addr_index);
581 uint32_t index_size = m_cu->GetAddressByteSize();
582 dw_offset_t addr_base = m_cu->GetAddrBase();
583 lldb::offset_t offset = addr_base + m_value.value.uval * index_size;
584 return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size);
587 uint64_t DWARFFormValue::Reference() const {
588 uint64_t die_offset = m_value.value.uval;
594 case DW_FORM_ref_udata:
595 assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile
596 // unit relative or we will get this wrong
597 die_offset += m_cu->GetOffset();
607 uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const {
608 uint64_t die_offset = m_value.value.uval;
614 case DW_FORM_ref_udata:
615 die_offset += base_offset;
625 const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; }
627 bool DWARFFormValue::IsBlockForm(const dw_form_t form) {
629 case DW_FORM_exprloc:
639 bool DWARFFormValue::IsDataForm(const dw_form_t form) {
652 int DWARFFormValue::Compare(const DWARFFormValue &a_value,
653 const DWARFFormValue &b_value) {
654 dw_form_t a_form = a_value.Form();
655 dw_form_t b_form = b_value.Form();
668 case DW_FORM_ref_addr:
669 case DW_FORM_sec_offset:
670 case DW_FORM_flag_present:
671 case DW_FORM_ref_sig8:
672 case DW_FORM_GNU_addr_index: {
673 uint64_t a = a_value.Unsigned();
674 uint64_t b = b_value.Unsigned();
682 case DW_FORM_sdata: {
683 int64_t a = a_value.Signed();
684 int64_t b = b_value.Signed();
694 case DW_FORM_GNU_str_index: {
695 const char *a_string = a_value.AsCString();
696 const char *b_string = b_value.AsCString();
697 if (a_string == b_string)
699 else if (a_string && b_string)
700 return strcmp(a_string, b_string);
701 else if (a_string == NULL)
702 return -1; // A string is NULL, and B is valid
704 return 1; // A string valid, and B is NULL
711 case DW_FORM_exprloc: {
712 uint64_t a_len = a_value.Unsigned();
713 uint64_t b_len = b_value.Unsigned();
718 // The block lengths are the same
719 return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned());
726 case DW_FORM_ref_udata: {
727 uint64_t a = a_value.Reference();
728 uint64_t b = b_value.Reference();
736 case DW_FORM_indirect:
738 "This shouldn't happen after the form has been extracted...");
741 llvm_unreachable("Unhandled DW_FORM");