diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 110 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.h | 17 |
2 files changed, 119 insertions, 8 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 10061e1907..c4c9d3f2b3 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -153,7 +153,7 @@ DIType DbgVariable::getType() const { } // end llvm namespace DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) - : Asm(A), MMI(Asm->MMI), FirstCU(0), + : Asm(A), MMI(Asm->MMI), FirstCU(0), FissionCU(0), AbbreviationsSet(InitAbbreviationsSetSize), SourceIdMap(DIEValueAllocator), StringPool(DIEValueAllocator), PrevLabel(NULL) { @@ -650,6 +650,9 @@ CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) { if (!FirstCU) FirstCU = NewCU; + if (useDwarfFission() && !FissionCU) + FissionCU = constructFissionCU(N); + CUMap.insert(std::make_pair(N, NewCU)); return NewCU; } @@ -927,8 +930,9 @@ void DwarfDebug::endModule() { // TODO: Fill this in for Fission sections and separate // out information into new sections. - // Emit all the DIEs into a debug info section. + // Emit the debug info section and compile units. emitDebugInfo(); + emitDebugInfoDWO(); // Corresponding abbreviations into a abbrev section. emitAbbreviations(); @@ -975,7 +979,9 @@ void DwarfDebug::endModule() { for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(), E = CUMap.end(); I != E; ++I) delete I->second; - FirstCU = NULL; // Reset for the next Module, if any. + // Reset these for the next Module if we have one. + FirstCU = NULL; + FissionCU = NULL; } // Find abstract variable, if any, associated with Var. @@ -1665,6 +1671,15 @@ DwarfDebug::computeSizeAndOffset(DIE *Die, unsigned Offset) { // Compute the size and offset of all the DIEs. void DwarfDebug::computeSizeAndOffsets() { + if (FissionCU) { + unsigned Offset = + sizeof(int32_t) + // Length of Compilation Unit Info + sizeof(int16_t) + // DWARF version number + sizeof(int32_t) + // Offset Into Abbrev. Section + sizeof(int8_t); // Pointer Size (in bytes) + + computeSizeAndOffset(FissionCU->getCUDie(), Offset); + } for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(), E = CUMap.end(); I != E; ++I) { // Compute size of compile unit header. @@ -1795,11 +1810,8 @@ void DwarfDebug::emitDIE(DIE *Die) { } } -// Emit the debug info section. -void DwarfDebug::emitDebugInfo() { - // Start debug info section. - Asm->OutStreamer.SwitchSection( - Asm->getObjFileLowering().getDwarfInfoSection()); +void DwarfDebug::emitCompileUnits(const MCSection *Section) { + Asm->OutStreamer.SwitchSection(Section); for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(), E = CUMap.end(); I != E; ++I) { CompileUnit *TheCU = I->second; @@ -1830,6 +1842,14 @@ void DwarfDebug::emitDebugInfo() { } } +// Emit the debug info section. +void DwarfDebug::emitDebugInfo() { + if (!useDwarfFission()) + emitCompileUnits(Asm->getObjFileLowering().getDwarfInfoSection()); + else + emitFissionSkeletonCU(Asm->getObjFileLowering().getDwarfInfoSection()); +} + // Emit the abbreviation section. void DwarfDebug::emitAbbreviations() { // Check to see if it is worth the effort. @@ -2286,3 +2306,77 @@ void DwarfDebug::emitDebugInlineInfo() { Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_end", 1)); } + +// DWARF5 Experimental Fission emitters. + +// This DIE has the following attributes: DW_AT_comp_dir, DW_AT_stmt_list, +// DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, DW_AT_dwo_name, DW_AT_dwo_id, +// DW_AT_ranges_base, DW_AT_addr_base. If DW_AT_ranges is present, +// DW_AT_low_pc and DW_AT_high_pc are not used, and vice versa. +CompileUnit *DwarfDebug::constructFissionCU(const MDNode *N) { + DICompileUnit DIUnit(N); + StringRef FN = DIUnit.getFilename(); + CompilationDir = DIUnit.getDirectory(); + unsigned ID = getOrCreateSourceID(FN, CompilationDir); + + DIE *Die = new DIE(dwarf::DW_TAG_compile_unit); + CompileUnit *NewCU = new CompileUnit(ID, DIUnit.getLanguage(), Die, + Asm, this); + // FIXME: This should be the .dwo file. + NewCU->addString(Die, dwarf::DW_AT_GNU_dwo_name, FN); + + // 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. + 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()) + NewCU->addLabel(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, + Asm->GetTempSymbol("section_line")); + else + NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0); + + if (!CompilationDir.empty()) + NewCU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir); + + return NewCU; +} + +void DwarfDebug::emitFissionSkeletonCU(const MCSection *Section) { + Asm->OutStreamer.SwitchSection(Section); + DIE *Die = FissionCU->getCUDie(); + + // Emit the compile units header. + Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("skel_info_begin", + FissionCU->getID())); + + // Emit size of content not including length itself + unsigned ContentSize = Die->getSize() + + sizeof(int16_t) + // DWARF version number + sizeof(int32_t) + // Offset Into Abbrev. Section + sizeof(int8_t); // Pointer Size (in bytes) + + Asm->OutStreamer.AddComment("Length of Compilation Unit Info"); + Asm->EmitInt32(ContentSize); + Asm->OutStreamer.AddComment("DWARF version number"); + Asm->EmitInt16(dwarf::DWARF_VERSION); + Asm->OutStreamer.AddComment("Offset Into Abbrev. Section"); + Asm->EmitSectionOffset(Asm->GetTempSymbol("abbrev_begin"), + DwarfAbbrevSectionSym); + Asm->OutStreamer.AddComment("Address Size (in bytes)"); + Asm->EmitInt8(Asm->getDataLayout().getPointerSize()); + + emitDIE(Die); + Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("skel_info_end", FissionCU->getID())); + + +} + +// Emit the .debug_info.dwo section for fission. This contains the compile +// units that would normally be in debug_info. +void DwarfDebug::emitDebugInfoDWO() { + assert(useDwarfFission() && "Got fission?"); + emitCompileUnits(Asm->getObjFileLowering().getDwarfInfoDWOSection()); +} diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index b6b28fa7e9..35bddee41b 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -205,6 +205,9 @@ class DwarfDebug { CompileUnit *FirstCU; + // The CU left in the original object file for Fission debug info. + CompileUnit *FissionCU; + // Maps MDNode with its corresponding CompileUnit. DenseMap <const MDNode *, CompileUnit *> CUMap; @@ -369,6 +372,9 @@ private: /// open. void endSections(); + /// \brief Emit all of the compile units to the target section. + void emitCompileUnits(const MCSection *); + /// \brief Emit the debug info section. void emitDebugInfo(); @@ -413,6 +419,17 @@ private: /// \brief Emit inline info using custom format. void emitDebugInlineInfo(); + /// DWARF 5 Experimental Fission Emitters + + /// \brief Construct the fission compile unit for the debug info section. + CompileUnit *constructFissionCU(const MDNode *); + + /// \brief Emit the fission debug info section. + void emitFissionSkeletonCU(const MCSection *); + + /// \brief Emit the debug info dwo section. + void emitDebugInfoDWO(); + /// \brief Create new CompileUnit for the given metadata node with tag /// DW_TAG_compile_unit. CompileUnit *constructCompileUnit(const MDNode *N); |