[llvm] r191052 - Added support for generate DWARF .debug_aranges sections automatically.

Richard Mitton richard at codersnotes.com
Thu Sep 19 16:21:02 PDT 2013


Author: rmitton
Date: Thu Sep 19 18:21:01 2013
New Revision: 191052

URL: http://llvm.org/viewvc/llvm-project?rev=191052&view=rev
Log:
Added support for generate DWARF .debug_aranges sections automatically.

Added:
    llvm/trunk/test/DebugInfo/dwarf-aranges.ll
    llvm/trunk/test/DebugInfo/multiple-aranges.ll
Modified:
    llvm/trunk/include/llvm/MC/MCELFStreamer.h
    llvm/trunk/include/llvm/MC/MCStreamer.h
    llvm/trunk/include/llvm/Support/Dwarf.h
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
    llvm/trunk/lib/MC/MCAsmStreamer.cpp
    llvm/trunk/lib/MC/MCELFStreamer.cpp
    llvm/trunk/lib/MC/MCMachOStreamer.cpp
    llvm/trunk/lib/MC/MCNullStreamer.cpp
    llvm/trunk/lib/MC/MCPureStreamer.cpp
    llvm/trunk/lib/MC/MCStreamer.cpp
    llvm/trunk/lib/MC/WinCOFFStreamer.cpp
    llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
    llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp

Modified: llvm/trunk/include/llvm/MC/MCELFStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCELFStreamer.h?rev=191052&r1=191051&r2=191052&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCELFStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCELFStreamer.h Thu Sep 19 18:21:01 2013
@@ -85,6 +85,8 @@ public:
 
   virtual void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned);
 
+  virtual void Flush();
+
   virtual void FinishImpl();
   /// @}
 

Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=191052&r1=191051&r2=191052&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Thu Sep 19 18:21:01 2013
@@ -86,6 +86,10 @@ private:
 
   MCSymbol *LastSymbol;
 
+  // SymbolOrdering - Tracks an index to represent the order
+  // a symbol was emitted in. Zero means we did not emit that symbol.
+  DenseMap<const MCSymbol *, unsigned> SymbolOrdering;
+
   /// SectionStack - This is stack of current and previous section
   /// values saved by PushSection.
   SmallVector<std::pair<MCSectionSubPair, MCSectionSubPair>, 4> SectionStack;
@@ -185,6 +189,12 @@ public:
     return MCSectionSubPair();
   }
 
+  /// GetSymbolOrder - Returns an index to represent the order
+  /// a symbol was emitted in. (zero if we did not emit that symbol)
+  unsigned GetSymbolOrder(const MCSymbol *Sym) const {
+    return SymbolOrdering.lookup(Sym);
+  }
+
   /// ChangeSection - Update streamer for a new active section.
   ///
   /// This is called by PopSection and SwitchSection, if the current
@@ -264,6 +274,12 @@ public:
   /// InitToTextSection - Create a text section and switch the streamer to it.
   virtual void InitToTextSection() = 0;
 
+  /// AssignSection - Sets the symbol's section.
+  ///
+  /// Each emitted symbol will be tracked in the ordering table,
+  /// so we can sort on them later.
+  void AssignSection(MCSymbol *Symbol, const MCSection *Section);
+
   /// EmitLabel - Emit a label for @p Symbol into the current section.
   ///
   /// This corresponds to an assembler statement such as:
@@ -620,6 +636,9 @@ public:
   /// these methods there.
   virtual void EmitTCEntry(const MCSymbol &S);
 
+  /// Flush - Causes any cached state to be written out.
+  virtual void Flush() {}
+
   /// FinishImpl - Streamer specific finalization.
   virtual void FinishImpl() = 0;
   /// Finish - Finish emission of machine code.

