// Define out of line so we don't have to include DwarfUnit.h in DwarfDebug.h.
DwarfDebug::~DwarfDebug() { }
-// Switch to the specified MCSection and emit an assembler
-// temporary label to it if SymbolStem is specified.
-static void emitSectionSym(AsmPrinter *Asm, const MCSection *Section) {
- Asm->OutStreamer.SwitchSection(Section);
- MCSymbol *TmpSym = Section->getBeginSymbol();
- Asm->OutStreamer.EmitLabel(TmpSym);
-}
-
static bool isObjCClass(StringRef Name) {
return Name.startswith("+") || Name.startswith("-");
}
return;
TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes);
- // Emit initial sections so we can reference labels later.
- emitSectionLabels();
-
SingleCU = CU_Nodes->getNumOperands() == 1;
for (MDNode *N : CU_Nodes->operands()) {
// Emit all Dwarf sections that should come after the content.
void DwarfDebug::endModule() {
- const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
assert(CurFn == nullptr);
assert(CurMI == nullptr);
// If we aren't actually generating debug info (check beginModule -
// conditionalized on !DisableDebugInfoPrinting and the presence of the
// llvm.dbg.cu metadata node)
- if (!TLOF.getDwarfInfoSection()->getBeginSymbol()->isInSection())
+ if (!MMI->hasDebugInfo())
return;
// Finalize the debug info for the module.
// Emit info into a debug loc section.
emitDebugLoc();
- // Emit all the DIEs into a debug info section.
- emitDebugInfo();
-
// Corresponding abbreviations into a abbrev section.
emitAbbreviations();
+ // Emit all the DIEs into a debug info section.
+ emitDebugInfo();
+
// Emit info into a debug aranges section.
if (GenerateARangeSection)
emitDebugARanges();
// Emit Methods
//===----------------------------------------------------------------------===//
-// Emit initial Dwarf sections with a label at the start of each one.
-void DwarfDebug::emitSectionLabels() {
- const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
-
- // Dwarf sections base addresses.
- emitSectionSym(Asm, TLOF.getDwarfInfoSection());
- if (useSplitDwarf()) {
- emitSectionSym(Asm, TLOF.getDwarfInfoDWOSection());
- emitSectionSym(Asm, TLOF.getDwarfTypesDWOSection());
- }
- emitSectionSym(Asm, TLOF.getDwarfAbbrevSection());
- if (useSplitDwarf())
- emitSectionSym(Asm, TLOF.getDwarfAbbrevDWOSection());
-
- emitSectionSym(Asm, TLOF.getDwarfLineSection());
- emitSectionSym(Asm, TLOF.getDwarfStrSection());
- if (useSplitDwarf()) {
- emitSectionSym(Asm, TLOF.getDwarfStrDWOSection());
- emitSectionSym(Asm, TLOF.getDwarfAddrSection());
- emitSectionSym(Asm, TLOF.getDwarfLocDWOSection());
- } else
- emitSectionSym(Asm, TLOF.getDwarfLocSection());
- emitSectionSym(Asm, TLOF.getDwarfRangesSection());
-}
-
// Emit the debug info section.
void DwarfDebug::emitDebugInfo() {
DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
void DwarfDebug::emitAccel(DwarfAccelTable &Accel, const MCSection *Section,
StringRef TableName) {
Accel.FinalizeTable(Asm, TableName);
- emitSectionSym(Asm, Section);
+ Asm->OutStreamer.SwitchSection(Section);
// Emit the full data.
Accel.emit(Asm, Section->getBeginSymbol(), this);
/// \brief Construct a DIE for this abstract scope.
void constructAbstractSubprogramScopeDIE(LexicalScope *Scope);
- /// \brief Emit initial Dwarf sections with a label at the start of each one.
- void emitSectionLabels();
-
/// \brief Compute the size and offset of a DIE given an incoming Offset.
unsigned computeSizeAndOffset(DIE *Die, unsigned Offset);
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCWin64EH.h"
#include "llvm/Support/ErrorHandling.h"
if (MCSectionSubPair(Section, Subsection) != curSection) {
SectionStack.back().first = MCSectionSubPair(Section, Subsection);
ChangeSection(Section, Subsection);
+ MCSymbol *Sym = Section->getBeginSymbol();
+ if (Sym && !Sym->isInSection())
+ EmitLabel(Sym);
}
}
; RUN: %llc_dwarf -O2 %s -o - | FileCheck %s
; Check struct X for dead variable xyz from inlined function foo.
+; CHECK: .Lsection_info
; CHECK: DW_TAG_structure_type
; CHECK-NEXT: info_string
; A by-value struct is a register-indirect value (breg).
; RUN: llc %s -filetype=asm -o - | FileCheck %s
+; CHECK: Lsection_info:
; CHECK: DW_AT_location
; CHECK-NEXT: .byte 112
; 112 = 0x70 = DW_OP_breg0
; CHECK-NEXT: .byte 224
; check that the expected TLS address description is the first thing in the debug_addr section
; CHECK: debug_addr
+; CHECK-NEXT: .Laddr_sec:
; CHECK-NEXT: .quad tls@dtprel+32768
@tls = thread_local global i32 0, align 4
; RUN: llc -mtriple=x86_64-linux < %s | FileCheck %s
+; CHECK: .section .debug_info
; CHECK: DW_AT_const_value
; CHECK-NEXT: 42
--- /dev/null
+; RUN: llc -mtriple x86_64-pc-linux < %s | FileCheck %s
+
+; Test that we don't pollute the start of the file with debug sections
+
+; CHECK: .text
+; CHECK-NEXT: .file "<stdin>"
+; CHECK-NEXT: .globl f
+; CHECK-NEXT: .align 16, 0x90
+; CHECK-NEXT: .type f,@function
+; CHECK-NEXT: f: # @f
+
+; CHECK: .section .debug_str
+
+define void @f() {
+ ret void, !dbg !9
+}
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!7, !8}
+
+!0 = !MDCompileUnit(language: DW_LANG_C99, file: !1, producer: "foo", isOptimized: true, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2)
+!1 = !MDFile(filename: "/foo/test.c", directory: "/foo")
+!2 = !{}
+!3 = !{!4}
+!4 = !MDSubprogram(name: "f", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, function: void ()* @f, variables: !2)
+!5 = !MDSubroutineType(types: !6)
+!6 = !{null}
+!7 = !{i32 2, !"Dwarf Version", i32 4}
+!8 = !{i32 2, !"Debug Info Version", i32 3}
+!9 = !MDLocation(line: 1, column: 15, scope: !4)
; RUN: llc -mtriple x86_64-pc-linux-gnu < %s | FileCheck %s
+; CHECK: .long .Lline_table_start0 # DW_AT_stmt_list
+
; CHECK: .section .debug_line,"",@progbits
; CHECK-NEXT: .Lsection_line:
-
-; CHECK: .long .Lline_table_start0 # DW_AT_stmt_list
+; CHECK-NEXT: .Lline_table_start0:
define void @f() {
entry:
; check that the expected TLS address description is the first thing in the debug_addr section
; FISSION: .section .debug_addr
+; FISSION: addr_sec:
; FISSION-NEXT: .quad tls@DTPOFF
; FISSION-NEXT: .quad glbl
; FISSION-NOT: .quad glbl
!7 = distinct !MDLexicalBlock(line: 3, column: 12, file: !14, scope: !0)
!8 = !MDCompositeType(tag: DW_TAG_array_type, align: 32, file: !14, scope: !2, baseType: !5, elements: !9)
!9 = !{!10}
+;CHECK: section_info:
;CHECK: DW_TAG_subrange_type
;CHECK-NEXT: DW_AT_type
;CHECK-NOT: DW_AT_lower_bound
// ASM: .section .debug_info
// ASM: .section .debug_abbrev
+// ASM-NEXT: .Lsection_abbrev:
// ASM-NEXT: [[ABBREV_LABEL:.Ltmp[0-9]+]]
// Second instance of the section has the CU
// ASM-NEXT: .long [[LINE_LABEL:.L[a-z0-9]+]]
// ASM: .section .debug_line
+// ASM-NEXT:.Lsection_line:
// ASM-NEXT: [[LINE_LABEL]]
// DWARF1: Dwarf version 1 is not supported.