1 //===-- DWARFFormValue.cpp ------------------------------------------------===//
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 //===----------------------------------------------------------------------===//
10 #include "SyntaxHighlighting.h"
11 #include "llvm/ADT/ArrayRef.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
14 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
15 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
16 #include "llvm/Support/Debug.h"
17 #include "llvm/Support/Dwarf.h"
18 #include "llvm/Support/Format.h"
19 #include "llvm/Support/raw_ostream.h"
23 using namespace dwarf;
24 using namespace syntax;
26 static const DWARFFormValue::FormClass DWARF4FormClasses[] = {
27 DWARFFormValue::FC_Unknown, // 0x0
28 DWARFFormValue::FC_Address, // 0x01 DW_FORM_addr
29 DWARFFormValue::FC_Unknown, // 0x02 unused
30 DWARFFormValue::FC_Block, // 0x03 DW_FORM_block2
31 DWARFFormValue::FC_Block, // 0x04 DW_FORM_block4
32 DWARFFormValue::FC_Constant, // 0x05 DW_FORM_data2
33 // --- These can be FC_SectionOffset in DWARF3 and below:
34 DWARFFormValue::FC_Constant, // 0x06 DW_FORM_data4
35 DWARFFormValue::FC_Constant, // 0x07 DW_FORM_data8
37 DWARFFormValue::FC_String, // 0x08 DW_FORM_string
38 DWARFFormValue::FC_Block, // 0x09 DW_FORM_block
39 DWARFFormValue::FC_Block, // 0x0a DW_FORM_block1
40 DWARFFormValue::FC_Constant, // 0x0b DW_FORM_data1
41 DWARFFormValue::FC_Flag, // 0x0c DW_FORM_flag
42 DWARFFormValue::FC_Constant, // 0x0d DW_FORM_sdata
43 DWARFFormValue::FC_String, // 0x0e DW_FORM_strp
44 DWARFFormValue::FC_Constant, // 0x0f DW_FORM_udata
45 DWARFFormValue::FC_Reference, // 0x10 DW_FORM_ref_addr
46 DWARFFormValue::FC_Reference, // 0x11 DW_FORM_ref1
47 DWARFFormValue::FC_Reference, // 0x12 DW_FORM_ref2
48 DWARFFormValue::FC_Reference, // 0x13 DW_FORM_ref4
49 DWARFFormValue::FC_Reference, // 0x14 DW_FORM_ref8
50 DWARFFormValue::FC_Reference, // 0x15 DW_FORM_ref_udata
51 DWARFFormValue::FC_Indirect, // 0x16 DW_FORM_indirect
52 DWARFFormValue::FC_SectionOffset, // 0x17 DW_FORM_sec_offset
53 DWARFFormValue::FC_Exprloc, // 0x18 DW_FORM_exprloc
54 DWARFFormValue::FC_Flag, // 0x19 DW_FORM_flag_present
59 /// A helper class that can be used in DWARFFormValue.cpp functions that need
60 /// to know the byte size of DW_FORM values that vary in size depending on the
61 /// DWARF version, address byte size, or DWARF32 or DWARF64.
62 class FormSizeHelper {
65 llvm::dwarf::DwarfFormat Format;
68 FormSizeHelper(uint16_t V, uint8_t A, llvm::dwarf::DwarfFormat F)
69 : Version(V), AddrSize(A), Format(F) {}
70 uint8_t getAddressByteSize() const { return AddrSize; }
71 uint8_t getRefAddrByteSize() const {
74 return getDwarfOffsetByteSize();
76 uint8_t getDwarfOffsetByteSize() const {
78 case dwarf::DwarfFormat::DWARF32:
80 case dwarf::DwarfFormat::DWARF64:
83 llvm_unreachable("Invalid Format value");
87 } // end anonymous namespace
90 static Optional<uint8_t> getFixedByteSize(dwarf::Form Form, const T *U) {
94 return U->getAddressByteSize();
97 case DW_FORM_block: // ULEB128 length L followed by L bytes.
98 case DW_FORM_block1: // 1 byte length L followed by L bytes.
99 case DW_FORM_block2: // 2 byte length L followed by L bytes.
100 case DW_FORM_block4: // 4 byte length L followed by L bytes.
101 case DW_FORM_string: // C-string with null terminator.
102 case DW_FORM_sdata: // SLEB128.
103 case DW_FORM_udata: // ULEB128.
104 case DW_FORM_ref_udata: // ULEB128.
105 case DW_FORM_indirect: // ULEB128.
106 case DW_FORM_exprloc: // ULEB128 length L followed by L bytes.
107 case DW_FORM_strx: // ULEB128.
108 case DW_FORM_addrx: // ULEB128.
109 case DW_FORM_loclistx: // ULEB128.
110 case DW_FORM_rnglistx: // ULEB128.
111 case DW_FORM_GNU_addr_index: // ULEB128.
112 case DW_FORM_GNU_str_index: // ULEB128.
115 case DW_FORM_ref_addr:
117 return U->getRefAddrByteSize();
134 case DW_FORM_GNU_ref_alt:
135 case DW_FORM_GNU_strp_alt:
136 case DW_FORM_line_strp:
137 case DW_FORM_sec_offset:
138 case DW_FORM_strp_sup:
139 case DW_FORM_ref_sup:
141 return U->getDwarfOffsetByteSize();
146 case DW_FORM_ref_sig8:
149 case DW_FORM_flag_present:
155 case DW_FORM_implicit_const:
156 // The implicit value is stored in the abbreviation as a ULEB128, any
157 // there no data in debug info.
161 llvm_unreachable("Handle this form in this switch statement");
167 static bool skipFormValue(dwarf::Form Form, const DataExtractor &DebugInfoData,
168 uint32_t *OffsetPtr, const T *U) {
169 bool Indirect = false;
172 // Blocks of inlined data that have a length field and the data bytes
173 // inlined in the .debug_info.
174 case DW_FORM_exprloc:
175 case DW_FORM_block: {
176 uint64_t size = DebugInfoData.getULEB128(OffsetPtr);
180 case DW_FORM_block1: {
181 uint8_t size = DebugInfoData.getU8(OffsetPtr);
185 case DW_FORM_block2: {
186 uint16_t size = DebugInfoData.getU16(OffsetPtr);
190 case DW_FORM_block4: {
191 uint32_t size = DebugInfoData.getU32(OffsetPtr);
196 // Inlined NULL terminated C-strings.
198 DebugInfoData.getCStr(OffsetPtr);
202 case DW_FORM_ref_addr:
203 case DW_FORM_flag_present:
213 case DW_FORM_ref_sig8:
214 case DW_FORM_ref_sup:
215 case DW_FORM_sec_offset:
217 case DW_FORM_strp_sup:
218 case DW_FORM_line_strp:
219 case DW_FORM_GNU_ref_alt:
220 case DW_FORM_GNU_strp_alt:
221 if (Optional<uint8_t> FixedSize = ::getFixedByteSize(Form, U)) {
222 *OffsetPtr += *FixedSize;
227 // signed or unsigned LEB 128 values.
229 DebugInfoData.getSLEB128(OffsetPtr);
233 case DW_FORM_ref_udata:
236 case DW_FORM_loclistx:
237 case DW_FORM_rnglistx:
238 case DW_FORM_GNU_addr_index:
239 case DW_FORM_GNU_str_index:
240 DebugInfoData.getULEB128(OffsetPtr);
243 case DW_FORM_indirect:
245 Form = static_cast<dwarf::Form>(DebugInfoData.getULEB128(OffsetPtr));
255 Optional<uint8_t> DWARFFormValue::getFixedByteSize(dwarf::Form Form,
256 const DWARFUnit *U) {
257 return ::getFixedByteSize(Form, U);
261 DWARFFormValue::getFixedByteSize(dwarf::Form Form, uint16_t Version,
263 llvm::dwarf::DwarfFormat Format) {
264 FormSizeHelper FSH(Version, AddrSize, Format);
265 return ::getFixedByteSize(Form, &FSH);
268 bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
269 // First, check DWARF4 form classes.
270 if (Form < makeArrayRef(DWARF4FormClasses).size() &&
271 DWARF4FormClasses[Form] == FC)
273 // Check more forms from DWARF4 and DWARF5 proposals.
275 case DW_FORM_ref_sig8:
276 case DW_FORM_GNU_ref_alt:
277 return (FC == FC_Reference);
278 case DW_FORM_GNU_addr_index:
279 return (FC == FC_Address);
280 case DW_FORM_GNU_str_index:
281 case DW_FORM_GNU_strp_alt:
282 return (FC == FC_String);
286 // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section offset.
287 // Don't check for DWARF version here, as some producers may still do this
289 return (Form == DW_FORM_data4 || Form == DW_FORM_data8) &&
290 FC == FC_SectionOffset;
293 bool DWARFFormValue::extractValue(const DataExtractor &data,
294 uint32_t *offset_ptr,
295 const DWARFUnit *cu) {
297 bool indirect = false;
298 bool is_block = false;
299 Value.data = nullptr;
300 // Read the value for the form into value and follow and DW_FORM_indirect
301 // instances we run into
306 case DW_FORM_ref_addr: {
310 (Form == DW_FORM_addr)
311 ? U->getAddressByteSize()
312 : U->getRefAddrByteSize();
313 RelocAddrMap::const_iterator AI = U->getRelocMap()->find(*offset_ptr);
314 if (AI != U->getRelocMap()->end()) {
315 Value.uval = data.getUnsigned(offset_ptr, AddrSize) + AI->second.second;
317 Value.uval = data.getUnsigned(offset_ptr, AddrSize);
320 case DW_FORM_exprloc:
322 Value.uval = data.getULEB128(offset_ptr);
326 Value.uval = data.getU8(offset_ptr);
330 Value.uval = data.getU16(offset_ptr);
334 Value.uval = data.getU32(offset_ptr);
340 Value.uval = data.getU8(offset_ptr);
344 Value.uval = data.getU16(offset_ptr);
348 Value.uval = data.getU32(offset_ptr);
351 RelocAddrMap::const_iterator AI = U->getRelocMap()->find(*offset_ptr-4);
352 if (AI != U->getRelocMap()->end())
353 Value.uval += AI->second.second;
358 Value.uval = data.getU64(offset_ptr);
361 Value.sval = data.getSLEB128(offset_ptr);
364 case DW_FORM_ref_udata:
365 Value.uval = data.getULEB128(offset_ptr);
368 Value.cstr = data.getCStr(offset_ptr);
370 case DW_FORM_indirect:
371 Form = static_cast<dwarf::Form>(data.getULEB128(offset_ptr));
375 case DW_FORM_sec_offset:
376 case DW_FORM_GNU_ref_alt:
377 case DW_FORM_GNU_strp_alt:
378 case DW_FORM_line_strp:
379 case DW_FORM_strp_sup:
380 case DW_FORM_ref_sup: {
383 RelocAddrMap::const_iterator AI = U->getRelocMap()->find(*offset_ptr);
384 uint8_t Size = U->getDwarfOffsetByteSize();
385 Value.uval = data.getUnsigned(offset_ptr, Size);
386 if (AI != U->getRelocMap()->end())
387 Value.uval += AI->second.second;
390 case DW_FORM_flag_present:
393 case DW_FORM_ref_sig8:
394 Value.uval = data.getU64(offset_ptr);
396 case DW_FORM_GNU_addr_index:
397 case DW_FORM_GNU_str_index:
398 Value.uval = data.getULEB128(offset_ptr);
406 StringRef str = data.getData().substr(*offset_ptr, Value.uval);
407 Value.data = nullptr;
409 Value.data = reinterpret_cast<const uint8_t *>(str.data());
410 *offset_ptr += Value.uval;
417 bool DWARFFormValue::skipValue(DataExtractor DebugInfoData,
418 uint32_t *offset_ptr, const DWARFUnit *U) const {
419 return DWARFFormValue::skipValue(Form, DebugInfoData, offset_ptr, U);
422 bool DWARFFormValue::skipValue(dwarf::Form form, DataExtractor DebugInfoData,
423 uint32_t *offset_ptr, const DWARFUnit *U) {
424 return skipFormValue(form, DebugInfoData, offset_ptr, U);
427 bool DWARFFormValue::skipValue(dwarf::Form form, DataExtractor DebugInfoData,
428 uint32_t *offset_ptr, uint16_t Version,
430 llvm::dwarf::DwarfFormat Format) {
431 FormSizeHelper FSH(Version, AddrSize, Format);
432 return skipFormValue(form, DebugInfoData, offset_ptr, &FSH);
436 DWARFFormValue::dump(raw_ostream &OS) const {
437 uint64_t uvalue = Value.uval;
438 bool cu_relative_offset = false;
441 case DW_FORM_addr: OS << format("0x%016" PRIx64, uvalue); break;
442 case DW_FORM_GNU_addr_index: {
443 OS << format(" indexed (%8.8x) address = ", (uint32_t)uvalue);
446 OS << "<invalid dwarf unit>";
447 else if (U->getAddrOffsetSectionItem(uvalue, Address))
448 OS << format("0x%016" PRIx64, Address);
450 OS << "<no .debug_addr section>";
453 case DW_FORM_flag_present: OS << "true"; break;
455 case DW_FORM_data1: OS << format("0x%02x", (uint8_t)uvalue); break;
456 case DW_FORM_data2: OS << format("0x%04x", (uint16_t)uvalue); break;
457 case DW_FORM_data4: OS << format("0x%08x", (uint32_t)uvalue); break;
458 case DW_FORM_ref_sig8:
459 case DW_FORM_data8: OS << format("0x%016" PRIx64, uvalue); break;
462 OS.write_escaped(Value.cstr);
465 case DW_FORM_exprloc:
472 case DW_FORM_exprloc:
473 case DW_FORM_block: OS << format("<0x%" PRIx64 "> ", uvalue); break;
474 case DW_FORM_block1: OS << format("<0x%2.2x> ", (uint8_t)uvalue); break;
475 case DW_FORM_block2: OS << format("<0x%4.4x> ", (uint16_t)uvalue); break;
476 case DW_FORM_block4: OS << format("<0x%8.8x> ", (uint32_t)uvalue); break;
480 const uint8_t* data_ptr = Value.data;
482 // uvalue contains size of block
483 const uint8_t* end_data_ptr = data_ptr + uvalue;
484 while (data_ptr < end_data_ptr) {
485 OS << format("%2.2x ", *data_ptr);
494 case DW_FORM_sdata: OS << Value.sval; break;
495 case DW_FORM_udata: OS << Value.uval; break;
497 OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
501 case DW_FORM_GNU_str_index: {
502 OS << format(" indexed (%8.8x) string = ", (uint32_t)uvalue);
506 case DW_FORM_GNU_strp_alt: {
507 OS << format("alt indirect string, offset: 0x%" PRIx64 "", uvalue);
511 case DW_FORM_ref_addr:
512 OS << format("0x%016" PRIx64, uvalue);
515 cu_relative_offset = true;
516 OS << format("cu + 0x%2.2x", (uint8_t)uvalue);
519 cu_relative_offset = true;
520 OS << format("cu + 0x%4.4x", (uint16_t)uvalue);
523 cu_relative_offset = true;
524 OS << format("cu + 0x%4.4x", (uint32_t)uvalue);
527 cu_relative_offset = true;
528 OS << format("cu + 0x%8.8" PRIx64, uvalue);
530 case DW_FORM_ref_udata:
531 cu_relative_offset = true;
532 OS << format("cu + 0x%" PRIx64, uvalue);
534 case DW_FORM_GNU_ref_alt:
535 OS << format("<alt 0x%" PRIx64 ">", uvalue);
538 // All DW_FORM_indirect attributes should be resolved prior to calling
540 case DW_FORM_indirect:
541 OS << "DW_FORM_indirect";
544 // Should be formatted to 64-bit for DWARF64.
545 case DW_FORM_sec_offset:
546 OS << format("0x%08x", (uint32_t)uvalue);
550 OS << format("DW_FORM(0x%4.4x)", Form);
554 if (cu_relative_offset) {
556 WithColor(OS, syntax::Address).get()
557 << format("0x%8.8" PRIx64, uvalue + (U ? U->getOffset() : 0));
562 void DWARFFormValue::dumpString(raw_ostream &OS) const {
563 Optional<const char *> DbgStr = getAsCString();
564 if (DbgStr.hasValue()) {
565 raw_ostream &COS = WithColor(OS, syntax::String);
567 COS.write_escaped(DbgStr.getValue());
572 Optional<const char *> DWARFFormValue::getAsCString() const {
573 if (!isFormClass(FC_String))
575 if (Form == DW_FORM_string)
577 // FIXME: Add support for DW_FORM_GNU_strp_alt
578 if (Form == DW_FORM_GNU_strp_alt || U == nullptr)
580 uint32_t Offset = Value.uval;
581 if (Form == DW_FORM_GNU_str_index) {
583 if (!U->getStringOffsetSectionItem(Offset, StrOffset))
587 if (const char *Str = U->getStringExtractor().getCStr(&Offset)) {
593 Optional<uint64_t> DWARFFormValue::getAsAddress() const {
594 if (!isFormClass(FC_Address))
596 if (Form == DW_FORM_GNU_addr_index) {
597 uint32_t Index = Value.uval;
599 if (!U || !U->getAddrOffsetSectionItem(Index, Result))
606 Optional<uint64_t> DWARFFormValue::getAsReference() const {
607 if (!isFormClass(FC_Reference))
614 case DW_FORM_ref_udata:
617 return Value.uval + U->getOffset();
618 case DW_FORM_ref_addr:
619 case DW_FORM_ref_sig8:
620 case DW_FORM_GNU_ref_alt:
627 Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
628 if (!isFormClass(FC_SectionOffset))
633 Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
634 if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag))
635 || Form == DW_FORM_sdata)
640 Optional<int64_t> DWARFFormValue::getAsSignedConstant() const {
641 if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
642 (Form == DW_FORM_udata && uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval))
646 return int32_t(Value.uval);
648 return int16_t(Value.uval);
650 return int8_t(Value.uval);
658 Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
659 if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc))
661 return makeArrayRef(Value.data, Value.uval);