void AsmPrinter::emitDwarfDIE(const DIE &Die) const { // Emit the code (index) for the abbreviation. if (isVerbose()) OutStreamer->AddComment("Abbrev [" + Twine(Die.getAbbrevNumber()) + "] 0x" + Twine::utohexstr(Die.getOffset()) + ":0x" + Twine::utohexstr(Die.getSize()) + " " + dwarf::TagString(Die.getTag())); EmitULEB128(Die.getAbbrevNumber()); // Emit the DIE attribute values. for (const auto &V : Die.values()) { dwarf::Attribute Attr = V.getAttribute(); assert(V.getForm() && "Too many attributes for DIE (check abbreviation)"); if (isVerbose()) { OutStreamer->AddComment(dwarf::AttributeString(Attr)); if (Attr == dwarf::DW_AT_accessibility) OutStreamer->AddComment( dwarf::AccessibilityString(V.getDIEInteger().getValue())); } // Emit an attribute using the defined form. V.EmitValue(this); } // Emit the DIE children if any. if (Die.hasChildren()) { for (auto &Child : Die.children()) emitDwarfDIE(Child); OutStreamer->AddComment("End Of Children Mark"); EmitInt8(0); } }
void CompileUnit::fixupForwardReferences() { for (const auto &Ref : ForwardDIEReferences) { DIE *RefDie; const CompileUnit *RefUnit; PatchLocation Attr; DeclContext *Ctxt; std::tie(RefDie, RefUnit, Ctxt, Attr) = Ref; if (Ctxt && Ctxt->getCanonicalDIEOffset()) Attr.set(Ctxt->getCanonicalDIEOffset()); else Attr.set(RefDie->getOffset() + RefUnit->getStartOffset()); } }
void AsmPrinter::emitDwarfDIE(const DIE &Die) const { // Get the abbreviation for this DIE. const DIEAbbrev &Abbrev = Die.getAbbrev(); // Emit the code (index) for the abbreviation. if (isVerbose()) OutStreamer.AddComment("Abbrev [" + Twine(Abbrev.getNumber()) + "] 0x" + Twine::utohexstr(Die.getOffset()) + ":0x" + Twine::utohexstr(Die.getSize()) + " " + dwarf::TagString(Abbrev.getTag())); EmitULEB128(Abbrev.getNumber()); const SmallVectorImpl<DIEValue *> &Values = Die.getValues(); const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData(); // Emit the DIE attribute values. for (unsigned i = 0, N = Values.size(); i < N; ++i) { dwarf::Attribute Attr = AbbrevData[i].getAttribute(); dwarf::Form Form = AbbrevData[i].getForm(); assert(Form && "Too many attributes for DIE (check abbreviation)"); if (isVerbose()) { OutStreamer.AddComment(dwarf::AttributeString(Attr)); if (Attr == dwarf::DW_AT_accessibility) OutStreamer.AddComment(dwarf::AccessibilityString( cast<DIEInteger>(Values[i])->getValue())); } // Emit an attribute using the defined form. Values[i]->EmitValue(this, Form); } // Emit the DIE children if any. if (Abbrev.hasChildren()) { for (auto &Child : Die.getChildren()) emitDwarfDIE(Child); OutStreamer.AddComment("End Of Children Mark"); EmitInt8(0); } }
// Compute the size and offset of a DIE. The offset is relative to start of the // CU. It returns the offset after laying out the DIE. unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) { // Record the abbreviation. assignAbbrevNumber(Die.getAbbrev()); // Get the abbreviation for this DIE. const DIEAbbrev &Abbrev = Die.getAbbrev(); // Set DIE offset Die.setOffset(Offset); // Start the size with the size of abbreviation code. Offset += getULEB128Size(Die.getAbbrevNumber()); const SmallVectorImpl<DIEValue *> &Values = Die.getValues(); const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData(); // Size the DIE attribute values. for (unsigned i = 0, N = Values.size(); i < N; ++i) // Size attribute value. Offset += Values[i]->SizeOf(Asm, AbbrevData[i].getForm()); // Get the children. const auto &Children = Die.getChildren(); // Size the DIE children if any. if (!Children.empty()) { assert(Abbrev.hasChildren() && "Children flag not set"); for (auto &Child : Children) Offset = computeSizeAndOffset(*Child, Offset); // End of children marker. Offset += sizeof(int8_t); } Die.setSize(Offset - Die.getOffset()); return Offset; }