diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -185,6 +185,9 @@ /// The maximum version of dwarf that we should emit. uint16_t DwarfVersion = 4; + /// The format of dwarf that we emit. + dwarf::DwarfFormat DwarfFormat = dwarf::DWARF32; + /// Honor temporary labels, this is useful for debugging semantic /// differences between temporary and non-temporary labels (primarily on /// Darwin). @@ -694,10 +697,8 @@ void setDwarfDebugProducer(StringRef S) { DwarfDebugProducer = S; } StringRef getDwarfDebugProducer() { return DwarfDebugProducer; } - dwarf::DwarfFormat getDwarfFormat() const { - // TODO: Support DWARF64 - return dwarf::DWARF32; - } + void setDwarfFormat(dwarf::DwarfFormat f) { DwarfFormat = f; } + dwarf::DwarfFormat getDwarfFormat() const { return DwarfFormat; } void setDwarfVersion(uint16_t v) { DwarfVersion = v; } uint16_t getDwarfVersion() const { return DwarfVersion; } diff --git a/llvm/include/llvm/MC/MCTargetOptions.h b/llvm/include/llvm/MC/MCTargetOptions.h --- a/llvm/include/llvm/MC/MCTargetOptions.h +++ b/llvm/include/llvm/MC/MCTargetOptions.h @@ -53,6 +53,7 @@ /// Preserve Comments in Assembly. bool PreserveAsmComments : 1; + bool Dwarf64 : 1; int DwarfVersion = 0; std::string ABIName; diff --git a/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h b/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h --- a/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h +++ b/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h @@ -30,6 +30,8 @@ int getDwarfVersion(); +bool getDwarf64(); + bool getShowMCInst(); bool getFatalWarnings(); diff --git a/llvm/lib/MC/MCTargetOptions.cpp b/llvm/lib/MC/MCTargetOptions.cpp --- a/llvm/lib/MC/MCTargetOptions.cpp +++ b/llvm/lib/MC/MCTargetOptions.cpp @@ -16,7 +16,7 @@ MCNoWarn(false), MCNoDeprecatedWarn(false), MCSaveTempLabels(false), MCUseDwarfDirectory(false), MCIncrementalLinkerCompatible(false), ShowMCEncoding(false), ShowMCInst(false), AsmVerbose(false), - PreserveAsmComments(true) {} + PreserveAsmComments(true), Dwarf64(false) {} StringRef MCTargetOptions::getABIName() const { return ABIName; diff --git a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp --- a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp +++ b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp @@ -38,6 +38,7 @@ MCOPT_EXP(bool, RelaxAll) MCOPT(bool, IncrementalLinkerCompatible) MCOPT(int, DwarfVersion) +MCOPT(bool, Dwarf64) MCOPT(bool, ShowMCInst) MCOPT(bool, FatalWarnings) MCOPT(bool, NoWarn) @@ -66,6 +67,11 @@ cl::init(0)); MCBINDOPT(DwarfVersion); + static cl::opt Dwarf64( + "dwarf64", + cl::desc("Generate debugging info in the 64-bit DWARF format")); + MCBINDOPT(Dwarf64); + static cl::opt ShowMCInst( "asm-show-inst", cl::desc("Emit internal instruction representation to assembly file")); @@ -97,6 +103,7 @@ MCTargetOptions Options; Options.MCRelaxAll = getRelaxAll(); Options.MCIncrementalLinkerCompatible = getIncrementalLinkerCompatible(); + Options.Dwarf64 = getDwarf64(); Options.DwarfVersion = getDwarfVersion(); Options.ShowMCInst = getShowMCInst(); Options.ABIName = getABIName(); diff --git a/llvm/test/MC/COFF/dwarf64-err.s b/llvm/test/MC/COFF/dwarf64-err.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/COFF/dwarf64-err.s @@ -0,0 +1,3 @@ +# RUN: not llvm-mc -dwarf64 -triple x86_64-unknown-windows-gnu %s -o - 2>&1 | FileCheck %s + +# CHECK: the 64-bit DWARF format is not supported for x86_64-unknown-windows-gnu diff --git a/llvm/test/MC/ELF/dwarf64-err.s b/llvm/test/MC/ELF/dwarf64-err.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/ELF/dwarf64-err.s @@ -0,0 +1,5 @@ +# RUN: not llvm-mc -g -dwarf-version 2 -dwarf64 -triple x86_64 %s -o - 2>&1 | FileCheck --check-prefix=DWARF2 %s +# RUN: not llvm-mc -g -dwarf-version 5 -dwarf64 -triple i686 %s -o - 2>&1 | FileCheck --check-prefix=I686 %s + +# DWARF2: the 64-bit DWARF format is not supported for DWARF versions prior to 3 +# I686: the 64-bit DWARF format is only supported for 64-bit targets diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp --- a/llvm/tools/llvm-mc/llvm-mc.cpp +++ b/llvm/tools/llvm-mc/llvm-mc.cpp @@ -387,6 +387,31 @@ return 1; } Ctx.setDwarfVersion(DwarfVersion); + if (MCOptions.Dwarf64) { + // The 64-bit DWARF format was introduced in DWARFv3. + if (DwarfVersion < 3) { + errs() << ProgName + << ": the 64-bit DWARF format is not supported for DWARF versions " + "prior to 3\n"; + return 1; + } + // 32-bit targets don't support DWARF64, which requires 64-bit relocations. + if (MAI->getCodePointerSize() < 8) { + errs() << ProgName + << ": the 64-bit DWARF format is only supported for 64-bit " + "targets\n"; + return 1; + } + // If needsDwarfSectionOffsetDirective is true, we would eventually call + // MCStreamer::emitSymbolValue() with IsSectionRelative = true, but that + // is supported only for 4-byte long references. + if (MAI->needsDwarfSectionOffsetDirective()) { + errs() << ProgName << ": the 64-bit DWARF format is not supported for " + << TheTriple.normalize() << "\n"; + return 1; + } + Ctx.setDwarfFormat(dwarf::DWARF64); + } if (!DwarfDebugFlags.empty()) Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags)); if (!DwarfDebugProducer.empty())