From 72c32c6c824004f4327796b70de1694a2f09c9e2 Mon Sep 17 00:00:00 2001 From: Frederic Riss Date: Wed, 12 Nov 2014 23:48:14 +0000 Subject: [PATCH] Fix emission of Dwarf accelerator table when there are multiple CUs. The DIE offset in the accel tables is an offset relative to the start of the debug_info section, but we were encoding the offset to the start of the containing CU. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221837 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp | 9 ++++++--- lib/CodeGen/AsmPrinter/DwarfAccelTable.h | 6 +++--- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 2 +- test/DebugInfo/cross-cu-inlining.ll | 16 ++++++++++++++-- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp b/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp index a9cbdbac076..7e87566a250 100644 --- a/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp @@ -13,6 +13,7 @@ #include "DwarfAccelTable.h" #include "DIE.h" +#include "DwarfCompileUnit.h" #include "DwarfDebug.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Twine.h" @@ -174,7 +175,7 @@ void DwarfAccelTable::EmitOffsets(AsmPrinter *Asm, MCSymbol *SecBegin) { // Walk through the buckets and emit the full data for each element in // the bucket. For the string case emit the dies and the various offsets. // Terminate each HashData bucket with 0. -void DwarfAccelTable::EmitData(AsmPrinter *Asm, DwarfFile *D, +void DwarfAccelTable::EmitData(AsmPrinter *Asm, DwarfDebug *D, MCSymbol *StrSym) { uint64_t PrevHash = UINT64_MAX; for (size_t i = 0, e = Buckets.size(); i < e; ++i) { @@ -189,7 +190,9 @@ void DwarfAccelTable::EmitData(AsmPrinter *Asm, DwarfFile *D, Asm->EmitInt32((*HI)->Data.Values.size()); for (HashDataContents *HD : (*HI)->Data.Values) { // Emit the DIE offset - Asm->EmitInt32(HD->Die->getOffset()); + DwarfCompileUnit *CU = D->lookupUnit(HD->Die->getUnit()); + assert(CU && "Accelerated DIE should belong to a CU."); + Asm->EmitInt32(HD->Die->getOffset() + CU->getDebugInfoOffset()); // If we have multiple Atoms emit that info too. // FIXME: A bit of a hack, we either emit only one atom or all info. if (HeaderData.Atoms.size() > 1) { @@ -206,7 +209,7 @@ void DwarfAccelTable::EmitData(AsmPrinter *Asm, DwarfFile *D, } // Emit the entire data structure to the output file. -void DwarfAccelTable::Emit(AsmPrinter *Asm, MCSymbol *SecBegin, DwarfFile *D, +void DwarfAccelTable::Emit(AsmPrinter *Asm, MCSymbol *SecBegin, DwarfDebug *D, MCSymbol *StrSym) { // Emit the header. EmitHeader(Asm); diff --git a/lib/CodeGen/AsmPrinter/DwarfAccelTable.h b/lib/CodeGen/AsmPrinter/DwarfAccelTable.h index ff809f25982..3cdf678ffb3 100644 --- a/lib/CodeGen/AsmPrinter/DwarfAccelTable.h +++ b/lib/CodeGen/AsmPrinter/DwarfAccelTable.h @@ -62,7 +62,7 @@ namespace llvm { class AsmPrinter; -class DwarfFile; +class DwarfDebug; class DwarfAccelTable { @@ -223,7 +223,7 @@ private: void EmitBuckets(AsmPrinter *); void EmitHashes(AsmPrinter *); void EmitOffsets(AsmPrinter *, MCSymbol *); - void EmitData(AsmPrinter *, DwarfFile *D, MCSymbol *StrSym); + void EmitData(AsmPrinter *, DwarfDebug *D, MCSymbol *StrSym); // Allocator for HashData and HashDataContents. BumpPtrAllocator Allocator; @@ -248,7 +248,7 @@ public: void AddName(StringRef Name, MCSymbol *StrSym, const DIE *Die, char Flags = 0); void FinalizeTable(AsmPrinter *, StringRef); - void Emit(AsmPrinter *, MCSymbol *, DwarfFile *, MCSymbol *StrSym); + void Emit(AsmPrinter *, MCSymbol *, DwarfDebug *, MCSymbol *StrSym); #ifndef NDEBUG void print(raw_ostream &O); void dump() { print(dbgs()); } diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 4acd7271be9..075c782d622 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1478,7 +1478,7 @@ void DwarfDebug::emitAccel(DwarfAccelTable &Accel, const MCSection *Section, Asm->OutStreamer.EmitLabel(SectionBegin); // Emit the full data. - Accel.Emit(Asm, SectionBegin, &InfoHolder, DwarfStrSectionSym); + Accel.Emit(Asm, SectionBegin, this, DwarfStrSectionSym); } // Emit visible names into a hashed accelerator table section. diff --git a/test/DebugInfo/cross-cu-inlining.ll b/test/DebugInfo/cross-cu-inlining.ll index 4ccb3ffbb5f..ba88bcccf33 100644 --- a/test/DebugInfo/cross-cu-inlining.ll +++ b/test/DebugInfo/cross-cu-inlining.ll @@ -1,6 +1,7 @@ ; REQUIRES: object-emission ; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck -implicit-check-not=DW_TAG %s +; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump - | FileCheck --check-prefix=CHECK-ACCEL --check-prefix=CHECK %s ; Build from source: ; $ clang++ a.cpp b.cpp -g -c -emit-llvm @@ -24,7 +25,7 @@ ; CHECK: DW_AT_name {{.*}} "a.cpp" ; CHECK: DW_TAG_subprogram ; CHECK: DW_AT_type [DW_FORM_ref_addr] (0x00000000[[INT:.*]]) -; CHECK: DW_TAG_inlined_subroutine +; CHECK: 0x[[INLINED:[0-9a-f]*]]:{{.*}}DW_TAG_inlined_subroutine ; CHECK: DW_AT_abstract_origin {{.*}}[[ABS_FUNC:........]] "_Z4funci" ; CHECK: DW_TAG_formal_parameter ; CHECK: DW_AT_abstract_origin {{.*}}[[ABS_VAR:........]] "x" @@ -45,13 +46,24 @@ ; Check the concrete out of line definition references the abstract and ; provides the address range and variable location -; CHECK: DW_TAG_subprogram +; CHECK: 0x[[FUNC:[0-9a-f]*]]{{.*}}DW_TAG_subprogram ; CHECK: DW_AT_low_pc ; CHECK: DW_AT_abstract_origin {{.*}} {0x[[ABS_FUNC]]} "_Z4funci" ; CHECK: DW_TAG_formal_parameter ; CHECK: DW_AT_location ; CHECK: DW_AT_abstract_origin {{.*}} {0x[[ABS_VAR]]} "x" +; CHECK-ACCEL: .apple_names contents: +; CHECK-ACCEL: Name{{.*}}"func" +; CHECK-ACCEL-NOT: Name +; CHECK-ACCEL: Atom[0]{{.*}}[[INLINED]] +; CHECK-ACCEL-NOT: Name +; CHECK-ACCEL: Atom[0]{{.*}}[[FUNC]] + +; CHECK-ACCEL: .apple_types contents: +; CHECK-ACCEL: Name{{.*}}"int" +; CHECK-ACCEL-NOT: Name +; CHECK-ACCEL: Atom[0]{{.*}}[[INT]] @i = external global i32