Index: include/llvm/CodeGen/AsmPrinter.h =================================================================== --- include/llvm/CodeGen/AsmPrinter.h +++ include/llvm/CodeGen/AsmPrinter.h @@ -475,6 +475,9 @@ EmitLabelPlusOffset(Label, 0, Size, IsSectionRelative); } + /// Emit something like ".long Label + Offset". + void EmitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const; + //===------------------------------------------------------------------===// // Dwarf Emission Helper Routines //===------------------------------------------------------------------===// Index: lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -179,6 +179,10 @@ EmitInt32(S.Offset); } +void AsmPrinter::EmitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const { + EmitLabelPlusOffset(Label, Offset, MAI->getCodePointerSize()); +} + //===----------------------------------------------------------------------===// // Dwarf Lowering Routines //===----------------------------------------------------------------------===// Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -270,15 +270,20 @@ void DwarfCompileUnit::initStmtList() { // Define start line table label for each Compile Unit. - MCSymbol *LineTableStartSym = - Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID()); + MCSymbol *LineTableStartSym; + const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); + if (DD->useSectionsAsReferences()) { + LineTableStartSym = TLOF.getDwarfLineSection()->getBeginSymbol(); + } else { + LineTableStartSym = + Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID()); + } // DW_AT_stmt_list is a offset of line number information for this // compile unit in debug_line section. For split dwarf this is // left in the skeleton CU and so not included. // The line table entries are not always emitted in assembly, so it // is not okay to use line_table_start here. - const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); StmtListValue = addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym, TLOF.getDwarfLineSection()->getBeginSymbol()); @@ -835,7 +840,7 @@ void DwarfCompileUnit::emitHeader(bool UseOffsets) { // Don't bother labeling the .dwo unit, as its offset isn't used. - if (!Skeleton) { + if (!Skeleton && !DD->useSectionsAsReferences()) { LabelBegin = Asm->createTempSymbol("cu_begin"); Asm->OutStreamer->EmitLabel(LabelBegin); } Index: lib/CodeGen/AsmPrinter/DwarfDebug.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.h +++ lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -264,6 +264,10 @@ /// Allow emission of .debug_ranges section. bool UseRangesSection = true; + /// True if the sections itself must be used as references and don't create + /// temp symbols inside DWARF sections. + bool UseSectionsAsReferences = false; + /// DWARF5 Experimental Options /// @{ bool HasDwarfAccelTables; @@ -513,6 +517,11 @@ /// Returns whether ranges section should be emitted. bool useRangesSection() const { return UseRangesSection; } + /// Returns whether to use sections as labels rather than temp symbols. + bool useSectionsAsReferences() const { + return UseSectionsAsReferences; + } + // Experimental DWARF5 features. /// Returns whether or not to emit tables that dwarf consumers can Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -133,6 +133,13 @@ cl::desc("Disable emission .debug_ranges section."), cl::init(false)); +static cl::opt DwarfSectionsAsReferences( + "dwarf-sections-as-references", cl::Hidden, + cl::desc("Use sections+offset as references rather than labels."), + cl::values(clEnumVal(Default, "Default for platform"), + clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), + cl::init(Default)); + enum LinkageNameOption { DefaultLinkageNames, AllLinkageNames, @@ -323,6 +330,9 @@ UsePubSections = !NoDwarfPubSections; UseRangesSection = !NoDwarfRangesSection; + // Use sections as references. + UseSectionsAsReferences = DwarfSectionsAsReferences == Enable; + // Work around a GDB bug. GDB doesn't support the standard opcode; // SCE doesn't support GNU's; LLDB prefers the standard opcode, which // is defined as of DWARF 3. @@ -1577,7 +1587,11 @@ Asm->EmitInt16(dwarf::DW_PUBNAMES_VERSION); Asm->OutStreamer->AddComment("Offset of Compilation Unit Info"); - Asm->emitDwarfSymbolReference(TheU->getLabelBegin()); + if (useSectionsAsReferences()) + Asm->EmitDwarfOffset(TheU->getSection()->getBeginSymbol(), + TheU->getDebugSectionOffset()); + else + Asm->emitDwarfSymbolReference(TheU->getLabelBegin()); Asm->OutStreamer->AddComment("Compilation Unit Length"); Asm->EmitInt32(TheU->getLength()); @@ -1876,7 +1890,11 @@ Asm->OutStreamer->AddComment("DWARF Arange version number"); Asm->EmitInt16(dwarf::DW_ARANGES_VERSION); Asm->OutStreamer->AddComment("Offset Into Debug Info Section"); - Asm->emitDwarfSymbolReference(CU->getLabelBegin()); + if (useSectionsAsReferences()) + Asm->EmitDwarfOffset(CU->getSection()->getBeginSymbol(), + CU->getDebugSectionOffset()); + else + Asm->emitDwarfSymbolReference(CU->getLabelBegin()); Asm->OutStreamer->AddComment("Address Size (in bytes)"); Asm->EmitInt8(PtrSize); Asm->OutStreamer->AddComment("Segment Size (in bytes)"); Index: test/DebugInfo/X86/sections_as_references.ll =================================================================== --- /dev/null +++ test/DebugInfo/X86/sections_as_references.ll @@ -0,0 +1,54 @@ +; RUN: llc -filetype=asm -O0 -mtriple=x86_64-linux-gnu < %s -dwarf-sections-as-references=Enable -dwarf-inlined-strings=Enable -no-dwarf-pub-sections -no-dwarf-ranges-section -dwarf-version 2 -debugger-tune=gdb | FileCheck %s + +; CHECK: .file + +; CHECK-NOT: .L + +; CHECK: .section .debug_abbrev +; CHECK-NOT: DW_FORM_str{{p|x}} +; CHECK-NOT: .L + +; CHECK: .section .debug_info +; CHECK-NOT: .L +; CHECK: .short 2 # DWARF version number +; CHECK-NOT: .L +; CHECK: .long .debug_abbrev # Offset Into Abbrev. Section +; CHECK-NOT: .L +; CHECK: .long .debug_line # DW_AT_stmt_list +; CHECK-NOT: .L +; CHECK: .long .debug_abbrev # Offset Into Abbrev. Section +; CHECK-NOT: .L +; CHECK: .long .debug_line # DW_AT_stmt_list +; CHECK-NOT: .L +; CHECK: .quad .debug_info+{{[0-9]+}} # DW_AT_type +; CHECK-NOT: .L +; CHECK: .byte 0 # End Of Children Mark +; CHECK-NOT: .L + +source_filename = "test/DebugInfo/X86/sections_as_references.ll" + +%struct.foo = type { i8 } + +@f = global %struct.foo zeroinitializer, align 1, !dbg !0 +@g = global %struct.foo zeroinitializer, align 1, !dbg !6 + +!llvm.dbg.cu = !{!9, !12} +!llvm.module.flags = !{!14, !15} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = !DIGlobalVariable(name: "f", scope: null, file: !2, line: 2, type: !3, isLocal: false, isDefinition: true) +!2 = !DIFile(filename: "tu1.cpp", directory: "/dir") +!3 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !4, line: 1, size: 8, align: 8, elements: !5, identifier: "_ZTS3foo") +!4 = !DIFile(filename: "./hdr.h", directory: "/dir") +!5 = !{} +!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression()) +!7 = !DIGlobalVariable(name: "g", scope: null, file: !8, line: 2, type: !3, isLocal: false, isDefinition: true) +!8 = !DIFile(filename: "tu2.cpp", directory: "/dir") +!9 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !10, globals: !11, imports: !5) +!10 = !{!3} +!11 = !{!0} +!12 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !8, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !10, globals: !13, imports: !5) +!13 = !{!6} +!14 = !{i32 2, !"Dwarf Version", i32 2} +!15 = !{i32 1, !"Debug Info Version", i32 3} +