From 8466ca86fe40e691fa9c326fbd95ef2aebe8ee71 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Mon, 1 Jul 2013 23:55:52 +0000 Subject: [PATCH] PR14728: DebugInfo: TLS variables with -gsplit-dwarf llvm-svn: 185398 --- llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 23 ++++++++++-------- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 17 ++++++++----- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 3 ++- llvm/test/DebugInfo/X86/tls-fission.ll | 31 ++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 17 deletions(-) create mode 100644 llvm/test/DebugInfo/X86/tls-fission.ll diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 339a5d2..f42a33e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -201,15 +201,12 @@ void CompileUnit::addLabelAddress(DIE *Die, unsigned Attribute, /// form given and an op of either DW_FORM_addr or DW_FORM_GNU_addr_index. /// void CompileUnit::addOpAddress(DIE *Die, const MCSymbol *Sym) { - if (!DD->useSplitDwarf()) { addUInt(Die, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); addLabel(Die, 0, dwarf::DW_FORM_udata, Sym); } else { - unsigned idx = DU->getAddrPoolIndex(Sym); - DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx); addUInt(Die, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_addr_index); - Die->addValue(0, dwarf::DW_FORM_GNU_addr_index, Value); + addUInt(Die, 0, dwarf::DW_FORM_GNU_addr_index, DU->getAddrPoolIndex(Sym)); } } @@ -1358,13 +1355,19 @@ void CompileUnit::createGlobalVariableDIE(const MDNode *N) { unsigned PointerSize = Asm->getDataLayout().getPointerSize(); assert((PointerSize == 4 || PointerSize == 8) && "Add support for other sizes if necessary"); + const MCSymbolRefExpr *Ref = + Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym); // Based on GCC's support for TLS: - // 1) Start with a constNu of the appropriate pointer size - addUInt(Block, 0, dwarf::DW_FORM_data1, - PointerSize == 4 ? dwarf::DW_OP_const4u : dwarf::DW_OP_const8u); - // 2) containing the (relocated) address of the TLS variable - addLabel(Block, 0, dwarf::DW_FORM_udata, - Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym)); + if (!DD->useSplitDwarf()) { + // 1) Start with a constNu of the appropriate pointer size + addUInt(Block, 0, dwarf::DW_FORM_data1, + PointerSize == 4 ? dwarf::DW_OP_const4u : dwarf::DW_OP_const8u); + // 2) containing the (relocated) address of the TLS variable + addLabel(Block, 0, dwarf::DW_FORM_udata, Ref); + } else { + addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index); + addUInt(Block, 0, dwarf::DW_FORM_udata, DU->getAddrPoolIndex(Ref)); + } // 3) followed by a custom OP to tell the debugger about TLS (presumably) addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_lo_user); } else diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index ead90c0..0731b90 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -248,7 +248,11 @@ unsigned DwarfUnits::getStringPoolIndex(StringRef Str) { } unsigned DwarfUnits::getAddrPoolIndex(const MCSymbol *Sym) { - std::pair::iterator, bool> P = + return getAddrPoolIndex(MCSymbolRefExpr::Create(Sym, Asm->OutContext)); +} + +unsigned DwarfUnits::getAddrPoolIndex(const MCSymbolRefExpr *Sym) { + std::pair::iterator, bool> P = AddressPool.insert(std::make_pair(Sym, NextAddrPoolNumber)); if (P.second) ++NextAddrPoolNumber; @@ -2357,10 +2361,11 @@ void DwarfUnits::emitAddresses(const MCSection *AddrSection) { // Get all of the address pool entries and put them in an array by their ID so // we can sort them. - SmallVector, 64> Entries; + SmallVector, 64> Entries; - for (DenseMap::iterator I = AddressPool.begin(), - E = AddressPool.end(); + for (DenseMap::iterator + I = AddressPool.begin(), + E = AddressPool.end(); I != E; ++I) Entries.push_back(std::make_pair(I->second, I->first)); @@ -2368,8 +2373,8 @@ void DwarfUnits::emitAddresses(const MCSection *AddrSection) { for (unsigned i = 0, e = Entries.size(); i != e; ++i) { // Emit a label for reference from debug information entries. - if (const MCSymbol *Sym = Entries[i].second) - Asm->EmitLabelReference(Sym, Asm->getDataLayout().getPointerSize()); + if (const MCSymbolRefExpr *Sym = Entries[i].second) + Asm->OutStreamer.EmitValue(Sym, Asm->getDataLayout().getPointerSize()); else Asm->OutStreamer.EmitIntValue(0, Asm->getDataLayout().getPointerSize()); } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 00d48d7..893505c 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -197,7 +197,7 @@ typedef StringMap, // A Symbol->unsigned mapping of addresses used by indirect // references. -typedef DenseMap AddrPool; +typedef DenseMap AddrPool; /// \brief Collects and handles information specific to a particular /// collection of units. @@ -270,6 +270,7 @@ public: /// \brief Returns the index into the address pool with the given /// label/symbol. + unsigned getAddrPoolIndex(const MCSymbolRefExpr *); unsigned getAddrPoolIndex(const MCSymbol *); /// \brief Returns the address pool. diff --git a/llvm/test/DebugInfo/X86/tls-fission.ll b/llvm/test/DebugInfo/X86/tls-fission.ll new file mode 100644 index 0000000..b95ff40 --- /dev/null +++ b/llvm/test/DebugInfo/X86/tls-fission.ll @@ -0,0 +1,31 @@ +; RUN: llc -split-dwarf=Enable -mtriple=x86_64-linux -O0 -filetype=asm < %s | FileCheck %s + +; FIXME: add relocation and DWARF expression support to llvm-dwarfdump & use +; that here instead of raw assembly printing + +; CHECK: debug_info.dwo +; 3 bytes of data in this DW_FORM_block1 representation of the location of 'tls' +; CHECK: .byte 3{{ *}}# DW_AT_location +; DW_OP_const_index (0xfx == 252) to refer to the debug_addr table +; CHECK-NEXT: .byte 252 +; an index of zero into the debug_addr table +; CHECK-NEXT: .byte 0 +; DW_OP_lo_user based on GCC/GDB extension presumably (by experiment) to support TLS +; 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: .quad tls@DTPOFF + +@tls = thread_local global i32 0, align 4 + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7} + +!0 = metadata !{i32 786449, metadata !1, i32 4, metadata !"clang version 3.4 ", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !2, metadata !3, metadata !2, metadata !"tls.dwo"} ; [ DW_TAG_compile_unit ] [/tmp/tls.cpp] [DW_LANG_C_plus_plus] +!1 = metadata !{metadata !"tls.cpp", metadata !"/tmp"} +!2 = metadata !{i32 0} +!3 = metadata !{metadata !4} +!4 = metadata !{i32 786484, i32 0, null, metadata !"tls", metadata !"tls", metadata !"", metadata !5, i32 1, metadata !6, i32 0, i32 1, i32* @tls, null} ; [ DW_TAG_variable ] [tls] [line 1] [def] +!5 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] [/tmp/tls.cpp] +!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 2, metadata !"Dwarf Version", i32 3} -- 2.7.4