From 72f7bfbf0e02bb11d3e7cca1f9598c5f9d9fa2ca Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Tue, 15 Jan 2013 23:56:56 +0000 Subject: [PATCH] Split address information for DWARF5 split dwarf proposal. This involves using the DW_FORM_GNU_addr_index and a separate .debug_addr section which stays in the executable and is fully linked. Sneak in two other small changes: a) Print out the debug_str_offsets.dwo section. b) Change form we're expecting the entries in the debug_str_offsets.dwo section to take from ULEB128 to U32. Add tests for all of this in the fission-cu.ll test. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172578 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCObjectFileInfo.h | 4 + lib/CodeGen/AsmPrinter/DIE.cpp | 2 + lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 20 +++++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.h | 5 ++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 85 ++++++++++++++++----- lib/CodeGen/AsmPrinter/DwarfDebug.h | 25 +++++- lib/DebugInfo/DWARFCompileUnit.h | 6 +- lib/DebugInfo/DWARFContext.cpp | 14 +++- lib/DebugInfo/DWARFContext.h | 5 ++ lib/DebugInfo/DWARFFormValue.cpp | 21 ++++- lib/DebugInfo/DWARFFormValue.h | 2 + lib/MC/MCObjectFileInfo.cpp | 3 + test/DebugInfo/X86/fission-cu.ll | 40 +++++++++- 13 files changed, 204 insertions(+), 28 deletions(-) diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h index c8444fda2a6..c52130a0947 100644 --- a/include/llvm/MC/MCObjectFileInfo.h +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -115,6 +115,7 @@ protected: const MCSection *DwarfLineDWOSection; const MCSection *DwarfLocDWOSection; const MCSection *DwarfStrOffDWOSection; + const MCSection *DwarfAddrSection; // Extra TLS Variable Data section. If the target needs to put additional // information for a TLS variable, it'll go here. @@ -251,6 +252,9 @@ public: const MCSection *getDwarfStrOffDWOSection() const { return DwarfStrOffDWOSection; } + const MCSection *getDwarfAddrSection() const { + return DwarfAddrSection; + } const MCSection *getTLSExtraDataSection() const { return TLSExtraDataSection; diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp index fecb0419c78..0a659c2a09c 100644 --- a/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/lib/CodeGen/AsmPrinter/DIE.cpp @@ -198,6 +198,7 @@ void DIEInteger::EmitValue(AsmPrinter *Asm, unsigned Form) const { case dwarf::DW_FORM_ref8: // Fall thru case dwarf::DW_FORM_data8: Size = 8; break; case dwarf::DW_FORM_GNU_str_index: Asm->EmitULEB128(Integer); return; + case dwarf::DW_FORM_GNU_addr_index: Asm->EmitULEB128(Integer); return; case dwarf::DW_FORM_udata: Asm->EmitULEB128(Integer); return; case dwarf::DW_FORM_sdata: Asm->EmitSLEB128(Integer); return; case dwarf::DW_FORM_addr: @@ -222,6 +223,7 @@ unsigned DIEInteger::SizeOf(AsmPrinter *AP, unsigned Form) const { case dwarf::DW_FORM_ref8: // Fall thru case dwarf::DW_FORM_data8: return sizeof(int64_t); case dwarf::DW_FORM_GNU_str_index: return MCAsmInfo::getULEB128Size(Integer); + case dwarf::DW_FORM_GNU_addr_index: return MCAsmInfo::getULEB128Size(Integer); case dwarf::DW_FORM_udata: return MCAsmInfo::getULEB128Size(Integer); case dwarf::DW_FORM_sdata: return MCAsmInfo::getSLEB128Size(Integer); case dwarf::DW_FORM_addr: return AP->getDataLayout().getPointerSize(); diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 21cceaf7c3c..589606522a4 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -170,6 +170,26 @@ void CompileUnit::addLabel(DIE *Die, unsigned Attribute, unsigned Form, Die->addValue(Attribute, Form, Value); } +/// addLabelAddress - Add a dwarf label attribute data and value using +/// DW_FORM_addr or DW_FORM_GNU_addr_index. +/// +void CompileUnit::addLabelAddress(DIE *Die, unsigned Attribute, + MCSymbol *Label) { + if (!DD->useSplitDwarf()) { + if (Label != NULL) { + DIEValue *Value = new (DIEValueAllocator) DIELabel(Label); + Die->addValue(Attribute, dwarf::DW_FORM_addr, Value); + } else { + DIEValue *Value = new (DIEValueAllocator) DIEInteger(0); + Die->addValue(Attribute, dwarf::DW_FORM_addr, Value); + } + } else { + unsigned idx = DU->getAddrPoolIndex(Label); + DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx); + Die->addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value); + } +} + /// addDelta - Add a label delta attribute data and value. /// void CompileUnit::addDelta(DIE *Die, unsigned Attribute, unsigned Form, diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index f210dcc03b5..0d84ca561bd 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -207,6 +207,11 @@ public: void addLabel(DIE *Die, unsigned Attribute, unsigned Form, const MCSymbol *Label); + /// addLabelAddress - Add a dwarf label attribute data and value using + /// either DW_FORM_addr or DW_FORM_GNU_addr_index. + /// + void addLabelAddress(DIE *Die, unsigned Attribute, MCSymbol *Label); + /// addDelta - Add a label delta attribute data and value. /// void addDelta(DIE *Die, unsigned Attribute, unsigned Form, diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 93106a05965..1813132f877 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -237,6 +237,15 @@ unsigned DwarfUnits::getStringPoolIndex(StringRef Str) { return Entry.second; } +unsigned DwarfUnits::getAddrPoolIndex(MCSymbol *Sym) { + std::pair &Entry = AddressPool[Sym]; + if (Entry.first) return Entry.second; + + Entry.second = NextAddrPoolNumber++; + Entry.first = Sym; + return Entry.second; +} + // Define a unique number for the abbreviation. // void DwarfUnits::assignAbbrevNumber(DIEAbbrev &Abbrev) { @@ -384,10 +393,12 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, } } - SPCU->addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, - Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber())); - SPCU->addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, - Asm->GetTempSymbol("func_end", Asm->getFunctionNumber())); + SPCU->addLabelAddress(SPDie, dwarf::DW_AT_low_pc, + Asm->GetTempSymbol("func_begin", + Asm->getFunctionNumber())); + SPCU->addLabelAddress(SPDie, dwarf::DW_AT_high_pc, + Asm->GetTempSymbol("func_end", + Asm->getFunctionNumber())); const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); MachineLocation Location(RI->getFrameRegister(*Asm->MF)); SPCU->addAddress(SPDie, dwarf::DW_AT_frame_base, Location); @@ -429,16 +440,16 @@ DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU, return ScopeDIE; } - const MCSymbol *Start = getLabelBeforeInsn(RI->first); - const MCSymbol *End = getLabelAfterInsn(RI->second); + MCSymbol *Start = getLabelBeforeInsn(RI->first); + MCSymbol *End = getLabelAfterInsn(RI->second); if (End == 0) return 0; assert(Start->isDefined() && "Invalid starting label for an inlined scope!"); assert(End->isDefined() && "Invalid end label for an inlined scope!"); - TheCU->addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, Start); - TheCU->addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, End); + TheCU->addLabelAddress(ScopeDIE, dwarf::DW_AT_low_pc, Start); + TheCU->addLabelAddress(ScopeDIE, dwarf::DW_AT_high_pc, End); return ScopeDIE; } @@ -462,8 +473,8 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU, } SmallVector::const_iterator RI = Ranges.begin(); - const MCSymbol *StartLabel = getLabelBeforeInsn(RI->first); - const MCSymbol *EndLabel = getLabelAfterInsn(RI->second); + MCSymbol *StartLabel = getLabelBeforeInsn(RI->first); + MCSymbol *EndLabel = getLabelAfterInsn(RI->second); if (StartLabel == 0 || EndLabel == 0) { llvm_unreachable("Unexpected Start and End labels for an inlined scope!"); @@ -492,10 +503,8 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU, DebugRangeSymbols.push_back(NULL); DebugRangeSymbols.push_back(NULL); } else { - TheCU->addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, - StartLabel); - TheCU->addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, - EndLabel); + TheCU->addLabelAddress(ScopeDIE, dwarf::DW_AT_low_pc, StartLabel); + TheCU->addLabelAddress(ScopeDIE, dwarf::DW_AT_high_pc, EndLabel); } InlinedSubprogramDIEs.insert(OriginDIE); @@ -646,8 +655,8 @@ CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) { DIUnit.getLanguage()); NewCU->addString(Die, dwarf::DW_AT_name, FN); // 2.17.1 requires that we use DW_AT_low_pc for a single entry point - // into an entity. - NewCU->addUInt(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0); + // into an entity. We're using 0 (or a NULL label) for this. + NewCU->addLabelAddress(Die, dwarf::DW_AT_low_pc, NULL); // DW_AT_stmt_list is a offset of line number information for this // compile unit in debug_line section. if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) @@ -975,6 +984,9 @@ void DwarfDebug::endModule() { // Emit info into a debug macinfo section. emitDebugMacInfo(); + // Emit DWO addresses. + InfoHolder.emitAddresses(Asm->getObjFileLowering().getDwarfAddrSection()); + // Emit inline info. // TODO: When we don't need the option anymore we // can remove all of the code that this section @@ -1234,14 +1246,14 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF, } // Return Label preceding the instruction. -const MCSymbol *DwarfDebug::getLabelBeforeInsn(const MachineInstr *MI) { +MCSymbol *DwarfDebug::getLabelBeforeInsn(const MachineInstr *MI) { MCSymbol *Label = LabelsBeforeInsn.lookup(MI); assert(Label && "Didn't insert label before instruction"); return Label; } // Return Label immediately following the instruction. -const MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) { +MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) { return LabelsAfterInsn.lookup(MI); } @@ -2158,7 +2170,7 @@ void DwarfUnits::emitStrings(const MCSection *StrSection, if (OffsetSection) { Asm->OutStreamer.SwitchSection(OffsetSection); unsigned offset = 0; - unsigned size = 4; + unsigned size = 4; // FIXME: DWARF64 is 8. for (unsigned i = 0, e = Entries.size(); i != e; ++i) { Asm->OutStreamer.EmitIntValue(offset, size); offset += Entries[i].second->getKeyLength() + 1; @@ -2166,6 +2178,38 @@ void DwarfUnits::emitStrings(const MCSection *StrSection, } } +// Emit strings into a string section. +void DwarfUnits::emitAddresses(const MCSection *AddrSection) { + + if (AddressPool.empty()) return; + + // Start the dwarf addr section. + Asm->OutStreamer.SwitchSection(AddrSection); + + // Get all of the string pool entries and put them in an array by their ID so + // we can sort them. + SmallVector* >, 64> Entries; + + for (DenseMap >::iterator + I = AddressPool.begin(), E = AddressPool.end(); + I != E; ++I) + Entries.push_back(std::make_pair(I->second.second, &(I->second))); + + array_pod_sort(Entries.begin(), Entries.end()); + + for (unsigned i = 0, e = Entries.size(); i != e; ++i) { + // Emit a label for reference from debug information entries. + MCSymbol *Sym = Entries[i].second->first; + if (Sym) + Asm->EmitLabelReference(Entries[i].second->first, + Asm->getDataLayout().getPointerSize()); + else + Asm->OutStreamer.EmitIntValue(0, Asm->getDataLayout().getPointerSize()); + } + +} + // Emit visible names into a debug str section. void DwarfDebug::emitDebugStr() { DwarfUnits &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; @@ -2402,8 +2446,9 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const MDNode *N) { // FIXME: We also need DW_AT_addr_base and DW_AT_dwo_id. // 2.17.1 requires that we use DW_AT_low_pc for a single entry point - // into an entity. + // into an entity. We're using 0, or a NULL label for this. NewCU->addUInt(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0); + // DW_AT_stmt_list is a offset of line number information for this // compile unit in debug_line section. if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 1e471f75f51..9cff12860cb 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -195,6 +195,10 @@ public: typedef StringMap, BumpPtrAllocator&> StrPool; +// A Symbol->pair mapping of addresses used by indirect +// references. +typedef DenseMap > AddrPool; + /// \brief Collects and handles information specific to a particular /// collection of units. class DwarfUnits { @@ -215,12 +219,17 @@ class DwarfUnits { unsigned NextStringPoolNumber; std::string StringPref; + // Collection of addresses for this unit and assorted labels. + AddrPool AddressPool; + unsigned NextAddrPoolNumber; + public: DwarfUnits(AsmPrinter *AP, FoldingSet *AS, std::vector *A, const char *Pref, BumpPtrAllocator &DA) : Asm(AP), AbbreviationsSet(AS), Abbreviations(A), - StringPool(DA), NextStringPoolNumber(0), StringPref(Pref) {} + StringPool(DA), NextStringPoolNumber(0), StringPref(Pref), + AddressPool(), NextAddrPoolNumber(0) {} /// \brief Compute the size and offset of a DIE given an incoming Offset. unsigned computeSizeAndOffset(DIE *Die, unsigned Offset); @@ -242,6 +251,9 @@ public: /// \brief Emit all of the strings to the section given. void emitStrings(const MCSection *, const MCSection *, const MCSymbol *); + /// \brief Emit all of the addresses to the section given. + void emitAddresses(const MCSection *); + /// \brief Returns the entry into the start of the pool. MCSymbol *getStringPoolSym(); @@ -255,6 +267,13 @@ public: /// \brief Returns the string pool. StrPool *getStringPool() { return &StringPool; } + + /// \brief Returns the index into the address pool with the given + /// label/symbol. + unsigned getAddrPoolIndex(MCSymbol *); + + /// \brief Returns the address pool. + AddrPool *getAddrPool() { return &AddressPool; } }; /// \brief Collects and handles dwarf debug information. @@ -560,7 +579,7 @@ private: } /// \brief Return Label preceding the instruction. - const MCSymbol *getLabelBeforeInsn(const MachineInstr *MI); + MCSymbol *getLabelBeforeInsn(const MachineInstr *MI); /// \brief Ensure that a label will be emitted after MI. void requestLabelAfterInsn(const MachineInstr *MI) { @@ -568,7 +587,7 @@ private: } /// \brief Return Label immediately following the instruction. - const MCSymbol *getLabelAfterInsn(const MachineInstr *MI); + MCSymbol *getLabelAfterInsn(const MachineInstr *MI); public: //===--------------------------------------------------------------------===// diff --git a/lib/DebugInfo/DWARFCompileUnit.h b/lib/DebugInfo/DWARFCompileUnit.h index c58664f2234..de70b2e2a90 100644 --- a/lib/DebugInfo/DWARFCompileUnit.h +++ b/lib/DebugInfo/DWARFCompileUnit.h @@ -29,6 +29,7 @@ class DWARFCompileUnit { StringRef RangeSection; StringRef StringSection; StringRef StringOffsetSection; + StringRef AddrOffsetSection; const RelocAddrMap *RelocMap; bool isLittleEndian; @@ -43,16 +44,17 @@ class DWARFCompileUnit { public: DWARFCompileUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef AS, - StringRef RS, StringRef SS, StringRef SOS, + StringRef RS, StringRef SS, StringRef SOS, StringRef AOS, const RelocAddrMap *M, bool LE) : Abbrev(DA), InfoSection(IS), AbbrevSection(AS), RangeSection(RS), StringSection(SS), StringOffsetSection(SOS), - RelocMap(M), isLittleEndian(LE) { + AddrOffsetSection(AOS), RelocMap(M), isLittleEndian(LE) { clear(); } StringRef getStringSection() const { return StringSection; } StringRef getStringOffsetSection() const { return StringOffsetSection; } + StringRef getAddrOffsetSection() const { return AddrOffsetSection; } const RelocAddrMap *getRelocMap() const { return RelocMap; } DataExtractor getDebugInfoExtractor() const; diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp index 247ee5b3575..13a527b7f80 100644 --- a/lib/DebugInfo/DWARFContext.cpp +++ b/lib/DebugInfo/DWARFContext.cpp @@ -86,6 +86,14 @@ void DWARFContext::dump(raw_ostream &OS) { OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s); strDWOOffset = offset; } + + OS << "\n.debug_str_offsets.dwo contents:\n"; + DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(), 0); + offset = 0; + while (offset < getStringOffsetDWOSection().size()) { + OS << format("0x%8.8x: ", offset); + OS << format("%8.8x\n", strOffsetExt.getU32(&offset)); + } } const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() { @@ -152,7 +160,8 @@ void DWARFContext::parseCompileUnits() { while (DIData.isValidOffset(offset)) { CUs.push_back(DWARFCompileUnit(getDebugAbbrev(), getInfoSection(), getAbbrevSection(), getRangeSection(), - getStringSection(), "", + getStringSection(), StringRef(), + getAddrSection(), &infoRelocMap(), isLittleEndian())); if (!CUs.back().extract(DIData, &offset)) { @@ -174,6 +183,7 @@ void DWARFContext::parseDWOCompileUnits() { getRangeDWOSection(), getStringDWOSection(), getStringOffsetDWOSection(), + getAddrSection(), &infoDWORelocMap(), isLittleEndian())); if (!DWOCUs.back().extract(DIData, &offset)) { @@ -386,6 +396,8 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) : StringDWOSection = data; else if (name == "debug_str_offsets.dwo") StringOffsetDWOSection = data; + else if (name == "debug_addr") + AddrSection = data; // Any more debug info sections go here. else continue; diff --git a/lib/DebugInfo/DWARFContext.h b/lib/DebugInfo/DWARFContext.h index 687ff93b079..7da5c85cd3b 100644 --- a/lib/DebugInfo/DWARFContext.h +++ b/lib/DebugInfo/DWARFContext.h @@ -108,6 +108,7 @@ public: virtual StringRef getStringDWOSection() = 0; virtual StringRef getStringOffsetDWOSection() = 0; virtual StringRef getRangeDWOSection() = 0; + virtual StringRef getAddrSection() = 0; virtual const RelocAddrMap &infoDWORelocMap() const = 0; static bool isSupportedVersion(unsigned version) { @@ -143,6 +144,7 @@ class DWARFContextInMemory : public DWARFContext { StringRef StringDWOSection; StringRef StringOffsetDWOSection; StringRef RangeDWOSection; + StringRef AddrSection; public: DWARFContextInMemory(object::ObjectFile *); @@ -163,6 +165,9 @@ public: return StringOffsetDWOSection; } virtual StringRef getRangeDWOSection() { return RangeDWOSection; } + virtual StringRef getAddrSection() { + return AddrSection; + } virtual const RelocAddrMap &infoDWORelocMap() const { return InfoDWORelocMap; } diff --git a/lib/DebugInfo/DWARFFormValue.cpp b/lib/DebugInfo/DWARFFormValue.cpp index 14c68049b30..d1bcf96f7fe 100644 --- a/lib/DebugInfo/DWARFFormValue.cpp +++ b/lib/DebugInfo/DWARFFormValue.cpp @@ -325,6 +325,16 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const { switch (Form) { case DW_FORM_addr: OS << format("0x%016" PRIx64, uvalue); break; + case DW_FORM_GNU_addr_index: { + StringRef AddrOffsetSec = cu->getAddrOffsetSection(); + OS << format(" indexed (%8.8x) address = ", (uint32_t)uvalue); + if (AddrOffsetSec.size() != 0) { + DataExtractor DA(AddrOffsetSec, true, cu->getAddressByteSize()); + OS << format("0x%016" PRIx64, getIndirectAddress(&DA, cu)); + } else + OS << ""; + break; + } case DW_FORM_flag_present: OS << "true"; break; case DW_FORM_flag: case DW_FORM_data1: OS << format("0x%02x", (uint8_t)uvalue); break; @@ -452,10 +462,19 @@ DWARFFormValue::getIndirectCString(const DataExtractor *DS, if (!DS || !DSO) return NULL; uint32_t offset = Value.uval * 4; - uint32_t soffset = DSO->getULEB128(&offset); + uint32_t soffset = DSO->getU32(&offset); return DS->getCStr(&soffset); } +uint64_t +DWARFFormValue::getIndirectAddress(const DataExtractor *DA, + const DWARFCompileUnit *cu) const { + if (!DA) return 0; + + uint32_t offset = Value.uval * cu->getAddressByteSize(); + return DA->getAddress(&offset); +} + uint64_t DWARFFormValue::getReference(const DWARFCompileUnit *cu) const { uint64_t die_offset = Value.uval; switch (Form) { diff --git a/lib/DebugInfo/DWARFFormValue.h b/lib/DebugInfo/DWARFFormValue.h index 7768c1848fa..b863001e4af 100644 --- a/lib/DebugInfo/DWARFFormValue.h +++ b/lib/DebugInfo/DWARFFormValue.h @@ -66,6 +66,8 @@ public: const char *getAsCString(const DataExtractor *debug_str_data_ptr) const; const char *getIndirectCString(const DataExtractor *, const DataExtractor *) const; + uint64_t getIndirectAddress(const DataExtractor *, + const DWARFCompileUnit *) const; bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr, const DWARFCompileUnit *cu) const; static bool skipValue(uint16_t form, DataExtractor debug_info_data, diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp index a3045848b62..1f5548f7798 100644 --- a/lib/MC/MCObjectFileInfo.cpp +++ b/lib/MC/MCObjectFileInfo.cpp @@ -437,6 +437,9 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { DwarfStrOffDWOSection = Ctx->getELFSection(".debug_str_offsets.dwo", ELF::SHT_PROGBITS, 0, SectionKind::getMetadata()); + DwarfAddrSection = + Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0, + SectionKind::getMetadata()); } diff --git a/test/DebugInfo/X86/fission-cu.ll b/test/DebugInfo/X86/fission-cu.ll index 3ada3ef383f..ef5f9586a21 100644 --- a/test/DebugInfo/X86/fission-cu.ll +++ b/test/DebugInfo/X86/fission-cu.ll @@ -26,14 +26,52 @@ ; CHECK: DW_AT_stmt_list [DW_FORM_data4] (0x00000000) ; CHECK: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x00000006] = "/usr/local/google/home/echristo/tmp") +; Check that we're using the right forms. +; CHECK: .debug_abbrev.dwo contents: +; CHECK: Abbrev table for offset: 0x00000000 +; CHECK: [1] DW_TAG_compile_unit DW_CHILDREN_yes +; CHECK: DW_AT_producer DW_FORM_GNU_str_index +; CHECK: DW_AT_language DW_FORM_data2 +; CHECK: DW_AT_name DW_FORM_GNU_str_index +; CHECK: DW_AT_low_pc DW_FORM_GNU_addr_index +; CHECK: DW_AT_stmt_list DW_FORM_data4 +; CHECK: DW_AT_comp_dir DW_FORM_GNU_str_index + +; CHECK: [2] DW_TAG_base_type DW_CHILDREN_no +; CHECK: DW_AT_name DW_FORM_GNU_str_index +; CHECK: DW_AT_encoding DW_FORM_data1 +; CHECK: DW_AT_byte_size DW_FORM_data1 + +; CHECK: [3] DW_TAG_variable DW_CHILDREN_no +; CHECK: DW_AT_name DW_FORM_GNU_str_index +; CHECK: DW_AT_type DW_FORM_ref4 +; CHECK: DW_AT_external DW_FORM_flag_present +; CHECK: DW_AT_decl_file DW_FORM_data1 +; CHECK: DW_AT_decl_line DW_FORM_data1 +; CHECK: DW_AT_location DW_FORM_block1 + ; Check that the rest of the compile units have information. -; FIXME: Strings will ultimately be a different form. ; CHECK: .debug_info.dwo contents: ; CHECK: DW_TAG_compile_unit ; CHECK: DW_AT_producer [DW_FORM_GNU_str_index] ( indexed (00000000) string = "clang version 3.3 (trunk 169021) (llvm/trunk 169020)") ; CHECK: DW_AT_language [DW_FORM_data2] (0x000c) ; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000001) string = "baz.c") +; CHECK: DW_AT_low_pc [DW_FORM_GNU_addr_index] ( indexed (00000000) address = 0x0000000000000000) ; CHECK: DW_TAG_base_type ; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000004) string = "int") ; CHECK: DW_TAG_variable ; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000003) string = "a") + +; CHECK: .debug_str.dwo contents: +; CHECK: 0x00000000: "clang version 3.3 (trunk 169021) (llvm/trunk 169020)" +; CHECK: 0x00000035: "baz.c" +; CHECK: 0x0000003b: "/usr/local/google/home/echristo/tmp" +; CHECK: 0x0000005f: "a" +; CHECK: 0x00000061: "int" + +; CHECK: .debug_str_offsets.dwo contents: +; CHECK: 0x00000000: 00000000 +; CHECK: 0x00000004: 00000035 +; CHECK: 0x00000008: 0000003b +; CHECK: 0x0000000c: 0000005f +; CHECK: 0x00000010: 00000061 -- 2.34.1