From ac8062bb724136609f422be9c5a82d3514645011 Mon Sep 17 00:00:00 2001 From: Manman Ren Date: Tue, 2 Jul 2013 23:40:10 +0000 Subject: [PATCH] Debug Info: use module flag to set up Dwarf version. Correctly handles ref_addr depending on the Dwarf version. Emit Dwarf with version from module flag. TODO: turn on/off features depending on the Dwarf version. llvm-svn: 185484 --- llvm/include/llvm/CodeGen/AsmPrinter.h | 2 ++ llvm/lib/CodeGen/AsmPrinter/DIE.cpp | 11 +++++++++ llvm/lib/CodeGen/AsmPrinter/DIE.h | 6 ++++- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 28 ++++++++++++++++++---- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 5 ++++ llvm/test/DebugInfo/version.ll | 27 +++++++++++++++++++++ 6 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 llvm/test/DebugInfo/version.ll diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h index c51a7f3e1a7f..677331b3bae4 100644 --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -121,6 +121,8 @@ namespace llvm { public: virtual ~AsmPrinter(); + const DwarfDebug *getDwarfDebug() const { return DD; } + /// isVerbose - Return true if assembly output should contain comments. /// bool isVerbose() const { return VerboseAsm; } diff --git a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp index 4b6698e374ea..d6caef7e5b85 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "DIE.h" +#include "DwarfDebug.h" #include "llvm/ADT/Twine.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/IR/DataLayout.h" @@ -331,6 +332,16 @@ void DIEEntry::EmitValue(AsmPrinter *AP, unsigned Form) const { AP->EmitInt32(Entry->getOffset()); } +unsigned DIEEntry::getRefAddrSize(AsmPrinter *AP) { + // DWARF4: References that use the attribute form DW_FORM_ref_addr are + // specified to be four bytes in the DWARF 32-bit format and eight bytes + // in the DWARF 64-bit format, while DWARF Version 2 specifies that such + // references have the same size as an address on the target system. + if (AP->getDwarfDebug()->getDwarfVersion() == 2) + return AP->getDataLayout().getPointerSize(); + return sizeof(int32_t); +} + #ifndef NDEBUG void DIEEntry::print(raw_ostream &O) const { O << format("Die: 0x%lx", (long)(intptr_t)Entry); diff --git a/llvm/lib/CodeGen/AsmPrinter/DIE.h b/llvm/lib/CodeGen/AsmPrinter/DIE.h index 412c09c6c8e5..3b04e206254b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DIE.h +++ b/llvm/lib/CodeGen/AsmPrinter/DIE.h @@ -365,9 +365,13 @@ namespace llvm { /// SizeOf - Determine size of debug information entry in bytes. /// virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const { - return sizeof(int32_t); + return Form == dwarf::DW_FORM_ref_addr ? getRefAddrSize(AP) : + sizeof(int32_t); } + /// Returns size of a ref_addr entry. + static unsigned getRefAddrSize(AsmPrinter *AP); + // Implement isa/cast/dyncast. static bool classof(const DIEValue *E) { return E->getType() == isEntry; } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 7e6336efeca5..cc5997d018f6 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -162,6 +162,21 @@ DIType DbgVariable::getType() const { } // end llvm namespace +/// Return Dwarf Version by checking module flags. +static unsigned getDwarfVersionFromModule(const Module *M) { + SmallVector ModuleFlags; + M->getModuleFlagsMetadata(ModuleFlags); + for (unsigned I = 0, E = ModuleFlags.size(); I < E; ++I) { + const Module::ModuleFlagEntry &MFE = ModuleFlags[I]; + StringRef Key = MFE.Key->getString(); + Value *Val = MFE.Val; + + if (Key == "Dwarf Version") + return cast(Val)->getZExtValue(); + } + return dwarf::DWARF_VERSION; +} + DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) : Asm(A), MMI(Asm->MMI), FirstCU(0), AbbreviationsSet(InitAbbreviationsSetSize), @@ -204,6 +219,8 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) else HasSplitDwarf = SplitDwarf == Enable ? true : false; + DwarfVersion = getDwarfVersionFromModule(MMI->getModule()); + { NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); beginModule(); @@ -1900,7 +1917,8 @@ void DwarfDebug::emitDIE(DIE *Die, std::vector *Abbrevs) { DwarfUnits &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; Addr += Holder.getCUOffset(Origin->getCompileUnit()); } - Asm->EmitInt32(Addr); + Asm->OutStreamer.EmitIntValue(Addr, + Form == dwarf::DW_FORM_ref_addr ? DIEEntry::getRefAddrSize(Asm) : 4); break; } case dwarf::DW_AT_ranges: { @@ -1984,7 +2002,7 @@ void DwarfUnits::emitUnits(DwarfDebug *DD, Asm->OutStreamer.AddComment("Length of Compilation Unit Info"); Asm->EmitInt32(ContentSize); Asm->OutStreamer.AddComment("DWARF version number"); - Asm->EmitInt16(dwarf::DWARF_VERSION); + Asm->EmitInt16(DD->getDwarfVersion()); Asm->OutStreamer.AddComment("Offset Into Abbrev. Section"); Asm->EmitSectionOffset(Asm->GetTempSymbol(ASection->getLabelBeginName()), ASectionSym); @@ -2225,7 +2243,7 @@ void DwarfDebug::emitDebugPubnames() { Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_begin", ID)); Asm->OutStreamer.AddComment("DWARF Version"); - Asm->EmitInt16(dwarf::DWARF_VERSION); + Asm->EmitInt16(DwarfVersion); Asm->OutStreamer.AddComment("Offset of Compilation Unit Info"); Asm->EmitSectionOffset(Asm->GetTempSymbol(ISec->getLabelBeginName(), ID), @@ -2272,7 +2290,7 @@ void DwarfDebug::emitDebugPubTypes() { TheCU->getUniqueID())); if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DWARF Version"); - Asm->EmitInt16(dwarf::DWARF_VERSION); + Asm->EmitInt16(DwarfVersion); Asm->OutStreamer.AddComment("Offset of Compilation Unit Info"); const MCSection *ISec = Asm->getObjFileLowering().getDwarfInfoSection(); @@ -2553,7 +2571,7 @@ void DwarfDebug::emitDebugInlineInfo() { Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_begin", 1)); Asm->OutStreamer.AddComment("Dwarf Version"); - Asm->EmitInt16(dwarf::DWARF_VERSION); + Asm->EmitInt16(DwarfVersion); Asm->OutStreamer.AddComment("Address Size (in bytes)"); Asm->EmitInt8(Asm->getDataLayout().getPointerSize()); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 60c6c3fa4c2c..1a036885b2ec 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -407,6 +407,8 @@ class DwarfDebug { bool HasDwarfAccelTables; bool HasSplitDwarf; + unsigned DwarfVersion; + // Separated Dwarf Variables // In general these will all be for bits that are left in the // original object file, rather than things that are meant @@ -650,6 +652,9 @@ public: /// \brief Returns whether or not to change the current debug info for the /// split dwarf proposal support. bool useSplitDwarf() { return HasSplitDwarf; } + + /// Returns the Dwarf Version. + unsigned getDwarfVersion() const { return DwarfVersion; } }; } // End of namespace llvm diff --git a/llvm/test/DebugInfo/version.ll b/llvm/test/DebugInfo/version.ll new file mode 100644 index 000000000000..5f963deb0f3b --- /dev/null +++ b/llvm/test/DebugInfo/version.ll @@ -0,0 +1,27 @@ +; RUN: llc -O0 < %s | FileCheck %s +; Make sure we are generating DWARF version 3 when module flag says so. +; CHECK: .short 3 ## DWARF version number + +define i32 @main() #0 { +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval + ret i32 0, !dbg !10 +} + +attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!9} + +!0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.4 (trunk 185475)", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] +!1 = metadata !{metadata !"CodeGen/dwarf-version.c", metadata !"test"} +!2 = metadata !{i32 0} +!3 = metadata !{metadata !4} +!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"main", metadata !"main", metadata !"", i32 6, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 ()* @main, null, null, metadata !2, i32 6} ; [ DW_TAG_subprogram ] [line 6] [def] [main] +!5 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] +!6 = metadata !{i32 786453, i32 0, i32 0, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!7 = metadata !{metadata !8} +!8 = 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] +!9 = metadata !{i32 2, metadata !"Dwarf Version", i32 3} +!10 = metadata !{i32 7, i32 0, metadata !4, null}