DebugInfo: Emit relocation to debug_line section when emitting asm for asm
authorDavid Blaikie <dblaikie@gmail.com>
Tue, 1 Apr 2014 07:35:52 +0000 (07:35 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Tue, 1 Apr 2014 07:35:52 +0000 (07:35 +0000)
I don't think this is reachable by any frontend (why would you transform
asm to asm+debug info?) but it helps tidy up some of this code, avoid
the weird special case of "emit the first CU, store the label, then emit
the rest" in MCDwarfLineTable::Emit by instead having the
DWARF-for-assembly case use the same codepath as DwarfDebug.cpp, by
registering the label of the debug_line section, thus causing it to be
emitted. (with a special case in asm output to just emit the label since
asm output uses the .loc directives, etc, rather than the debug_loc
directly)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205286 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCDwarf.h
lib/MC/MCAsmStreamer.cpp
lib/MC/MCDwarf.cpp
lib/MC/MCObjectStreamer.cpp
lib/MC/MCParser/AsmParser.cpp
test/MC/ELF/gen-dwarf.s

index 731ffb14fb3a0543e2147f1c479d8f07210ef1a0..6e77c6ca07201618c93716a47f733f38bc1f90e4 100644 (file)
@@ -210,10 +210,10 @@ class MCDwarfLineTable {
 
 public:
   // This emits the Dwarf file and the line tables for all Compile Units.
-  static const MCSymbol *Emit(MCStreamer *MCOS);
+  static void Emit(MCStreamer *MCOS);
 
   // This emits the Dwarf file and the line tables for a given Compile Unit.
-  const MCSymbol *EmitCU(MCStreamer *MCOS) const;
+  void EmitCU(MCStreamer *MCOS) const;
 
   unsigned getFile(StringRef &Directory, StringRef &FileName,
                    unsigned FileNumber = 0);
@@ -270,7 +270,7 @@ public:
   // When generating dwarf for assembly source files this emits the Dwarf
   // sections.
   //
-  static void Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol);
+  static void Emit(MCStreamer *MCOS);
 };
 
 // When generating dwarf for assembly source files this is the info that is
