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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185484 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp
index 4b6698e..d6caef7 100644
--- a/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/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 @@
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/lib/CodeGen/AsmPrinter/DIE.h b/lib/CodeGen/AsmPrinter/DIE.h
index 412c09c..3b04e20 100644
--- a/lib/CodeGen/AsmPrinter/DIE.h
+++ b/lib/CodeGen/AsmPrinter/DIE.h
@@ -365,9 +365,13 @@
/// 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/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 7e6336e..cc5997d 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -162,6 +162,21 @@
} // end llvm namespace
+/// Return Dwarf Version by checking module flags.
+static unsigned getDwarfVersionFromModule(const Module *M) {
+ SmallVector<Module::ModuleFlagEntry, 8> 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<ConstantInt>(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 @@
else
HasSplitDwarf = SplitDwarf == Enable ? true : false;
+ DwarfVersion = getDwarfVersionFromModule(MMI->getModule());
+
{
NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
beginModule();
@@ -1900,7 +1917,8 @@
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 @@
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 @@
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 @@
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 @@
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/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 60c6c3f..1a03688 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -407,6 +407,8 @@
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 @@
/// \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