Modified: llvm/trunk/include/llvm/Support/Dwarf.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Dwarf.h?rev=191052&r1=191051&r2=191052&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/Dwarf.h (original)
+++ llvm/trunk/include/llvm/Support/Dwarf.h Thu Sep 19 18:21:01 2013
@@ -59,7 +59,8 @@ enum LLVMConstants {
   DWARF_VERSION = 4,       // Default dwarf version we output.
   DW_CIE_VERSION = 1,      // Common frame information version.
   DW_PUBTYPES_VERSION = 2, // Section version number for .debug_pubtypes.
-  DW_PUBNAMES_VERSION = 2  // Section version number for .debug_pubnames.
+  DW_PUBNAMES_VERSION = 2, // Section version number for .debug_pubnames.
+  DW_ARANGES_VERSION = 2   // Section version number for .debug_aranges.
 };
 
 // Special ID values that distinguish a CIE from a FDE in DWARF CFI.

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=191052&r1=191051&r2=191052&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Thu Sep 19 18:21:01 2013
@@ -881,6 +881,9 @@ bool AsmPrinter::doFinalization(Module &
   if (!ModuleFlags.empty())
     getObjFileLowering().emitModuleFlags(OutStreamer, ModuleFlags, Mang, TM);
 
+  // Make sure we wrote out everything we need.
+  OutStreamer.Flush();
+
   // Finalize debug and EH information.
   if (DE) {
     {

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp?rev=191052&r1=191051&r2=191052&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Thu Sep 19 18:21:01 2013
@@ -181,6 +181,12 @@ void CompileUnit::addLabel(DIE *Die, uin
                            const MCSymbol *Label) {
   DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
   Die->addValue(Attribute, Form, Value);
+
+  SymbolCU Entry;
+  Entry.CU = this;
+  Entry.Sym = Label;
+
+  DD->addLabel(Entry);
 }
 
 /// addLabelAddress - Add a dwarf label attribute data and value using
@@ -188,6 +194,14 @@ void CompileUnit::addLabel(DIE *Die, uin
 ///
 void CompileUnit::addLabelAddress(DIE *Die, uint16_t Attribute,
                                   MCSymbol *Label) {
+  if (Label) {
+    SymbolCU Entry;
+    Entry.CU = this;
+    Entry.Sym = Label;
+
+    DD->addLabel(Entry);
+  }
+
   if (!DD->useSplitDwarf()) {
     if (Label != NULL) {
       DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=191052&r1=191051&r2=191052&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Thu Sep 19 18:21:01 2013
@@ -924,7 +924,7 @@ void DwarfDebug::beginModule() {
   MMI->setDebugInfoAvailability(true);
 
   // Prime section data.
-  SectionMap.insert(Asm->getObjFileLowering().getTextSection());
+  SectionMap[Asm->getObjFileLowering().getTextSection()];
 }
 
 // Attach DW_AT_inline attribute with inlined subprogram DIEs.
@@ -1077,16 +1077,39 @@ void DwarfDebug::finalizeModuleInfo() {
 }
 
 void DwarfDebug::endSections() {
-  // Standard sections final addresses.
-  Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getTextSection());
-  Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("text_end"));
-  Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getDataSection());
-  Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("data_end"));
-
-  // End text sections.
-  for (unsigned I = 0, E = SectionMap.size(); I != E; ++I) {
-    Asm->OutStreamer.SwitchSection(SectionMap[I]);
-    Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_end", I+1));
+   // Filter labels by section.
+  for (size_t n = 0; n < Labels.size(); n++) {
+    const SymbolCU &SCU = Labels[n];
+    if (SCU.Sym->isInSection()) {
+      // Make a note of this symbol and it's section.
+      const MCSection *Section = &SCU.Sym->getSection();
+      if (!Section->getKind().isMetadata())
+        SectionMap[Section].push_back(SCU);
+    } else {
+      // Some symbols (e.g. common/bss on mach-o) can have no section but still
+      // appear in the output. This sucks as we rely on sections to build
+      // arange spans. We can do it without, but it's icky.
+      SectionMap[NULL].push_back(SCU);
+    }
+  }
+
+  // Add terminating symbols for each section.
+  for (SectionMapType::iterator it = SectionMap.begin(); it != SectionMap.end();
+       it++) {
+    const MCSection *Section = it->first;
+    MCSymbol *Sym = NULL;
+
+    if (Section) {
+      Sym = Asm->GetTempSymbol(Section->getLabelEndName());
+      Asm->OutStreamer.SwitchSection(Section);
+      Asm->OutStreamer.EmitLabel(Sym);
+    }
+
+    // Insert a final terminator.
+    SymbolCU Entry;
+    Entry.CU = NULL;
+    Entry.Sym = Sym;
+    SectionMap[Section].push_back(Entry);
   }
 }
 
@@ -2659,11 +2682,172 @@ void DwarfDebug::emitDebugLoc() {
   }
 }
 
-// Emit visible names into a debug aranges section.
+struct SymbolCUSorter {
+  SymbolCUSorter(const MCStreamer &s) : Streamer(s) {}
+  const MCStreamer &Streamer;
+
+  bool operator() (const SymbolCU &A, const SymbolCU &B) {
+    unsigned IA = A.Sym ? Streamer.GetSymbolOrder(A.Sym) : 0;
+    unsigned IB = B.Sym ? Streamer.GetSymbolOrder(B.Sym) : 0;
+
+    // Symbols with no order assigned should be placed at the end.
+    // (e.g. section end labels)
+    if (IA == 0)
+      IA = (unsigned)(-1);
+    if (IB == 0)
+      IB = (unsigned)(-1);
+    return IA < IB;
+  }
+};
+
+static bool SectionSort(const MCSection *A, const MCSection *B) {
+    std::string LA = (A ? A->getLabelBeginName() : "");
+    std::string LB = (B ? B->getLabelBeginName() : "");
+    return LA < LB;
+}
+
+static bool CUSort(const CompileUnit *A, const CompileUnit *B) {
+    return (A->getUniqueID() < B->getUniqueID());
+}
+
+struct ArangeSpan {
+  const MCSymbol *Start, *End;
+};
+
+// Emit a debug aranges section, containing a CU lookup for any
+// address we can tie back to a CU.
 void DwarfDebug::emitDebugARanges() {
   // Start the dwarf aranges section.
   Asm->OutStreamer
       .SwitchSection(Asm->getObjFileLowering().getDwarfARangesSection());
+
+  typedef DenseMap<CompileUnit *, std::vector<ArangeSpan> > SpansType;
+
+  SpansType Spans;
+
+  // Build a list of sections used.
+  std::vector<const MCSection *> Sections;
+  for (SectionMapType::iterator it = SectionMap.begin(); it != SectionMap.end();
+       it++) {
+    const MCSection *Section = it->first;
+    Sections.push_back(Section);
+  }
+
+  // Sort the sections into order.
+  // This is only done to ensure consistent output order across different runs.
+  std::sort(Sections.begin(), Sections.end(), SectionSort);
+
+  // Build a set of address spans, sorted by CU.
+  for (size_t SecIdx=0;SecIdx<Sections.size();SecIdx++) {
+    const MCSection *Section = Sections[SecIdx];
+    SmallVector<SymbolCU, 8> &List = SectionMap[Section];
+    if (List.size() < 2)
+      continue;
+
+    // Sort the symbols by offset within the section.
+    SymbolCUSorter sorter(Asm->OutStreamer);
+    std::sort(List.begin(), List.end(), sorter);
+
+    // If we have no section (e.g. common), just write out
+    // individual spans for each symbol.
+    if (Section == NULL) {
+      for (size_t n = 0; n < List.size(); n++) {
+        const SymbolCU &Cur = List[n];
+
+        ArangeSpan Span;
+        Span.Start = Cur.Sym;
+        Span.End = NULL;
+        if (Cur.CU)
+          Spans[Cur.CU].push_back(Span);
+      }
+    } else {
+      // Build spans between each label.
+      const MCSymbol *StartSym = List[0].Sym;
+      for (size_t n = 1; n < List.size(); n++) {
+        const SymbolCU &Prev = List[n - 1];
+        const SymbolCU &Cur = List[n];
+
+        // Try and build the longest span we can within the same CU.
+        if (Cur.CU != Prev.CU) {
+          ArangeSpan Span;
+          Span.Start = StartSym;
+          Span.End = Cur.Sym;
+          Spans[Prev.CU].push_back(Span);
+          StartSym = Cur.Sym;
+        }
+      }
+    }
+  }
+
+  const MCSection *ISec = Asm->getObjFileLowering().getDwarfInfoSection();
+  unsigned PtrSize = Asm->getDataLayout().getPointerSize();
+
+  // Build a list of CUs used.
+  std::vector<CompileUnit *> CUs;
+  for (SpansType::iterator it = Spans.begin(); it != Spans.end(); it++) {
+    CompileUnit *CU = it->first;
+    CUs.push_back(CU);
+  }
+
+  // Sort the CU list (again, to ensure consistent output order).
+  std::sort(CUs.begin(), CUs.end(), CUSort);
+
+  // Emit an arange table for each CU we used.
+  for (size_t CUIdx=0;CUIdx<CUs.size();CUIdx++) {
+    CompileUnit *CU = CUs[CUIdx];
+    std::vector<ArangeSpan> &List = Spans[CU];
+
+    // Emit size of content not including length itself.
+    unsigned ContentSize
+        = sizeof(int16_t) // DWARF ARange version number
+        + sizeof(int32_t) // Offset of CU in the .debug_info section
+        + sizeof(int8_t)  // Pointer Size (in bytes)
+        + sizeof(int8_t); // Segment Size (in bytes)
+
+    unsigned TupleSize = PtrSize * 2;
+
+    // 7.20 in the Dwarf specs requires the table to be aligned to a tuple.
+    unsigned Padding = 0;
+    while (((sizeof(int32_t) + ContentSize + Padding) % TupleSize) != 0)
+      Padding++;
+
+    ContentSize += Padding;
+    ContentSize += (List.size() + 1) * TupleSize;
+
+    // For each compile unit, write the list of spans it covers.
+    Asm->OutStreamer.AddComment("Length of ARange Set");
+    Asm->EmitInt32(ContentSize);
+    Asm->OutStreamer.AddComment("DWARF Arange version number");
+    Asm->EmitInt16(dwarf::DW_ARANGES_VERSION);
+    Asm->OutStreamer.AddComment("Offset Into Debug Info Section");
+    Asm->EmitSectionOffset(
+        Asm->GetTempSymbol(ISec->getLabelBeginName(), CU->getUniqueID()),
+        DwarfInfoSectionSym);
+    Asm->OutStreamer.AddComment("Address Size (in bytes)");
+    Asm->EmitInt8(PtrSize);
+    Asm->OutStreamer.AddComment("Segment Size (in bytes)");
+    Asm->EmitInt8(0);
+
+    for (unsigned n = 0; n < Padding; n++)
+      Asm->EmitInt8(0xff);
+
+    for (unsigned n = 0; n < List.size(); n++) {
+      const ArangeSpan &Span = List[n];
+      Asm->EmitLabelReference(Span.Start, PtrSize);
+
+      // Calculate the size as being from the span start to it's end.
+      // If we have no valid end symbol, then we just cover the first byte.
+      // (this sucks, but I can't seem to figure out how to get the size)
+      if (Span.End)
+        Asm->EmitLabelDifference(Span.End, Span.Start, PtrSize);
+      else
+        Asm->OutStreamer.EmitIntValue(1, PtrSize);
+    }
+
+    Asm->OutStreamer.AddComment("ARange terminator");
+    Asm->OutStreamer.EmitIntValue(0, PtrSize);
+    Asm->OutStreamer.EmitIntValue(0, PtrSize);
+  }
 }
 
 // Emit visible names into a debug ranges section.

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=191052&r1=191051&r2=191052&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Thu Sep 19 18:21:01 2013
@@ -300,6 +300,12 @@ public:
   unsigned getCUOffset(DIE *Die);
 };
 
+/// \brief Helper used to pair up a symbol and it's DWARF compile unit.
+struct SymbolCU {
+  const MCSymbol *Sym;
+  CompileUnit *CU;
+};
+
 /// \brief Collects and handles dwarf debug information.
 class DwarfDebug {
   // Target of Dwarf emission.
@@ -332,8 +338,12 @@ class DwarfDebug {
   // separated by a zero byte, mapped to a unique id.
   StringMap<unsigned, BumpPtrAllocator&> SourceIdMap;
 
+  // List of all labels used in the output.
+  std::vector<SymbolCU> Labels;
+
   // Provides a unique id per text section.
-  SetVector<const MCSection*> SectionMap;
+  typedef DenseMap<const MCSection *, SmallVector<SymbolCU, 8> > SectionMapType;
+  SectionMapType SectionMap;
 
   // List of arguments for current function.
   SmallVector<DbgVariable *, 8> CurrentFnArguments;
@@ -669,6 +679,9 @@ public:
   /// type units.
   void addTypeUnitType(DIE *Die) { TypeUnits.push_back(Die); }
 
+  /// \brief Add a label so that arange data can be generated for it.
+  void addLabel(SymbolCU SCU) { Labels.push_back(SCU); }
+
   /// \brief Look up the source id with the given directory and source file
   /// names. If none currently exists, create a new id and insert it in the
   /// SourceIds map.

Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=191052&r1=191051&r2=191052&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Thu Sep 19 18:21:01 2013
@@ -533,6 +533,9 @@ void MCAsmStreamer::EmitELFSize(MCSymbol
 
 void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
                                      unsigned ByteAlignment) {
+  const MCSection *Section = getContext().getObjectFileInfo()->getBSSSection();
+  AssignSection(Symbol, Section);
+
   OS << "\t.comm\t" << *Symbol << ',' << Size;
   if (ByteAlignment != 0) {
     if (MAI->getCOMMDirectiveAlignmentIsInBytes())
@@ -549,6 +552,9 @@ void MCAsmStreamer::EmitCommonSymbol(MCS
 /// @param Size - The size of the common symbol.
 void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
                                           unsigned ByteAlign) {
+  const MCSection *Section = getContext().getObjectFileInfo()->getBSSSection();
+  AssignSection(Symbol, Section);
+
   OS << "\t.lcomm\t" << *Symbol << ',' << Size;
   if (ByteAlign > 1) {
     switch (MAI->getLCOMMDirectiveAlignmentType()) {
@@ -568,6 +574,9 @@ void MCAsmStreamer::EmitLocalCommonSymbo
 
 void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
                                  uint64_t Size, unsigned ByteAlignment) {
+  if (Symbol)
+    AssignSection(Symbol, Section);
+
   // Note: a .zerofill directive does not switch sections.
   OS << ".zerofill ";
 
@@ -588,6 +597,8 @@ void MCAsmStreamer::EmitZerofill(const M
 // e.g. _a.
 void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
                                    uint64_t Size, unsigned ByteAlignment) {
+  AssignSection(Symbol, Section);
+
   assert(Symbol != NULL && "Symbol shouldn't be NULL!");
   // Instead of using the Section we'll just use the shortcut.
   // This is a mach-o specific directive and section.

Modified: llvm/trunk/lib/MC/MCELFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELFStreamer.cpp?rev=191052&r1=191051&r2=191052&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCELFStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCELFStreamer.cpp Thu Sep 19 18:21:01 2013
@@ -272,7 +272,8 @@ void MCELFStreamer::EmitCommonSymbol(MCS
                                                          ELF::SHF_WRITE |
                                                          ELF::SHF_ALLOC,
                                                          SectionKind::getBSS());
-    Symbol->setSection(*Section);
+
+    AssignSection(Symbol, Section);
 
     struct LocalCommon L = {&SD, Size, ByteAlignment};
     LocalCommons.push_back(L);
@@ -527,9 +528,7 @@ void MCELFStreamer::EmitBundleUnlock() {
   SD->setBundleLockState(MCSectionData::NotBundleLocked);
 }
 
-void MCELFStreamer::FinishImpl() {
-  EmitFrames(NULL, true);
-
+void MCELFStreamer::Flush() {
   for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(),
                                                 e = LocalCommons.end();
        i != e; ++i) {
@@ -550,8 +549,17 @@ void MCELFStreamer::FinishImpl() {
       SectData.setAlignment(ByteAlignment);
   }
 
+  LocalCommons.clear();
+}
+
+void MCELFStreamer::FinishImpl() {
+  EmitFrames(NULL, true);
+
+  Flush();
+
   this->MCObjectStreamer::FinishImpl();
 }
+
 void MCELFStreamer::EmitTCEntry(const MCSymbol &S) {
   // Creates a R_PPC64_TOC relocation
   MCObjectStreamer::EmitSymbolValue(&S, 8);

Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=191052&r1=191051&r2=191052&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Thu Sep 19 18:21:01 2013
@@ -123,7 +123,7 @@ void MCMachOStreamer::EmitLabel(MCSymbol
   assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
 
   // isSymbolLinkerVisible uses the section.
-  Symbol->setSection(*getCurrentSection().first);
+  AssignSection(Symbol, getCurrentSection().first);
   // We have to create a new fragment if this is an atom defining symbol,
   // fragments cannot span atoms.
   if (getAssembler().isSymbolLinkerVisible(*Symbol))
@@ -327,6 +327,8 @@ void MCMachOStreamer::EmitCommonSymbol(M
   // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
   assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
 
+  AssignSection(Symbol, NULL);
+
   MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
   SD.setExternal(true);
   SD.setCommon(Size, ByteAlignment);
@@ -363,7 +365,7 @@ void MCMachOStreamer::EmitZerofill(const
   MCFragment *F = new MCFillFragment(0, 0, Size, &SectData);
   SD.setFragment(F);
 
-  Symbol->setSection(*Section);
+  AssignSection(Symbol, Section);
 
   // Update the maximum alignment on the zero fill section if necessary.
   if (ByteAlignment > SectData.getAlignment())

Modified: llvm/trunk/lib/MC/MCNullStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCNullStreamer.cpp?rev=191052&r1=191051&r2=191052&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCNullStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCNullStreamer.cpp Thu Sep 19 18:21:01 2013
@@ -37,7 +37,7 @@ namespace {
     virtual void EmitLabel(MCSymbol *Symbol) {
       assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
       assert(getCurrentSection().first &&"Cannot emit before setting section!");
-      Symbol->setSection(*getCurrentSection().first);
+      AssignSection(Symbol, getCurrentSection().first);
     }
     virtual void EmitDebugLabel(MCSymbol *Symbol) {
       EmitLabel(Symbol);

Modified: llvm/trunk/lib/MC/MCPureStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCPureStreamer.cpp?rev=191052&r1=191051&r2=191052&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCPureStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCPureStreamer.cpp Thu Sep 19 18:21:01 2013
@@ -121,7 +121,7 @@ void MCPureStreamer::EmitLabel(MCSymbol
   assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
   assert(getCurrentSection().first && "Cannot emit before setting section!");
 
-  Symbol->setSection(*getCurrentSection().first);
+  AssignSection(Symbol, getCurrentSection().first);
 
   MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
 

Modified: llvm/trunk/lib/MC/MCStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=191052&r1=191051&r2=191052&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCStreamer.cpp Thu Sep 19 18:21:01 2013
@@ -191,17 +191,28 @@ void MCStreamer::EmitEHSymAttributes(con
                                      MCSymbol *EHSymbol) {
 }
 
+void MCStreamer::AssignSection(MCSymbol *Symbol, const MCSection *Section) {
+  if (Section)
+    Symbol->setSection(*Section);
+  else
+    Symbol->setUndefined();
+
+  // As we emit symbols into a section, track the order so that they can
+  // be sorted upon later. Zero is reserved to mean 'unemitted'.
+  SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
+}
+
 void MCStreamer::EmitLabel(MCSymbol *Symbol) {
   assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
   assert(getCurrentSection().first && "Cannot emit before setting section!");
-  Symbol->setSection(*getCurrentSection().first);
+  AssignSection(Symbol, getCurrentSection().first);
   LastSymbol = Symbol;
 }
 
 void MCStreamer::EmitDebugLabel(MCSymbol *Symbol) {
   assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
   assert(getCurrentSection().first && "Cannot emit before setting section!");
-  Symbol->setSection(*getCurrentSection().first);
+  AssignSection(Symbol, getCurrentSection().first);
   LastSymbol = Symbol;
 }
 

Modified: llvm/trunk/lib/MC/WinCOFFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WinCOFFStreamer.cpp?rev=191052&r1=191051&r2=191052&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WinCOFFStreamer.cpp (original)
+++ llvm/trunk/lib/MC/WinCOFFStreamer.cpp Thu Sep 19 18:21:01 2013
@@ -164,7 +164,7 @@ void WinCOFFStreamer::AddCommonSymbol(MC
 
   SymbolData.setExternal(External);
 
-  Symbol->setSection(*Section);
+  AssignSection(Symbol, Section);
 
   if (ByteAlignment != 1)
       new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, &SectionData);

Modified: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp?rev=191052&r1=191051&r2=191052&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp Thu Sep 19 18:21:01 2013
@@ -129,7 +129,7 @@ private:
     MCELF::SetType(SD, ELF::STT_NOTYPE);
     MCELF::SetBinding(SD, ELF::STB_LOCAL);
     SD.setExternal(false);
-    Symbol->setSection(*getCurrentSection().first);
+    AssignSection(Symbol, getCurrentSection().first);
 
     const MCExpr *Value = MCSymbolRefExpr::Create(Start, getContext());
     Symbol->setVariableValue(Value);

Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp?rev=191052&r1=191051&r2=191052&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp Thu Sep 19 18:21:01 2013
@@ -183,7 +183,7 @@ private:
     MCELF::SetType(SD, ELF::STT_NOTYPE);
     MCELF::SetBinding(SD, ELF::STB_LOCAL);
     SD.setExternal(false);
-    Symbol->setSection(*getCurrentSection().first);
+    AssignSection(Symbol, getCurrentSection().first);
 
     const MCExpr *Value = MCSymbolRefExpr::Create(Start, getContext());
     Symbol->setVariableValue(Value);

Added: llvm/trunk/test/DebugInfo/dwarf-aranges.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/dwarf-aranges.ll?rev=191052&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/dwarf-aranges.ll (added)
+++ llvm/trunk/test/DebugInfo/dwarf-aranges.ll Thu Sep 19 18:21:01 2013
@@ -0,0 +1,94 @@
+; RUN: llc < %s | FileCheck -check-prefix=CHECK-HEADER %s
+; RUN: llc < %s | FileCheck -check-prefix=CHECK-CODE %s
+; RUN: llc < %s | FileCheck -check-prefix=CHECK-DATA %s
+; RUN: llc < %s | FileCheck -check-prefix=CHECK-BSS %s
+; RUN: llc < %s | FileCheck -check-prefix=CHECK-CUSTOM %s
+
+
+; -- header --
+; CHECK-HEADER: .short 2 # DWARF Arange version number
+; CHECK-HEADER-NEXT: .long .L.debug_info_begin0
+; CHECK-HEADER-NEXT: .byte 8 # Address Size (in bytes)
+; CHECK-HEADER-NEXT: .byte 0 # Segment Size (in bytes)
+; -- alignment --
+; CHECK-HEADER-NEXT: .byte
+; CHECK-HEADER-NEXT: .byte
+; CHECK-HEADER-NEXT: .byte
+; CHECK-HEADER-NEXT: .byte
+; -- finish --
+; CHECK-HEADER: # ARange terminator
+
+
+; CHECK-CODE: .short 2 # DWARF Arange version number
+; CHECK-CODE: .quad .Lfunc_begin0
+; CHECK-CODE: # ARange terminator
+
+; CHECK-DATA: .short 2 # DWARF Arange version number
+; CHECK-DATA: .quad some_data
+; CHECK-DATA-NEXT: -some_data
+; CHECK-DATA-NEXT: .quad
+; CHECK-DATA: # ARange terminator
+
+; CHECK-BSS: .short 2 # DWARF Arange version number
+; CHECK-BSS: .quad some_bss
+; CHECK-BSS-NEXT: -some_bss
+; CHECK-BSS-NEXT: .quad
+; CHECK-BSS: # ARange terminator
+
+; CHECK-CUSTOM: .short 2 # DWARF Arange version number
+; CHECK-CUSTOM: .quad some_other
+; CHECK-CUSTOM-NEXT: -some_other
+; CHECK-CUSTOM-NEXT: .quad
+; CHECK-CUSTOM: # ARange terminator
+
+
+
+
+; -- source code --
+; Generated from: "clang -c -g -emit-llvm"
+;
+; int some_data = 4;
+; int some_bss;
+; int some_other __attribute__ ((section ("strangesection"))) = 5;
+; 
+; void some_code()
+; {
+;    some_bss += some_data + some_other;
+; }
+
+target triple = "x86_64-unknown-linux-gnu"
+
+ at some_data = global i32 4, align 4
+ at some_other = global i32 5, section "strangesection", align 4
+ at some_bss = common global i32 0, align 4
+
+define void @some_code() {
+entry:
+  %0 = load i32* @some_data, align 4, !dbg !14
+  %1 = load i32* @some_other, align 4, !dbg !14
+  %add = add nsw i32 %0, %1, !dbg !14
+  %2 = load i32* @some_bss, align 4, !dbg !14
+  %add1 = add nsw i32 %2, %add, !dbg !14
+  store i32 %add1, i32* @some_bss, align 4, !dbg !14
+  ret void, !dbg !15
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!13}
+
+!0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.4 ", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !8, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/home/kayamon/test.c] [DW_LANG_C99]
+!1 = metadata !{metadata !"test.c", metadata !"/home/kayamon"}
+!2 = metadata !{i32 0}
+!3 = metadata !{metadata !4}
+!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"some_code", metadata !"some_code", metadata !"", i32 5, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, void ()* @some_code, null, null, metadata !2, i32 6} ; [ DW_TAG_subprogram ] [line 5] [def] [scope 6] [some_code]
+!5 = metadata !{i32 786473, metadata !1}          ; [ DW_TAG_file_type ] [/home/kayamon/test.c]
+!6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = metadata !{null}
+!8 = metadata !{metadata !9, metadata !11, metadata !12}
+!9 = metadata !{i32 786484, i32 0, null, metadata !"some_data", metadata !"some_data", metadata !"", metadata !5, i32 1, metadata !10, i32 0, i32 1, i32* @some_data, null} ; [ DW_TAG_variable ] [some_data] [line 1] [def]
+!10 = metadata !{i32 786468, null, null, metadata !"int", i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!11 = metadata !{i32 786484, i32 0, null, metadata !"some_other", metadata !"some_other", metadata !"", metadata !5, i32 3, metadata !10, i32 0, i32 1, i32* @some_other, null} ; [ DW_TAG_variable ] [some_other] [line 3] [def]
+!12 = metadata !{i32 786484, i32 0, null, metadata !"some_bss", metadata !"some_bss", metadata !"", metadata !5, i32 2, metadata !10, i32 0, i32 1, i32* @some_bss, null} ; [ DW_TAG_variable ] [some_bss] [line 2] [def]
+!13 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
+!14 = metadata !{i32 7, i32 0, metadata !4, null}
+!15 = metadata !{i32 8, i32 0, metadata !4, null} ; [ DW_TAG_imported_declaration ]

Added: llvm/trunk/test/DebugInfo/multiple-aranges.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/multiple-aranges.ll?rev=191052&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/multiple-aranges.ll (added)
+++ llvm/trunk/test/DebugInfo/multiple-aranges.ll Thu Sep 19 18:21:01 2013
@@ -0,0 +1,65 @@
+; RUN: llc < %s | FileCheck %s
+
+; First CU
+; CHECK:      .long   44                      # Length of ARange Set
+; CHECK-NEXT: .short  2                       # DWARF Arange version number
+; CHECK-NEXT: .long   .L.debug_info_begin0    # Offset Into Debug Info Section
+; CHECK-NEXT: .byte   8                       # Address Size (in bytes)
+; CHECK-NEXT: .byte   0                       # Segment Size (in bytes)
+; CHECK-NEXT: .byte   255
+; CHECK-NEXT: .byte   255
+; CHECK-NEXT: .byte   255
+; CHECK-NEXT: .byte   255
+; CHECK-NEXT: .quad   kittens
+; CHECK-NEXT: .Lset0 = rainbows-kittens
+; CHECK-NEXT: .quad   .Lset0
+; CHECK-NEXT: .quad   0                       # ARange terminator
+; CHECK-NEXT: .quad   0
+
+; Second CU
+; CHECK-NEXT: .long   44                      # Length of ARange Set
+; CHECK-NEXT: .short  2                       # DWARF Arange version number
+; CHECK-NEXT: .long   .L.debug_info_begin1    # Offset Into Debug Info Section
+; CHECK-NEXT: .byte   8                       # Address Size (in bytes)
+; CHECK-NEXT: .byte   0                       # Segment Size (in bytes)
+; CHECK-NEXT: .byte   255
+; CHECK-NEXT: .byte   255
+; CHECK-NEXT: .byte   255
+; CHECK-NEXT: .byte   255
+; CHECK-NEXT: .quad   rainbows
+; CHECK-NEXT: .Lset1 = .L.data_end-rainbows
+; CHECK-NEXT: .quad   .Lset1
+; CHECK-NEXT: .quad   0                       # ARange terminator
+; CHECK-NEXT: .quad   0
+
+
+; Generated from: clang -c -g -emit-llvm
+;                 llvm-link test1.bc test2.bc -o test.bc
+; test1.c: int kittens = 4;
+; test2.c: int rainbows = 5;
+
+
+
+
+; ModuleID = 'test.bc'
+target triple = "x86_64-unknown-linux-gnu"
+
+ at kittens = global i32 4, align 4
+ at rainbows = global i32 5, align 4
+
+!llvm.dbg.cu = !{!0, !7}
+!llvm.module.flags = !{!12}
+
+!0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.4 ", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !2, metadata !3, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/home/kayamon/test1.c] [DW_LANG_C99]
+!1 = metadata !{metadata !"test1.c", metadata !"/home/kayamon"}
+!2 = metadata !{i32 0}
+!3 = metadata !{metadata !4}
+!4 = metadata !{i32 786484, i32 0, null, metadata !"kittens", metadata !"kittens", metadata !"", metadata !5, i32 1, metadata !6, i32 0, i32 1, i32* @kittens, null} ; [ DW_TAG_variable ] [kittens] [line 1] [def]
+!5 = metadata !{i32 786473, metadata !1}          ; [ DW_TAG_file_type ] [/home/kayamon/test1.c]
+!6 = metadata !{i32 786468, null, null, metadata !"int", i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!7 = metadata !{i32 786449, metadata !8, i32 12, metadata !"clang version 3.4 ", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !2, metadata !9, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/home/kayamon/test2.c] [DW_LANG_C99]
+!8 = metadata !{metadata !"test2.c", metadata !"/home/kayamon"}
+!9 = metadata !{metadata !10}
+!10 = metadata !{i32 786484, i32 0, null, metadata !"rainbows", metadata !"rainbows", metadata !"", metadata !11, i32 1, metadata !6, i32 0, i32 1, i32* @rainbows, null} ; [ DW_TAG_variable ] [rainbows] [line 1] [def]
+!11 = metadata !{i32 786473, metadata !8}         ; [ DW_TAG_file_type ] [/home/kayamon/test2.c]
+!12 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}





More information about the llvm-commits mailing list