872 lines · cpp
1//===--- lib/CodeGen/DIE.cpp - DWARF Info Entries -------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Data structures for DWARF info entries.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/CodeGen/DIE.h"14#include "DwarfCompileUnit.h"15#include "DwarfDebug.h"16#include "llvm/CodeGen/AsmPrinter.h"17#include "llvm/Config/llvm-config.h"18#include "llvm/MC/MCAsmInfo.h"19#include "llvm/MC/MCStreamer.h"20#include "llvm/MC/MCSymbol.h"21#include "llvm/Support/Debug.h"22#include "llvm/Support/ErrorHandling.h"23#include "llvm/Support/Format.h"24#include "llvm/Support/LEB128.h"25#include "llvm/Support/raw_ostream.h"26using namespace llvm;27 28#define DEBUG_TYPE "dwarfdebug"29 30//===----------------------------------------------------------------------===//31// DIEAbbrevData Implementation32//===----------------------------------------------------------------------===//33 34/// Profile - Used to gather unique data for the abbreviation folding set.35///36void DIEAbbrevData::Profile(FoldingSetNodeID &ID) const {37 // Explicitly cast to an integer type for which FoldingSetNodeID has38 // overloads. Otherwise MSVC 2010 thinks this call is ambiguous.39 ID.AddInteger(unsigned(Attribute));40 ID.AddInteger(unsigned(Form));41 if (Form == dwarf::DW_FORM_implicit_const)42 ID.AddInteger(Value);43}44 45//===----------------------------------------------------------------------===//46// DIEAbbrev Implementation47//===----------------------------------------------------------------------===//48 49/// Profile - Used to gather unique data for the abbreviation folding set.50///51void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {52 ID.AddInteger(unsigned(Tag));53 ID.AddInteger(unsigned(Children));54 55 // For each attribute description.56 for (const DIEAbbrevData &D : Data)57 D.Profile(ID);58}59 60/// Emit - Print the abbreviation using the specified asm printer.61///62void DIEAbbrev::Emit(const AsmPrinter *AP) const {63 // Emit its Dwarf tag type.64 AP->emitULEB128(Tag, dwarf::TagString(Tag).data());65 66 // Emit whether it has children DIEs.67 AP->emitULEB128((unsigned)Children, dwarf::ChildrenString(Children).data());68 69 // For each attribute description.70 for (const DIEAbbrevData &AttrData : Data) {71 // Emit attribute type.72 AP->emitULEB128(AttrData.getAttribute(),73 dwarf::AttributeString(AttrData.getAttribute()).data());74 75 // Emit form type.76#ifndef NDEBUG77 // Could be an assertion, but this way we can see the failing form code78 // easily, which helps track down where it came from.79 if (!dwarf::isValidFormForVersion(AttrData.getForm(),80 AP->getDwarfVersion())) {81 LLVM_DEBUG(dbgs() << "Invalid form " << format("0x%x", AttrData.getForm())82 << " for DWARF version " << AP->getDwarfVersion()83 << "\n");84 llvm_unreachable("Invalid form for specified DWARF version");85 }86#endif87 AP->emitULEB128(AttrData.getForm(),88 dwarf::FormEncodingString(AttrData.getForm()).data());89 90 // Emit value for DW_FORM_implicit_const.91 if (AttrData.getForm() == dwarf::DW_FORM_implicit_const)92 AP->emitSLEB128(AttrData.getValue());93 }94 95 // Mark end of abbreviation.96 AP->emitULEB128(0, "EOM(1)");97 AP->emitULEB128(0, "EOM(2)");98}99 100LLVM_DUMP_METHOD101void DIEAbbrev::print(raw_ostream &O) const {102 O << "Abbreviation @"103 << format("0x%lx", (long)(intptr_t)this)104 << " "105 << dwarf::TagString(Tag)106 << " "107 << dwarf::ChildrenString(Children)108 << '\n';109 110 for (const DIEAbbrevData &D : Data) {111 O << " " << dwarf::AttributeString(D.getAttribute()) << " "112 << dwarf::FormEncodingString(D.getForm());113 114 if (D.getForm() == dwarf::DW_FORM_implicit_const)115 O << " " << D.getValue();116 117 O << '\n';118 }119}120 121#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)122LLVM_DUMP_METHOD void DIEAbbrev::dump() const {123 print(dbgs());124}125#endif126 127//===----------------------------------------------------------------------===//128// DIEAbbrevSet Implementation129//===----------------------------------------------------------------------===//130 131DIEAbbrevSet::~DIEAbbrevSet() {132 for (DIEAbbrev *Abbrev : Abbreviations)133 Abbrev->~DIEAbbrev();134}135 136DIEAbbrev &DIEAbbrevSet::uniqueAbbreviation(DIE &Die) {137 138 FoldingSetNodeID ID;139 DIEAbbrev Abbrev = Die.generateAbbrev();140 Abbrev.Profile(ID);141 142 void *InsertPos;143 if (DIEAbbrev *Existing =144 AbbreviationsSet.FindNodeOrInsertPos(ID, InsertPos)) {145 Die.setAbbrevNumber(Existing->getNumber());146 return *Existing;147 }148 149 // Move the abbreviation to the heap and assign a number.150 DIEAbbrev *New = new (Alloc) DIEAbbrev(std::move(Abbrev));151 Abbreviations.push_back(New);152 New->setNumber(Abbreviations.size());153 Die.setAbbrevNumber(Abbreviations.size());154 155 // Store it for lookup.156 AbbreviationsSet.InsertNode(New, InsertPos);157 return *New;158}159 160void DIEAbbrevSet::Emit(const AsmPrinter *AP, MCSection *Section) const {161 if (!Abbreviations.empty()) {162 // Start the debug abbrev section.163 AP->OutStreamer->switchSection(Section);164 AP->emitDwarfAbbrevs(Abbreviations);165 }166}167 168//===----------------------------------------------------------------------===//169// DIE Implementation170//===----------------------------------------------------------------------===//171 172DIE *DIE::getParent() const { return dyn_cast_if_present<DIE *>(Owner); }173 174DIEAbbrev DIE::generateAbbrev() const {175 DIEAbbrev Abbrev(Tag, hasChildren());176 for (const DIEValue &V : values())177 if (V.getForm() == dwarf::DW_FORM_implicit_const)178 Abbrev.AddImplicitConstAttribute(V.getAttribute(),179 V.getDIEInteger().getValue());180 else181 Abbrev.AddAttribute(V.getAttribute(), V.getForm());182 return Abbrev;183}184 185uint64_t DIE::getDebugSectionOffset() const {186 const DIEUnit *Unit = getUnit();187 assert(Unit && "DIE must be owned by a DIEUnit to get its absolute offset");188 return Unit->getDebugSectionOffset() + getOffset();189}190 191const DIE *DIE::getUnitDie() const {192 const DIE *p = this;193 while (p) {194 if (p->getTag() == dwarf::DW_TAG_compile_unit ||195 p->getTag() == dwarf::DW_TAG_skeleton_unit ||196 p->getTag() == dwarf::DW_TAG_type_unit)197 return p;198 p = p->getParent();199 }200 return nullptr;201}202 203DIEUnit *DIE::getUnit() const {204 const DIE *UnitDie = getUnitDie();205 if (UnitDie)206 return dyn_cast_if_present<DIEUnit *>(UnitDie->Owner);207 return nullptr;208}209 210DIEValue DIE::findAttribute(dwarf::Attribute Attribute) const {211 // Iterate through all the attributes until we find the one we're212 // looking for, if we can't find it return NULL.213 for (const auto &V : values())214 if (V.getAttribute() == Attribute)215 return V;216 return DIEValue();217}218 219LLVM_DUMP_METHOD220static void printValues(raw_ostream &O, const DIEValueList &Values,221 StringRef Type, unsigned Size, unsigned IndentCount) {222 O << Type << ": Size: " << Size << "\n";223 224 unsigned I = 0;225 const std::string Indent(IndentCount, ' ');226 for (const auto &V : Values.values()) {227 O << Indent;228 O << "Blk[" << I++ << "]";229 O << " " << dwarf::FormEncodingString(V.getForm()) << " ";230 V.print(O);231 O << "\n";232 }233}234 235LLVM_DUMP_METHOD236void DIE::print(raw_ostream &O, unsigned IndentCount) const {237 const std::string Indent(IndentCount, ' ');238 O << Indent << "Die: " << format("0x%lx", (long)(intptr_t) this)239 << ", Offset: " << Offset << ", Size: " << Size << "\n";240 241 O << Indent << dwarf::TagString(getTag()) << " "242 << dwarf::ChildrenString(hasChildren()) << "\n";243 244 IndentCount += 2;245 for (const auto &V : values()) {246 O << Indent;247 O << dwarf::AttributeString(V.getAttribute());248 O << " " << dwarf::FormEncodingString(V.getForm()) << " ";249 V.print(O);250 O << "\n";251 }252 IndentCount -= 2;253 254 for (const auto &Child : children())255 Child.print(O, IndentCount + 4);256 257 O << "\n";258}259 260#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)261LLVM_DUMP_METHOD void DIE::dump() const {262 print(dbgs());263}264#endif265 266unsigned DIE::computeOffsetsAndAbbrevs(const dwarf::FormParams &FormParams,267 DIEAbbrevSet &AbbrevSet,268 unsigned CUOffset) {269 // Unique the abbreviation and fill in the abbreviation number so this DIE270 // can be emitted.271 const DIEAbbrev &Abbrev = AbbrevSet.uniqueAbbreviation(*this);272 273 // Set compile/type unit relative offset of this DIE.274 setOffset(CUOffset);275 276 // Add the byte size of the abbreviation code.277 CUOffset += getULEB128Size(getAbbrevNumber());278 279 // Add the byte size of all the DIE attribute values.280 for (const auto &V : values())281 CUOffset += V.sizeOf(FormParams);282 283 // Let the children compute their offsets and abbreviation numbers.284 if (hasChildren()) {285 (void)Abbrev;286 assert(Abbrev.hasChildren() && "Children flag not set");287 288 for (auto &Child : children())289 CUOffset =290 Child.computeOffsetsAndAbbrevs(FormParams, AbbrevSet, CUOffset);291 292 // Each child chain is terminated with a zero byte, adjust the offset.293 CUOffset += sizeof(int8_t);294 }295 296 // Compute the byte size of this DIE and all of its children correctly. This297 // is needed so that top level DIE can help the compile unit set its length298 // correctly.299 setSize(CUOffset - getOffset());300 return CUOffset;301}302 303//===----------------------------------------------------------------------===//304// DIEUnit Implementation305//===----------------------------------------------------------------------===//306DIEUnit::DIEUnit(dwarf::Tag UnitTag) : Die(UnitTag) {307 Die.Owner = this;308 assert((UnitTag == dwarf::DW_TAG_compile_unit ||309 UnitTag == dwarf::DW_TAG_skeleton_unit ||310 UnitTag == dwarf::DW_TAG_type_unit ||311 UnitTag == dwarf::DW_TAG_partial_unit) &&312 "expected a unit TAG");313}314 315void DIEValue::emitValue(const AsmPrinter *AP) const {316 switch (Ty) {317 case isNone:318 llvm_unreachable("Expected valid DIEValue");319#define HANDLE_DIEVALUE(T) \320 case is##T: \321 getDIE##T().emitValue(AP, Form); \322 break;323#include "llvm/CodeGen/DIEValue.def"324 }325}326 327unsigned DIEValue::sizeOf(const dwarf::FormParams &FormParams) const {328 switch (Ty) {329 case isNone:330 llvm_unreachable("Expected valid DIEValue");331#define HANDLE_DIEVALUE(T) \332 case is##T: \333 return getDIE##T().sizeOf(FormParams, Form);334#include "llvm/CodeGen/DIEValue.def"335 }336 llvm_unreachable("Unknown DIE kind");337}338 339LLVM_DUMP_METHOD340void DIEValue::print(raw_ostream &O) const {341 switch (Ty) {342 case isNone:343 llvm_unreachable("Expected valid DIEValue");344#define HANDLE_DIEVALUE(T) \345 case is##T: \346 getDIE##T().print(O); \347 break;348#include "llvm/CodeGen/DIEValue.def"349 }350}351 352#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)353LLVM_DUMP_METHOD void DIEValue::dump() const {354 print(dbgs());355}356#endif357 358//===----------------------------------------------------------------------===//359// DIEInteger Implementation360//===----------------------------------------------------------------------===//361 362/// EmitValue - Emit integer of appropriate size.363///364void DIEInteger::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {365 switch (Form) {366 case dwarf::DW_FORM_implicit_const:367 case dwarf::DW_FORM_flag_present:368 // Emit something to keep the lines and comments in sync.369 // FIXME: Is there a better way to do this?370 Asm->OutStreamer->addBlankLine();371 return;372 case dwarf::DW_FORM_flag:373 case dwarf::DW_FORM_ref1:374 case dwarf::DW_FORM_data1:375 case dwarf::DW_FORM_strx1:376 case dwarf::DW_FORM_addrx1:377 case dwarf::DW_FORM_ref2:378 case dwarf::DW_FORM_data2:379 case dwarf::DW_FORM_strx2:380 case dwarf::DW_FORM_addrx2:381 case dwarf::DW_FORM_strx3:382 case dwarf::DW_FORM_addrx3:383 case dwarf::DW_FORM_strp:384 case dwarf::DW_FORM_ref4:385 case dwarf::DW_FORM_data4:386 case dwarf::DW_FORM_ref_sup4:387 case dwarf::DW_FORM_strx4:388 case dwarf::DW_FORM_addrx4:389 case dwarf::DW_FORM_ref8:390 case dwarf::DW_FORM_ref_sig8:391 case dwarf::DW_FORM_data8:392 case dwarf::DW_FORM_ref_sup8:393 case dwarf::DW_FORM_GNU_ref_alt:394 case dwarf::DW_FORM_GNU_strp_alt:395 case dwarf::DW_FORM_line_strp:396 case dwarf::DW_FORM_sec_offset:397 case dwarf::DW_FORM_strp_sup:398 case dwarf::DW_FORM_addr:399 case dwarf::DW_FORM_ref_addr:400 Asm->OutStreamer->emitIntValue(Integer,401 sizeOf(Asm->getDwarfFormParams(), Form));402 return;403 case dwarf::DW_FORM_GNU_str_index:404 case dwarf::DW_FORM_GNU_addr_index:405 case dwarf::DW_FORM_ref_udata:406 case dwarf::DW_FORM_strx:407 case dwarf::DW_FORM_addrx:408 case dwarf::DW_FORM_rnglistx:409 case dwarf::DW_FORM_udata:410 Asm->emitULEB128(Integer);411 return;412 case dwarf::DW_FORM_sdata:413 Asm->emitSLEB128(Integer);414 return;415 default: llvm_unreachable("DIE Value form not supported yet");416 }417}418 419/// sizeOf - Determine size of integer value in bytes.420///421unsigned DIEInteger::sizeOf(const dwarf::FormParams &FormParams,422 dwarf::Form Form) const {423 if (std::optional<uint8_t> FixedSize =424 dwarf::getFixedFormByteSize(Form, FormParams))425 return *FixedSize;426 427 switch (Form) {428 case dwarf::DW_FORM_GNU_str_index:429 case dwarf::DW_FORM_GNU_addr_index:430 case dwarf::DW_FORM_ref_udata:431 case dwarf::DW_FORM_strx:432 case dwarf::DW_FORM_addrx:433 case dwarf::DW_FORM_rnglistx:434 case dwarf::DW_FORM_udata:435 return getULEB128Size(Integer);436 case dwarf::DW_FORM_sdata:437 return getSLEB128Size(Integer);438 default: llvm_unreachable("DIE Value form not supported yet");439 }440}441 442LLVM_DUMP_METHOD443void DIEInteger::print(raw_ostream &O) const {444 O << "Int: " << (int64_t)Integer << " 0x";445 O.write_hex(Integer);446}447 448//===----------------------------------------------------------------------===//449// DIEExpr Implementation450//===----------------------------------------------------------------------===//451 452/// EmitValue - Emit expression value.453///454void DIEExpr::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {455 AP->emitDebugValue(Expr, sizeOf(AP->getDwarfFormParams(), Form));456}457 458/// SizeOf - Determine size of expression value in bytes.459///460unsigned DIEExpr::sizeOf(const dwarf::FormParams &FormParams,461 dwarf::Form Form) const {462 switch (Form) {463 case dwarf::DW_FORM_data4:464 return 4;465 case dwarf::DW_FORM_data8:466 return 8;467 case dwarf::DW_FORM_sec_offset:468 return FormParams.getDwarfOffsetByteSize();469 default:470 llvm_unreachable("DIE Value form not supported yet");471 }472}473 474LLVM_DUMP_METHOD475void DIEExpr::print(raw_ostream &O) const {476 O << "Expr: ";477 MCAsmInfo().printExpr(O, *Expr);478}479 480//===----------------------------------------------------------------------===//481// DIELabel Implementation482//===----------------------------------------------------------------------===//483 484/// EmitValue - Emit label value.485///486void DIELabel::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {487 bool IsSectionRelative = Form != dwarf::DW_FORM_addr;488 AP->emitLabelReference(Label, sizeOf(AP->getDwarfFormParams(), Form),489 IsSectionRelative);490}491 492/// sizeOf - Determine size of label value in bytes.493///494unsigned DIELabel::sizeOf(const dwarf::FormParams &FormParams,495 dwarf::Form Form) const {496 switch (Form) {497 case dwarf::DW_FORM_data4:498 return 4;499 case dwarf::DW_FORM_data8:500 return 8;501 case dwarf::DW_FORM_sec_offset:502 case dwarf::DW_FORM_strp:503 return FormParams.getDwarfOffsetByteSize();504 case dwarf::DW_FORM_addr:505 return FormParams.AddrSize;506 default:507 llvm_unreachable("DIE Value form not supported yet");508 }509}510 511LLVM_DUMP_METHOD512void DIELabel::print(raw_ostream &O) const { O << "Lbl: " << Label->getName(); }513 514//===----------------------------------------------------------------------===//515// DIEBaseTypeRef Implementation516//===----------------------------------------------------------------------===//517 518void DIEBaseTypeRef::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {519 uint64_t Offset = CU->ExprRefedBaseTypes[Index].Die->getOffset();520 assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit");521 AP->emitULEB128(Offset, nullptr, ULEB128PadSize);522}523 524unsigned DIEBaseTypeRef::sizeOf(const dwarf::FormParams &, dwarf::Form) const {525 return ULEB128PadSize;526}527 528LLVM_DUMP_METHOD529void DIEBaseTypeRef::print(raw_ostream &O) const { O << "BaseTypeRef: " << Index; }530 531//===----------------------------------------------------------------------===//532// DIEDelta Implementation533//===----------------------------------------------------------------------===//534 535/// EmitValue - Emit delta value.536///537void DIEDelta::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {538 AP->emitLabelDifference(LabelHi, LabelLo,539 sizeOf(AP->getDwarfFormParams(), Form));540}541 542/// SizeOf - Determine size of delta value in bytes.543///544unsigned DIEDelta::sizeOf(const dwarf::FormParams &FormParams,545 dwarf::Form Form) const {546 switch (Form) {547 case dwarf::DW_FORM_data4:548 return 4;549 case dwarf::DW_FORM_data8:550 return 8;551 case dwarf::DW_FORM_sec_offset:552 return FormParams.getDwarfOffsetByteSize();553 default:554 llvm_unreachable("DIE Value form not supported yet");555 }556}557 558LLVM_DUMP_METHOD559void DIEDelta::print(raw_ostream &O) const {560 O << "Del: " << LabelHi->getName() << "-" << LabelLo->getName();561}562 563//===----------------------------------------------------------------------===//564// DIEString Implementation565//===----------------------------------------------------------------------===//566 567/// EmitValue - Emit string value.568///569void DIEString::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {570 // Index of string in symbol table.571 switch (Form) {572 case dwarf::DW_FORM_GNU_str_index:573 case dwarf::DW_FORM_strx:574 case dwarf::DW_FORM_strx1:575 case dwarf::DW_FORM_strx2:576 case dwarf::DW_FORM_strx3:577 case dwarf::DW_FORM_strx4:578 DIEInteger(S.getIndex()).emitValue(AP, Form);579 return;580 case dwarf::DW_FORM_strp:581 if (AP->doesDwarfUseRelocationsAcrossSections())582 DIELabel(S.getSymbol()).emitValue(AP, Form);583 else584 DIEInteger(S.getOffset()).emitValue(AP, Form);585 return;586 default:587 llvm_unreachable("Expected valid string form");588 }589}590 591/// sizeOf - Determine size of delta value in bytes.592///593unsigned DIEString::sizeOf(const dwarf::FormParams &FormParams,594 dwarf::Form Form) const {595 // Index of string in symbol table.596 switch (Form) {597 case dwarf::DW_FORM_GNU_str_index:598 case dwarf::DW_FORM_strx:599 case dwarf::DW_FORM_strx1:600 case dwarf::DW_FORM_strx2:601 case dwarf::DW_FORM_strx3:602 case dwarf::DW_FORM_strx4:603 return DIEInteger(S.getIndex()).sizeOf(FormParams, Form);604 case dwarf::DW_FORM_strp:605 if (FormParams.DwarfUsesRelocationsAcrossSections)606 return DIELabel(S.getSymbol()).sizeOf(FormParams, Form);607 return DIEInteger(S.getOffset()).sizeOf(FormParams, Form);608 default:609 llvm_unreachable("Expected valid string form");610 }611}612 613LLVM_DUMP_METHOD614void DIEString::print(raw_ostream &O) const {615 O << "String: " << S.getString();616}617 618//===----------------------------------------------------------------------===//619// DIEInlineString Implementation620//===----------------------------------------------------------------------===//621void DIEInlineString::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {622 if (Form == dwarf::DW_FORM_string) {623 AP->OutStreamer->emitBytes(S);624 AP->emitInt8(0);625 return;626 }627 llvm_unreachable("Expected valid string form");628}629 630unsigned DIEInlineString::sizeOf(const dwarf::FormParams &, dwarf::Form) const {631 // Emit string bytes + NULL byte.632 return S.size() + 1;633}634 635LLVM_DUMP_METHOD636void DIEInlineString::print(raw_ostream &O) const {637 O << "InlineString: " << S;638}639 640//===----------------------------------------------------------------------===//641// DIEEntry Implementation642//===----------------------------------------------------------------------===//643 644/// EmitValue - Emit debug information entry offset.645///646void DIEEntry::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {647 648 switch (Form) {649 case dwarf::DW_FORM_ref1:650 case dwarf::DW_FORM_ref2:651 case dwarf::DW_FORM_ref4:652 case dwarf::DW_FORM_ref8:653 AP->OutStreamer->emitIntValue(Entry->getOffset(),654 sizeOf(AP->getDwarfFormParams(), Form));655 return;656 657 case dwarf::DW_FORM_ref_udata:658 AP->emitULEB128(Entry->getOffset());659 return;660 661 case dwarf::DW_FORM_ref_addr: {662 // Get the absolute offset for this DIE within the debug info/types section.663 uint64_t Addr = Entry->getDebugSectionOffset();664 if (const MCSymbol *SectionSym =665 Entry->getUnit()->getCrossSectionRelativeBaseAddress()) {666 AP->emitLabelPlusOffset(SectionSym, Addr,667 sizeOf(AP->getDwarfFormParams(), Form), true);668 return;669 }670 671 AP->OutStreamer->emitIntValue(Addr, sizeOf(AP->getDwarfFormParams(), Form));672 return;673 }674 default:675 llvm_unreachable("Improper form for DIE reference");676 }677}678 679unsigned DIEEntry::sizeOf(const dwarf::FormParams &FormParams,680 dwarf::Form Form) const {681 switch (Form) {682 case dwarf::DW_FORM_ref1:683 return 1;684 case dwarf::DW_FORM_ref2:685 return 2;686 case dwarf::DW_FORM_ref4:687 return 4;688 case dwarf::DW_FORM_ref8:689 return 8;690 case dwarf::DW_FORM_ref_udata:691 return getULEB128Size(Entry->getOffset());692 case dwarf::DW_FORM_ref_addr:693 return FormParams.getRefAddrByteSize();694 695 default:696 llvm_unreachable("Improper form for DIE reference");697 }698}699 700LLVM_DUMP_METHOD701void DIEEntry::print(raw_ostream &O) const {702 O << format("Die: 0x%lx", (long)(intptr_t)&Entry);703}704 705//===----------------------------------------------------------------------===//706// DIELoc Implementation707//===----------------------------------------------------------------------===//708 709unsigned DIELoc::computeSize(const dwarf::FormParams &FormParams) const {710 if (!Size) {711 for (const auto &V : values())712 Size += V.sizeOf(FormParams);713 }714 715 return Size;716}717 718/// EmitValue - Emit location data.719///720void DIELoc::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {721 switch (Form) {722 default: llvm_unreachable("Improper form for block");723 case dwarf::DW_FORM_block1: Asm->emitInt8(Size); break;724 case dwarf::DW_FORM_block2: Asm->emitInt16(Size); break;725 case dwarf::DW_FORM_block4: Asm->emitInt32(Size); break;726 case dwarf::DW_FORM_block:727 case dwarf::DW_FORM_exprloc:728 Asm->emitULEB128(Size);729 break;730 }731 732 for (const auto &V : values())733 V.emitValue(Asm);734}735 736/// sizeOf - Determine size of location data in bytes.737///738unsigned DIELoc::sizeOf(const dwarf::FormParams &, dwarf::Form Form) const {739 switch (Form) {740 case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);741 case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);742 case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);743 case dwarf::DW_FORM_block:744 case dwarf::DW_FORM_exprloc:745 return Size + getULEB128Size(Size);746 default: llvm_unreachable("Improper form for block");747 }748}749 750LLVM_DUMP_METHOD751void DIELoc::print(raw_ostream &O) const {752 printValues(O, *this, "ExprLoc", Size, 5);753}754 755//===----------------------------------------------------------------------===//756// DIEBlock Implementation757//===----------------------------------------------------------------------===//758 759unsigned DIEBlock::computeSize(const dwarf::FormParams &FormParams) const {760 if (!Size) {761 for (const auto &V : values())762 Size += V.sizeOf(FormParams);763 }764 765 return Size;766}767 768/// EmitValue - Emit block data.769///770void DIEBlock::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {771 switch (Form) {772 default: llvm_unreachable("Improper form for block");773 case dwarf::DW_FORM_block1: Asm->emitInt8(Size); break;774 case dwarf::DW_FORM_block2: Asm->emitInt16(Size); break;775 case dwarf::DW_FORM_block4: Asm->emitInt32(Size); break;776 case dwarf::DW_FORM_exprloc:777 case dwarf::DW_FORM_block:778 Asm->emitULEB128(Size);779 break;780 case dwarf::DW_FORM_string: break;781 case dwarf::DW_FORM_data16: break;782 }783 784 for (const auto &V : values())785 V.emitValue(Asm);786}787 788/// sizeOf - Determine size of block data in bytes.789///790unsigned DIEBlock::sizeOf(const dwarf::FormParams &, dwarf::Form Form) const {791 switch (Form) {792 case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);793 case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);794 case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);795 case dwarf::DW_FORM_exprloc:796 case dwarf::DW_FORM_block: return Size + getULEB128Size(Size);797 case dwarf::DW_FORM_data16: return 16;798 default: llvm_unreachable("Improper form for block");799 }800}801 802LLVM_DUMP_METHOD803void DIEBlock::print(raw_ostream &O) const {804 printValues(O, *this, "Blk", Size, 5);805}806 807//===----------------------------------------------------------------------===//808// DIELocList Implementation809//===----------------------------------------------------------------------===//810 811unsigned DIELocList::sizeOf(const dwarf::FormParams &FormParams,812 dwarf::Form Form) const {813 switch (Form) {814 case dwarf::DW_FORM_loclistx:815 return getULEB128Size(Index);816 case dwarf::DW_FORM_data4:817 assert(FormParams.Format != dwarf::DWARF64 &&818 "DW_FORM_data4 is not suitable to emit a pointer to a location list "819 "in the 64-bit DWARF format");820 return 4;821 case dwarf::DW_FORM_data8:822 assert(FormParams.Format == dwarf::DWARF64 &&823 "DW_FORM_data8 is not suitable to emit a pointer to a location list "824 "in the 32-bit DWARF format");825 return 8;826 case dwarf::DW_FORM_sec_offset:827 return FormParams.getDwarfOffsetByteSize();828 default:829 llvm_unreachable("DIE Value form not supported yet");830 }831}832 833/// EmitValue - Emit label value.834///835void DIELocList::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {836 if (Form == dwarf::DW_FORM_loclistx) {837 AP->emitULEB128(Index);838 return;839 }840 DwarfDebug *DD = AP->getDwarfDebug();841 MCSymbol *Label = DD->getDebugLocs().getList(Index).Label;842 AP->emitDwarfSymbolReference(Label, /*ForceOffset*/ DD->useSplitDwarf());843}844 845LLVM_DUMP_METHOD846void DIELocList::print(raw_ostream &O) const { O << "LocList: " << Index; }847 848//===----------------------------------------------------------------------===//849// DIEAddrOffset Implementation850//===----------------------------------------------------------------------===//851 852unsigned DIEAddrOffset::sizeOf(const dwarf::FormParams &FormParams,853 dwarf::Form) const {854 return Addr.sizeOf(FormParams, dwarf::DW_FORM_addrx) +855 Offset.sizeOf(FormParams, dwarf::DW_FORM_data4);856}857 858/// EmitValue - Emit label value.859///860void DIEAddrOffset::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {861 Addr.emitValue(AP, dwarf::DW_FORM_addrx);862 Offset.emitValue(AP, dwarf::DW_FORM_data4);863}864 865LLVM_DUMP_METHOD866void DIEAddrOffset::print(raw_ostream &O) const {867 O << "AddrOffset: ";868 Addr.print(O);869 O << " + ";870 Offset.print(O);871}872