17330f729Sjoerg //===--- lib/CodeGen/DIE.cpp - DWARF Info Entries -------------------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // Data structures for DWARF info entries.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg
137330f729Sjoerg #include "llvm/CodeGen/DIE.h"
147330f729Sjoerg #include "DwarfCompileUnit.h"
157330f729Sjoerg #include "DwarfDebug.h"
167330f729Sjoerg #include "DwarfUnit.h"
177330f729Sjoerg #include "llvm/ADT/Twine.h"
187330f729Sjoerg #include "llvm/CodeGen/AsmPrinter.h"
197330f729Sjoerg #include "llvm/Config/llvm-config.h"
207330f729Sjoerg #include "llvm/IR/DataLayout.h"
217330f729Sjoerg #include "llvm/MC/MCAsmInfo.h"
227330f729Sjoerg #include "llvm/MC/MCContext.h"
237330f729Sjoerg #include "llvm/MC/MCStreamer.h"
247330f729Sjoerg #include "llvm/MC/MCSymbol.h"
257330f729Sjoerg #include "llvm/Support/Debug.h"
267330f729Sjoerg #include "llvm/Support/ErrorHandling.h"
277330f729Sjoerg #include "llvm/Support/Format.h"
287330f729Sjoerg #include "llvm/Support/FormattedStream.h"
297330f729Sjoerg #include "llvm/Support/LEB128.h"
307330f729Sjoerg #include "llvm/Support/MD5.h"
317330f729Sjoerg #include "llvm/Support/raw_ostream.h"
327330f729Sjoerg using namespace llvm;
337330f729Sjoerg
347330f729Sjoerg #define DEBUG_TYPE "dwarfdebug"
357330f729Sjoerg
367330f729Sjoerg //===----------------------------------------------------------------------===//
377330f729Sjoerg // DIEAbbrevData Implementation
387330f729Sjoerg //===----------------------------------------------------------------------===//
397330f729Sjoerg
407330f729Sjoerg /// Profile - Used to gather unique data for the abbreviation folding set.
417330f729Sjoerg ///
Profile(FoldingSetNodeID & ID) const427330f729Sjoerg void DIEAbbrevData::Profile(FoldingSetNodeID &ID) const {
437330f729Sjoerg // Explicitly cast to an integer type for which FoldingSetNodeID has
447330f729Sjoerg // overloads. Otherwise MSVC 2010 thinks this call is ambiguous.
457330f729Sjoerg ID.AddInteger(unsigned(Attribute));
467330f729Sjoerg ID.AddInteger(unsigned(Form));
477330f729Sjoerg if (Form == dwarf::DW_FORM_implicit_const)
487330f729Sjoerg ID.AddInteger(Value);
497330f729Sjoerg }
507330f729Sjoerg
517330f729Sjoerg //===----------------------------------------------------------------------===//
527330f729Sjoerg // DIEAbbrev Implementation
537330f729Sjoerg //===----------------------------------------------------------------------===//
547330f729Sjoerg
557330f729Sjoerg /// Profile - Used to gather unique data for the abbreviation folding set.
567330f729Sjoerg ///
Profile(FoldingSetNodeID & ID) const577330f729Sjoerg void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {
587330f729Sjoerg ID.AddInteger(unsigned(Tag));
597330f729Sjoerg ID.AddInteger(unsigned(Children));
607330f729Sjoerg
617330f729Sjoerg // For each attribute description.
627330f729Sjoerg for (unsigned i = 0, N = Data.size(); i < N; ++i)
637330f729Sjoerg Data[i].Profile(ID);
647330f729Sjoerg }
657330f729Sjoerg
667330f729Sjoerg /// Emit - Print the abbreviation using the specified asm printer.
677330f729Sjoerg ///
Emit(const AsmPrinter * AP) const687330f729Sjoerg void DIEAbbrev::Emit(const AsmPrinter *AP) const {
697330f729Sjoerg // Emit its Dwarf tag type.
70*82d56013Sjoerg AP->emitULEB128(Tag, dwarf::TagString(Tag).data());
717330f729Sjoerg
727330f729Sjoerg // Emit whether it has children DIEs.
73*82d56013Sjoerg AP->emitULEB128((unsigned)Children, dwarf::ChildrenString(Children).data());
747330f729Sjoerg
757330f729Sjoerg // For each attribute description.
767330f729Sjoerg for (unsigned i = 0, N = Data.size(); i < N; ++i) {
777330f729Sjoerg const DIEAbbrevData &AttrData = Data[i];
787330f729Sjoerg
797330f729Sjoerg // Emit attribute type.
80*82d56013Sjoerg AP->emitULEB128(AttrData.getAttribute(),
817330f729Sjoerg dwarf::AttributeString(AttrData.getAttribute()).data());
827330f729Sjoerg
837330f729Sjoerg // Emit form type.
847330f729Sjoerg #ifndef NDEBUG
857330f729Sjoerg // Could be an assertion, but this way we can see the failing form code
867330f729Sjoerg // easily, which helps track down where it came from.
877330f729Sjoerg if (!dwarf::isValidFormForVersion(AttrData.getForm(),
887330f729Sjoerg AP->getDwarfVersion())) {
897330f729Sjoerg LLVM_DEBUG(dbgs() << "Invalid form " << format("0x%x", AttrData.getForm())
907330f729Sjoerg << " for DWARF version " << AP->getDwarfVersion()
917330f729Sjoerg << "\n");
927330f729Sjoerg llvm_unreachable("Invalid form for specified DWARF version");
937330f729Sjoerg }
947330f729Sjoerg #endif
95*82d56013Sjoerg AP->emitULEB128(AttrData.getForm(),
967330f729Sjoerg dwarf::FormEncodingString(AttrData.getForm()).data());
977330f729Sjoerg
987330f729Sjoerg // Emit value for DW_FORM_implicit_const.
997330f729Sjoerg if (AttrData.getForm() == dwarf::DW_FORM_implicit_const)
100*82d56013Sjoerg AP->emitSLEB128(AttrData.getValue());
1017330f729Sjoerg }
1027330f729Sjoerg
1037330f729Sjoerg // Mark end of abbreviation.
104*82d56013Sjoerg AP->emitULEB128(0, "EOM(1)");
105*82d56013Sjoerg AP->emitULEB128(0, "EOM(2)");
1067330f729Sjoerg }
1077330f729Sjoerg
1087330f729Sjoerg LLVM_DUMP_METHOD
print(raw_ostream & O) const1097330f729Sjoerg void DIEAbbrev::print(raw_ostream &O) const {
1107330f729Sjoerg O << "Abbreviation @"
1117330f729Sjoerg << format("0x%lx", (long)(intptr_t)this)
1127330f729Sjoerg << " "
1137330f729Sjoerg << dwarf::TagString(Tag)
1147330f729Sjoerg << " "
1157330f729Sjoerg << dwarf::ChildrenString(Children)
1167330f729Sjoerg << '\n';
1177330f729Sjoerg
1187330f729Sjoerg for (unsigned i = 0, N = Data.size(); i < N; ++i) {
1197330f729Sjoerg O << " "
1207330f729Sjoerg << dwarf::AttributeString(Data[i].getAttribute())
1217330f729Sjoerg << " "
1227330f729Sjoerg << dwarf::FormEncodingString(Data[i].getForm());
1237330f729Sjoerg
1247330f729Sjoerg if (Data[i].getForm() == dwarf::DW_FORM_implicit_const)
1257330f729Sjoerg O << " " << Data[i].getValue();
1267330f729Sjoerg
1277330f729Sjoerg O << '\n';
1287330f729Sjoerg }
1297330f729Sjoerg }
1307330f729Sjoerg
1317330f729Sjoerg #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const1327330f729Sjoerg LLVM_DUMP_METHOD void DIEAbbrev::dump() const {
1337330f729Sjoerg print(dbgs());
1347330f729Sjoerg }
1357330f729Sjoerg #endif
1367330f729Sjoerg
1377330f729Sjoerg //===----------------------------------------------------------------------===//
1387330f729Sjoerg // DIEAbbrevSet Implementation
1397330f729Sjoerg //===----------------------------------------------------------------------===//
1407330f729Sjoerg
~DIEAbbrevSet()1417330f729Sjoerg DIEAbbrevSet::~DIEAbbrevSet() {
1427330f729Sjoerg for (DIEAbbrev *Abbrev : Abbreviations)
1437330f729Sjoerg Abbrev->~DIEAbbrev();
1447330f729Sjoerg }
1457330f729Sjoerg
uniqueAbbreviation(DIE & Die)1467330f729Sjoerg DIEAbbrev &DIEAbbrevSet::uniqueAbbreviation(DIE &Die) {
1477330f729Sjoerg
1487330f729Sjoerg FoldingSetNodeID ID;
1497330f729Sjoerg DIEAbbrev Abbrev = Die.generateAbbrev();
1507330f729Sjoerg Abbrev.Profile(ID);
1517330f729Sjoerg
1527330f729Sjoerg void *InsertPos;
1537330f729Sjoerg if (DIEAbbrev *Existing =
1547330f729Sjoerg AbbreviationsSet.FindNodeOrInsertPos(ID, InsertPos)) {
1557330f729Sjoerg Die.setAbbrevNumber(Existing->getNumber());
1567330f729Sjoerg return *Existing;
1577330f729Sjoerg }
1587330f729Sjoerg
1597330f729Sjoerg // Move the abbreviation to the heap and assign a number.
1607330f729Sjoerg DIEAbbrev *New = new (Alloc) DIEAbbrev(std::move(Abbrev));
1617330f729Sjoerg Abbreviations.push_back(New);
1627330f729Sjoerg New->setNumber(Abbreviations.size());
1637330f729Sjoerg Die.setAbbrevNumber(Abbreviations.size());
1647330f729Sjoerg
1657330f729Sjoerg // Store it for lookup.
1667330f729Sjoerg AbbreviationsSet.InsertNode(New, InsertPos);
1677330f729Sjoerg return *New;
1687330f729Sjoerg }
1697330f729Sjoerg
Emit(const AsmPrinter * AP,MCSection * Section) const1707330f729Sjoerg void DIEAbbrevSet::Emit(const AsmPrinter *AP, MCSection *Section) const {
1717330f729Sjoerg if (!Abbreviations.empty()) {
1727330f729Sjoerg // Start the debug abbrev section.
1737330f729Sjoerg AP->OutStreamer->SwitchSection(Section);
1747330f729Sjoerg AP->emitDwarfAbbrevs(Abbreviations);
1757330f729Sjoerg }
1767330f729Sjoerg }
1777330f729Sjoerg
1787330f729Sjoerg //===----------------------------------------------------------------------===//
1797330f729Sjoerg // DIE Implementation
1807330f729Sjoerg //===----------------------------------------------------------------------===//
1817330f729Sjoerg
getParent() const1827330f729Sjoerg DIE *DIE::getParent() const {
1837330f729Sjoerg return Owner.dyn_cast<DIE*>();
1847330f729Sjoerg }
1857330f729Sjoerg
generateAbbrev() const1867330f729Sjoerg DIEAbbrev DIE::generateAbbrev() const {
1877330f729Sjoerg DIEAbbrev Abbrev(Tag, hasChildren());
1887330f729Sjoerg for (const DIEValue &V : values())
1897330f729Sjoerg if (V.getForm() == dwarf::DW_FORM_implicit_const)
1907330f729Sjoerg Abbrev.AddImplicitConstAttribute(V.getAttribute(),
1917330f729Sjoerg V.getDIEInteger().getValue());
1927330f729Sjoerg else
1937330f729Sjoerg Abbrev.AddAttribute(V.getAttribute(), V.getForm());
1947330f729Sjoerg return Abbrev;
1957330f729Sjoerg }
1967330f729Sjoerg
getDebugSectionOffset() const197*82d56013Sjoerg uint64_t DIE::getDebugSectionOffset() const {
1987330f729Sjoerg const DIEUnit *Unit = getUnit();
1997330f729Sjoerg assert(Unit && "DIE must be owned by a DIEUnit to get its absolute offset");
2007330f729Sjoerg return Unit->getDebugSectionOffset() + getOffset();
2017330f729Sjoerg }
2027330f729Sjoerg
getUnitDie() const2037330f729Sjoerg const DIE *DIE::getUnitDie() const {
2047330f729Sjoerg const DIE *p = this;
2057330f729Sjoerg while (p) {
2067330f729Sjoerg if (p->getTag() == dwarf::DW_TAG_compile_unit ||
2077330f729Sjoerg p->getTag() == dwarf::DW_TAG_type_unit)
2087330f729Sjoerg return p;
2097330f729Sjoerg p = p->getParent();
2107330f729Sjoerg }
2117330f729Sjoerg return nullptr;
2127330f729Sjoerg }
2137330f729Sjoerg
getUnit() const2147330f729Sjoerg DIEUnit *DIE::getUnit() const {
2157330f729Sjoerg const DIE *UnitDie = getUnitDie();
2167330f729Sjoerg if (UnitDie)
2177330f729Sjoerg return UnitDie->Owner.dyn_cast<DIEUnit*>();
2187330f729Sjoerg return nullptr;
2197330f729Sjoerg }
2207330f729Sjoerg
findAttribute(dwarf::Attribute Attribute) const2217330f729Sjoerg DIEValue DIE::findAttribute(dwarf::Attribute Attribute) const {
2227330f729Sjoerg // Iterate through all the attributes until we find the one we're
2237330f729Sjoerg // looking for, if we can't find it return NULL.
2247330f729Sjoerg for (const auto &V : values())
2257330f729Sjoerg if (V.getAttribute() == Attribute)
2267330f729Sjoerg return V;
2277330f729Sjoerg return DIEValue();
2287330f729Sjoerg }
2297330f729Sjoerg
2307330f729Sjoerg LLVM_DUMP_METHOD
printValues(raw_ostream & O,const DIEValueList & Values,StringRef Type,unsigned Size,unsigned IndentCount)2317330f729Sjoerg static void printValues(raw_ostream &O, const DIEValueList &Values,
2327330f729Sjoerg StringRef Type, unsigned Size, unsigned IndentCount) {
2337330f729Sjoerg O << Type << ": Size: " << Size << "\n";
2347330f729Sjoerg
2357330f729Sjoerg unsigned I = 0;
2367330f729Sjoerg const std::string Indent(IndentCount, ' ');
2377330f729Sjoerg for (const auto &V : Values.values()) {
2387330f729Sjoerg O << Indent;
2397330f729Sjoerg O << "Blk[" << I++ << "]";
2407330f729Sjoerg O << " " << dwarf::FormEncodingString(V.getForm()) << " ";
2417330f729Sjoerg V.print(O);
2427330f729Sjoerg O << "\n";
2437330f729Sjoerg }
2447330f729Sjoerg }
2457330f729Sjoerg
2467330f729Sjoerg LLVM_DUMP_METHOD
print(raw_ostream & O,unsigned IndentCount) const2477330f729Sjoerg void DIE::print(raw_ostream &O, unsigned IndentCount) const {
2487330f729Sjoerg const std::string Indent(IndentCount, ' ');
2497330f729Sjoerg O << Indent << "Die: " << format("0x%lx", (long)(intptr_t) this)
2507330f729Sjoerg << ", Offset: " << Offset << ", Size: " << Size << "\n";
2517330f729Sjoerg
2527330f729Sjoerg O << Indent << dwarf::TagString(getTag()) << " "
2537330f729Sjoerg << dwarf::ChildrenString(hasChildren()) << "\n";
2547330f729Sjoerg
2557330f729Sjoerg IndentCount += 2;
2567330f729Sjoerg for (const auto &V : values()) {
2577330f729Sjoerg O << Indent;
2587330f729Sjoerg O << dwarf::AttributeString(V.getAttribute());
2597330f729Sjoerg O << " " << dwarf::FormEncodingString(V.getForm()) << " ";
2607330f729Sjoerg V.print(O);
2617330f729Sjoerg O << "\n";
2627330f729Sjoerg }
2637330f729Sjoerg IndentCount -= 2;
2647330f729Sjoerg
2657330f729Sjoerg for (const auto &Child : children())
2667330f729Sjoerg Child.print(O, IndentCount + 4);
2677330f729Sjoerg
2687330f729Sjoerg O << "\n";
2697330f729Sjoerg }
2707330f729Sjoerg
2717330f729Sjoerg #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const2727330f729Sjoerg LLVM_DUMP_METHOD void DIE::dump() const {
2737330f729Sjoerg print(dbgs());
2747330f729Sjoerg }
2757330f729Sjoerg #endif
2767330f729Sjoerg
computeOffsetsAndAbbrevs(const AsmPrinter * AP,DIEAbbrevSet & AbbrevSet,unsigned CUOffset)2777330f729Sjoerg unsigned DIE::computeOffsetsAndAbbrevs(const AsmPrinter *AP,
2787330f729Sjoerg DIEAbbrevSet &AbbrevSet,
2797330f729Sjoerg unsigned CUOffset) {
2807330f729Sjoerg // Unique the abbreviation and fill in the abbreviation number so this DIE
2817330f729Sjoerg // can be emitted.
2827330f729Sjoerg const DIEAbbrev &Abbrev = AbbrevSet.uniqueAbbreviation(*this);
2837330f729Sjoerg
2847330f729Sjoerg // Set compile/type unit relative offset of this DIE.
2857330f729Sjoerg setOffset(CUOffset);
2867330f729Sjoerg
2877330f729Sjoerg // Add the byte size of the abbreviation code.
2887330f729Sjoerg CUOffset += getULEB128Size(getAbbrevNumber());
2897330f729Sjoerg
2907330f729Sjoerg // Add the byte size of all the DIE attribute values.
2917330f729Sjoerg for (const auto &V : values())
2927330f729Sjoerg CUOffset += V.SizeOf(AP);
2937330f729Sjoerg
2947330f729Sjoerg // Let the children compute their offsets and abbreviation numbers.
2957330f729Sjoerg if (hasChildren()) {
2967330f729Sjoerg (void)Abbrev;
2977330f729Sjoerg assert(Abbrev.hasChildren() && "Children flag not set");
2987330f729Sjoerg
2997330f729Sjoerg for (auto &Child : children())
3007330f729Sjoerg CUOffset = Child.computeOffsetsAndAbbrevs(AP, AbbrevSet, CUOffset);
3017330f729Sjoerg
3027330f729Sjoerg // Each child chain is terminated with a zero byte, adjust the offset.
3037330f729Sjoerg CUOffset += sizeof(int8_t);
3047330f729Sjoerg }
3057330f729Sjoerg
3067330f729Sjoerg // Compute the byte size of this DIE and all of its children correctly. This
3077330f729Sjoerg // is needed so that top level DIE can help the compile unit set its length
3087330f729Sjoerg // correctly.
3097330f729Sjoerg setSize(CUOffset - getOffset());
3107330f729Sjoerg return CUOffset;
3117330f729Sjoerg }
3127330f729Sjoerg
3137330f729Sjoerg //===----------------------------------------------------------------------===//
3147330f729Sjoerg // DIEUnit Implementation
3157330f729Sjoerg //===----------------------------------------------------------------------===//
DIEUnit(dwarf::Tag UnitTag)316*82d56013Sjoerg DIEUnit::DIEUnit(dwarf::Tag UnitTag)
317*82d56013Sjoerg : Die(UnitTag), Section(nullptr), Offset(0) {
3187330f729Sjoerg Die.Owner = this;
3197330f729Sjoerg assert((UnitTag == dwarf::DW_TAG_compile_unit ||
320*82d56013Sjoerg UnitTag == dwarf::DW_TAG_skeleton_unit ||
3217330f729Sjoerg UnitTag == dwarf::DW_TAG_type_unit ||
322*82d56013Sjoerg UnitTag == dwarf::DW_TAG_partial_unit) &&
323*82d56013Sjoerg "expected a unit TAG");
3247330f729Sjoerg }
3257330f729Sjoerg
emitValue(const AsmPrinter * AP) const326*82d56013Sjoerg void DIEValue::emitValue(const AsmPrinter *AP) const {
3277330f729Sjoerg switch (Ty) {
3287330f729Sjoerg case isNone:
3297330f729Sjoerg llvm_unreachable("Expected valid DIEValue");
3307330f729Sjoerg #define HANDLE_DIEVALUE(T) \
3317330f729Sjoerg case is##T: \
332*82d56013Sjoerg getDIE##T().emitValue(AP, Form); \
3337330f729Sjoerg break;
3347330f729Sjoerg #include "llvm/CodeGen/DIEValue.def"
3357330f729Sjoerg }
3367330f729Sjoerg }
3377330f729Sjoerg
SizeOf(const AsmPrinter * AP) const3387330f729Sjoerg unsigned DIEValue::SizeOf(const AsmPrinter *AP) const {
3397330f729Sjoerg switch (Ty) {
3407330f729Sjoerg case isNone:
3417330f729Sjoerg llvm_unreachable("Expected valid DIEValue");
3427330f729Sjoerg #define HANDLE_DIEVALUE(T) \
3437330f729Sjoerg case is##T: \
3447330f729Sjoerg return getDIE##T().SizeOf(AP, Form);
3457330f729Sjoerg #include "llvm/CodeGen/DIEValue.def"
3467330f729Sjoerg }
3477330f729Sjoerg llvm_unreachable("Unknown DIE kind");
3487330f729Sjoerg }
3497330f729Sjoerg
3507330f729Sjoerg LLVM_DUMP_METHOD
print(raw_ostream & O) const3517330f729Sjoerg void DIEValue::print(raw_ostream &O) const {
3527330f729Sjoerg switch (Ty) {
3537330f729Sjoerg case isNone:
3547330f729Sjoerg llvm_unreachable("Expected valid DIEValue");
3557330f729Sjoerg #define HANDLE_DIEVALUE(T) \
3567330f729Sjoerg case is##T: \
3577330f729Sjoerg getDIE##T().print(O); \
3587330f729Sjoerg break;
3597330f729Sjoerg #include "llvm/CodeGen/DIEValue.def"
3607330f729Sjoerg }
3617330f729Sjoerg }
3627330f729Sjoerg
3637330f729Sjoerg #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const3647330f729Sjoerg LLVM_DUMP_METHOD void DIEValue::dump() const {
3657330f729Sjoerg print(dbgs());
3667330f729Sjoerg }
3677330f729Sjoerg #endif
3687330f729Sjoerg
3697330f729Sjoerg //===----------------------------------------------------------------------===//
3707330f729Sjoerg // DIEInteger Implementation
3717330f729Sjoerg //===----------------------------------------------------------------------===//
3727330f729Sjoerg
3737330f729Sjoerg /// EmitValue - Emit integer of appropriate size.
3747330f729Sjoerg ///
emitValue(const AsmPrinter * Asm,dwarf::Form Form) const375*82d56013Sjoerg void DIEInteger::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
3767330f729Sjoerg switch (Form) {
3777330f729Sjoerg case dwarf::DW_FORM_implicit_const:
3787330f729Sjoerg case dwarf::DW_FORM_flag_present:
3797330f729Sjoerg // Emit something to keep the lines and comments in sync.
3807330f729Sjoerg // FIXME: Is there a better way to do this?
3817330f729Sjoerg Asm->OutStreamer->AddBlankLine();
3827330f729Sjoerg return;
3837330f729Sjoerg case dwarf::DW_FORM_flag:
3847330f729Sjoerg case dwarf::DW_FORM_ref1:
3857330f729Sjoerg case dwarf::DW_FORM_data1:
3867330f729Sjoerg case dwarf::DW_FORM_strx1:
3877330f729Sjoerg case dwarf::DW_FORM_addrx1:
3887330f729Sjoerg case dwarf::DW_FORM_ref2:
3897330f729Sjoerg case dwarf::DW_FORM_data2:
3907330f729Sjoerg case dwarf::DW_FORM_strx2:
3917330f729Sjoerg case dwarf::DW_FORM_addrx2:
3927330f729Sjoerg case dwarf::DW_FORM_strx3:
3937330f729Sjoerg case dwarf::DW_FORM_strp:
3947330f729Sjoerg case dwarf::DW_FORM_ref4:
3957330f729Sjoerg case dwarf::DW_FORM_data4:
3967330f729Sjoerg case dwarf::DW_FORM_ref_sup4:
3977330f729Sjoerg case dwarf::DW_FORM_strx4:
3987330f729Sjoerg case dwarf::DW_FORM_addrx4:
3997330f729Sjoerg case dwarf::DW_FORM_ref8:
4007330f729Sjoerg case dwarf::DW_FORM_ref_sig8:
4017330f729Sjoerg case dwarf::DW_FORM_data8:
4027330f729Sjoerg case dwarf::DW_FORM_ref_sup8:
4037330f729Sjoerg case dwarf::DW_FORM_GNU_ref_alt:
4047330f729Sjoerg case dwarf::DW_FORM_GNU_strp_alt:
4057330f729Sjoerg case dwarf::DW_FORM_line_strp:
4067330f729Sjoerg case dwarf::DW_FORM_sec_offset:
4077330f729Sjoerg case dwarf::DW_FORM_strp_sup:
4087330f729Sjoerg case dwarf::DW_FORM_addr:
4097330f729Sjoerg case dwarf::DW_FORM_ref_addr:
410*82d56013Sjoerg Asm->OutStreamer->emitIntValue(Integer, SizeOf(Asm, Form));
4117330f729Sjoerg return;
4127330f729Sjoerg case dwarf::DW_FORM_GNU_str_index:
4137330f729Sjoerg case dwarf::DW_FORM_GNU_addr_index:
4147330f729Sjoerg case dwarf::DW_FORM_ref_udata:
4157330f729Sjoerg case dwarf::DW_FORM_strx:
4167330f729Sjoerg case dwarf::DW_FORM_addrx:
4177330f729Sjoerg case dwarf::DW_FORM_rnglistx:
4187330f729Sjoerg case dwarf::DW_FORM_udata:
419*82d56013Sjoerg Asm->emitULEB128(Integer);
4207330f729Sjoerg return;
4217330f729Sjoerg case dwarf::DW_FORM_sdata:
422*82d56013Sjoerg Asm->emitSLEB128(Integer);
4237330f729Sjoerg return;
4247330f729Sjoerg default: llvm_unreachable("DIE Value form not supported yet");
4257330f729Sjoerg }
4267330f729Sjoerg }
4277330f729Sjoerg
4287330f729Sjoerg /// SizeOf - Determine size of integer value in bytes.
4297330f729Sjoerg ///
SizeOf(const AsmPrinter * AP,dwarf::Form Form) const4307330f729Sjoerg unsigned DIEInteger::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
431*82d56013Sjoerg assert(AP && "AsmPrinter is required to set FormParams");
432*82d56013Sjoerg dwarf::FormParams Params = {AP->getDwarfVersion(),
433*82d56013Sjoerg uint8_t(AP->getPointerSize()),
4347330f729Sjoerg AP->OutStreamer->getContext().getDwarfFormat()};
4357330f729Sjoerg
4367330f729Sjoerg if (Optional<uint8_t> FixedSize = dwarf::getFixedFormByteSize(Form, Params))
4377330f729Sjoerg return *FixedSize;
4387330f729Sjoerg
4397330f729Sjoerg switch (Form) {
4407330f729Sjoerg case dwarf::DW_FORM_GNU_str_index:
4417330f729Sjoerg case dwarf::DW_FORM_GNU_addr_index:
4427330f729Sjoerg case dwarf::DW_FORM_ref_udata:
4437330f729Sjoerg case dwarf::DW_FORM_strx:
4447330f729Sjoerg case dwarf::DW_FORM_addrx:
4457330f729Sjoerg case dwarf::DW_FORM_rnglistx:
4467330f729Sjoerg case dwarf::DW_FORM_udata:
4477330f729Sjoerg return getULEB128Size(Integer);
4487330f729Sjoerg case dwarf::DW_FORM_sdata:
4497330f729Sjoerg return getSLEB128Size(Integer);
4507330f729Sjoerg default: llvm_unreachable("DIE Value form not supported yet");
4517330f729Sjoerg }
4527330f729Sjoerg }
4537330f729Sjoerg
4547330f729Sjoerg LLVM_DUMP_METHOD
print(raw_ostream & O) const4557330f729Sjoerg void DIEInteger::print(raw_ostream &O) const {
4567330f729Sjoerg O << "Int: " << (int64_t)Integer << " 0x";
4577330f729Sjoerg O.write_hex(Integer);
4587330f729Sjoerg }
4597330f729Sjoerg
4607330f729Sjoerg //===----------------------------------------------------------------------===//
4617330f729Sjoerg // DIEExpr Implementation
4627330f729Sjoerg //===----------------------------------------------------------------------===//
4637330f729Sjoerg
4647330f729Sjoerg /// EmitValue - Emit expression value.
4657330f729Sjoerg ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const466*82d56013Sjoerg void DIEExpr::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
467*82d56013Sjoerg AP->emitDebugValue(Expr, SizeOf(AP, Form));
4687330f729Sjoerg }
4697330f729Sjoerg
4707330f729Sjoerg /// SizeOf - Determine size of expression value in bytes.
4717330f729Sjoerg ///
SizeOf(const AsmPrinter * AP,dwarf::Form Form) const4727330f729Sjoerg unsigned DIEExpr::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
473*82d56013Sjoerg switch (Form) {
474*82d56013Sjoerg case dwarf::DW_FORM_data4:
475*82d56013Sjoerg return 4;
476*82d56013Sjoerg case dwarf::DW_FORM_data8:
477*82d56013Sjoerg return 8;
478*82d56013Sjoerg case dwarf::DW_FORM_sec_offset:
479*82d56013Sjoerg return AP->getDwarfOffsetByteSize();
480*82d56013Sjoerg default:
481*82d56013Sjoerg llvm_unreachable("DIE Value form not supported yet");
482*82d56013Sjoerg }
4837330f729Sjoerg }
4847330f729Sjoerg
4857330f729Sjoerg LLVM_DUMP_METHOD
print(raw_ostream & O) const4867330f729Sjoerg void DIEExpr::print(raw_ostream &O) const { O << "Expr: " << *Expr; }
4877330f729Sjoerg
4887330f729Sjoerg //===----------------------------------------------------------------------===//
4897330f729Sjoerg // DIELabel Implementation
4907330f729Sjoerg //===----------------------------------------------------------------------===//
4917330f729Sjoerg
4927330f729Sjoerg /// EmitValue - Emit label value.
4937330f729Sjoerg ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const494*82d56013Sjoerg void DIELabel::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
495*82d56013Sjoerg bool IsSectionRelative = Form != dwarf::DW_FORM_addr;
496*82d56013Sjoerg AP->emitLabelReference(Label, SizeOf(AP, Form), IsSectionRelative);
4977330f729Sjoerg }
4987330f729Sjoerg
4997330f729Sjoerg /// SizeOf - Determine size of label value in bytes.
5007330f729Sjoerg ///
SizeOf(const AsmPrinter * AP,dwarf::Form Form) const5017330f729Sjoerg unsigned DIELabel::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
502*82d56013Sjoerg switch (Form) {
503*82d56013Sjoerg case dwarf::DW_FORM_data4:
504*82d56013Sjoerg return 4;
505*82d56013Sjoerg case dwarf::DW_FORM_data8:
506*82d56013Sjoerg return 8;
507*82d56013Sjoerg case dwarf::DW_FORM_sec_offset:
508*82d56013Sjoerg case dwarf::DW_FORM_strp:
509*82d56013Sjoerg return AP->getDwarfOffsetByteSize();
510*82d56013Sjoerg case dwarf::DW_FORM_addr:
5117330f729Sjoerg return AP->MAI->getCodePointerSize();
512*82d56013Sjoerg default:
513*82d56013Sjoerg llvm_unreachable("DIE Value form not supported yet");
514*82d56013Sjoerg }
5157330f729Sjoerg }
5167330f729Sjoerg
5177330f729Sjoerg LLVM_DUMP_METHOD
print(raw_ostream & O) const5187330f729Sjoerg void DIELabel::print(raw_ostream &O) const { O << "Lbl: " << Label->getName(); }
5197330f729Sjoerg
5207330f729Sjoerg //===----------------------------------------------------------------------===//
5217330f729Sjoerg // DIEBaseTypeRef Implementation
5227330f729Sjoerg //===----------------------------------------------------------------------===//
5237330f729Sjoerg
emitValue(const AsmPrinter * AP,dwarf::Form Form) const524*82d56013Sjoerg void DIEBaseTypeRef::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
5257330f729Sjoerg uint64_t Offset = CU->ExprRefedBaseTypes[Index].Die->getOffset();
5267330f729Sjoerg assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit");
527*82d56013Sjoerg AP->emitULEB128(Offset, nullptr, ULEB128PadSize);
5287330f729Sjoerg }
5297330f729Sjoerg
SizeOf(const AsmPrinter * AP,dwarf::Form Form) const5307330f729Sjoerg unsigned DIEBaseTypeRef::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
5317330f729Sjoerg return ULEB128PadSize;
5327330f729Sjoerg }
5337330f729Sjoerg
5347330f729Sjoerg LLVM_DUMP_METHOD
print(raw_ostream & O) const5357330f729Sjoerg void DIEBaseTypeRef::print(raw_ostream &O) const { O << "BaseTypeRef: " << Index; }
5367330f729Sjoerg
5377330f729Sjoerg //===----------------------------------------------------------------------===//
5387330f729Sjoerg // DIEDelta Implementation
5397330f729Sjoerg //===----------------------------------------------------------------------===//
5407330f729Sjoerg
5417330f729Sjoerg /// EmitValue - Emit delta value.
5427330f729Sjoerg ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const543*82d56013Sjoerg void DIEDelta::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
544*82d56013Sjoerg AP->emitLabelDifference(LabelHi, LabelLo, SizeOf(AP, Form));
5457330f729Sjoerg }
5467330f729Sjoerg
5477330f729Sjoerg /// SizeOf - Determine size of delta value in bytes.
5487330f729Sjoerg ///
SizeOf(const AsmPrinter * AP,dwarf::Form Form) const5497330f729Sjoerg unsigned DIEDelta::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
550*82d56013Sjoerg switch (Form) {
551*82d56013Sjoerg case dwarf::DW_FORM_data4:
552*82d56013Sjoerg return 4;
553*82d56013Sjoerg case dwarf::DW_FORM_data8:
554*82d56013Sjoerg return 8;
555*82d56013Sjoerg case dwarf::DW_FORM_sec_offset:
556*82d56013Sjoerg return AP->getDwarfOffsetByteSize();
557*82d56013Sjoerg default:
558*82d56013Sjoerg llvm_unreachable("DIE Value form not supported yet");
559*82d56013Sjoerg }
5607330f729Sjoerg }
5617330f729Sjoerg
5627330f729Sjoerg LLVM_DUMP_METHOD
print(raw_ostream & O) const5637330f729Sjoerg void DIEDelta::print(raw_ostream &O) const {
5647330f729Sjoerg O << "Del: " << LabelHi->getName() << "-" << LabelLo->getName();
5657330f729Sjoerg }
5667330f729Sjoerg
5677330f729Sjoerg //===----------------------------------------------------------------------===//
5687330f729Sjoerg // DIEString Implementation
5697330f729Sjoerg //===----------------------------------------------------------------------===//
5707330f729Sjoerg
5717330f729Sjoerg /// EmitValue - Emit string value.
5727330f729Sjoerg ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const573*82d56013Sjoerg void DIEString::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
5747330f729Sjoerg // Index of string in symbol table.
5757330f729Sjoerg switch (Form) {
5767330f729Sjoerg case dwarf::DW_FORM_GNU_str_index:
5777330f729Sjoerg case dwarf::DW_FORM_strx:
5787330f729Sjoerg case dwarf::DW_FORM_strx1:
5797330f729Sjoerg case dwarf::DW_FORM_strx2:
5807330f729Sjoerg case dwarf::DW_FORM_strx3:
5817330f729Sjoerg case dwarf::DW_FORM_strx4:
582*82d56013Sjoerg DIEInteger(S.getIndex()).emitValue(AP, Form);
5837330f729Sjoerg return;
5847330f729Sjoerg case dwarf::DW_FORM_strp:
5857330f729Sjoerg if (AP->MAI->doesDwarfUseRelocationsAcrossSections())
586*82d56013Sjoerg DIELabel(S.getSymbol()).emitValue(AP, Form);
5877330f729Sjoerg else
588*82d56013Sjoerg DIEInteger(S.getOffset()).emitValue(AP, Form);
5897330f729Sjoerg return;
5907330f729Sjoerg default:
5917330f729Sjoerg llvm_unreachable("Expected valid string form");
5927330f729Sjoerg }
5937330f729Sjoerg }
5947330f729Sjoerg
5957330f729Sjoerg /// SizeOf - Determine size of delta value in bytes.
5967330f729Sjoerg ///
SizeOf(const AsmPrinter * AP,dwarf::Form Form) const5977330f729Sjoerg unsigned DIEString::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
5987330f729Sjoerg // Index of string in symbol table.
5997330f729Sjoerg switch (Form) {
6007330f729Sjoerg case dwarf::DW_FORM_GNU_str_index:
6017330f729Sjoerg case dwarf::DW_FORM_strx:
6027330f729Sjoerg case dwarf::DW_FORM_strx1:
6037330f729Sjoerg case dwarf::DW_FORM_strx2:
6047330f729Sjoerg case dwarf::DW_FORM_strx3:
6057330f729Sjoerg case dwarf::DW_FORM_strx4:
6067330f729Sjoerg return DIEInteger(S.getIndex()).SizeOf(AP, Form);
6077330f729Sjoerg case dwarf::DW_FORM_strp:
6087330f729Sjoerg if (AP->MAI->doesDwarfUseRelocationsAcrossSections())
6097330f729Sjoerg return DIELabel(S.getSymbol()).SizeOf(AP, Form);
6107330f729Sjoerg return DIEInteger(S.getOffset()).SizeOf(AP, Form);
6117330f729Sjoerg default:
6127330f729Sjoerg llvm_unreachable("Expected valid string form");
6137330f729Sjoerg }
6147330f729Sjoerg }
6157330f729Sjoerg
6167330f729Sjoerg LLVM_DUMP_METHOD
print(raw_ostream & O) const6177330f729Sjoerg void DIEString::print(raw_ostream &O) const {
6187330f729Sjoerg O << "String: " << S.getString();
6197330f729Sjoerg }
6207330f729Sjoerg
6217330f729Sjoerg //===----------------------------------------------------------------------===//
6227330f729Sjoerg // DIEInlineString Implementation
6237330f729Sjoerg //===----------------------------------------------------------------------===//
emitValue(const AsmPrinter * AP,dwarf::Form Form) const624*82d56013Sjoerg void DIEInlineString::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
6257330f729Sjoerg if (Form == dwarf::DW_FORM_string) {
626*82d56013Sjoerg AP->OutStreamer->emitBytes(S);
6277330f729Sjoerg AP->emitInt8(0);
6287330f729Sjoerg return;
6297330f729Sjoerg }
6307330f729Sjoerg llvm_unreachable("Expected valid string form");
6317330f729Sjoerg }
6327330f729Sjoerg
SizeOf(const AsmPrinter * AP,dwarf::Form Form) const6337330f729Sjoerg unsigned DIEInlineString::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
6347330f729Sjoerg // Emit string bytes + NULL byte.
6357330f729Sjoerg return S.size() + 1;
6367330f729Sjoerg }
6377330f729Sjoerg
6387330f729Sjoerg LLVM_DUMP_METHOD
print(raw_ostream & O) const6397330f729Sjoerg void DIEInlineString::print(raw_ostream &O) const {
6407330f729Sjoerg O << "InlineString: " << S;
6417330f729Sjoerg }
6427330f729Sjoerg
6437330f729Sjoerg //===----------------------------------------------------------------------===//
6447330f729Sjoerg // DIEEntry Implementation
6457330f729Sjoerg //===----------------------------------------------------------------------===//
6467330f729Sjoerg
6477330f729Sjoerg /// EmitValue - Emit debug information entry offset.
6487330f729Sjoerg ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const649*82d56013Sjoerg void DIEEntry::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
6507330f729Sjoerg
6517330f729Sjoerg switch (Form) {
6527330f729Sjoerg case dwarf::DW_FORM_ref1:
6537330f729Sjoerg case dwarf::DW_FORM_ref2:
6547330f729Sjoerg case dwarf::DW_FORM_ref4:
6557330f729Sjoerg case dwarf::DW_FORM_ref8:
656*82d56013Sjoerg AP->OutStreamer->emitIntValue(Entry->getOffset(), SizeOf(AP, Form));
6577330f729Sjoerg return;
6587330f729Sjoerg
6597330f729Sjoerg case dwarf::DW_FORM_ref_udata:
660*82d56013Sjoerg AP->emitULEB128(Entry->getOffset());
6617330f729Sjoerg return;
6627330f729Sjoerg
6637330f729Sjoerg case dwarf::DW_FORM_ref_addr: {
6647330f729Sjoerg // Get the absolute offset for this DIE within the debug info/types section.
665*82d56013Sjoerg uint64_t Addr = Entry->getDebugSectionOffset();
6667330f729Sjoerg if (const MCSymbol *SectionSym =
6677330f729Sjoerg Entry->getUnit()->getCrossSectionRelativeBaseAddress()) {
668*82d56013Sjoerg AP->emitLabelPlusOffset(SectionSym, Addr, SizeOf(AP, Form), true);
6697330f729Sjoerg return;
6707330f729Sjoerg }
6717330f729Sjoerg
672*82d56013Sjoerg AP->OutStreamer->emitIntValue(Addr, SizeOf(AP, Form));
6737330f729Sjoerg return;
6747330f729Sjoerg }
6757330f729Sjoerg default:
6767330f729Sjoerg llvm_unreachable("Improper form for DIE reference");
6777330f729Sjoerg }
6787330f729Sjoerg }
6797330f729Sjoerg
SizeOf(const AsmPrinter * AP,dwarf::Form Form) const6807330f729Sjoerg unsigned DIEEntry::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
6817330f729Sjoerg switch (Form) {
6827330f729Sjoerg case dwarf::DW_FORM_ref1:
6837330f729Sjoerg return 1;
6847330f729Sjoerg case dwarf::DW_FORM_ref2:
6857330f729Sjoerg return 2;
6867330f729Sjoerg case dwarf::DW_FORM_ref4:
6877330f729Sjoerg return 4;
6887330f729Sjoerg case dwarf::DW_FORM_ref8:
6897330f729Sjoerg return 8;
6907330f729Sjoerg case dwarf::DW_FORM_ref_udata:
6917330f729Sjoerg return getULEB128Size(Entry->getOffset());
6927330f729Sjoerg case dwarf::DW_FORM_ref_addr:
6937330f729Sjoerg if (AP->getDwarfVersion() == 2)
6947330f729Sjoerg return AP->MAI->getCodePointerSize();
6957330f729Sjoerg switch (AP->OutStreamer->getContext().getDwarfFormat()) {
6967330f729Sjoerg case dwarf::DWARF32:
6977330f729Sjoerg return 4;
6987330f729Sjoerg case dwarf::DWARF64:
6997330f729Sjoerg return 8;
7007330f729Sjoerg }
7017330f729Sjoerg llvm_unreachable("Invalid DWARF format");
7027330f729Sjoerg
7037330f729Sjoerg default:
7047330f729Sjoerg llvm_unreachable("Improper form for DIE reference");
7057330f729Sjoerg }
7067330f729Sjoerg }
7077330f729Sjoerg
7087330f729Sjoerg LLVM_DUMP_METHOD
print(raw_ostream & O) const7097330f729Sjoerg void DIEEntry::print(raw_ostream &O) const {
7107330f729Sjoerg O << format("Die: 0x%lx", (long)(intptr_t)&Entry);
7117330f729Sjoerg }
7127330f729Sjoerg
7137330f729Sjoerg //===----------------------------------------------------------------------===//
7147330f729Sjoerg // DIELoc Implementation
7157330f729Sjoerg //===----------------------------------------------------------------------===//
7167330f729Sjoerg
7177330f729Sjoerg /// ComputeSize - calculate the size of the location expression.
7187330f729Sjoerg ///
ComputeSize(const AsmPrinter * AP) const7197330f729Sjoerg unsigned DIELoc::ComputeSize(const AsmPrinter *AP) const {
7207330f729Sjoerg if (!Size) {
7217330f729Sjoerg for (const auto &V : values())
7227330f729Sjoerg Size += V.SizeOf(AP);
7237330f729Sjoerg }
7247330f729Sjoerg
7257330f729Sjoerg return Size;
7267330f729Sjoerg }
7277330f729Sjoerg
7287330f729Sjoerg /// EmitValue - Emit location data.
7297330f729Sjoerg ///
emitValue(const AsmPrinter * Asm,dwarf::Form Form) const730*82d56013Sjoerg void DIELoc::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
7317330f729Sjoerg switch (Form) {
7327330f729Sjoerg default: llvm_unreachable("Improper form for block");
7337330f729Sjoerg case dwarf::DW_FORM_block1: Asm->emitInt8(Size); break;
7347330f729Sjoerg case dwarf::DW_FORM_block2: Asm->emitInt16(Size); break;
7357330f729Sjoerg case dwarf::DW_FORM_block4: Asm->emitInt32(Size); break;
7367330f729Sjoerg case dwarf::DW_FORM_block:
7377330f729Sjoerg case dwarf::DW_FORM_exprloc:
738*82d56013Sjoerg Asm->emitULEB128(Size);
739*82d56013Sjoerg break;
7407330f729Sjoerg }
7417330f729Sjoerg
7427330f729Sjoerg for (const auto &V : values())
743*82d56013Sjoerg V.emitValue(Asm);
7447330f729Sjoerg }
7457330f729Sjoerg
7467330f729Sjoerg /// SizeOf - Determine size of location data in bytes.
7477330f729Sjoerg ///
SizeOf(const AsmPrinter * AP,dwarf::Form Form) const7487330f729Sjoerg unsigned DIELoc::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
7497330f729Sjoerg switch (Form) {
7507330f729Sjoerg case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
7517330f729Sjoerg case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
7527330f729Sjoerg case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
7537330f729Sjoerg case dwarf::DW_FORM_block:
7547330f729Sjoerg case dwarf::DW_FORM_exprloc:
7557330f729Sjoerg return Size + getULEB128Size(Size);
7567330f729Sjoerg default: llvm_unreachable("Improper form for block");
7577330f729Sjoerg }
7587330f729Sjoerg }
7597330f729Sjoerg
7607330f729Sjoerg LLVM_DUMP_METHOD
print(raw_ostream & O) const7617330f729Sjoerg void DIELoc::print(raw_ostream &O) const {
7627330f729Sjoerg printValues(O, *this, "ExprLoc", Size, 5);
7637330f729Sjoerg }
7647330f729Sjoerg
7657330f729Sjoerg //===----------------------------------------------------------------------===//
7667330f729Sjoerg // DIEBlock Implementation
7677330f729Sjoerg //===----------------------------------------------------------------------===//
7687330f729Sjoerg
7697330f729Sjoerg /// ComputeSize - calculate the size of the block.
7707330f729Sjoerg ///
ComputeSize(const AsmPrinter * AP) const7717330f729Sjoerg unsigned DIEBlock::ComputeSize(const AsmPrinter *AP) const {
7727330f729Sjoerg if (!Size) {
7737330f729Sjoerg for (const auto &V : values())
7747330f729Sjoerg Size += V.SizeOf(AP);
7757330f729Sjoerg }
7767330f729Sjoerg
7777330f729Sjoerg return Size;
7787330f729Sjoerg }
7797330f729Sjoerg
7807330f729Sjoerg /// EmitValue - Emit block data.
7817330f729Sjoerg ///
emitValue(const AsmPrinter * Asm,dwarf::Form Form) const782*82d56013Sjoerg void DIEBlock::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
7837330f729Sjoerg switch (Form) {
7847330f729Sjoerg default: llvm_unreachable("Improper form for block");
7857330f729Sjoerg case dwarf::DW_FORM_block1: Asm->emitInt8(Size); break;
7867330f729Sjoerg case dwarf::DW_FORM_block2: Asm->emitInt16(Size); break;
7877330f729Sjoerg case dwarf::DW_FORM_block4: Asm->emitInt32(Size); break;
788*82d56013Sjoerg case dwarf::DW_FORM_exprloc:
789*82d56013Sjoerg case dwarf::DW_FORM_block:
790*82d56013Sjoerg Asm->emitULEB128(Size);
791*82d56013Sjoerg break;
7927330f729Sjoerg case dwarf::DW_FORM_string: break;
7937330f729Sjoerg case dwarf::DW_FORM_data16: break;
7947330f729Sjoerg }
7957330f729Sjoerg
7967330f729Sjoerg for (const auto &V : values())
797*82d56013Sjoerg V.emitValue(Asm);
7987330f729Sjoerg }
7997330f729Sjoerg
8007330f729Sjoerg /// SizeOf - Determine size of block data in bytes.
8017330f729Sjoerg ///
SizeOf(const AsmPrinter * AP,dwarf::Form Form) const8027330f729Sjoerg unsigned DIEBlock::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
8037330f729Sjoerg switch (Form) {
8047330f729Sjoerg case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
8057330f729Sjoerg case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
8067330f729Sjoerg case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
807*82d56013Sjoerg case dwarf::DW_FORM_exprloc:
8087330f729Sjoerg case dwarf::DW_FORM_block: return Size + getULEB128Size(Size);
8097330f729Sjoerg case dwarf::DW_FORM_data16: return 16;
8107330f729Sjoerg default: llvm_unreachable("Improper form for block");
8117330f729Sjoerg }
8127330f729Sjoerg }
8137330f729Sjoerg
8147330f729Sjoerg LLVM_DUMP_METHOD
print(raw_ostream & O) const8157330f729Sjoerg void DIEBlock::print(raw_ostream &O) const {
8167330f729Sjoerg printValues(O, *this, "Blk", Size, 5);
8177330f729Sjoerg }
8187330f729Sjoerg
8197330f729Sjoerg //===----------------------------------------------------------------------===//
8207330f729Sjoerg // DIELocList Implementation
8217330f729Sjoerg //===----------------------------------------------------------------------===//
8227330f729Sjoerg
SizeOf(const AsmPrinter * AP,dwarf::Form Form) const8237330f729Sjoerg unsigned DIELocList::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
824*82d56013Sjoerg switch (Form) {
825*82d56013Sjoerg case dwarf::DW_FORM_loclistx:
826*82d56013Sjoerg return getULEB128Size(Index);
827*82d56013Sjoerg case dwarf::DW_FORM_data4:
828*82d56013Sjoerg assert(!AP->isDwarf64() &&
829*82d56013Sjoerg "DW_FORM_data4 is not suitable to emit a pointer to a location list "
830*82d56013Sjoerg "in the 64-bit DWARF format");
8317330f729Sjoerg return 4;
832*82d56013Sjoerg case dwarf::DW_FORM_data8:
833*82d56013Sjoerg assert(AP->isDwarf64() &&
834*82d56013Sjoerg "DW_FORM_data8 is not suitable to emit a pointer to a location list "
835*82d56013Sjoerg "in the 32-bit DWARF format");
836*82d56013Sjoerg return 8;
837*82d56013Sjoerg case dwarf::DW_FORM_sec_offset:
838*82d56013Sjoerg return AP->getDwarfOffsetByteSize();
839*82d56013Sjoerg default:
840*82d56013Sjoerg llvm_unreachable("DIE Value form not supported yet");
841*82d56013Sjoerg }
8427330f729Sjoerg }
8437330f729Sjoerg
8447330f729Sjoerg /// EmitValue - Emit label value.
8457330f729Sjoerg ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const846*82d56013Sjoerg void DIELocList::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
847*82d56013Sjoerg if (Form == dwarf::DW_FORM_loclistx) {
848*82d56013Sjoerg AP->emitULEB128(Index);
849*82d56013Sjoerg return;
850*82d56013Sjoerg }
8517330f729Sjoerg DwarfDebug *DD = AP->getDwarfDebug();
8527330f729Sjoerg MCSymbol *Label = DD->getDebugLocs().getList(Index).Label;
8537330f729Sjoerg AP->emitDwarfSymbolReference(Label, /*ForceOffset*/ DD->useSplitDwarf());
8547330f729Sjoerg }
8557330f729Sjoerg
8567330f729Sjoerg LLVM_DUMP_METHOD
print(raw_ostream & O) const8577330f729Sjoerg void DIELocList::print(raw_ostream &O) const { O << "LocList: " << Index; }
858*82d56013Sjoerg
859*82d56013Sjoerg //===----------------------------------------------------------------------===//
860*82d56013Sjoerg // DIEAddrOffset Implementation
861*82d56013Sjoerg //===----------------------------------------------------------------------===//
862*82d56013Sjoerg
SizeOf(const AsmPrinter * AP,dwarf::Form Form) const863*82d56013Sjoerg unsigned DIEAddrOffset::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
864*82d56013Sjoerg return Addr.SizeOf(AP, dwarf::DW_FORM_addrx) +
865*82d56013Sjoerg Offset.SizeOf(AP, dwarf::DW_FORM_data4);
866*82d56013Sjoerg }
867*82d56013Sjoerg
868*82d56013Sjoerg /// EmitValue - Emit label value.
869*82d56013Sjoerg ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const870*82d56013Sjoerg void DIEAddrOffset::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
871*82d56013Sjoerg Addr.emitValue(AP, dwarf::DW_FORM_addrx);
872*82d56013Sjoerg Offset.emitValue(AP, dwarf::DW_FORM_data4);
873*82d56013Sjoerg }
874*82d56013Sjoerg
875*82d56013Sjoerg LLVM_DUMP_METHOD
print(raw_ostream & O) const876*82d56013Sjoerg void DIEAddrOffset::print(raw_ostream &O) const {
877*82d56013Sjoerg O << "AddrOffset: ";
878*82d56013Sjoerg Addr.print(O);
879*82d56013Sjoerg O << " + ";
880*82d56013Sjoerg Offset.print(O);
881*82d56013Sjoerg }
882