diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index e66237706bc..de08b77012b 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -292,6 +292,9 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { // sections and expected to be contiguous (e.g. ObjC metadata). unsigned AlignLog = getGVAlignmentLog2(GV, *TD); + if (DD) + DD->setSymbolSize(GVSym, Size); + // Handle common and BSS local symbols (.lcomm). if (GVKind.isCommon() || GVKind.isBSSLocal()) { if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 6414969774b..48a7c185ec2 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -2838,12 +2838,17 @@ void DwarfDebug::emitDebugARanges() { 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) + if (Span.End) { Asm->EmitLabelDifference(Span.End, Span.Start, PtrSize); - else - Asm->OutStreamer.EmitIntValue(1, PtrSize); + } else { + // For symbols without an end marker (e.g. common), we + // write a single arange entry containing just that one symbol. + uint64_t Size = SymSize[Span.Start]; + if (Size == 0) + Size = 1; + + Asm->OutStreamer.EmitIntValue(Size, PtrSize); + } } Asm->OutStreamer.AddComment("ARange terminator"); diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 8fe60c77be5..e774c653945 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -341,6 +341,9 @@ class DwarfDebug { // List of all labels used in the output. std::vector Labels; + // Size of each symbol emitted (for those symbols that have a specific size). + DenseMap SymSize; + // Provides a unique id per text section. typedef DenseMap > SectionMapType; SectionMapType SectionMap; @@ -682,6 +685,10 @@ public: /// \brief Add a label so that arange data can be generated for it. void addLabel(SymbolCU SCU) { Labels.push_back(SCU); } + /// \brief For symbols that have a size designated (e.g. common symbols), + /// this tracks that size. + void setSymbolSize(const MCSymbol *Sym, uint64_t Size) { SymSize[Sym] = Size;} + /// \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. diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index e57025e1019..80b0acec846 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -533,8 +533,8 @@ void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { - const MCSection *Section = getContext().getObjectFileInfo()->getBSSSection(); - AssignSection(Symbol, Section); + // Common symbols do not belong to any actual section. + AssignSection(Symbol, NULL); OS << "\t.comm\t" << *Symbol << ',' << Size; if (ByteAlignment != 0) { @@ -552,8 +552,8 @@ void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, /// @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); + // Common symbols do not belong to any actual section. + AssignSection(Symbol, NULL); OS << "\t.lcomm\t" << *Symbol << ',' << Size; if (ByteAlign > 1) { diff --git a/test/DebugInfo/X86/dwarf-aranges.ll b/test/DebugInfo/X86/dwarf-aranges.ll index eae5c790d82..a2f0059ed25 100644 --- a/test/DebugInfo/X86/dwarf-aranges.ll +++ b/test/DebugInfo/X86/dwarf-aranges.ll @@ -18,27 +18,28 @@ ; -- finish -- ; CHECK-HEADER: # ARange terminator - +; - it should have made one span covering all functions in this CU. ; CHECK-CODE: .short 2 # DWARF Arange version number ; CHECK-CODE: .quad .Lfunc_begin0 +; CHECK-CODE-NEXT: .Lset1 = .L.text_end-.Lfunc_begin0 ; CHECK-CODE: # ARange terminator +; - it should have made one span covering all vars in this CU. ; 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 +; - it should have made one span for each symbol. ; CHECK-BSS: .short 2 # DWARF Arange version number ; CHECK-BSS: .quad some_bss -; CHECK-BSS-NEXT: -some_bss -; CHECK-BSS-NEXT: .quad +; CHECK-BSS-NEXT: .quad 4 ; CHECK-BSS: # ARange terminator +; - it should have made one span covering all vars in this CU. ; 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