10b57cec5SDimitry Andric //===--- lib/CodeGen/DIE.cpp - DWARF Info Entries -------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Data structures for DWARF info entries.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "llvm/CodeGen/DIE.h"
140b57cec5SDimitry Andric #include "DwarfCompileUnit.h"
150b57cec5SDimitry Andric #include "DwarfDebug.h"
160b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h"
170b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h"
210b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
220b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
230b57cec5SDimitry Andric #include "llvm/Support/Format.h"
240b57cec5SDimitry Andric #include "llvm/Support/LEB128.h"
250b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
260b57cec5SDimitry Andric using namespace llvm;
270b57cec5SDimitry Andric
280b57cec5SDimitry Andric #define DEBUG_TYPE "dwarfdebug"
290b57cec5SDimitry Andric
300b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
310b57cec5SDimitry Andric // DIEAbbrevData Implementation
320b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
330b57cec5SDimitry Andric
340b57cec5SDimitry Andric /// Profile - Used to gather unique data for the abbreviation folding set.
350b57cec5SDimitry Andric ///
Profile(FoldingSetNodeID & ID) const360b57cec5SDimitry Andric void DIEAbbrevData::Profile(FoldingSetNodeID &ID) const {
370b57cec5SDimitry Andric // Explicitly cast to an integer type for which FoldingSetNodeID has
380b57cec5SDimitry Andric // overloads. Otherwise MSVC 2010 thinks this call is ambiguous.
390b57cec5SDimitry Andric ID.AddInteger(unsigned(Attribute));
400b57cec5SDimitry Andric ID.AddInteger(unsigned(Form));
410b57cec5SDimitry Andric if (Form == dwarf::DW_FORM_implicit_const)
420b57cec5SDimitry Andric ID.AddInteger(Value);
430b57cec5SDimitry Andric }
440b57cec5SDimitry Andric
450b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
460b57cec5SDimitry Andric // DIEAbbrev Implementation
470b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
480b57cec5SDimitry Andric
490b57cec5SDimitry Andric /// Profile - Used to gather unique data for the abbreviation folding set.
500b57cec5SDimitry Andric ///
Profile(FoldingSetNodeID & ID) const510b57cec5SDimitry Andric void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {
520b57cec5SDimitry Andric ID.AddInteger(unsigned(Tag));
530b57cec5SDimitry Andric ID.AddInteger(unsigned(Children));
540b57cec5SDimitry Andric
550b57cec5SDimitry Andric // For each attribute description.
560b57cec5SDimitry Andric for (unsigned i = 0, N = Data.size(); i < N; ++i)
570b57cec5SDimitry Andric Data[i].Profile(ID);
580b57cec5SDimitry Andric }
590b57cec5SDimitry Andric
600b57cec5SDimitry Andric /// Emit - Print the abbreviation using the specified asm printer.
610b57cec5SDimitry Andric ///
Emit(const AsmPrinter * AP) const620b57cec5SDimitry Andric void DIEAbbrev::Emit(const AsmPrinter *AP) const {
630b57cec5SDimitry Andric // Emit its Dwarf tag type.
645ffd83dbSDimitry Andric AP->emitULEB128(Tag, dwarf::TagString(Tag).data());
650b57cec5SDimitry Andric
660b57cec5SDimitry Andric // Emit whether it has children DIEs.
675ffd83dbSDimitry Andric AP->emitULEB128((unsigned)Children, dwarf::ChildrenString(Children).data());
680b57cec5SDimitry Andric
690b57cec5SDimitry Andric // For each attribute description.
700b57cec5SDimitry Andric for (unsigned i = 0, N = Data.size(); i < N; ++i) {
710b57cec5SDimitry Andric const DIEAbbrevData &AttrData = Data[i];
720b57cec5SDimitry Andric
730b57cec5SDimitry Andric // Emit attribute type.
745ffd83dbSDimitry Andric AP->emitULEB128(AttrData.getAttribute(),
750b57cec5SDimitry Andric dwarf::AttributeString(AttrData.getAttribute()).data());
760b57cec5SDimitry Andric
770b57cec5SDimitry Andric // Emit form type.
780b57cec5SDimitry Andric #ifndef NDEBUG
790b57cec5SDimitry Andric // Could be an assertion, but this way we can see the failing form code
800b57cec5SDimitry Andric // easily, which helps track down where it came from.
810b57cec5SDimitry Andric if (!dwarf::isValidFormForVersion(AttrData.getForm(),
820b57cec5SDimitry Andric AP->getDwarfVersion())) {
830b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Invalid form " << format("0x%x", AttrData.getForm())
840b57cec5SDimitry Andric << " for DWARF version " << AP->getDwarfVersion()
850b57cec5SDimitry Andric << "\n");
860b57cec5SDimitry Andric llvm_unreachable("Invalid form for specified DWARF version");
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric #endif
895ffd83dbSDimitry Andric AP->emitULEB128(AttrData.getForm(),
900b57cec5SDimitry Andric dwarf::FormEncodingString(AttrData.getForm()).data());
910b57cec5SDimitry Andric
920b57cec5SDimitry Andric // Emit value for DW_FORM_implicit_const.
930b57cec5SDimitry Andric if (AttrData.getForm() == dwarf::DW_FORM_implicit_const)
945ffd83dbSDimitry Andric AP->emitSLEB128(AttrData.getValue());
950b57cec5SDimitry Andric }
960b57cec5SDimitry Andric
970b57cec5SDimitry Andric // Mark end of abbreviation.
985ffd83dbSDimitry Andric AP->emitULEB128(0, "EOM(1)");
995ffd83dbSDimitry Andric AP->emitULEB128(0, "EOM(2)");
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric
1020b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const1030b57cec5SDimitry Andric void DIEAbbrev::print(raw_ostream &O) const {
1040b57cec5SDimitry Andric O << "Abbreviation @"
1050b57cec5SDimitry Andric << format("0x%lx", (long)(intptr_t)this)
1060b57cec5SDimitry Andric << " "
1070b57cec5SDimitry Andric << dwarf::TagString(Tag)
1080b57cec5SDimitry Andric << " "
1090b57cec5SDimitry Andric << dwarf::ChildrenString(Children)
1100b57cec5SDimitry Andric << '\n';
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andric for (unsigned i = 0, N = Data.size(); i < N; ++i) {
1130b57cec5SDimitry Andric O << " "
1140b57cec5SDimitry Andric << dwarf::AttributeString(Data[i].getAttribute())
1150b57cec5SDimitry Andric << " "
1160b57cec5SDimitry Andric << dwarf::FormEncodingString(Data[i].getForm());
1170b57cec5SDimitry Andric
1180b57cec5SDimitry Andric if (Data[i].getForm() == dwarf::DW_FORM_implicit_const)
1190b57cec5SDimitry Andric O << " " << Data[i].getValue();
1200b57cec5SDimitry Andric
1210b57cec5SDimitry Andric O << '\n';
1220b57cec5SDimitry Andric }
1230b57cec5SDimitry Andric }
1240b57cec5SDimitry Andric
1250b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const1260b57cec5SDimitry Andric LLVM_DUMP_METHOD void DIEAbbrev::dump() const {
1270b57cec5SDimitry Andric print(dbgs());
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric #endif
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1320b57cec5SDimitry Andric // DIEAbbrevSet Implementation
1330b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1340b57cec5SDimitry Andric
~DIEAbbrevSet()1350b57cec5SDimitry Andric DIEAbbrevSet::~DIEAbbrevSet() {
1360b57cec5SDimitry Andric for (DIEAbbrev *Abbrev : Abbreviations)
1370b57cec5SDimitry Andric Abbrev->~DIEAbbrev();
1380b57cec5SDimitry Andric }
1390b57cec5SDimitry Andric
uniqueAbbreviation(DIE & Die)1400b57cec5SDimitry Andric DIEAbbrev &DIEAbbrevSet::uniqueAbbreviation(DIE &Die) {
1410b57cec5SDimitry Andric
1420b57cec5SDimitry Andric FoldingSetNodeID ID;
1430b57cec5SDimitry Andric DIEAbbrev Abbrev = Die.generateAbbrev();
1440b57cec5SDimitry Andric Abbrev.Profile(ID);
1450b57cec5SDimitry Andric
1460b57cec5SDimitry Andric void *InsertPos;
1470b57cec5SDimitry Andric if (DIEAbbrev *Existing =
1480b57cec5SDimitry Andric AbbreviationsSet.FindNodeOrInsertPos(ID, InsertPos)) {
1490b57cec5SDimitry Andric Die.setAbbrevNumber(Existing->getNumber());
1500b57cec5SDimitry Andric return *Existing;
1510b57cec5SDimitry Andric }
1520b57cec5SDimitry Andric
1530b57cec5SDimitry Andric // Move the abbreviation to the heap and assign a number.
1540b57cec5SDimitry Andric DIEAbbrev *New = new (Alloc) DIEAbbrev(std::move(Abbrev));
1550b57cec5SDimitry Andric Abbreviations.push_back(New);
1560b57cec5SDimitry Andric New->setNumber(Abbreviations.size());
1570b57cec5SDimitry Andric Die.setAbbrevNumber(Abbreviations.size());
1580b57cec5SDimitry Andric
1590b57cec5SDimitry Andric // Store it for lookup.
1600b57cec5SDimitry Andric AbbreviationsSet.InsertNode(New, InsertPos);
1610b57cec5SDimitry Andric return *New;
1620b57cec5SDimitry Andric }
1630b57cec5SDimitry Andric
Emit(const AsmPrinter * AP,MCSection * Section) const1640b57cec5SDimitry Andric void DIEAbbrevSet::Emit(const AsmPrinter *AP, MCSection *Section) const {
1650b57cec5SDimitry Andric if (!Abbreviations.empty()) {
1660b57cec5SDimitry Andric // Start the debug abbrev section.
16781ad6265SDimitry Andric AP->OutStreamer->switchSection(Section);
1680b57cec5SDimitry Andric AP->emitDwarfAbbrevs(Abbreviations);
1690b57cec5SDimitry Andric }
1700b57cec5SDimitry Andric }
1710b57cec5SDimitry Andric
1720b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1730b57cec5SDimitry Andric // DIE Implementation
1740b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1750b57cec5SDimitry Andric
getParent() const17606c3fb27SDimitry Andric DIE *DIE::getParent() const { return dyn_cast_if_present<DIE *>(Owner); }
1770b57cec5SDimitry Andric
generateAbbrev() const1780b57cec5SDimitry Andric DIEAbbrev DIE::generateAbbrev() const {
1790b57cec5SDimitry Andric DIEAbbrev Abbrev(Tag, hasChildren());
1800b57cec5SDimitry Andric for (const DIEValue &V : values())
1810b57cec5SDimitry Andric if (V.getForm() == dwarf::DW_FORM_implicit_const)
1820b57cec5SDimitry Andric Abbrev.AddImplicitConstAttribute(V.getAttribute(),
1830b57cec5SDimitry Andric V.getDIEInteger().getValue());
1840b57cec5SDimitry Andric else
1850b57cec5SDimitry Andric Abbrev.AddAttribute(V.getAttribute(), V.getForm());
1860b57cec5SDimitry Andric return Abbrev;
1870b57cec5SDimitry Andric }
1880b57cec5SDimitry Andric
getDebugSectionOffset() const189e8d8bef9SDimitry Andric uint64_t DIE::getDebugSectionOffset() const {
1900b57cec5SDimitry Andric const DIEUnit *Unit = getUnit();
1910b57cec5SDimitry Andric assert(Unit && "DIE must be owned by a DIEUnit to get its absolute offset");
1920b57cec5SDimitry Andric return Unit->getDebugSectionOffset() + getOffset();
1930b57cec5SDimitry Andric }
1940b57cec5SDimitry Andric
getUnitDie() const1950b57cec5SDimitry Andric const DIE *DIE::getUnitDie() const {
1960b57cec5SDimitry Andric const DIE *p = this;
1970b57cec5SDimitry Andric while (p) {
1980b57cec5SDimitry Andric if (p->getTag() == dwarf::DW_TAG_compile_unit ||
19981ad6265SDimitry Andric p->getTag() == dwarf::DW_TAG_skeleton_unit ||
2000b57cec5SDimitry Andric p->getTag() == dwarf::DW_TAG_type_unit)
2010b57cec5SDimitry Andric return p;
2020b57cec5SDimitry Andric p = p->getParent();
2030b57cec5SDimitry Andric }
2040b57cec5SDimitry Andric return nullptr;
2050b57cec5SDimitry Andric }
2060b57cec5SDimitry Andric
getUnit() const2070b57cec5SDimitry Andric DIEUnit *DIE::getUnit() const {
2080b57cec5SDimitry Andric const DIE *UnitDie = getUnitDie();
2090b57cec5SDimitry Andric if (UnitDie)
21006c3fb27SDimitry Andric return dyn_cast_if_present<DIEUnit *>(UnitDie->Owner);
2110b57cec5SDimitry Andric return nullptr;
2120b57cec5SDimitry Andric }
2130b57cec5SDimitry Andric
findAttribute(dwarf::Attribute Attribute) const2140b57cec5SDimitry Andric DIEValue DIE::findAttribute(dwarf::Attribute Attribute) const {
2150b57cec5SDimitry Andric // Iterate through all the attributes until we find the one we're
2160b57cec5SDimitry Andric // looking for, if we can't find it return NULL.
2170b57cec5SDimitry Andric for (const auto &V : values())
2180b57cec5SDimitry Andric if (V.getAttribute() == Attribute)
2190b57cec5SDimitry Andric return V;
2200b57cec5SDimitry Andric return DIEValue();
2210b57cec5SDimitry Andric }
2220b57cec5SDimitry Andric
2230b57cec5SDimitry Andric LLVM_DUMP_METHOD
printValues(raw_ostream & O,const DIEValueList & Values,StringRef Type,unsigned Size,unsigned IndentCount)2240b57cec5SDimitry Andric static void printValues(raw_ostream &O, const DIEValueList &Values,
2250b57cec5SDimitry Andric StringRef Type, unsigned Size, unsigned IndentCount) {
2260b57cec5SDimitry Andric O << Type << ": Size: " << Size << "\n";
2270b57cec5SDimitry Andric
2280b57cec5SDimitry Andric unsigned I = 0;
2290b57cec5SDimitry Andric const std::string Indent(IndentCount, ' ');
2300b57cec5SDimitry Andric for (const auto &V : Values.values()) {
2310b57cec5SDimitry Andric O << Indent;
2320b57cec5SDimitry Andric O << "Blk[" << I++ << "]";
2330b57cec5SDimitry Andric O << " " << dwarf::FormEncodingString(V.getForm()) << " ";
2340b57cec5SDimitry Andric V.print(O);
2350b57cec5SDimitry Andric O << "\n";
2360b57cec5SDimitry Andric }
2370b57cec5SDimitry Andric }
2380b57cec5SDimitry Andric
2390b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O,unsigned IndentCount) const2400b57cec5SDimitry Andric void DIE::print(raw_ostream &O, unsigned IndentCount) const {
2410b57cec5SDimitry Andric const std::string Indent(IndentCount, ' ');
2420b57cec5SDimitry Andric O << Indent << "Die: " << format("0x%lx", (long)(intptr_t) this)
2430b57cec5SDimitry Andric << ", Offset: " << Offset << ", Size: " << Size << "\n";
2440b57cec5SDimitry Andric
2450b57cec5SDimitry Andric O << Indent << dwarf::TagString(getTag()) << " "
2460b57cec5SDimitry Andric << dwarf::ChildrenString(hasChildren()) << "\n";
2470b57cec5SDimitry Andric
2480b57cec5SDimitry Andric IndentCount += 2;
2490b57cec5SDimitry Andric for (const auto &V : values()) {
2500b57cec5SDimitry Andric O << Indent;
2510b57cec5SDimitry Andric O << dwarf::AttributeString(V.getAttribute());
2520b57cec5SDimitry Andric O << " " << dwarf::FormEncodingString(V.getForm()) << " ";
2530b57cec5SDimitry Andric V.print(O);
2540b57cec5SDimitry Andric O << "\n";
2550b57cec5SDimitry Andric }
2560b57cec5SDimitry Andric IndentCount -= 2;
2570b57cec5SDimitry Andric
2580b57cec5SDimitry Andric for (const auto &Child : children())
2590b57cec5SDimitry Andric Child.print(O, IndentCount + 4);
2600b57cec5SDimitry Andric
2610b57cec5SDimitry Andric O << "\n";
2620b57cec5SDimitry Andric }
2630b57cec5SDimitry Andric
2640b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const2650b57cec5SDimitry Andric LLVM_DUMP_METHOD void DIE::dump() const {
2660b57cec5SDimitry Andric print(dbgs());
2670b57cec5SDimitry Andric }
2680b57cec5SDimitry Andric #endif
2690b57cec5SDimitry Andric
computeOffsetsAndAbbrevs(const dwarf::FormParams & FormParams,DIEAbbrevSet & AbbrevSet,unsigned CUOffset)27004eeddc0SDimitry Andric unsigned DIE::computeOffsetsAndAbbrevs(const dwarf::FormParams &FormParams,
2710b57cec5SDimitry Andric DIEAbbrevSet &AbbrevSet,
2720b57cec5SDimitry Andric unsigned CUOffset) {
2730b57cec5SDimitry Andric // Unique the abbreviation and fill in the abbreviation number so this DIE
2740b57cec5SDimitry Andric // can be emitted.
2750b57cec5SDimitry Andric const DIEAbbrev &Abbrev = AbbrevSet.uniqueAbbreviation(*this);
2760b57cec5SDimitry Andric
2770b57cec5SDimitry Andric // Set compile/type unit relative offset of this DIE.
2780b57cec5SDimitry Andric setOffset(CUOffset);
2790b57cec5SDimitry Andric
2800b57cec5SDimitry Andric // Add the byte size of the abbreviation code.
2810b57cec5SDimitry Andric CUOffset += getULEB128Size(getAbbrevNumber());
2820b57cec5SDimitry Andric
2830b57cec5SDimitry Andric // Add the byte size of all the DIE attribute values.
2840b57cec5SDimitry Andric for (const auto &V : values())
28504eeddc0SDimitry Andric CUOffset += V.sizeOf(FormParams);
2860b57cec5SDimitry Andric
2870b57cec5SDimitry Andric // Let the children compute their offsets and abbreviation numbers.
2880b57cec5SDimitry Andric if (hasChildren()) {
2890b57cec5SDimitry Andric (void)Abbrev;
2900b57cec5SDimitry Andric assert(Abbrev.hasChildren() && "Children flag not set");
2910b57cec5SDimitry Andric
2920b57cec5SDimitry Andric for (auto &Child : children())
29304eeddc0SDimitry Andric CUOffset =
29404eeddc0SDimitry Andric Child.computeOffsetsAndAbbrevs(FormParams, AbbrevSet, CUOffset);
2950b57cec5SDimitry Andric
2960b57cec5SDimitry Andric // Each child chain is terminated with a zero byte, adjust the offset.
2970b57cec5SDimitry Andric CUOffset += sizeof(int8_t);
2980b57cec5SDimitry Andric }
2990b57cec5SDimitry Andric
3000b57cec5SDimitry Andric // Compute the byte size of this DIE and all of its children correctly. This
3010b57cec5SDimitry Andric // is needed so that top level DIE can help the compile unit set its length
3020b57cec5SDimitry Andric // correctly.
3030b57cec5SDimitry Andric setSize(CUOffset - getOffset());
3040b57cec5SDimitry Andric return CUOffset;
3050b57cec5SDimitry Andric }
3060b57cec5SDimitry Andric
3070b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
3080b57cec5SDimitry Andric // DIEUnit Implementation
3090b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
DIEUnit(dwarf::Tag UnitTag)3101fd87a68SDimitry Andric DIEUnit::DIEUnit(dwarf::Tag UnitTag) : Die(UnitTag) {
3110b57cec5SDimitry Andric Die.Owner = this;
3120b57cec5SDimitry Andric assert((UnitTag == dwarf::DW_TAG_compile_unit ||
313480093f4SDimitry Andric UnitTag == dwarf::DW_TAG_skeleton_unit ||
3140b57cec5SDimitry Andric UnitTag == dwarf::DW_TAG_type_unit ||
315480093f4SDimitry Andric UnitTag == dwarf::DW_TAG_partial_unit) &&
316480093f4SDimitry Andric "expected a unit TAG");
3170b57cec5SDimitry Andric }
3180b57cec5SDimitry Andric
emitValue(const AsmPrinter * AP) const3195ffd83dbSDimitry Andric void DIEValue::emitValue(const AsmPrinter *AP) const {
3200b57cec5SDimitry Andric switch (Ty) {
3210b57cec5SDimitry Andric case isNone:
3220b57cec5SDimitry Andric llvm_unreachable("Expected valid DIEValue");
3230b57cec5SDimitry Andric #define HANDLE_DIEVALUE(T) \
3240b57cec5SDimitry Andric case is##T: \
3255ffd83dbSDimitry Andric getDIE##T().emitValue(AP, Form); \
3260b57cec5SDimitry Andric break;
3270b57cec5SDimitry Andric #include "llvm/CodeGen/DIEValue.def"
3280b57cec5SDimitry Andric }
3290b57cec5SDimitry Andric }
3300b57cec5SDimitry Andric
sizeOf(const dwarf::FormParams & FormParams) const33104eeddc0SDimitry Andric unsigned DIEValue::sizeOf(const dwarf::FormParams &FormParams) const {
3320b57cec5SDimitry Andric switch (Ty) {
3330b57cec5SDimitry Andric case isNone:
3340b57cec5SDimitry Andric llvm_unreachable("Expected valid DIEValue");
3350b57cec5SDimitry Andric #define HANDLE_DIEVALUE(T) \
3360b57cec5SDimitry Andric case is##T: \
33704eeddc0SDimitry Andric return getDIE##T().sizeOf(FormParams, Form);
3380b57cec5SDimitry Andric #include "llvm/CodeGen/DIEValue.def"
3390b57cec5SDimitry Andric }
3400b57cec5SDimitry Andric llvm_unreachable("Unknown DIE kind");
3410b57cec5SDimitry Andric }
3420b57cec5SDimitry Andric
3430b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const3440b57cec5SDimitry Andric void DIEValue::print(raw_ostream &O) const {
3450b57cec5SDimitry Andric switch (Ty) {
3460b57cec5SDimitry Andric case isNone:
3470b57cec5SDimitry Andric llvm_unreachable("Expected valid DIEValue");
3480b57cec5SDimitry Andric #define HANDLE_DIEVALUE(T) \
3490b57cec5SDimitry Andric case is##T: \
3500b57cec5SDimitry Andric getDIE##T().print(O); \
3510b57cec5SDimitry Andric break;
3520b57cec5SDimitry Andric #include "llvm/CodeGen/DIEValue.def"
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric }
3550b57cec5SDimitry Andric
3560b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const3570b57cec5SDimitry Andric LLVM_DUMP_METHOD void DIEValue::dump() const {
3580b57cec5SDimitry Andric print(dbgs());
3590b57cec5SDimitry Andric }
3600b57cec5SDimitry Andric #endif
3610b57cec5SDimitry Andric
3620b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
3630b57cec5SDimitry Andric // DIEInteger Implementation
3640b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
3650b57cec5SDimitry Andric
3660b57cec5SDimitry Andric /// EmitValue - Emit integer of appropriate size.
3670b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * Asm,dwarf::Form Form) const3685ffd83dbSDimitry Andric void DIEInteger::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
3690b57cec5SDimitry Andric switch (Form) {
3700b57cec5SDimitry Andric case dwarf::DW_FORM_implicit_const:
3710b57cec5SDimitry Andric case dwarf::DW_FORM_flag_present:
3720b57cec5SDimitry Andric // Emit something to keep the lines and comments in sync.
3730b57cec5SDimitry Andric // FIXME: Is there a better way to do this?
37481ad6265SDimitry Andric Asm->OutStreamer->addBlankLine();
3750b57cec5SDimitry Andric return;
3760b57cec5SDimitry Andric case dwarf::DW_FORM_flag:
3770b57cec5SDimitry Andric case dwarf::DW_FORM_ref1:
3780b57cec5SDimitry Andric case dwarf::DW_FORM_data1:
3790b57cec5SDimitry Andric case dwarf::DW_FORM_strx1:
3800b57cec5SDimitry Andric case dwarf::DW_FORM_addrx1:
3810b57cec5SDimitry Andric case dwarf::DW_FORM_ref2:
3820b57cec5SDimitry Andric case dwarf::DW_FORM_data2:
3830b57cec5SDimitry Andric case dwarf::DW_FORM_strx2:
3840b57cec5SDimitry Andric case dwarf::DW_FORM_addrx2:
3850b57cec5SDimitry Andric case dwarf::DW_FORM_strx3:
38606c3fb27SDimitry Andric case dwarf::DW_FORM_addrx3:
3870b57cec5SDimitry Andric case dwarf::DW_FORM_strp:
3880b57cec5SDimitry Andric case dwarf::DW_FORM_ref4:
3890b57cec5SDimitry Andric case dwarf::DW_FORM_data4:
3900b57cec5SDimitry Andric case dwarf::DW_FORM_ref_sup4:
3910b57cec5SDimitry Andric case dwarf::DW_FORM_strx4:
3920b57cec5SDimitry Andric case dwarf::DW_FORM_addrx4:
3930b57cec5SDimitry Andric case dwarf::DW_FORM_ref8:
3940b57cec5SDimitry Andric case dwarf::DW_FORM_ref_sig8:
3950b57cec5SDimitry Andric case dwarf::DW_FORM_data8:
3960b57cec5SDimitry Andric case dwarf::DW_FORM_ref_sup8:
3970b57cec5SDimitry Andric case dwarf::DW_FORM_GNU_ref_alt:
3980b57cec5SDimitry Andric case dwarf::DW_FORM_GNU_strp_alt:
3990b57cec5SDimitry Andric case dwarf::DW_FORM_line_strp:
4000b57cec5SDimitry Andric case dwarf::DW_FORM_sec_offset:
4010b57cec5SDimitry Andric case dwarf::DW_FORM_strp_sup:
4020b57cec5SDimitry Andric case dwarf::DW_FORM_addr:
4030b57cec5SDimitry Andric case dwarf::DW_FORM_ref_addr:
40404eeddc0SDimitry Andric Asm->OutStreamer->emitIntValue(Integer,
40504eeddc0SDimitry Andric sizeOf(Asm->getDwarfFormParams(), Form));
4060b57cec5SDimitry Andric return;
4070b57cec5SDimitry Andric case dwarf::DW_FORM_GNU_str_index:
4080b57cec5SDimitry Andric case dwarf::DW_FORM_GNU_addr_index:
4090b57cec5SDimitry Andric case dwarf::DW_FORM_ref_udata:
4100b57cec5SDimitry Andric case dwarf::DW_FORM_strx:
4110b57cec5SDimitry Andric case dwarf::DW_FORM_addrx:
4120b57cec5SDimitry Andric case dwarf::DW_FORM_rnglistx:
4130b57cec5SDimitry Andric case dwarf::DW_FORM_udata:
4145ffd83dbSDimitry Andric Asm->emitULEB128(Integer);
4150b57cec5SDimitry Andric return;
4160b57cec5SDimitry Andric case dwarf::DW_FORM_sdata:
4175ffd83dbSDimitry Andric Asm->emitSLEB128(Integer);
4180b57cec5SDimitry Andric return;
4190b57cec5SDimitry Andric default: llvm_unreachable("DIE Value form not supported yet");
4200b57cec5SDimitry Andric }
4210b57cec5SDimitry Andric }
4220b57cec5SDimitry Andric
42304eeddc0SDimitry Andric /// sizeOf - Determine size of integer value in bytes.
4240b57cec5SDimitry Andric ///
sizeOf(const dwarf::FormParams & FormParams,dwarf::Form Form) const42504eeddc0SDimitry Andric unsigned DIEInteger::sizeOf(const dwarf::FormParams &FormParams,
42604eeddc0SDimitry Andric dwarf::Form Form) const {
427bdd1243dSDimitry Andric if (std::optional<uint8_t> FixedSize =
42804eeddc0SDimitry Andric dwarf::getFixedFormByteSize(Form, FormParams))
4290b57cec5SDimitry Andric return *FixedSize;
4300b57cec5SDimitry Andric
4310b57cec5SDimitry Andric switch (Form) {
4320b57cec5SDimitry Andric case dwarf::DW_FORM_GNU_str_index:
4330b57cec5SDimitry Andric case dwarf::DW_FORM_GNU_addr_index:
4340b57cec5SDimitry Andric case dwarf::DW_FORM_ref_udata:
4350b57cec5SDimitry Andric case dwarf::DW_FORM_strx:
4360b57cec5SDimitry Andric case dwarf::DW_FORM_addrx:
4370b57cec5SDimitry Andric case dwarf::DW_FORM_rnglistx:
4380b57cec5SDimitry Andric case dwarf::DW_FORM_udata:
4390b57cec5SDimitry Andric return getULEB128Size(Integer);
4400b57cec5SDimitry Andric case dwarf::DW_FORM_sdata:
4410b57cec5SDimitry Andric return getSLEB128Size(Integer);
4420b57cec5SDimitry Andric default: llvm_unreachable("DIE Value form not supported yet");
4430b57cec5SDimitry Andric }
4440b57cec5SDimitry Andric }
4450b57cec5SDimitry Andric
4460b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const4470b57cec5SDimitry Andric void DIEInteger::print(raw_ostream &O) const {
4480b57cec5SDimitry Andric O << "Int: " << (int64_t)Integer << " 0x";
4490b57cec5SDimitry Andric O.write_hex(Integer);
4500b57cec5SDimitry Andric }
4510b57cec5SDimitry Andric
4520b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4530b57cec5SDimitry Andric // DIEExpr Implementation
4540b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4550b57cec5SDimitry Andric
4560b57cec5SDimitry Andric /// EmitValue - Emit expression value.
4570b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const4585ffd83dbSDimitry Andric void DIEExpr::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
45904eeddc0SDimitry Andric AP->emitDebugValue(Expr, sizeOf(AP->getDwarfFormParams(), Form));
4600b57cec5SDimitry Andric }
4610b57cec5SDimitry Andric
4620b57cec5SDimitry Andric /// SizeOf - Determine size of expression value in bytes.
4630b57cec5SDimitry Andric ///
sizeOf(const dwarf::FormParams & FormParams,dwarf::Form Form) const46404eeddc0SDimitry Andric unsigned DIEExpr::sizeOf(const dwarf::FormParams &FormParams,
46504eeddc0SDimitry Andric dwarf::Form Form) const {
466e8d8bef9SDimitry Andric switch (Form) {
467e8d8bef9SDimitry Andric case dwarf::DW_FORM_data4:
468e8d8bef9SDimitry Andric return 4;
469e8d8bef9SDimitry Andric case dwarf::DW_FORM_data8:
470e8d8bef9SDimitry Andric return 8;
471e8d8bef9SDimitry Andric case dwarf::DW_FORM_sec_offset:
47204eeddc0SDimitry Andric return FormParams.getDwarfOffsetByteSize();
473e8d8bef9SDimitry Andric default:
474e8d8bef9SDimitry Andric llvm_unreachable("DIE Value form not supported yet");
475e8d8bef9SDimitry Andric }
4760b57cec5SDimitry Andric }
4770b57cec5SDimitry Andric
4780b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const4790b57cec5SDimitry Andric void DIEExpr::print(raw_ostream &O) const { O << "Expr: " << *Expr; }
4800b57cec5SDimitry Andric
4810b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4820b57cec5SDimitry Andric // DIELabel Implementation
4830b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4840b57cec5SDimitry Andric
4850b57cec5SDimitry Andric /// EmitValue - Emit label value.
4860b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const4875ffd83dbSDimitry Andric void DIELabel::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
488e8d8bef9SDimitry Andric bool IsSectionRelative = Form != dwarf::DW_FORM_addr;
48904eeddc0SDimitry Andric AP->emitLabelReference(Label, sizeOf(AP->getDwarfFormParams(), Form),
49004eeddc0SDimitry Andric IsSectionRelative);
4910b57cec5SDimitry Andric }
4920b57cec5SDimitry Andric
49304eeddc0SDimitry Andric /// sizeOf - Determine size of label value in bytes.
4940b57cec5SDimitry Andric ///
sizeOf(const dwarf::FormParams & FormParams,dwarf::Form Form) const49504eeddc0SDimitry Andric unsigned DIELabel::sizeOf(const dwarf::FormParams &FormParams,
49604eeddc0SDimitry Andric dwarf::Form Form) const {
497e8d8bef9SDimitry Andric switch (Form) {
498e8d8bef9SDimitry Andric case dwarf::DW_FORM_data4:
499e8d8bef9SDimitry Andric return 4;
500e8d8bef9SDimitry Andric case dwarf::DW_FORM_data8:
501e8d8bef9SDimitry Andric return 8;
502e8d8bef9SDimitry Andric case dwarf::DW_FORM_sec_offset:
503e8d8bef9SDimitry Andric case dwarf::DW_FORM_strp:
50404eeddc0SDimitry Andric return FormParams.getDwarfOffsetByteSize();
505e8d8bef9SDimitry Andric case dwarf::DW_FORM_addr:
50604eeddc0SDimitry Andric return FormParams.AddrSize;
507e8d8bef9SDimitry Andric default:
508e8d8bef9SDimitry Andric llvm_unreachable("DIE Value form not supported yet");
509e8d8bef9SDimitry Andric }
5100b57cec5SDimitry Andric }
5110b57cec5SDimitry Andric
5120b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const5130b57cec5SDimitry Andric void DIELabel::print(raw_ostream &O) const { O << "Lbl: " << Label->getName(); }
5140b57cec5SDimitry Andric
5150b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5160b57cec5SDimitry Andric // DIEBaseTypeRef Implementation
5170b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5180b57cec5SDimitry Andric
emitValue(const AsmPrinter * AP,dwarf::Form Form) const5195ffd83dbSDimitry Andric void DIEBaseTypeRef::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
5200b57cec5SDimitry Andric uint64_t Offset = CU->ExprRefedBaseTypes[Index].Die->getOffset();
5210b57cec5SDimitry Andric assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit");
5225ffd83dbSDimitry Andric AP->emitULEB128(Offset, nullptr, ULEB128PadSize);
5230b57cec5SDimitry Andric }
5240b57cec5SDimitry Andric
sizeOf(const dwarf::FormParams &,dwarf::Form) const52504eeddc0SDimitry Andric unsigned DIEBaseTypeRef::sizeOf(const dwarf::FormParams &, dwarf::Form) const {
5260b57cec5SDimitry Andric return ULEB128PadSize;
5270b57cec5SDimitry Andric }
5280b57cec5SDimitry Andric
5290b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const5300b57cec5SDimitry Andric void DIEBaseTypeRef::print(raw_ostream &O) const { O << "BaseTypeRef: " << Index; }
5310b57cec5SDimitry Andric
5320b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5330b57cec5SDimitry Andric // DIEDelta Implementation
5340b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5350b57cec5SDimitry Andric
5360b57cec5SDimitry Andric /// EmitValue - Emit delta value.
5370b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const5385ffd83dbSDimitry Andric void DIEDelta::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
53904eeddc0SDimitry Andric AP->emitLabelDifference(LabelHi, LabelLo,
54004eeddc0SDimitry Andric sizeOf(AP->getDwarfFormParams(), Form));
5410b57cec5SDimitry Andric }
5420b57cec5SDimitry Andric
5430b57cec5SDimitry Andric /// SizeOf - Determine size of delta value in bytes.
5440b57cec5SDimitry Andric ///
sizeOf(const dwarf::FormParams & FormParams,dwarf::Form Form) const54504eeddc0SDimitry Andric unsigned DIEDelta::sizeOf(const dwarf::FormParams &FormParams,
54604eeddc0SDimitry Andric dwarf::Form Form) const {
547e8d8bef9SDimitry Andric switch (Form) {
548e8d8bef9SDimitry Andric case dwarf::DW_FORM_data4:
549e8d8bef9SDimitry Andric return 4;
550e8d8bef9SDimitry Andric case dwarf::DW_FORM_data8:
551e8d8bef9SDimitry Andric return 8;
552e8d8bef9SDimitry Andric case dwarf::DW_FORM_sec_offset:
55304eeddc0SDimitry Andric return FormParams.getDwarfOffsetByteSize();
554e8d8bef9SDimitry Andric default:
555e8d8bef9SDimitry Andric llvm_unreachable("DIE Value form not supported yet");
556e8d8bef9SDimitry Andric }
5570b57cec5SDimitry Andric }
5580b57cec5SDimitry Andric
5590b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const5600b57cec5SDimitry Andric void DIEDelta::print(raw_ostream &O) const {
5610b57cec5SDimitry Andric O << "Del: " << LabelHi->getName() << "-" << LabelLo->getName();
5620b57cec5SDimitry Andric }
5630b57cec5SDimitry Andric
5640b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5650b57cec5SDimitry Andric // DIEString Implementation
5660b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5670b57cec5SDimitry Andric
5680b57cec5SDimitry Andric /// EmitValue - Emit string value.
5690b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const5705ffd83dbSDimitry Andric void DIEString::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
5710b57cec5SDimitry Andric // Index of string in symbol table.
5720b57cec5SDimitry Andric switch (Form) {
5730b57cec5SDimitry Andric case dwarf::DW_FORM_GNU_str_index:
5740b57cec5SDimitry Andric case dwarf::DW_FORM_strx:
5750b57cec5SDimitry Andric case dwarf::DW_FORM_strx1:
5760b57cec5SDimitry Andric case dwarf::DW_FORM_strx2:
5770b57cec5SDimitry Andric case dwarf::DW_FORM_strx3:
5780b57cec5SDimitry Andric case dwarf::DW_FORM_strx4:
5795ffd83dbSDimitry Andric DIEInteger(S.getIndex()).emitValue(AP, Form);
5800b57cec5SDimitry Andric return;
5810b57cec5SDimitry Andric case dwarf::DW_FORM_strp:
582bdd1243dSDimitry Andric if (AP->doesDwarfUseRelocationsAcrossSections())
5835ffd83dbSDimitry Andric DIELabel(S.getSymbol()).emitValue(AP, Form);
5840b57cec5SDimitry Andric else
5855ffd83dbSDimitry Andric DIEInteger(S.getOffset()).emitValue(AP, Form);
5860b57cec5SDimitry Andric return;
5870b57cec5SDimitry Andric default:
5880b57cec5SDimitry Andric llvm_unreachable("Expected valid string form");
5890b57cec5SDimitry Andric }
5900b57cec5SDimitry Andric }
5910b57cec5SDimitry Andric
59204eeddc0SDimitry Andric /// sizeOf - Determine size of delta value in bytes.
5930b57cec5SDimitry Andric ///
sizeOf(const dwarf::FormParams & FormParams,dwarf::Form Form) const59404eeddc0SDimitry Andric unsigned DIEString::sizeOf(const dwarf::FormParams &FormParams,
59504eeddc0SDimitry Andric dwarf::Form Form) const {
5960b57cec5SDimitry Andric // Index of string in symbol table.
5970b57cec5SDimitry Andric switch (Form) {
5980b57cec5SDimitry Andric case dwarf::DW_FORM_GNU_str_index:
5990b57cec5SDimitry Andric case dwarf::DW_FORM_strx:
6000b57cec5SDimitry Andric case dwarf::DW_FORM_strx1:
6010b57cec5SDimitry Andric case dwarf::DW_FORM_strx2:
6020b57cec5SDimitry Andric case dwarf::DW_FORM_strx3:
6030b57cec5SDimitry Andric case dwarf::DW_FORM_strx4:
60404eeddc0SDimitry Andric return DIEInteger(S.getIndex()).sizeOf(FormParams, Form);
6050b57cec5SDimitry Andric case dwarf::DW_FORM_strp:
60604eeddc0SDimitry Andric if (FormParams.DwarfUsesRelocationsAcrossSections)
60704eeddc0SDimitry Andric return DIELabel(S.getSymbol()).sizeOf(FormParams, Form);
60804eeddc0SDimitry Andric return DIEInteger(S.getOffset()).sizeOf(FormParams, Form);
6090b57cec5SDimitry Andric default:
6100b57cec5SDimitry Andric llvm_unreachable("Expected valid string form");
6110b57cec5SDimitry Andric }
6120b57cec5SDimitry Andric }
6130b57cec5SDimitry Andric
6140b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const6150b57cec5SDimitry Andric void DIEString::print(raw_ostream &O) const {
6160b57cec5SDimitry Andric O << "String: " << S.getString();
6170b57cec5SDimitry Andric }
6180b57cec5SDimitry Andric
6190b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6200b57cec5SDimitry Andric // DIEInlineString Implementation
6210b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
emitValue(const AsmPrinter * AP,dwarf::Form Form) const6225ffd83dbSDimitry Andric void DIEInlineString::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
6230b57cec5SDimitry Andric if (Form == dwarf::DW_FORM_string) {
6245ffd83dbSDimitry Andric AP->OutStreamer->emitBytes(S);
6250b57cec5SDimitry Andric AP->emitInt8(0);
6260b57cec5SDimitry Andric return;
6270b57cec5SDimitry Andric }
6280b57cec5SDimitry Andric llvm_unreachable("Expected valid string form");
6290b57cec5SDimitry Andric }
6300b57cec5SDimitry Andric
sizeOf(const dwarf::FormParams &,dwarf::Form) const63104eeddc0SDimitry Andric unsigned DIEInlineString::sizeOf(const dwarf::FormParams &, dwarf::Form) const {
6320b57cec5SDimitry Andric // Emit string bytes + NULL byte.
6330b57cec5SDimitry Andric return S.size() + 1;
6340b57cec5SDimitry Andric }
6350b57cec5SDimitry Andric
6360b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const6370b57cec5SDimitry Andric void DIEInlineString::print(raw_ostream &O) const {
6380b57cec5SDimitry Andric O << "InlineString: " << S;
6390b57cec5SDimitry Andric }
6400b57cec5SDimitry Andric
6410b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6420b57cec5SDimitry Andric // DIEEntry Implementation
6430b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6440b57cec5SDimitry Andric
6450b57cec5SDimitry Andric /// EmitValue - Emit debug information entry offset.
6460b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const6475ffd83dbSDimitry Andric void DIEEntry::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
6480b57cec5SDimitry Andric
6490b57cec5SDimitry Andric switch (Form) {
6500b57cec5SDimitry Andric case dwarf::DW_FORM_ref1:
6510b57cec5SDimitry Andric case dwarf::DW_FORM_ref2:
6520b57cec5SDimitry Andric case dwarf::DW_FORM_ref4:
6530b57cec5SDimitry Andric case dwarf::DW_FORM_ref8:
65404eeddc0SDimitry Andric AP->OutStreamer->emitIntValue(Entry->getOffset(),
65504eeddc0SDimitry Andric sizeOf(AP->getDwarfFormParams(), Form));
6560b57cec5SDimitry Andric return;
6570b57cec5SDimitry Andric
6580b57cec5SDimitry Andric case dwarf::DW_FORM_ref_udata:
6595ffd83dbSDimitry Andric AP->emitULEB128(Entry->getOffset());
6600b57cec5SDimitry Andric return;
6610b57cec5SDimitry Andric
6620b57cec5SDimitry Andric case dwarf::DW_FORM_ref_addr: {
6630b57cec5SDimitry Andric // Get the absolute offset for this DIE within the debug info/types section.
664e8d8bef9SDimitry Andric uint64_t Addr = Entry->getDebugSectionOffset();
6650b57cec5SDimitry Andric if (const MCSymbol *SectionSym =
6660b57cec5SDimitry Andric Entry->getUnit()->getCrossSectionRelativeBaseAddress()) {
66704eeddc0SDimitry Andric AP->emitLabelPlusOffset(SectionSym, Addr,
66804eeddc0SDimitry Andric sizeOf(AP->getDwarfFormParams(), Form), true);
6690b57cec5SDimitry Andric return;
6700b57cec5SDimitry Andric }
6710b57cec5SDimitry Andric
67204eeddc0SDimitry Andric AP->OutStreamer->emitIntValue(Addr, sizeOf(AP->getDwarfFormParams(), Form));
6730b57cec5SDimitry Andric return;
6740b57cec5SDimitry Andric }
6750b57cec5SDimitry Andric default:
6760b57cec5SDimitry Andric llvm_unreachable("Improper form for DIE reference");
6770b57cec5SDimitry Andric }
6780b57cec5SDimitry Andric }
6790b57cec5SDimitry Andric
sizeOf(const dwarf::FormParams & FormParams,dwarf::Form Form) const68004eeddc0SDimitry Andric unsigned DIEEntry::sizeOf(const dwarf::FormParams &FormParams,
68104eeddc0SDimitry Andric dwarf::Form Form) const {
6820b57cec5SDimitry Andric switch (Form) {
6830b57cec5SDimitry Andric case dwarf::DW_FORM_ref1:
6840b57cec5SDimitry Andric return 1;
6850b57cec5SDimitry Andric case dwarf::DW_FORM_ref2:
6860b57cec5SDimitry Andric return 2;
6870b57cec5SDimitry Andric case dwarf::DW_FORM_ref4:
6880b57cec5SDimitry Andric return 4;
6890b57cec5SDimitry Andric case dwarf::DW_FORM_ref8:
6900b57cec5SDimitry Andric return 8;
6910b57cec5SDimitry Andric case dwarf::DW_FORM_ref_udata:
6920b57cec5SDimitry Andric return getULEB128Size(Entry->getOffset());
6930b57cec5SDimitry Andric case dwarf::DW_FORM_ref_addr:
69404eeddc0SDimitry Andric return FormParams.getRefAddrByteSize();
6950b57cec5SDimitry Andric
6960b57cec5SDimitry Andric default:
6970b57cec5SDimitry Andric llvm_unreachable("Improper form for DIE reference");
6980b57cec5SDimitry Andric }
6990b57cec5SDimitry Andric }
7000b57cec5SDimitry Andric
7010b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const7020b57cec5SDimitry Andric void DIEEntry::print(raw_ostream &O) const {
7030b57cec5SDimitry Andric O << format("Die: 0x%lx", (long)(intptr_t)&Entry);
7040b57cec5SDimitry Andric }
7050b57cec5SDimitry Andric
7060b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7070b57cec5SDimitry Andric // DIELoc Implementation
7080b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7090b57cec5SDimitry Andric
computeSize(const dwarf::FormParams & FormParams) const71004eeddc0SDimitry Andric unsigned DIELoc::computeSize(const dwarf::FormParams &FormParams) const {
7110b57cec5SDimitry Andric if (!Size) {
7120b57cec5SDimitry Andric for (const auto &V : values())
71304eeddc0SDimitry Andric Size += V.sizeOf(FormParams);
7140b57cec5SDimitry Andric }
7150b57cec5SDimitry Andric
7160b57cec5SDimitry Andric return Size;
7170b57cec5SDimitry Andric }
7180b57cec5SDimitry Andric
7190b57cec5SDimitry Andric /// EmitValue - Emit location data.
7200b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * Asm,dwarf::Form Form) const7215ffd83dbSDimitry Andric void DIELoc::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
7220b57cec5SDimitry Andric switch (Form) {
7230b57cec5SDimitry Andric default: llvm_unreachable("Improper form for block");
7240b57cec5SDimitry Andric case dwarf::DW_FORM_block1: Asm->emitInt8(Size); break;
7250b57cec5SDimitry Andric case dwarf::DW_FORM_block2: Asm->emitInt16(Size); break;
7260b57cec5SDimitry Andric case dwarf::DW_FORM_block4: Asm->emitInt32(Size); break;
7270b57cec5SDimitry Andric case dwarf::DW_FORM_block:
7280b57cec5SDimitry Andric case dwarf::DW_FORM_exprloc:
7295ffd83dbSDimitry Andric Asm->emitULEB128(Size);
7305ffd83dbSDimitry Andric break;
7310b57cec5SDimitry Andric }
7320b57cec5SDimitry Andric
7330b57cec5SDimitry Andric for (const auto &V : values())
7345ffd83dbSDimitry Andric V.emitValue(Asm);
7350b57cec5SDimitry Andric }
7360b57cec5SDimitry Andric
73704eeddc0SDimitry Andric /// sizeOf - Determine size of location data in bytes.
7380b57cec5SDimitry Andric ///
sizeOf(const dwarf::FormParams &,dwarf::Form Form) const73904eeddc0SDimitry Andric unsigned DIELoc::sizeOf(const dwarf::FormParams &, dwarf::Form Form) const {
7400b57cec5SDimitry Andric switch (Form) {
7410b57cec5SDimitry Andric case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
7420b57cec5SDimitry Andric case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
7430b57cec5SDimitry Andric case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
7440b57cec5SDimitry Andric case dwarf::DW_FORM_block:
7450b57cec5SDimitry Andric case dwarf::DW_FORM_exprloc:
7460b57cec5SDimitry Andric return Size + getULEB128Size(Size);
7470b57cec5SDimitry Andric default: llvm_unreachable("Improper form for block");
7480b57cec5SDimitry Andric }
7490b57cec5SDimitry Andric }
7500b57cec5SDimitry Andric
7510b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const7520b57cec5SDimitry Andric void DIELoc::print(raw_ostream &O) const {
7530b57cec5SDimitry Andric printValues(O, *this, "ExprLoc", Size, 5);
7540b57cec5SDimitry Andric }
7550b57cec5SDimitry Andric
7560b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7570b57cec5SDimitry Andric // DIEBlock Implementation
7580b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7590b57cec5SDimitry Andric
computeSize(const dwarf::FormParams & FormParams) const76004eeddc0SDimitry Andric unsigned DIEBlock::computeSize(const dwarf::FormParams &FormParams) const {
7610b57cec5SDimitry Andric if (!Size) {
7620b57cec5SDimitry Andric for (const auto &V : values())
76304eeddc0SDimitry Andric Size += V.sizeOf(FormParams);
7640b57cec5SDimitry Andric }
7650b57cec5SDimitry Andric
7660b57cec5SDimitry Andric return Size;
7670b57cec5SDimitry Andric }
7680b57cec5SDimitry Andric
7690b57cec5SDimitry Andric /// EmitValue - Emit block data.
7700b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * Asm,dwarf::Form Form) const7715ffd83dbSDimitry Andric void DIEBlock::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
7720b57cec5SDimitry Andric switch (Form) {
7730b57cec5SDimitry Andric default: llvm_unreachable("Improper form for block");
7740b57cec5SDimitry Andric case dwarf::DW_FORM_block1: Asm->emitInt8(Size); break;
7750b57cec5SDimitry Andric case dwarf::DW_FORM_block2: Asm->emitInt16(Size); break;
7760b57cec5SDimitry Andric case dwarf::DW_FORM_block4: Asm->emitInt32(Size); break;
777fe6060f1SDimitry Andric case dwarf::DW_FORM_exprloc:
7785ffd83dbSDimitry Andric case dwarf::DW_FORM_block:
7795ffd83dbSDimitry Andric Asm->emitULEB128(Size);
7805ffd83dbSDimitry Andric break;
7810b57cec5SDimitry Andric case dwarf::DW_FORM_string: break;
7820b57cec5SDimitry Andric case dwarf::DW_FORM_data16: break;
7830b57cec5SDimitry Andric }
7840b57cec5SDimitry Andric
7850b57cec5SDimitry Andric for (const auto &V : values())
7865ffd83dbSDimitry Andric V.emitValue(Asm);
7870b57cec5SDimitry Andric }
7880b57cec5SDimitry Andric
78904eeddc0SDimitry Andric /// sizeOf - Determine size of block data in bytes.
7900b57cec5SDimitry Andric ///
sizeOf(const dwarf::FormParams &,dwarf::Form Form) const79104eeddc0SDimitry Andric unsigned DIEBlock::sizeOf(const dwarf::FormParams &, dwarf::Form Form) const {
7920b57cec5SDimitry Andric switch (Form) {
7930b57cec5SDimitry Andric case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
7940b57cec5SDimitry Andric case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
7950b57cec5SDimitry Andric case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
796fe6060f1SDimitry Andric case dwarf::DW_FORM_exprloc:
7970b57cec5SDimitry Andric case dwarf::DW_FORM_block: return Size + getULEB128Size(Size);
7980b57cec5SDimitry Andric case dwarf::DW_FORM_data16: return 16;
7990b57cec5SDimitry Andric default: llvm_unreachable("Improper form for block");
8000b57cec5SDimitry Andric }
8010b57cec5SDimitry Andric }
8020b57cec5SDimitry Andric
8030b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const8040b57cec5SDimitry Andric void DIEBlock::print(raw_ostream &O) const {
8050b57cec5SDimitry Andric printValues(O, *this, "Blk", Size, 5);
8060b57cec5SDimitry Andric }
8070b57cec5SDimitry Andric
8080b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8090b57cec5SDimitry Andric // DIELocList Implementation
8100b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8110b57cec5SDimitry Andric
sizeOf(const dwarf::FormParams & FormParams,dwarf::Form Form) const81204eeddc0SDimitry Andric unsigned DIELocList::sizeOf(const dwarf::FormParams &FormParams,
81304eeddc0SDimitry Andric dwarf::Form Form) const {
814e8d8bef9SDimitry Andric switch (Form) {
815e8d8bef9SDimitry Andric case dwarf::DW_FORM_loclistx:
816480093f4SDimitry Andric return getULEB128Size(Index);
817e8d8bef9SDimitry Andric case dwarf::DW_FORM_data4:
81804eeddc0SDimitry Andric assert(FormParams.Format != dwarf::DWARF64 &&
819e8d8bef9SDimitry Andric "DW_FORM_data4 is not suitable to emit a pointer to a location list "
820e8d8bef9SDimitry Andric "in the 64-bit DWARF format");
8210b57cec5SDimitry Andric return 4;
822e8d8bef9SDimitry Andric case dwarf::DW_FORM_data8:
82304eeddc0SDimitry Andric assert(FormParams.Format == dwarf::DWARF64 &&
824e8d8bef9SDimitry Andric "DW_FORM_data8 is not suitable to emit a pointer to a location list "
825e8d8bef9SDimitry Andric "in the 32-bit DWARF format");
826e8d8bef9SDimitry Andric return 8;
827e8d8bef9SDimitry Andric case dwarf::DW_FORM_sec_offset:
82804eeddc0SDimitry Andric return FormParams.getDwarfOffsetByteSize();
829e8d8bef9SDimitry Andric default:
830e8d8bef9SDimitry Andric llvm_unreachable("DIE Value form not supported yet");
831e8d8bef9SDimitry Andric }
8320b57cec5SDimitry Andric }
8330b57cec5SDimitry Andric
8340b57cec5SDimitry Andric /// EmitValue - Emit label value.
8350b57cec5SDimitry Andric ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const8365ffd83dbSDimitry Andric void DIELocList::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
837480093f4SDimitry Andric if (Form == dwarf::DW_FORM_loclistx) {
8385ffd83dbSDimitry Andric AP->emitULEB128(Index);
839480093f4SDimitry Andric return;
840480093f4SDimitry Andric }
8410b57cec5SDimitry Andric DwarfDebug *DD = AP->getDwarfDebug();
8420b57cec5SDimitry Andric MCSymbol *Label = DD->getDebugLocs().getList(Index).Label;
8430b57cec5SDimitry Andric AP->emitDwarfSymbolReference(Label, /*ForceOffset*/ DD->useSplitDwarf());
8440b57cec5SDimitry Andric }
8450b57cec5SDimitry Andric
8460b57cec5SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const8470b57cec5SDimitry Andric void DIELocList::print(raw_ostream &O) const { O << "LocList: " << Index; }
848fe6060f1SDimitry Andric
849fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
850fe6060f1SDimitry Andric // DIEAddrOffset Implementation
851fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
852fe6060f1SDimitry Andric
sizeOf(const dwarf::FormParams & FormParams,dwarf::Form) const85304eeddc0SDimitry Andric unsigned DIEAddrOffset::sizeOf(const dwarf::FormParams &FormParams,
85404eeddc0SDimitry Andric dwarf::Form) const {
85504eeddc0SDimitry Andric return Addr.sizeOf(FormParams, dwarf::DW_FORM_addrx) +
85604eeddc0SDimitry Andric Offset.sizeOf(FormParams, dwarf::DW_FORM_data4);
857fe6060f1SDimitry Andric }
858fe6060f1SDimitry Andric
859fe6060f1SDimitry Andric /// EmitValue - Emit label value.
860fe6060f1SDimitry Andric ///
emitValue(const AsmPrinter * AP,dwarf::Form Form) const861fe6060f1SDimitry Andric void DIEAddrOffset::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
862fe6060f1SDimitry Andric Addr.emitValue(AP, dwarf::DW_FORM_addrx);
863fe6060f1SDimitry Andric Offset.emitValue(AP, dwarf::DW_FORM_data4);
864fe6060f1SDimitry Andric }
865fe6060f1SDimitry Andric
866fe6060f1SDimitry Andric LLVM_DUMP_METHOD
print(raw_ostream & O) const867fe6060f1SDimitry Andric void DIEAddrOffset::print(raw_ostream &O) const {
868fe6060f1SDimitry Andric O << "AddrOffset: ";
869fe6060f1SDimitry Andric Addr.print(O);
870fe6060f1SDimitry Andric O << " + ";
871fe6060f1SDimitry Andric Offset.print(O);
872fe6060f1SDimitry Andric }
873