From 2d5d104c5b945a214c117328fd9982360782cef0 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Thu, 21 Nov 2013 23:46:41 +0000 Subject: In Dwarf 3 (and Dwarf 2) attributes whose value are offsets into a section use the form DW_FORM_data4 whilst in Dwarf 4 and later they use the form DW_FORM_sec_offset. This patch updates the places where such attributes are generated to use the appropriate form depending on the Dwarf version. The DIE entries affected have the following tags: DW_AT_stmt_list, DW_AT_ranges, DW_AT_location, DW_AT_GNU_pubnames, DW_AT_GNU_pubtypes, DW_AT_GNU_addr_base, DW_AT_GNU_ranges_base It also adds a hidden command line option "--dwarf-version=" to llc which allows the version of Dwarf to be generated to override what is specified in the metadata; this makes it possible to update existing tests to check the debugging information generated for both Dwarf 4 (the default) and Dwarf 3 using the same metadata. Patch (slightly modified) by Keith Walker! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195391 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/AsmPrinter/DIE.cpp | 1 + lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 38 +++++++++--- lib/CodeGen/AsmPrinter/DwarfCompileUnit.h | 14 ++++- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 91 ++++++++++++++++------------- 4 files changed, 92 insertions(+), 52 deletions(-) (limited to 'lib/CodeGen') diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp index b1bcf7c63f..8a7b8608b7 100644 --- a/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/lib/CodeGen/AsmPrinter/DIE.cpp @@ -341,6 +341,7 @@ void DIEDelta::EmitValue(AsmPrinter *AP, dwarf::Form Form) const { /// unsigned DIEDelta::SizeOf(AsmPrinter *AP, dwarf::Form Form) const { if (Form == dwarf::DW_FORM_data4) return 4; + if (Form == dwarf::DW_FORM_sec_offset) return 4; if (Form == dwarf::DW_FORM_strp) return 4; return AP->getDataLayout().getPointerSize(); } diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index a63968c441..73d0a839a7 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -245,6 +245,26 @@ void CompileUnit::addLabel(DIEBlock *Die, dwarf::Form Form, addLabel(Die, (dwarf::Attribute)0, Form, Label); } +/// addSectionLabel - Add a Dwarf section label attribute data and value. +/// +void CompileUnit::addSectionLabel(DIE *Die, dwarf::Attribute Attribute, + const MCSymbol *Label) { + if (DD->getDwarfVersion() >= 4) + addLabel(Die, Attribute, dwarf::DW_FORM_sec_offset, Label); + else + addLabel(Die, Attribute, dwarf::DW_FORM_data4, Label); +} + +/// addSectionOffset - Add an offset into a section attribute data and value. +/// +void CompileUnit::addSectionOffset(DIE *Die, dwarf::Attribute Attribute, + uint64_t Integer) { + if (DD->getDwarfVersion() >= 4) + addUInt(Die, Attribute, dwarf::DW_FORM_sec_offset, Integer); + else + addUInt(Die, Attribute, dwarf::DW_FORM_data4, Integer); +} + /// addLabelAddress - Add a dwarf label attribute data and value using /// DW_FORM_addr or DW_FORM_GNU_addr_index. /// @@ -282,13 +302,15 @@ void CompileUnit::addOpAddress(DIEBlock *Die, const MCSymbol *Sym) { } } -/// addDelta - Add a label delta attribute data and value. +/// addSectionDelta - Add a section label delta attribute data and value. /// -void CompileUnit::addDelta(DIE *Die, dwarf::Attribute Attribute, - dwarf::Form Form, const MCSymbol *Hi, - const MCSymbol *Lo) { +void CompileUnit::addSectionDelta(DIE *Die, dwarf::Attribute Attribute, + const MCSymbol *Hi, const MCSymbol *Lo) { DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo); - Die->addValue(Attribute, Form, Value); + if (DD->getDwarfVersion() >= 4) + Die->addValue(Attribute, dwarf::DW_FORM_sec_offset, Value); + else + Die->addValue(Attribute, dwarf::DW_FORM_data4, Value); } /// addDIEEntry - Add a DIE attribute data and value. @@ -1814,10 +1836,8 @@ DIE *CompileUnit::constructVariableDIE(DbgVariable &DV, bool isScopeAbstract) { unsigned Offset = DV.getDotDebugLocOffset(); if (Offset != ~0U) { - addLabel(VariableDie, dwarf::DW_AT_location, - DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset - : dwarf::DW_FORM_data4, - Asm->GetTempSymbol("debug_loc", Offset)); + addSectionLabel(VariableDie, dwarf::DW_AT_location, + Asm->GetTempSymbol("debug_loc", Offset)); DV.setDIE(VariableDie); return VariableDie; } diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 23d3afc024..0821a9a2b9 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -212,6 +212,14 @@ public: void addLabel(DIEBlock *Die, dwarf::Form Form, const MCSymbol *Label); + /// addSectionLabel - Add a Dwarf section label attribute data and value. + /// + void addSectionLabel(DIE *Die, dwarf::Attribute Attribute, const MCSymbol *Label); + + /// addSectionOffset - Add an offset into a section attribute data and value. + /// + void addSectionOffset(DIE *Die, dwarf::Attribute Attribute, uint64_t Integer); + /// addLabelAddress - Add a dwarf label attribute data and value using /// either DW_FORM_addr or DW_FORM_GNU_addr_index. void addLabelAddress(DIE *Die, dwarf::Attribute Attribute, MCSymbol *Label); @@ -220,9 +228,9 @@ public: /// form given and an op of either DW_FORM_addr or DW_FORM_GNU_addr_index. void addOpAddress(DIEBlock *Die, const MCSymbol *Label); - /// addDelta - Add a label delta attribute data and value. - void addDelta(DIE *Die, dwarf::Attribute Attribute, dwarf::Form Form, - const MCSymbol *Hi, const MCSymbol *Lo); + /// addSectionDelta - Add a label delta attribute data and value. + void addSectionDelta(DIE *Die, dwarf::Attribute Attribute, const MCSymbol *Hi, + const MCSymbol *Lo); /// addDIEEntry - Add a DIE attribute data and value. void addDIEEntry(DIE *Die, dwarf::Attribute Attribute, DIE *Entry); diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index d81e19c07a..6613aac87d 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -104,6 +104,11 @@ DwarfPubSections("generate-dwarf-pub-sections", cl::Hidden, clEnumVal(Disable, "Disabled"), clEnumValEnd), cl::init(Default)); +static cl::opt +DwarfVersionNumber("dwarf-version", cl::Hidden, + cl::desc("Generate DWARF for dwarf version."), + cl::init(0)); + static const char *const DWARFGroupName = "DWARF Emission"; static const char *const DbgTimerName = "DWARF Debug Writer"; @@ -212,7 +217,9 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) else HasDwarfPubSections = DwarfPubSections == Enable; - DwarfVersion = getDwarfVersionFromModule(MMI->getModule()); + DwarfVersion = DwarfVersionNumber + ? DwarfVersionNumber + : getDwarfVersionFromModule(MMI->getModule()); { NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); @@ -470,9 +477,9 @@ DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU, // .debug_range section has not been laid out yet. Emit offset in // .debug_range as a uint, size 4, for now. emitDIE will handle // DW_AT_ranges appropriately. - TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4, - DebugRangeSymbols.size() * - Asm->getDataLayout().getPointerSize()); + TheCU->addSectionOffset(ScopeDIE, dwarf::DW_AT_ranges, + DebugRangeSymbols.size() * + Asm->getDataLayout().getPointerSize()); for (SmallVectorImpl::const_iterator RI = Ranges.begin(), RE = Ranges.end(); RI != RE; ++RI) { @@ -526,9 +533,9 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU, // .debug_range section has not been laid out yet. Emit offset in // .debug_range as a uint, size 4, for now. emitDIE will handle // DW_AT_ranges appropriately. - TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4, - DebugRangeSymbols.size() * - Asm->getDataLayout().getPointerSize()); + TheCU->addSectionOffset(ScopeDIE, dwarf::DW_AT_ranges, + DebugRangeSymbols.size() * + Asm->getDataLayout().getPointerSize()); for (SmallVectorImpl::const_iterator RI = Ranges.begin(), RE = Ranges.end(); RI != RE; ++RI) { @@ -766,14 +773,15 @@ CompileUnit *DwarfDebug::constructCompileUnit(DICompileUnit DIUnit) { // The line table entries are not always emitted in assembly, so it // is not okay to use line_table_start here. if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addLabel(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_sec_offset, - UseTheFirstCU ? Asm->GetTempSymbol("section_line") - : LineTableStartSym); + NewCU->addSectionLabel( + Die, dwarf::DW_AT_stmt_list, + UseTheFirstCU ? Asm->GetTempSymbol("section_line") + : LineTableStartSym); else if (UseTheFirstCU) - NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0); + NewCU->addSectionOffset(Die, dwarf::DW_AT_stmt_list, 0); else - NewCU->addDelta(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, - LineTableStartSym, DwarfLineSectionSym); + NewCU->addSectionDelta(Die, dwarf::DW_AT_stmt_list, + LineTableStartSym, DwarfLineSectionSym); // If we're using split dwarf the compilation dir is going to be in the // skeleton CU and so we don't need to duplicate it here. @@ -784,22 +792,22 @@ CompileUnit *DwarfDebug::constructCompileUnit(DICompileUnit DIUnit) { // emit it here if we don't have a skeleton CU for split dwarf. if (GenerateGnuPubSections) { if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addLabel( - Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_sec_offset, + NewCU->addSectionLabel( + Die, dwarf::DW_AT_GNU_pubnames, Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID())); else - NewCU->addDelta( - Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_data4, + NewCU->addSectionDelta( + Die, dwarf::DW_AT_GNU_pubnames, Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()), DwarfGnuPubNamesSectionSym); if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addLabel( - Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_sec_offset, + NewCU->addSectionLabel( + Die, dwarf::DW_AT_GNU_pubtypes, Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID())); else - NewCU->addDelta( - Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_data4, + NewCU->addSectionDelta( + Die, dwarf::DW_AT_GNU_pubtypes, Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()), DwarfGnuPubTypesSectionSym); } @@ -2957,11 +2965,10 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const CompileUnit *CU) { // Relocate to the beginning of the addr_base section, else 0 for the // beginning of the one for this compile unit. if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addLabel(Die, dwarf::DW_AT_GNU_addr_base, dwarf::DW_FORM_sec_offset, - DwarfAddrSectionSym); + NewCU->addSectionLabel(Die, dwarf::DW_AT_GNU_addr_base, + DwarfAddrSectionSym); else - NewCU->addUInt(Die, dwarf::DW_AT_GNU_addr_base, dwarf::DW_FORM_sec_offset, - 0); + NewCU->addSectionOffset(Die, dwarf::DW_AT_GNU_addr_base, 0); // 2.17.1 requires that we use DW_AT_low_pc for a single entry point // into an entity. We're using 0, or a NULL label for this. @@ -2971,10 +2978,10 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const CompileUnit *CU) { // compile unit in debug_line section. // FIXME: Should handle multiple compile units. if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addLabel(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_sec_offset, - DwarfLineSectionSym); + NewCU->addSectionLabel(Die, dwarf::DW_AT_stmt_list, + DwarfLineSectionSym); else - NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_sec_offset, 0); + NewCU->addSectionOffset(Die, dwarf::DW_AT_stmt_list, 0); if (!CompilationDir.empty()) NewCU->addLocalString(Die, dwarf::DW_AT_comp_dir, CompilationDir); @@ -2982,27 +2989,31 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const CompileUnit *CU) { // Flags to let the linker know we have emitted new style pubnames. if (GenerateGnuPubSections) { if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addLabel(Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_sec_offset, - Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID())); + NewCU->addSectionLabel( + Die, dwarf::DW_AT_GNU_pubnames, + Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID())); else - NewCU->addDelta(Die, dwarf::DW_AT_GNU_pubnames, dwarf::DW_FORM_data4, - Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()), - DwarfGnuPubNamesSectionSym); + NewCU->addSectionDelta( + Die, dwarf::DW_AT_GNU_pubnames, + Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()), + DwarfGnuPubNamesSectionSym); if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addLabel(Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_sec_offset, - Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID())); + NewCU->addSectionLabel( + Die, dwarf::DW_AT_GNU_pubtypes, + Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID())); else - NewCU->addDelta(Die, dwarf::DW_AT_GNU_pubtypes, dwarf::DW_FORM_data4, - Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()), - DwarfGnuPubTypesSectionSym); + NewCU->addSectionDelta( + Die, dwarf::DW_AT_GNU_pubtypes, + Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()), + DwarfGnuPubTypesSectionSym); } // Flag if we've emitted any ranges and their location for the compile unit. if (DebugRangeSymbols.size()) { if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addLabel(Die, dwarf::DW_AT_GNU_ranges_base, - dwarf::DW_FORM_sec_offset, DwarfDebugRangeSectionSym); + NewCU->addSectionLabel(Die, dwarf::DW_AT_GNU_ranges_base, + DwarfDebugRangeSectionSym); else NewCU->addUInt(Die, dwarf::DW_AT_GNU_ranges_base, dwarf::DW_FORM_data4, 0); -- cgit v1.2.3