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 "llvm/DebugInfo/DWARF/DWARFFormValue.h"
11 #include "llvm/ADT/ArrayRef.h"
12 #include "llvm/ADT/None.h"
13 #include "llvm/ADT/Optional.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/BinaryFormat/Dwarf.h"
16 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
17 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
18 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/Format.h"
21 #include "llvm/Support/WithColor.h"
22 #include "llvm/Support/raw_ostream.h"
28 using namespace dwarf;
30 static const DWARFFormValue::FormClass DWARF5FormClasses[] = {
31 DWARFFormValue::FC_Unknown, // 0x0
32 DWARFFormValue::FC_Address, // 0x01 DW_FORM_addr
33 DWARFFormValue::FC_Unknown, // 0x02 unused
34 DWARFFormValue::FC_Block, // 0x03 DW_FORM_block2
35 DWARFFormValue::FC_Block, // 0x04 DW_FORM_block4
36 DWARFFormValue::FC_Constant, // 0x05 DW_FORM_data2
37 // --- These can be FC_SectionOffset in DWARF3 and below:
38 DWARFFormValue::FC_Constant, // 0x06 DW_FORM_data4
39 DWARFFormValue::FC_Constant, // 0x07 DW_FORM_data8
41 DWARFFormValue::FC_String, // 0x08 DW_FORM_string
42 DWARFFormValue::FC_Block, // 0x09 DW_FORM_block
43 DWARFFormValue::FC_Block, // 0x0a DW_FORM_block1
44 DWARFFormValue::FC_Constant, // 0x0b DW_FORM_data1
45 DWARFFormValue::FC_Flag, // 0x0c DW_FORM_flag
46 DWARFFormValue::FC_Constant, // 0x0d DW_FORM_sdata
47 DWARFFormValue::FC_String, // 0x0e DW_FORM_strp
48 DWARFFormValue::FC_Constant, // 0x0f DW_FORM_udata
49 DWARFFormValue::FC_Reference, // 0x10 DW_FORM_ref_addr
50 DWARFFormValue::FC_Reference, // 0x11 DW_FORM_ref1
51 DWARFFormValue::FC_Reference, // 0x12 DW_FORM_ref2
52 DWARFFormValue::FC_Reference, // 0x13 DW_FORM_ref4
53 DWARFFormValue::FC_Reference, // 0x14 DW_FORM_ref8
54 DWARFFormValue::FC_Reference, // 0x15 DW_FORM_ref_udata
55 DWARFFormValue::FC_Indirect, // 0x16 DW_FORM_indirect
56 DWARFFormValue::FC_SectionOffset, // 0x17 DW_FORM_sec_offset
57 DWARFFormValue::FC_Exprloc, // 0x18 DW_FORM_exprloc
58 DWARFFormValue::FC_Flag, // 0x19 DW_FORM_flag_present
59 DWARFFormValue::FC_String, // 0x1a DW_FORM_strx
60 DWARFFormValue::FC_Address, // 0x1b DW_FORM_addrx
61 DWARFFormValue::FC_Reference, // 0x1c DW_FORM_ref_sup4
62 DWARFFormValue::FC_String, // 0x1d DW_FORM_strp_sup
63 DWARFFormValue::FC_Constant, // 0x1e DW_FORM_data16
64 DWARFFormValue::FC_String, // 0x1f DW_FORM_line_strp
65 DWARFFormValue::FC_Reference, // 0x20 DW_FORM_ref_sig8
66 DWARFFormValue::FC_Constant, // 0x21 DW_FORM_implicit_const
67 DWARFFormValue::FC_SectionOffset, // 0x22 DW_FORM_loclistx
68 DWARFFormValue::FC_SectionOffset, // 0x23 DW_FORM_rnglistx
69 DWARFFormValue::FC_Reference, // 0x24 DW_FORM_ref_sup8
70 DWARFFormValue::FC_String, // 0x25 DW_FORM_strx1
71 DWARFFormValue::FC_String, // 0x26 DW_FORM_strx2
72 DWARFFormValue::FC_String, // 0x27 DW_FORM_strx3
73 DWARFFormValue::FC_String, // 0x28 DW_FORM_strx4
74 DWARFFormValue::FC_Address, // 0x29 DW_FORM_addrx1
75 DWARFFormValue::FC_Address, // 0x2a DW_FORM_addrx2
76 DWARFFormValue::FC_Address, // 0x2b DW_FORM_addrx3
77 DWARFFormValue::FC_Address, // 0x2c DW_FORM_addrx4
82 DWARFFormValue::getFixedByteSize(dwarf::Form Form,
83 const DWARFFormParams Params) {
87 return Params.AddrSize;
90 case DW_FORM_block: // ULEB128 length L followed by L bytes.
91 case DW_FORM_block1: // 1 byte length L followed by L bytes.
92 case DW_FORM_block2: // 2 byte length L followed by L bytes.
93 case DW_FORM_block4: // 4 byte length L followed by L bytes.
94 case DW_FORM_string: // C-string with null terminator.
95 case DW_FORM_sdata: // SLEB128.
96 case DW_FORM_udata: // ULEB128.
97 case DW_FORM_ref_udata: // ULEB128.
98 case DW_FORM_indirect: // ULEB128.
99 case DW_FORM_exprloc: // ULEB128 length L followed by L bytes.
100 case DW_FORM_strx: // ULEB128.
101 case DW_FORM_addrx: // ULEB128.
102 case DW_FORM_loclistx: // ULEB128.
103 case DW_FORM_rnglistx: // ULEB128.
104 case DW_FORM_GNU_addr_index: // ULEB128.
105 case DW_FORM_GNU_str_index: // ULEB128.
108 case DW_FORM_ref_addr:
110 return Params.getRefAddrByteSize();
131 case DW_FORM_ref_sup4:
137 case DW_FORM_GNU_ref_alt:
138 case DW_FORM_GNU_strp_alt:
139 case DW_FORM_line_strp:
140 case DW_FORM_sec_offset:
141 case DW_FORM_strp_sup:
143 return Params.getDwarfOffsetByteSize();
148 case DW_FORM_ref_sig8:
149 case DW_FORM_ref_sup8:
152 case DW_FORM_flag_present:
158 case DW_FORM_implicit_const:
159 // The implicit value is stored in the abbreviation as a SLEB128, and
160 // there no data in debug info.
164 llvm_unreachable("Handle this form in this switch statement");
169 bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
171 const DWARFFormParams Params) {
172 bool Indirect = false;
175 // Blocks of inlined data that have a length field and the data bytes
176 // inlined in the .debug_info.
177 case DW_FORM_exprloc:
178 case DW_FORM_block: {
179 uint64_t size = DebugInfoData.getULEB128(OffsetPtr);
183 case DW_FORM_block1: {
184 uint8_t size = DebugInfoData.getU8(OffsetPtr);
188 case DW_FORM_block2: {
189 uint16_t size = DebugInfoData.getU16(OffsetPtr);
193 case DW_FORM_block4: {
194 uint32_t size = DebugInfoData.getU32(OffsetPtr);
199 // Inlined NULL terminated C-strings.
201 DebugInfoData.getCStr(OffsetPtr);
205 case DW_FORM_ref_addr:
206 case DW_FORM_flag_present:
217 case DW_FORM_ref_sig8:
218 case DW_FORM_ref_sup4:
219 case DW_FORM_ref_sup8:
226 case DW_FORM_sec_offset:
228 case DW_FORM_strp_sup:
229 case DW_FORM_line_strp:
230 case DW_FORM_GNU_ref_alt:
231 case DW_FORM_GNU_strp_alt:
232 if (Optional<uint8_t> FixedSize =
233 DWARFFormValue::getFixedByteSize(Form, Params)) {
234 *OffsetPtr += *FixedSize;
239 // signed or unsigned LEB 128 values.
241 DebugInfoData.getSLEB128(OffsetPtr);
245 case DW_FORM_ref_udata:
248 case DW_FORM_loclistx:
249 case DW_FORM_rnglistx:
250 case DW_FORM_GNU_addr_index:
251 case DW_FORM_GNU_str_index:
252 DebugInfoData.getULEB128(OffsetPtr);
255 case DW_FORM_indirect:
257 Form = static_cast<dwarf::Form>(DebugInfoData.getULEB128(OffsetPtr));
267 bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
268 // First, check DWARF5 form classes.
269 if (Form < makeArrayRef(DWARF5FormClasses).size() &&
270 DWARF5FormClasses[Form] == FC)
272 // Check more forms from extensions and proposals.
274 case DW_FORM_GNU_ref_alt:
275 return (FC == FC_Reference);
276 case DW_FORM_GNU_addr_index:
277 return (FC == FC_Address);
278 case DW_FORM_GNU_str_index:
279 case DW_FORM_GNU_strp_alt:
280 return (FC == FC_String);
284 // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section offset.
285 // Don't check for DWARF version here, as some producers may still do this
286 // by mistake. Also accept DW_FORM_[line_]strp since these are
287 // .debug_[line_]str section offsets.
288 return (Form == DW_FORM_data4 || Form == DW_FORM_data8 ||
289 Form == DW_FORM_strp || Form == DW_FORM_line_strp) &&
290 FC == FC_SectionOffset;
293 bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
294 uint32_t *OffsetPtr, DWARFFormParams FP,
295 const DWARFContext *Ctx,
296 const DWARFUnit *CU) {
298 Ctx = &CU->getContext();
301 bool Indirect = false;
302 bool IsBlock = false;
303 Value.data = nullptr;
304 // Read the value for the form into value and follow and DW_FORM_indirect
305 // instances we run into
310 case DW_FORM_ref_addr: {
312 (Form == DW_FORM_addr) ? FP.AddrSize : FP.getRefAddrByteSize();
313 Value.uval = Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex);
316 case DW_FORM_exprloc:
318 Value.uval = Data.getULEB128(OffsetPtr);
322 Value.uval = Data.getU8(OffsetPtr);
326 Value.uval = Data.getU16(OffsetPtr);
330 Value.uval = Data.getU32(OffsetPtr);
338 Value.uval = Data.getU8(OffsetPtr);
344 Value.uval = Data.getU16(OffsetPtr);
347 Value.uval = Data.getU24(OffsetPtr);
351 case DW_FORM_ref_sup4:
354 Value.uval = Data.getRelocatedValue(4, OffsetPtr);
358 case DW_FORM_ref_sup8:
359 Value.uval = Data.getU64(OffsetPtr);
362 // Treat this like a 16-byte block.
367 Value.sval = Data.getSLEB128(OffsetPtr);
370 case DW_FORM_ref_udata:
371 Value.uval = Data.getULEB128(OffsetPtr);
374 Value.cstr = Data.getCStr(OffsetPtr);
376 case DW_FORM_indirect:
377 Form = static_cast<dwarf::Form>(Data.getULEB128(OffsetPtr));
381 case DW_FORM_sec_offset:
382 case DW_FORM_GNU_ref_alt:
383 case DW_FORM_GNU_strp_alt:
384 case DW_FORM_line_strp:
385 case DW_FORM_strp_sup: {
387 Data.getRelocatedValue(FP.getDwarfOffsetByteSize(), OffsetPtr);
390 case DW_FORM_flag_present:
393 case DW_FORM_ref_sig8:
394 Value.uval = Data.getU64(OffsetPtr);
396 case DW_FORM_GNU_addr_index:
397 case DW_FORM_GNU_str_index:
399 Value.uval = Data.getULEB128(OffsetPtr);
402 // DWARFFormValue::skipValue() will have caught this and caused all
403 // DWARF DIEs to fail to be parsed, so this code is not be reachable.
404 llvm_unreachable("unsupported form");
409 StringRef Str = Data.getData().substr(*OffsetPtr, Value.uval);
410 Value.data = nullptr;
412 Value.data = reinterpret_cast<const uint8_t *>(Str.data());
413 *OffsetPtr += Value.uval;
420 void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
421 uint64_t UValue = Value.uval;
422 bool CURelativeOffset = false;
423 raw_ostream &AddrOS = DumpOpts.ShowAddresses
424 ? WithColor(OS, HighlightColor::Address).get()
428 AddrOS << format("0x%016" PRIx64, UValue);
430 case DW_FORM_GNU_addr_index: {
431 AddrOS << format(" indexed (%8.8x) address = ", (uint32_t)UValue);
434 OS << "<invalid dwarf unit>";
435 else if (U->getAddrOffsetSectionItem(UValue, Address))
436 AddrOS << format("0x%016" PRIx64, Address);
438 OS << "<no .debug_addr section>";
441 case DW_FORM_flag_present:
446 OS << format("0x%02x", (uint8_t)UValue);
449 OS << format("0x%04x", (uint16_t)UValue);
452 OS << format("0x%08x", (uint32_t)UValue);
454 case DW_FORM_ref_sig8:
455 AddrOS << format("0x%016" PRIx64, UValue);
458 OS << format("0x%016" PRIx64, UValue);
461 OS << format_bytes(ArrayRef<uint8_t>(Value.data, 16), None, 16, 16);
465 OS.write_escaped(Value.cstr);
468 case DW_FORM_exprloc:
475 case DW_FORM_exprloc:
477 OS << format("<0x%" PRIx64 "> ", UValue);
480 OS << format("<0x%2.2x> ", (uint8_t)UValue);
483 OS << format("<0x%4.4x> ", (uint16_t)UValue);
486 OS << format("<0x%8.8x> ", (uint32_t)UValue);
492 const uint8_t *DataPtr = Value.data;
494 // UValue contains size of block
495 const uint8_t *EndDataPtr = DataPtr + UValue;
496 while (DataPtr < EndDataPtr) {
497 OS << format("%2.2x ", *DataPtr);
512 if (DumpOpts.Verbose)
513 OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)UValue);
516 case DW_FORM_line_strp:
517 if (DumpOpts.Verbose)
518 OS << format(" .debug_line_str[0x%8.8x] = ", (uint32_t)UValue);
526 case DW_FORM_GNU_str_index:
527 if (DumpOpts.Verbose)
528 OS << format(" indexed (%8.8x) string = ", (uint32_t)UValue);
531 case DW_FORM_GNU_strp_alt:
532 if (DumpOpts.Verbose)
533 OS << format("alt indirect string, offset: 0x%" PRIx64 "", UValue);
536 case DW_FORM_ref_addr:
537 AddrOS << format("0x%016" PRIx64, UValue);
540 CURelativeOffset = true;
541 if (DumpOpts.Verbose)
542 AddrOS << format("cu + 0x%2.2x", (uint8_t)UValue);
545 CURelativeOffset = true;
546 if (DumpOpts.Verbose)
547 AddrOS << format("cu + 0x%4.4x", (uint16_t)UValue);
550 CURelativeOffset = true;
551 if (DumpOpts.Verbose)
552 AddrOS << format("cu + 0x%4.4x", (uint32_t)UValue);
555 CURelativeOffset = true;
556 if (DumpOpts.Verbose)
557 AddrOS << format("cu + 0x%8.8" PRIx64, UValue);
559 case DW_FORM_ref_udata:
560 CURelativeOffset = true;
561 if (DumpOpts.Verbose)
562 AddrOS << format("cu + 0x%" PRIx64, UValue);
564 case DW_FORM_GNU_ref_alt:
565 AddrOS << format("<alt 0x%" PRIx64 ">", UValue);
568 // All DW_FORM_indirect attributes should be resolved prior to calling
570 case DW_FORM_indirect:
571 OS << "DW_FORM_indirect";
574 // Should be formatted to 64-bit for DWARF64.
575 case DW_FORM_sec_offset:
576 AddrOS << format("0x%08x", (uint32_t)UValue);
580 OS << format("DW_FORM(0x%4.4x)", Form);
584 if (CURelativeOffset) {
585 if (DumpOpts.Verbose)
587 WithColor(OS, HighlightColor::Address).get()
588 << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0));
589 if (DumpOpts.Verbose)
594 void DWARFFormValue::dumpString(raw_ostream &OS) const {
595 Optional<const char *> DbgStr = getAsCString();
596 if (DbgStr.hasValue()) {
597 auto COS = WithColor(OS, HighlightColor::String);
599 COS.get().write_escaped(DbgStr.getValue());
604 Optional<const char *> DWARFFormValue::getAsCString() const {
605 if (!isFormClass(FC_String))
607 if (Form == DW_FORM_string)
609 // FIXME: Add support for DW_FORM_GNU_strp_alt
610 if (Form == DW_FORM_GNU_strp_alt || C == nullptr)
612 uint32_t Offset = Value.uval;
613 if (Form == DW_FORM_line_strp) {
614 // .debug_line_str is tracked in the Context.
615 if (const char *Str = C->getLineStringExtractor().getCStr(&Offset))
619 if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx ||
620 Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 ||
621 Form == DW_FORM_strx4) {
623 if (!U || !U->getStringOffsetSectionItem(Offset, StrOffset))
627 // Prefer the Unit's string extractor, because for .dwo it will point to
628 // .debug_str.dwo, while the Context's extractor always uses .debug_str.
630 if (const char *Str = U->getStringExtractor().getCStr(&Offset))
634 if (const char *Str = C->getStringExtractor().getCStr(&Offset))
639 Optional<uint64_t> DWARFFormValue::getAsAddress() const {
640 if (!isFormClass(FC_Address))
642 if (Form == DW_FORM_GNU_addr_index) {
643 uint32_t Index = Value.uval;
645 if (!U || !U->getAddrOffsetSectionItem(Index, Result))
652 Optional<uint64_t> DWARFFormValue::getAsReference() const {
653 if (!isFormClass(FC_Reference))
660 case DW_FORM_ref_udata:
663 return Value.uval + U->getOffset();
664 case DW_FORM_ref_addr:
665 case DW_FORM_ref_sig8:
666 case DW_FORM_GNU_ref_alt:
673 Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
674 if (!isFormClass(FC_SectionOffset))
679 Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
680 if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
681 Form == DW_FORM_sdata)
686 Optional<int64_t> DWARFFormValue::getAsSignedConstant() const {
687 if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
688 (Form == DW_FORM_udata &&
689 uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval))
693 return int32_t(Value.uval);
695 return int16_t(Value.uval);
697 return int8_t(Value.uval);
705 Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
706 if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc) &&
707 Form != DW_FORM_data16)
709 return makeArrayRef(Value.data, Value.uval);
712 Optional<uint64_t> DWARFFormValue::getAsCStringOffset() const {
713 if (!isFormClass(FC_String) && Form == DW_FORM_string)
718 Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const {
719 if (!isFormClass(FC_Reference))