public:
virtual ~AsmPrinter();
+ const DwarfDebug *getDwarfDebug() const { return DD; }
+
/// isVerbose - Return true if assembly output should contain comments.
///
bool isVerbose() const { return VerboseAsm; }
//===----------------------------------------------------------------------===//
#include "DIE.h"
+#include "DwarfDebug.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/IR/DataLayout.h"
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);
/// 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; }
} // 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),
else
HasSplitDwarf = SplitDwarf == Enable ? true : false;
+ DwarfVersion = getDwarfVersionFromModule(MMI->getModule());
+
{
NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
beginModule();
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: {
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);
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),
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();
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());
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
/// \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
--- /dev/null
+; 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}