index cc30d056a215c3a2c3e004891eef427095aea20b..fa54c1a8da1964c20d81a70f5939f445b595d797 100644 (file)
@@ -1435,7 +1435,20 @@ void MCAsmStreamer::EmitRawTextImpl(StringRef String) {
 void MCAsmStreamer::FinishImpl() {
   // If we are generating dwarf for assembly source files dump out the sections.
   if (getContext().getGenDwarfForAssembly())
-    MCGenDwarfInfo::Emit(this, NULL);
+    MCGenDwarfInfo::Emit(this);
+
+  // Emit the label for the line table, if requested - since the rest of the
+  // line table will be defined by .loc/.file directives, and not emitted
+  // directly, the label is the only work required here.
+  auto &Tables = getContext().getMCDwarfLineTables();
+  if (!Tables.empty()) {
+    // FIXME: assert Tables.size() == 1 here, except that's not currently true
+    // due to DwarfUnit.cpp:2074.
+    if (auto *Label = Tables.begin()->second.getLabel()) {
+      SwitchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
+      EmitLabel(Label);
+    }
+  }
 
   if (!UseCFI)
     EmitFrames(AsmBackend.get(), false);
index 5fa8f66422b9ba5e5f9968aab2352a8da8e65402..231948eaff5626b62886a2e5902b40e57bb89d80 100644 (file)
@@ -204,24 +204,22 @@ EmitDwarfLineTable(MCStreamer *MCOS, const MCSection *Section,
 //
 // This emits the Dwarf file and the line tables.
 //
-const MCSymbol *MCDwarfLineTable::Emit(MCStreamer *MCOS) {
+void MCDwarfLineTable::Emit(MCStreamer *MCOS) {
   MCContext &context = MCOS->getContext();
 
-  // CUID and MCLineTableSymbols are set in DwarfDebug, when DwarfDebug does
-  // not exist, CUID will be 0 and MCLineTableSymbols will be empty.
-  // Handle Compile Unit 0, the line table start symbol is the section symbol.
-  auto I = MCOS->getContext().getMCDwarfLineTables().begin(),
-       E = MCOS->getContext().getMCDwarfLineTables().end();
+  auto &LineTables = context.getMCDwarfLineTables();
+
+  // Bail out early so we don't switch to the debug_line section needlessly and
+  // in doing so create an unnecessary (if empty) section.
+  if (LineTables.empty())
+    return;
 
   // Switch to the section where the table will be emitted into.
   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
 
-  const MCSymbol *LineStartSym = I->second.EmitCU(MCOS);
   // Handle the rest of the Compile Units.
-  for (++I; I != E; ++I)
-    I->second.EmitCU(MCOS);
-
-  return LineStartSym;
+  for (const auto &CUIDTablePair : LineTables)
+    CUIDTablePair.second.EmitCU(MCOS);
 }
 
 void MCDwarfDwoLineTable::Emit(MCStreamer &MCOS) const {
@@ -320,10 +318,8 @@ MCDwarfLineTableHeader::Emit(MCStreamer *MCOS,
   return std::make_pair(LineStartSym, LineEndSym);
 }
 
-const MCSymbol *MCDwarfLineTable::EmitCU(MCStreamer *MCOS) const {
-  MCSymbol *LineStartSym;
-  MCSymbol *LineEndSym;
-  std::tie(LineStartSym, LineEndSym) = Header.Emit(MCOS);
+void MCDwarfLineTable::EmitCU(MCStreamer *MCOS) const {
+  MCSymbol *LineEndSym = Header.Emit(MCOS).second;
 
   // Put out the line tables.
   for (const auto &LineSec : MCLineSections.getMCLineEntries())
@@ -344,8 +340,6 @@ const MCSymbol *MCDwarfLineTable::EmitCU(MCStreamer *MCOS) const {
   // This is the end of the section, so set the value of the symbol at the end
   // of this section (that was used in a previous expression).
   MCOS->EmitLabel(LineEndSym);
-
-  return LineStartSym;
 }
 
 unsigned MCDwarfLineTable::getFile(StringRef &Directory, StringRef &FileName,
@@ -787,14 +781,17 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
 // When generating dwarf for assembly source files this emits the Dwarf
 // sections.
 //
-void MCGenDwarfInfo::Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol) {
+void MCGenDwarfInfo::Emit(MCStreamer *MCOS) {
   // Create the dwarf sections in this order (.debug_line already created).
   MCContext &context = MCOS->getContext();
   const MCAsmInfo *AsmInfo = context.getAsmInfo();
   bool CreateDwarfSectionSymbols =
       AsmInfo->doesDwarfUseRelocationsAcrossSections();
-  if (!CreateDwarfSectionSymbols)
-    LineSectionSymbol = NULL;
+  MCSymbol *LineSectionSymbol = nullptr;
+  if (CreateDwarfSectionSymbols) {
+    LineSectionSymbol = context.CreateTempSymbol();
+    context.setMCLineTableSymbol(LineSectionSymbol, 0);
+  }
   MCSymbol *AbbrevSectionSymbol = NULL;
   MCSymbol *InfoSectionSymbol = NULL;
   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
index 35786accb429bcdd36fd0b8a903de88b373dd938..4451264cff6815ed5f8fc0049013decc81175b20 100644 (file)
@@ -383,14 +383,12 @@ void MCObjectStreamer::EmitZeros(uint64_t NumBytes) {
 }
 
 void MCObjectStreamer::FinishImpl() {
-  // Dump out the dwarf file & directory tables and line tables.
-  const MCSymbol *LineSectionSymbol = NULL;
-  if (getContext().hasMCLineSections())
-    LineSectionSymbol = MCDwarfLineTable::Emit(this);
-
   // If we are generating dwarf for assembly source files dump out the sections.
   if (getContext().getGenDwarfForAssembly())
-    MCGenDwarfInfo::Emit(this, LineSectionSymbol);
+    MCGenDwarfInfo::Emit(this);
+
+  // Dump out the dwarf file & directory tables and line tables.
+  MCDwarfLineTable::Emit(this);
 
   getAssembler().Finish();
 }
index ac6ebbde7b2a5c671d15c3ce1612dcb4750422c3..910a424ce847c7f5d4381859a775181350e0c991 100644 (file)
@@ -661,11 +661,15 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
     return TokError("unmatched .ifs or .elses");
 
   // Check to see there are no empty DwarfFile slots.
-  const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles =
-      getContext().getMCDwarfFiles();
-  for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
-    if (MCDwarfFiles[i].Name.empty())
-      TokError("unassigned file number: " + Twine(i) + " for .file directives");
+  const auto &LineTables = getContext().getMCDwarfLineTables();
+  if (!LineTables.empty()) {
+    unsigned Index = 0;
+    for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
+      if (File.Name.empty() && Index != 0)
+        TokError("unassigned file number: " + Twine(Index) +
+                 " for .file directives");
+      ++Index;
+    }
   }
 
   // Check to see that all assembler local symbols were actually defined.
index a702bc8610c80be55b9e08f4597a7b0f59fbd740..e83b14c4e388917a03cb277ec927f5be81757f7c 100644 (file)
@@ -1,4 +1,5 @@
 // RUN: llvm-mc -g -triple  i686-pc-linux-gnu %s -filetype=obj -o - | llvm-readobj -r | FileCheck %s
+// RUN: llvm-mc -g -triple  i686-pc-linux-gnu %s -filetype=asm -o - | FileCheck --check-prefix=ASM %s
 
 
 // Test that on ELF:
@@ -23,4 +24,23 @@ foo:
 // CHECK-NEXT:     0x6 R_386_32 .debug_info 0x0
 // CHECK-NEXT:     0x10 R_386_32 .text 0x0
 // CHECK-NEXT:   }
-// CHECK-NEXT: ]
+// CHECK:      ]
+
+// First instance of the section is just to give it a label for debug_aranges to refer to
+// ASM: .section .debug_info
+
+// ASM: .section .debug_abbrev
+// ASM-NEXT: [[ABBREV_LABEL:.Ltmp[0-9]+]]
+
+// Second instance of the section has the CU
+// ASM: .section .debug_info
+// Dwarf version
+// ASM: .short 2
+// ASM-NEXT: .long [[ABBREV_LABEL]]
+// First .byte 1 is the abbreviation number for the compile_unit abbrev
+// ASM: .byte 1
+// ASM-NEXT: .long [[LINE_LABEL:.Ltmp[0-9]+]]
+
+// ASM: .section .debug_line
+// ASM-NEXT: [[LINE_LABEL]]
+