[MC][re-land] Omit DWARF unwind info if compact unwind is present where eligible
This reverts commit d941d59783
.
Differential Revision: https://reviews.llvm.org/D122258
This commit is contained in:
parent
775a22e32a
commit
d4bcb45db7
|
@ -114,6 +114,10 @@ CODEGENOPT(StackSizeSection , 1, 0) ///< Set when -fstack-size-section is enabl
|
||||||
CODEGENOPT(ForceDwarfFrameSection , 1, 0) ///< Set when -fforce-dwarf-frame is
|
CODEGENOPT(ForceDwarfFrameSection , 1, 0) ///< Set when -fforce-dwarf-frame is
|
||||||
///< enabled.
|
///< enabled.
|
||||||
|
|
||||||
|
///< Set when -femit-dwarf-unwind is passed.
|
||||||
|
ENUM_CODEGENOPT(EmitDwarfUnwind, llvm::EmitDwarfUnwindType, 2,
|
||||||
|
llvm::EmitDwarfUnwindType::Default)
|
||||||
|
|
||||||
///< Set when -fxray-always-emit-customevents is enabled.
|
///< Set when -fxray-always-emit-customevents is enabled.
|
||||||
CODEGENOPT(XRayAlwaysEmitCustomEvents , 1, 0)
|
CODEGENOPT(XRayAlwaysEmitCustomEvents , 1, 0)
|
||||||
|
|
||||||
|
|
|
@ -3044,6 +3044,13 @@ def fmacro_prefix_map_EQ
|
||||||
defm force_dwarf_frame : BoolFOption<"force-dwarf-frame",
|
defm force_dwarf_frame : BoolFOption<"force-dwarf-frame",
|
||||||
CodeGenOpts<"ForceDwarfFrameSection">, DefaultFalse,
|
CodeGenOpts<"ForceDwarfFrameSection">, DefaultFalse,
|
||||||
PosFlag<SetTrue, [CC1Option], "Always emit a debug frame section">, NegFlag<SetFalse>>;
|
PosFlag<SetTrue, [CC1Option], "Always emit a debug frame section">, NegFlag<SetFalse>>;
|
||||||
|
def femit_dwarf_unwind_EQ : Joined<["-"], "femit-dwarf-unwind=">,
|
||||||
|
Group<f_Group>, Flags<[CC1Option, CC1AsOption]>,
|
||||||
|
HelpText<"When to emit DWARF unwind (EH frame) info">,
|
||||||
|
Values<"always,no-compact-unwind,default">,
|
||||||
|
NormalizedValues<["Always", "NoCompactUnwind", "Default"]>,
|
||||||
|
NormalizedValuesScope<"llvm::EmitDwarfUnwindType">,
|
||||||
|
MarshallingInfoEnum<CodeGenOpts<"EmitDwarfUnwind">, "Default">;
|
||||||
def g_Flag : Flag<["-"], "g">, Group<g_Group>,
|
def g_Flag : Flag<["-"], "g">, Group<g_Group>,
|
||||||
HelpText<"Generate source-level debug information">;
|
HelpText<"Generate source-level debug information">;
|
||||||
def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<gN_Group>,
|
def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<gN_Group>,
|
||||||
|
|
|
@ -453,6 +453,7 @@ static bool initTargetOptions(DiagnosticsEngine &Diags,
|
||||||
}
|
}
|
||||||
|
|
||||||
Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;
|
Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;
|
||||||
|
Options.MCOptions.EmitDwarfUnwind = CodeGenOpts.getEmitDwarfUnwind();
|
||||||
Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
|
Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
|
||||||
Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
|
Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
|
||||||
Options.MCOptions.MCUseDwarfDirectory =
|
Options.MCOptions.MCUseDwarfDirectory =
|
||||||
|
|
|
@ -2518,6 +2518,8 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
|
||||||
DefaultIncrementalLinkerCompatible))
|
DefaultIncrementalLinkerCompatible))
|
||||||
CmdArgs.push_back("-mincremental-linker-compatible");
|
CmdArgs.push_back("-mincremental-linker-compatible");
|
||||||
|
|
||||||
|
Args.AddLastArg(CmdArgs, options::OPT_femit_dwarf_unwind_EQ);
|
||||||
|
|
||||||
// If you add more args here, also add them to the block below that
|
// If you add more args here, also add them to the block below that
|
||||||
// starts with "// If CollectArgsForIntegratedAssembler() isn't called below".
|
// starts with "// If CollectArgsForIntegratedAssembler() isn't called below".
|
||||||
|
|
||||||
|
@ -4622,6 +4624,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||||
}
|
}
|
||||||
Args.ClaimAllArgs(options::OPT_Wa_COMMA);
|
Args.ClaimAllArgs(options::OPT_Wa_COMMA);
|
||||||
Args.ClaimAllArgs(options::OPT_Xassembler);
|
Args.ClaimAllArgs(options::OPT_Xassembler);
|
||||||
|
Args.ClaimAllArgs(options::OPT_femit_dwarf_unwind_EQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isa<AnalyzeJobAction>(JA)) {
|
if (isa<AnalyzeJobAction>(JA)) {
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
// REQUIRES: x86-registered-target
|
||||||
|
|
||||||
|
// RUN: rm -rf %t; mkdir %t
|
||||||
|
// RUN: %clang -target x86_64-apple-macos11.0 -c %s -o %t/x86_64.o
|
||||||
|
// RUN: %clang -target x86_64-apple-macos11.0 -femit-dwarf-unwind=no-compact-unwind -c %s -o %t/x86_64-no-dwarf.o
|
||||||
|
// RUN: llvm-objdump --macho --dwarf=frames %t/x86_64.o | FileCheck %s --check-prefix=WITH-FDE
|
||||||
|
// RUN: llvm-objdump --macho --dwarf=frames %t/x86_64-no-dwarf.o | FileCheck %s --check-prefix=NO-FDE
|
||||||
|
|
||||||
|
// WITH-FDE: FDE
|
||||||
|
// NO-FDE-NOT: FDE
|
||||||
|
|
||||||
|
int foo() {
|
||||||
|
return 1;
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
// REQUIRES: x86-registered-target
|
||||||
|
|
||||||
|
// RUN: rm -rf %t; mkdir %t
|
||||||
|
// RUN: %clang -target x86_64-apple-macos11.0 -c %s -o %t/x86_64.o
|
||||||
|
// RUN: %clang -target x86_64-apple-macos11.0 -femit-dwarf-unwind=no-compact-unwind -c %s -o %t/x86_64-no-dwarf.o
|
||||||
|
// RUN: llvm-objdump --macho --dwarf=frames %t/x86_64.o | FileCheck %s --check-prefix=WITH-FDE
|
||||||
|
// RUN: llvm-objdump --macho --dwarf=frames %t/x86_64-no-dwarf.o | FileCheck %s --check-prefix=NO-FDE
|
||||||
|
|
||||||
|
// WITH-FDE: FDE
|
||||||
|
// NO-FDE-NOT: FDE
|
||||||
|
|
||||||
|
.text
|
||||||
|
_foo:
|
||||||
|
.cfi_startproc
|
||||||
|
.cfi_def_cfa_offset 8
|
||||||
|
ret
|
||||||
|
.cfi_endproc
|
|
@ -137,6 +137,9 @@ struct AssemblerInvocation {
|
||||||
unsigned IncrementalLinkerCompatible : 1;
|
unsigned IncrementalLinkerCompatible : 1;
|
||||||
unsigned EmbedBitcode : 1;
|
unsigned EmbedBitcode : 1;
|
||||||
|
|
||||||
|
/// Whether to emit DWARF unwind info.
|
||||||
|
EmitDwarfUnwindType EmitDwarfUnwind;
|
||||||
|
|
||||||
/// The name of the relocation model to use.
|
/// The name of the relocation model to use.
|
||||||
std::string RelocationModel;
|
std::string RelocationModel;
|
||||||
|
|
||||||
|
@ -317,6 +320,14 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
|
||||||
.Default(0);
|
.Default(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (auto *A = Args.getLastArg(OPT_femit_dwarf_unwind_EQ)) {
|
||||||
|
Opts.EmitDwarfUnwind =
|
||||||
|
llvm::StringSwitch<EmitDwarfUnwindType>(A->getValue())
|
||||||
|
.Case("always", EmitDwarfUnwindType::Always)
|
||||||
|
.Case("no-compact-unwind", EmitDwarfUnwindType::NoCompactUnwind)
|
||||||
|
.Case("default", EmitDwarfUnwindType::Default);
|
||||||
|
}
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,6 +378,8 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
|
||||||
assert(MRI && "Unable to create target register info!");
|
assert(MRI && "Unable to create target register info!");
|
||||||
|
|
||||||
MCTargetOptions MCOptions;
|
MCTargetOptions MCOptions;
|
||||||
|
MCOptions.EmitDwarfUnwind = Opts.EmitDwarfUnwind;
|
||||||
|
|
||||||
std::unique_ptr<MCAsmInfo> MAI(
|
std::unique_ptr<MCAsmInfo> MAI(
|
||||||
TheTarget->createMCAsmInfo(*MRI, Opts.Triple, MCOptions));
|
TheTarget->createMCAsmInfo(*MRI, Opts.Triple, MCOptions));
|
||||||
assert(MAI && "Unable to create target asm info!");
|
assert(MAI && "Unable to create target asm info!");
|
||||||
|
|
|
@ -67,6 +67,7 @@ template <typename T> class SmallVectorImpl;
|
||||||
class SMDiagnostic;
|
class SMDiagnostic;
|
||||||
class SMLoc;
|
class SMLoc;
|
||||||
class SourceMgr;
|
class SourceMgr;
|
||||||
|
enum class EmitDwarfUnwindType;
|
||||||
|
|
||||||
/// Context object for machine code objects. This class owns all of the
|
/// Context object for machine code objects. This class owns all of the
|
||||||
/// sections that it creates.
|
/// sections that it creates.
|
||||||
|
@ -772,6 +773,7 @@ public:
|
||||||
bool getGenDwarfForAssembly() { return GenDwarfForAssembly; }
|
bool getGenDwarfForAssembly() { return GenDwarfForAssembly; }
|
||||||
void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; }
|
void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; }
|
||||||
unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; }
|
unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; }
|
||||||
|
EmitDwarfUnwindType emitDwarfUnwindInfo() const;
|
||||||
|
|
||||||
void setGenDwarfFileNumber(unsigned FileNumber) {
|
void setGenDwarfFileNumber(unsigned FileNumber) {
|
||||||
GenDwarfFileNumber = FileNumber;
|
GenDwarfFileNumber = FileNumber;
|
||||||
|
|
|
@ -31,6 +31,12 @@ enum class DebugCompressionType {
|
||||||
Z, ///< zlib style complession
|
Z, ///< zlib style complession
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class EmitDwarfUnwindType {
|
||||||
|
Always, // Always emit dwarf unwind
|
||||||
|
NoCompactUnwind, // Only emit if compact unwind isn't available
|
||||||
|
Default, // Default behavior is based on the target
|
||||||
|
};
|
||||||
|
|
||||||
class StringRef;
|
class StringRef;
|
||||||
|
|
||||||
class MCTargetOptions {
|
class MCTargetOptions {
|
||||||
|
@ -56,6 +62,9 @@ public:
|
||||||
bool PreserveAsmComments : 1;
|
bool PreserveAsmComments : 1;
|
||||||
|
|
||||||
bool Dwarf64 : 1;
|
bool Dwarf64 : 1;
|
||||||
|
|
||||||
|
EmitDwarfUnwindType EmitDwarfUnwind;
|
||||||
|
|
||||||
int DwarfVersion = 0;
|
int DwarfVersion = 0;
|
||||||
|
|
||||||
enum DwarfDirectory {
|
enum DwarfDirectory {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class MCTargetOptions;
|
class MCTargetOptions;
|
||||||
|
enum class EmitDwarfUnwindType;
|
||||||
|
|
||||||
namespace mc {
|
namespace mc {
|
||||||
|
|
||||||
|
@ -32,6 +33,8 @@ int getDwarfVersion();
|
||||||
|
|
||||||
bool getDwarf64();
|
bool getDwarf64();
|
||||||
|
|
||||||
|
EmitDwarfUnwindType getEmitDwarfUnwind();
|
||||||
|
|
||||||
bool getShowMCInst();
|
bool getShowMCInst();
|
||||||
|
|
||||||
bool getFatalWarnings();
|
bool getFatalWarnings();
|
||||||
|
|
|
@ -264,6 +264,9 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx,
|
||||||
"Cannot emit MC with limited codegen pipeline");
|
"Cannot emit MC with limited codegen pipeline");
|
||||||
|
|
||||||
Ctx = &MMIWP->getMMI().getContext();
|
Ctx = &MMIWP->getMMI().getContext();
|
||||||
|
// libunwind is unable to load compact unwind dynamically, so we must generate
|
||||||
|
// DWARF unwind info for the JIT.
|
||||||
|
Options.MCOptions.EmitDwarfUnwind = EmitDwarfUnwindType::Always;
|
||||||
if (Options.MCOptions.MCSaveTempLabels)
|
if (Options.MCOptions.MCSaveTempLabels)
|
||||||
Ctx->setAllowTemporaryLabels(false);
|
Ctx->setAllowTemporaryLabels(false);
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI)
|
||||||
: TM(std::move(MMI.TM)),
|
: TM(std::move(MMI.TM)),
|
||||||
Context(MMI.TM.getTargetTriple(), MMI.TM.getMCAsmInfo(),
|
Context(MMI.TM.getTargetTriple(), MMI.TM.getMCAsmInfo(),
|
||||||
MMI.TM.getMCRegisterInfo(), MMI.TM.getMCSubtargetInfo(), nullptr,
|
MMI.TM.getMCRegisterInfo(), MMI.TM.getMCSubtargetInfo(), nullptr,
|
||||||
nullptr, false),
|
&MMI.TM.Options.MCOptions, false),
|
||||||
MachineFunctions(std::move(MMI.MachineFunctions)) {
|
MachineFunctions(std::move(MMI.MachineFunctions)) {
|
||||||
Context.setObjectFileInfo(MMI.TM.getObjFileLowering());
|
Context.setObjectFileInfo(MMI.TM.getObjFileLowering());
|
||||||
ObjFileMMI = MMI.ObjFileMMI;
|
ObjFileMMI = MMI.ObjFileMMI;
|
||||||
|
@ -72,7 +72,7 @@ MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI)
|
||||||
MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM)
|
MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM)
|
||||||
: TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(),
|
: TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(),
|
||||||
TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(),
|
TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(),
|
||||||
nullptr, nullptr, false) {
|
nullptr, &TM->Options.MCOptions, false) {
|
||||||
Context.setObjectFileInfo(TM->getObjFileLowering());
|
Context.setObjectFileInfo(TM->getObjFileLowering());
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM,
|
||||||
MCContext *ExtContext)
|
MCContext *ExtContext)
|
||||||
: TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(),
|
: TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(),
|
||||||
TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(),
|
TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(),
|
||||||
nullptr, nullptr, false),
|
nullptr, &TM->Options.MCOptions, false),
|
||||||
ExternalContext(ExtContext) {
|
ExternalContext(ExtContext) {
|
||||||
Context.setObjectFileInfo(TM->getObjFileLowering());
|
Context.setObjectFileInfo(TM->getObjFileLowering());
|
||||||
initialize();
|
initialize();
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "llvm/IR/LegacyPassManager.h"
|
#include "llvm/IR/LegacyPassManager.h"
|
||||||
#include "llvm/IR/Mangler.h"
|
#include "llvm/IR/Mangler.h"
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
|
#include "llvm/MC/MCContext.h"
|
||||||
#include "llvm/Object/Archive.h"
|
#include "llvm/Object/Archive.h"
|
||||||
#include "llvm/Object/ObjectFile.h"
|
#include "llvm/Object/ObjectFile.h"
|
||||||
#include "llvm/Support/DynamicLibrary.h"
|
#include "llvm/Support/DynamicLibrary.h"
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "llvm/ExecutionEngine/ObjectCache.h"
|
#include "llvm/ExecutionEngine/ObjectCache.h"
|
||||||
#include "llvm/IR/LegacyPassManager.h"
|
#include "llvm/IR/LegacyPassManager.h"
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
|
#include "llvm/MC/MCContext.h"
|
||||||
#include "llvm/Object/ObjectFile.h"
|
#include "llvm/Object/ObjectFile.h"
|
||||||
#include "llvm/Support/Error.h"
|
#include "llvm/Support/Error.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
|
|
|
@ -95,18 +95,16 @@ void RTDyldMemoryManager::registerEHFramesInProcess(uint8_t *Addr,
|
||||||
// and projects/libunwind/src/UnwindLevel1-gcc-ext.c.
|
// and projects/libunwind/src/UnwindLevel1-gcc-ext.c.
|
||||||
const char *P = (const char *)Addr;
|
const char *P = (const char *)Addr;
|
||||||
const char *End = P + Size;
|
const char *End = P + Size;
|
||||||
do {
|
while (P != End)
|
||||||
P = processFDE(P, false);
|
P = processFDE(P, false);
|
||||||
} while(P != End);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTDyldMemoryManager::deregisterEHFramesInProcess(uint8_t *Addr,
|
void RTDyldMemoryManager::deregisterEHFramesInProcess(uint8_t *Addr,
|
||||||
size_t Size) {
|
size_t Size) {
|
||||||
const char *P = (const char *)Addr;
|
const char *P = (const char *)Addr;
|
||||||
const char *End = P + Size;
|
const char *End = P + Size;
|
||||||
do {
|
while (P != End)
|
||||||
P = processFDE(P, true);
|
P = processFDE(P, true);
|
||||||
} while(P != End);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -877,6 +877,12 @@ void MCContext::RemapDebugPaths() {
|
||||||
// Dwarf Management
|
// Dwarf Management
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
EmitDwarfUnwindType MCContext::emitDwarfUnwindInfo() const {
|
||||||
|
if (!TargetOptions)
|
||||||
|
return EmitDwarfUnwindType::Default;
|
||||||
|
return TargetOptions->EmitDwarfUnwind;
|
||||||
|
}
|
||||||
|
|
||||||
void MCContext::setGenDwarfRootFile(StringRef InputFileName, StringRef Buffer) {
|
void MCContext::setGenDwarfRootFile(StringRef InputFileName, StringRef Buffer) {
|
||||||
// MCDwarf needs the root file as well as the compilation directory.
|
// MCDwarf needs the root file as well as the compilation directory.
|
||||||
// If we find a '.file 0' directive that will supersede these values.
|
// If we find a '.file 0' directive that will supersede these values.
|
||||||
|
|
|
@ -1842,8 +1842,6 @@ template <> struct DenseMapInfo<CIEKey> {
|
||||||
|
|
||||||
void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB,
|
void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB,
|
||||||
bool IsEH) {
|
bool IsEH) {
|
||||||
Streamer.generateCompactUnwindEncodings(MAB);
|
|
||||||
|
|
||||||
MCContext &Context = Streamer.getContext();
|
MCContext &Context = Streamer.getContext();
|
||||||
const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
|
const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
|
||||||
const MCAsmInfo *AsmInfo = Context.getAsmInfo();
|
const MCAsmInfo *AsmInfo = Context.getAsmInfo();
|
||||||
|
@ -1853,6 +1851,7 @@ void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB,
|
||||||
// Emit the compact unwind info if available.
|
// Emit the compact unwind info if available.
|
||||||
bool NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame();
|
bool NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame();
|
||||||
if (IsEH && MOFI->getCompactUnwindSection()) {
|
if (IsEH && MOFI->getCompactUnwindSection()) {
|
||||||
|
Streamer.generateCompactUnwindEncodings(MAB);
|
||||||
bool SectionEmitted = false;
|
bool SectionEmitted = false;
|
||||||
for (const MCDwarfFrameInfo &Frame : FrameArray) {
|
for (const MCDwarfFrameInfo &Frame : FrameArray) {
|
||||||
if (Frame.CompactUnwindEncoding == 0) continue;
|
if (Frame.CompactUnwindEncoding == 0) continue;
|
||||||
|
|
|
@ -64,8 +64,18 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(const Triple &T) {
|
||||||
(T.getArch() == Triple::aarch64 || T.getArch() == Triple::aarch64_32))
|
(T.getArch() == Triple::aarch64 || T.getArch() == Triple::aarch64_32))
|
||||||
SupportsCompactUnwindWithoutEHFrame = true;
|
SupportsCompactUnwindWithoutEHFrame = true;
|
||||||
|
|
||||||
if (T.isWatchABI())
|
switch (Ctx->emitDwarfUnwindInfo()) {
|
||||||
|
case EmitDwarfUnwindType::Always:
|
||||||
|
OmitDwarfIfHaveCompactUnwind = false;
|
||||||
|
break;
|
||||||
|
case EmitDwarfUnwindType::NoCompactUnwind:
|
||||||
OmitDwarfIfHaveCompactUnwind = true;
|
OmitDwarfIfHaveCompactUnwind = true;
|
||||||
|
break;
|
||||||
|
case EmitDwarfUnwindType::Default:
|
||||||
|
OmitDwarfIfHaveCompactUnwind =
|
||||||
|
T.isWatchABI() || SupportsCompactUnwindWithoutEHFrame;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
FDECFIEncoding = dwarf::DW_EH_PE_pcrel;
|
FDECFIEncoding = dwarf::DW_EH_PE_pcrel;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ MCTargetOptions::MCTargetOptions()
|
||||||
MCSaveTempLabels(false), MCIncrementalLinkerCompatible(false),
|
MCSaveTempLabels(false), MCIncrementalLinkerCompatible(false),
|
||||||
ShowMCEncoding(false), ShowMCInst(false), AsmVerbose(false),
|
ShowMCEncoding(false), ShowMCInst(false), AsmVerbose(false),
|
||||||
PreserveAsmComments(true), Dwarf64(false),
|
PreserveAsmComments(true), Dwarf64(false),
|
||||||
|
EmitDwarfUnwind(EmitDwarfUnwindType::Default),
|
||||||
MCUseDwarfDirectory(DefaultDwarfDirectory) {}
|
MCUseDwarfDirectory(DefaultDwarfDirectory) {}
|
||||||
|
|
||||||
StringRef MCTargetOptions::getABIName() const {
|
StringRef MCTargetOptions::getABIName() const {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//===-- MCTargetOptionsCommandFlags.cpp --------------------------*- C++
|
//===-- MCTargetOptionsCommandFlags.cpp -----------------------*- C++ //-*-===//
|
||||||
//-*-===//
|
|
||||||
//
|
//
|
||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
// See https://llvm.org/LICENSE.txt for license information.
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
@ -39,6 +38,7 @@ MCOPT_EXP(bool, RelaxAll)
|
||||||
MCOPT(bool, IncrementalLinkerCompatible)
|
MCOPT(bool, IncrementalLinkerCompatible)
|
||||||
MCOPT(int, DwarfVersion)
|
MCOPT(int, DwarfVersion)
|
||||||
MCOPT(bool, Dwarf64)
|
MCOPT(bool, Dwarf64)
|
||||||
|
MCOPT(EmitDwarfUnwindType, EmitDwarfUnwind)
|
||||||
MCOPT(bool, ShowMCInst)
|
MCOPT(bool, ShowMCInst)
|
||||||
MCOPT(bool, FatalWarnings)
|
MCOPT(bool, FatalWarnings)
|
||||||
MCOPT(bool, NoWarn)
|
MCOPT(bool, NoWarn)
|
||||||
|
@ -73,6 +73,19 @@ llvm::mc::RegisterMCTargetOptionsFlags::RegisterMCTargetOptionsFlags() {
|
||||||
cl::desc("Generate debugging info in the 64-bit DWARF format"));
|
cl::desc("Generate debugging info in the 64-bit DWARF format"));
|
||||||
MCBINDOPT(Dwarf64);
|
MCBINDOPT(Dwarf64);
|
||||||
|
|
||||||
|
static cl::opt<EmitDwarfUnwindType> EmitDwarfUnwind(
|
||||||
|
"emit-dwarf-unwind", cl::desc("Whether to emit DWARF EH frame entries."),
|
||||||
|
cl::init(EmitDwarfUnwindType::Default),
|
||||||
|
cl::values(clEnumValN(EmitDwarfUnwindType::Always, "always",
|
||||||
|
"Always emit EH frame entries"),
|
||||||
|
clEnumValN(EmitDwarfUnwindType::NoCompactUnwind,
|
||||||
|
"no-compact-unwind",
|
||||||
|
"Only emit EH frame entries when compact unwind is "
|
||||||
|
"not available"),
|
||||||
|
clEnumValN(EmitDwarfUnwindType::Default, "default",
|
||||||
|
"Use target platform default")));
|
||||||
|
MCBINDOPT(EmitDwarfUnwind);
|
||||||
|
|
||||||
static cl::opt<bool> ShowMCInst(
|
static cl::opt<bool> ShowMCInst(
|
||||||
"asm-show-inst",
|
"asm-show-inst",
|
||||||
cl::desc("Emit internal instruction representation to assembly file"));
|
cl::desc("Emit internal instruction representation to assembly file"));
|
||||||
|
@ -116,5 +129,7 @@ MCTargetOptions llvm::mc::InitMCTargetOptionsFromFlags() {
|
||||||
Options.MCNoWarn = getNoWarn();
|
Options.MCNoWarn = getNoWarn();
|
||||||
Options.MCNoDeprecatedWarn = getNoDeprecatedWarn();
|
Options.MCNoDeprecatedWarn = getNoDeprecatedWarn();
|
||||||
Options.MCNoTypeCheck = getNoTypeCheck();
|
Options.MCNoTypeCheck = getNoTypeCheck();
|
||||||
|
Options.EmitDwarfUnwind = getEmitDwarfUnwind();
|
||||||
|
|
||||||
return Options;
|
return Options;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1377,7 +1377,7 @@ public:
|
||||||
default:
|
default:
|
||||||
// Any other CFI directives indicate a frame that we aren't prepared
|
// Any other CFI directives indicate a frame that we aren't prepared
|
||||||
// to represent via compact unwind, so just bail out.
|
// to represent via compact unwind, so just bail out.
|
||||||
return 0;
|
return CU::UNWIND_MODE_DWARF;
|
||||||
case MCCFIInstruction::OpDefCfaRegister: {
|
case MCCFIInstruction::OpDefCfaRegister: {
|
||||||
// Defines a frame pointer. E.g.
|
// Defines a frame pointer. E.g.
|
||||||
//
|
//
|
||||||
|
@ -1391,7 +1391,7 @@ public:
|
||||||
// generate a compact unwinding representation, so bail out.
|
// generate a compact unwinding representation, so bail out.
|
||||||
if (*MRI.getLLVMRegNum(Inst.getRegister(), true) !=
|
if (*MRI.getLLVMRegNum(Inst.getRegister(), true) !=
|
||||||
(Is64Bit ? X86::RBP : X86::EBP))
|
(Is64Bit ? X86::RBP : X86::EBP))
|
||||||
return 0;
|
return CU::UNWIND_MODE_DWARF;
|
||||||
|
|
||||||
// Reset the counts.
|
// Reset the counts.
|
||||||
memset(SavedRegs, 0, sizeof(SavedRegs));
|
memset(SavedRegs, 0, sizeof(SavedRegs));
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
// RUN: rm -rf %t; mkdir %t
|
||||||
|
// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o
|
||||||
|
// RUN: llvm-objdump --macho --dwarf=frames %t/x86_64.o | FileCheck %s --check-prefix TWO-FDES
|
||||||
|
// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o
|
||||||
|
// RUN: llvm-objdump --macho --dwarf=frames %t/arm64.o | FileCheck %s --check-prefix ONE-FDE
|
||||||
|
// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o
|
||||||
|
// RUN: llvm-objdump --macho --dwarf=frames %t/x86_64-no-dwarf.o | FileCheck %s --check-prefix ONE-FDE
|
||||||
|
// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o
|
||||||
|
// RUN: llvm-objdump --macho --dwarf=frames %t/arm64-dwarf.o | FileCheck %s --check-prefix TWO-FDES
|
||||||
|
|
||||||
|
// TWO-FDES: FDE
|
||||||
|
// TWO-FDES: FDE
|
||||||
|
|
||||||
|
// ONE-FDE-NOT: FDE
|
||||||
|
// ONE-FDE: FDE
|
||||||
|
// ONE-FDE-NOT: FDE
|
||||||
|
|
||||||
|
_main:
|
||||||
|
.cfi_startproc
|
||||||
|
.cfi_def_cfa_offset 16
|
||||||
|
ret
|
||||||
|
.cfi_endproc
|
||||||
|
|
||||||
|
_foo:
|
||||||
|
.cfi_startproc
|
||||||
|
.cfi_def_cfa_offset 16
|
||||||
|
/// This encodes DW_CFA_GNU_args_size which cannot be expressed using compact
|
||||||
|
/// unwind, so we must use DWARf unwind for this function.
|
||||||
|
.cfi_escape 0x2e, 0x10
|
||||||
|
ret
|
||||||
|
.cfi_endproc
|
||||||
|
|
||||||
|
.subsections_via_symbols
|
|
@ -0,0 +1,50 @@
|
||||||
|
// RUN: llvm-mc -triple x86_64-apple-macos10.6 -filetype=obj %s -o %t.o
|
||||||
|
// RUN: llvm-objdump --macho --unwind-info --dwarf=frames %t.o | FileCheck %s
|
||||||
|
|
||||||
|
/// For functions whose unwind info cannot be encoded with compact unwind, make
|
||||||
|
/// sure that we encode them using DWARF unwind, and make sure we emit a compact
|
||||||
|
/// unwind entry that indicates that a DWARF encoding is being used.
|
||||||
|
|
||||||
|
_f:
|
||||||
|
.cfi_startproc
|
||||||
|
## This encodes DW_CFA_GNU_args_size which cannot be expressed using compact
|
||||||
|
## unwind, so we must use DWARF unwind instead.
|
||||||
|
.cfi_escape 0x2e, 0x10
|
||||||
|
ret
|
||||||
|
.cfi_endproc
|
||||||
|
|
||||||
|
_g:
|
||||||
|
.cfi_startproc
|
||||||
|
## This encodes DW_CFA_GNU_args_size which cannot be expressed using compact
|
||||||
|
## unwind, so we must use DWARF unwind instead.
|
||||||
|
.cfi_escape 0x2e, 0x10
|
||||||
|
ret
|
||||||
|
.cfi_endproc
|
||||||
|
|
||||||
|
// CHECK: Contents of __compact_unwind section:
|
||||||
|
// CHECK: Entry at offset 0x0:
|
||||||
|
// CHECK: start: 0x[[#%x,F:]] _f
|
||||||
|
// CHECK: length: 0x1
|
||||||
|
// CHECK: compact encoding: 0x04000000
|
||||||
|
// CHECK: Entry at offset 0x20:
|
||||||
|
// CHECK: start: 0x[[#%x,G:]] _g
|
||||||
|
// CHECK: length: 0x1
|
||||||
|
// CHECK: compact encoding: 0x04000000
|
||||||
|
|
||||||
|
// CHECK: .eh_frame contents:
|
||||||
|
// CHECK: 00000000 00000014 00000000 CIE
|
||||||
|
// CHECK: Format: DWARF32
|
||||||
|
// CHECK: Version: 1
|
||||||
|
// CHECK: Augmentation: "zR"
|
||||||
|
// CHECK: Code alignment factor: 1
|
||||||
|
// CHECK: Data alignment factor: -8
|
||||||
|
// CHECK: Return address column: 16
|
||||||
|
// CHECK: Augmentation data: 10
|
||||||
|
|
||||||
|
// CHECK: FDE cie=00000000 pc=[[#%.8x,F]]...
|
||||||
|
// CHECK: Format: DWARF32
|
||||||
|
// CHECK: DW_CFA_GNU_args_size: +16
|
||||||
|
|
||||||
|
// CHECK: FDE cie=00000000 pc=[[#%.8x,G]]...
|
||||||
|
// CHECK: Format: DWARF32
|
||||||
|
// CHECK: DW_CFA_GNU_args_size: +16
|
Loading…
Reference in New Issue