From 9c550ac4e79b20a4e78fc99ec6b57bc62cf502b0 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Tue, 25 Mar 2014 01:44:02 +0000 Subject: DebugInfo: Support debug_loc under fission Implement debug_loc.dwo, as well as llvm-dwarfdump support for dumping this section. Outlined in the DWARF5 spec and http://gcc.gnu.org/wiki/DebugFission the debug_loc.dwo section has more variation than the standard debug_loc, allowing 3 different forms of entry (plus the end of list entry). GCC seems to, and Clang certainly, only use one form, so I've just implemented dumping support for that for now. It wasn't immediately obvious that there was a good refactoring to share the implementation of dumping support between debug_loc and debug_loc.dwo, so they're separate for now - ideas welcome or I may come back to it at some point. As per a comment in the code, we could choose different forms that may reduce the number of debug_addr entries we emit, but that will require further study. llvm-svn: 204697 --- llvm/lib/CodeGen/AsmPrinter/DIE.cpp | 10 +++++---- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 34 +++++++++++++++++++++--------- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 5 ++++- 3 files changed, 34 insertions(+), 15 deletions(-) (limited to 'llvm/lib/CodeGen') diff --git a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp index eb3a622ae7f..34f070e0edb 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp @@ -559,13 +559,15 @@ unsigned DIELocList::SizeOf(AsmPrinter *AP, dwarf::Form Form) const { /// EmitValue - Emit label value. /// void DIELocList::EmitValue(AsmPrinter *AP, dwarf::Form Form) const { + DwarfDebug *DD = AP->getDwarfDebug(); MCSymbol *Label = AP->GetTempSymbol("debug_loc", Index); - MCSymbol *DwarfDebugLocSectionSym = AP->getDwarfDebug()->getDebugLocSym(); - if (AP->MAI->doesDwarfUseRelocationsAcrossSections()) - AP->EmitSectionOffset(Label, DwarfDebugLocSectionSym); + if (DD->useSplitDwarf()) + AP->EmitLabelDifference(Label, DD->getDebugLocDWOSym(), 4); + else if (AP->MAI->doesDwarfUseRelocationsAcrossSections()) + AP->EmitSectionOffset(Label, DD->getDebugLocSym()); else - AP->EmitLabelDifference(Label, DwarfDebugLocSectionSym, 4); + AP->EmitLabelDifference(Label, DD->getDebugLocSym(), 4); } #ifndef NDEBUG diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 792a9c48cdf..a9ed9dbcb5b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -184,7 +184,7 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) DwarfInfoSectionSym = DwarfAbbrevSectionSym = DwarfStrSectionSym = 0; DwarfDebugRangeSectionSym = DwarfDebugLocSectionSym = DwarfLineSectionSym = 0; - DwarfAddrSectionSym = 0; + DwarfAddrSectionSym = DwarfDebugLocDWOSectionSym = 0; DwarfAbbrevDWOSectionSym = DwarfStrDWOSectionSym = 0; FunctionBeginSym = FunctionEndSym = 0; CurFn = 0; @@ -1865,7 +1865,6 @@ void DwarfDebug::emitSectionLabels() { DwarfLineSectionSym = emitSectionSym(Asm, TLOF.getDwarfLineSection(), "section_line"); - emitSectionSym(Asm, TLOF.getDwarfLocSection()); if (GenerateGnuPubSections) { DwarfGnuPubNamesSectionSym = emitSectionSym(Asm, TLOF.getDwarfGnuPubNamesSection()); @@ -1883,12 +1882,13 @@ void DwarfDebug::emitSectionLabels() { emitSectionSym(Asm, TLOF.getDwarfStrDWOSection(), "skel_string"); DwarfAddrSectionSym = emitSectionSym(Asm, TLOF.getDwarfAddrSection(), "addr_sec"); - } + DwarfDebugLocDWOSectionSym = + emitSectionSym(Asm, TLOF.getDwarfLocDWOSection(), "skel_loc"); + } else + DwarfDebugLocSectionSym = + emitSectionSym(Asm, TLOF.getDwarfLocSection(), "section_debug_loc"); DwarfDebugRangeSectionSym = emitSectionSym(Asm, TLOF.getDwarfRangesSection(), "debug_range"); - - DwarfDebugLocSectionSym = - emitSectionSym(Asm, TLOF.getDwarfLocSection(), "section_debug_loc"); } // Recursively emits a debug information entry. @@ -2379,7 +2379,8 @@ void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer, void DwarfDebug::emitDebugLoc() { // Start the dwarf loc section. Asm->OutStreamer.SwitchSection( - Asm->getObjFileLowering().getDwarfLocSection()); + useSplitDwarf() ? Asm->getObjFileLowering().getDwarfLocDWOSection() + : Asm->getObjFileLowering().getDwarfLocSection()); unsigned char Size = Asm->getDataLayout().getPointerSize(); unsigned index = 0; for (const auto &DebugLoc : DotDebugLocEntries) { @@ -2389,7 +2390,16 @@ void DwarfDebug::emitDebugLoc() { // compile unit. This is a hard coded 0 for low_pc when we're emitting // ranges, or the DW_AT_low_pc on the compile unit otherwise. const DwarfCompileUnit *CU = Entry.getCU(); - if (CU->getRanges().size() == 1) { + if (useSplitDwarf()) { + // Just always use start_length for now - at least that's one address + // rather than two. We could get fancier and try to, say, reuse an + // address we know we've emitted elsewhere (the start of the function? + // The start of the CU or CU subrange that encloses this range?) + Asm->EmitInt8(dwarf::DW_LLE_start_length_entry); + unsigned idx = InfoHolder.getAddrPoolIndex(Entry.getBeginSym()); + Asm->EmitULEB128(idx); + Asm->EmitLabelDifference(Entry.getEndSym(), Entry.getBeginSym(), 4); + } else if (CU->getRanges().size() == 1) { // Grab the begin symbol from the first range as our base. const MCSymbol *Base = CU->getRanges()[0].getStart(); Asm->EmitLabelDifference(Entry.getBeginSym(), Base, Size); @@ -2409,8 +2419,12 @@ void DwarfDebug::emitDebugLoc() { // Close the range. Asm->OutStreamer.EmitLabel(end); } - Asm->OutStreamer.EmitIntValue(0, Size); - Asm->OutStreamer.EmitIntValue(0, Size); + if (useSplitDwarf()) + Asm->EmitInt8(dwarf::DW_LLE_end_of_list_entry); + else { + Asm->OutStreamer.EmitIntValue(0, Size); + Asm->OutStreamer.EmitIntValue(0, Size); + } ++index; } } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 064c0fa7624..0b0f0a8b7aa 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -423,7 +423,7 @@ class DwarfDebug : public AsmPrinterHandler { MCSymbol *DwarfDebugLocSectionSym, *DwarfLineSectionSym, *DwarfAddrSectionSym; MCSymbol *FunctionBeginSym, *FunctionEndSym; MCSymbol *DwarfInfoDWOSectionSym, *DwarfAbbrevDWOSectionSym; - MCSymbol *DwarfStrDWOSectionSym; + MCSymbol *DwarfStrDWOSectionSym, *DwarfDebugLocDWOSectionSym; MCSymbol *DwarfGnuPubNamesSectionSym, *DwarfGnuPubTypesSectionSym; // As an optimization, there is no need to emit an entry in the directory @@ -756,6 +756,9 @@ public: /// Returns the section symbol for the .debug_loc section. MCSymbol *getDebugLocSym() const { return DwarfDebugLocSectionSym; } + /// Returns the section symbol for the .debug_loc section. + MCSymbol *getDebugLocDWOSym() const { return DwarfDebugLocDWOSectionSym; } + /// Returns the previous section that was emitted into. const MCSection *getPrevSection() const { return PrevSection; } -- cgit v1.2.3