mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-28 20:41:07 +00:00
[cfi] Add flag to always generate .debug_frame
This adds a flag to LLVM and clang to always generate a .debug_frame section, even if other debug information is not being generated. In situations where .eh_frame would normally be emitted, both .debug_frame and .eh_frame will be used. Differential Revision: https://reviews.llvm.org/D67216
This commit is contained in:
parent
9c73925226
commit
92aa0c2dbc
@ -97,6 +97,8 @@ CODEGENOPT(CFProtectionBranch , 1, 0) ///< if -fcf-protection is
|
||||
CODEGENOPT(XRayInstrumentFunctions , 1, 0) ///< Set when -fxray-instrument is
|
||||
///< enabled.
|
||||
CODEGENOPT(StackSizeSection , 1, 0) ///< Set when -fstack-size-section is enabled.
|
||||
CODEGENOPT(ForceDwarfFrameSection , 1, 0) ///< Set when -fforce-dwarf-frame is
|
||||
///< enabled.
|
||||
|
||||
///< Set when -fxray-always-emit-customevents is enabled.
|
||||
CODEGENOPT(XRayAlwaysEmitCustomEvents , 1, 0)
|
||||
|
@ -1950,6 +1950,10 @@ def fdebug_prefix_map_EQ
|
||||
: Joined<["-"], "fdebug-prefix-map=">, Group<f_Group>,
|
||||
Flags<[CC1Option,CC1AsOption]>,
|
||||
HelpText<"remap file source paths in debug info">;
|
||||
def fforce_dwarf_frame : Flag<["-"], "fforce-dwarf-frame">, Group<f_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Always emit a debug frame section">;
|
||||
def fno_force_dwarf_frame : Flag<["-"], "fno-force-dwarf-frame">, Group<f_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Don't always emit a debug frame section">;
|
||||
def g_Flag : Flag<["-"], "g">, Group<g_Group>,
|
||||
HelpText<"Generate source-level debug information">;
|
||||
def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<gN_Group>,
|
||||
|
@ -485,6 +485,7 @@ static void initTargetOptions(llvm::TargetOptions &Options,
|
||||
Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection;
|
||||
Options.EmitAddrsig = CodeGenOpts.Addrsig;
|
||||
Options.EnableDebugEntryValues = CodeGenOpts.EnableDebugEntryValues;
|
||||
Options.ForceDwarfFrameSection = CodeGenOpts.ForceDwarfFrameSection;
|
||||
|
||||
Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;
|
||||
Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
|
||||
|
@ -3339,6 +3339,10 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
|
||||
CmdArgs.push_back("-generate-arange-section");
|
||||
}
|
||||
|
||||
if (Args.hasFlag(options::OPT_fforce_dwarf_frame,
|
||||
options::OPT_fno_force_dwarf_frame, false))
|
||||
CmdArgs.push_back("-fforce-dwarf-frame");
|
||||
|
||||
if (Args.hasFlag(options::OPT_fdebug_types_section,
|
||||
options::OPT_fno_debug_types_section, false)) {
|
||||
if (!T.isOSBinFormatELF()) {
|
||||
|
@ -769,6 +769,9 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
|
||||
Opts.DebugFwdTemplateParams = Args.hasArg(OPT_debug_forward_template_params);
|
||||
Opts.EmbedSource = Args.hasArg(OPT_gembed_source);
|
||||
|
||||
Opts.ForceDwarfFrameSection =
|
||||
Args.hasFlag(OPT_fforce_dwarf_frame, OPT_fno_force_dwarf_frame, false);
|
||||
|
||||
for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ))
|
||||
Opts.DebugPrefixMap.insert(StringRef(Arg).split('='));
|
||||
|
||||
|
6
clang/test/Driver/fforce-dwarf-frame.c
Normal file
6
clang/test/Driver/fforce-dwarf-frame.c
Normal file
@ -0,0 +1,6 @@
|
||||
// RUN: %clang -target arm -c -### %s -fforce-dwarf-frame 2>&1 | FileCheck --check-prefix=CHECK-ALWAYS %s
|
||||
// RUN: %clang -target arm -c -### %s -fno-force-dwarf-frame 2>&1 | FileCheck --check-prefix=CHECK-NO-ALWAYS %s
|
||||
// RUN: %clang -target arm -c -### %s 2>&1 | FileCheck --check-prefix=CHECK-NO-ALWAYS %s
|
||||
|
||||
// CHECK-ALWAYS: -fforce-dwarf-frame
|
||||
// CHECK-NO-ALWAYS-NOT: -fforce-dwarf-frame
|
@ -276,6 +276,11 @@ static cl::opt<bool>
|
||||
cl::desc("Emit debug info about parameter's entry values"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool>
|
||||
ForceDwarfFrameSection("force-dwarf-frame-section",
|
||||
cl::desc("Always emit a debug frame section."),
|
||||
cl::init(false));
|
||||
|
||||
// Common utility function tightly tied to the options listed here. Initializes
|
||||
// a TargetOptions object with CodeGen flags and returns it.
|
||||
static TargetOptions InitTargetOptionsFromCodeGenFlags() {
|
||||
@ -306,6 +311,7 @@ static TargetOptions InitTargetOptionsFromCodeGenFlags() {
|
||||
Options.EmitStackSizeSection = EnableStackSizeSection;
|
||||
Options.EmitAddrsig = EnableAddrsig;
|
||||
Options.EnableDebugEntryValues = EnableDebugEntryValues;
|
||||
Options.ForceDwarfFrameSection = ForceDwarfFrameSection;
|
||||
|
||||
Options.MCOptions = InitMCTargetOptionsFromFlags();
|
||||
|
||||
|
@ -560,6 +560,9 @@ public:
|
||||
}
|
||||
void setHasWinCFI(bool v) { HasWinCFI = v; }
|
||||
|
||||
/// True if this function needs frame moves for debug or exceptions.
|
||||
bool needsFrameMoves() const;
|
||||
|
||||
/// Get the function properties
|
||||
const MachineFunctionProperties &getProperties() const { return Properties; }
|
||||
MachineFunctionProperties &getProperties() { return Properties; }
|
||||
|
@ -119,7 +119,7 @@ namespace llvm {
|
||||
ExplicitEmulatedTLS(false), EnableIPRA(false),
|
||||
EmitStackSizeSection(false), EnableMachineOutliner(false),
|
||||
SupportsDefaultOutlining(false), EmitAddrsig(false),
|
||||
EnableDebugEntryValues(false) {}
|
||||
EnableDebugEntryValues(false), ForceDwarfFrameSection(false) {}
|
||||
|
||||
/// PrintMachineCode - This flag is enabled when the -print-machineinstrs
|
||||
/// option is specified on the command line, and should enable debugging
|
||||
@ -256,6 +256,9 @@ namespace llvm {
|
||||
/// Emit debug info about parameter's entry values.
|
||||
unsigned EnableDebugEntryValues : 1;
|
||||
|
||||
/// Emit DWARF debug frame section.
|
||||
unsigned ForceDwarfFrameSection : 1;
|
||||
|
||||
/// FloatABIType - This setting is set by -float-abi=xxx option is specfied
|
||||
/// on the command line. This setting may either be Default, Soft, or Hard.
|
||||
/// Default selects the target's default behavior. Soft selects the ABI for
|
||||
|
@ -935,7 +935,7 @@ AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() const {
|
||||
MF->getFunction().needsUnwindTableEntry())
|
||||
return CFI_M_EH;
|
||||
|
||||
if (MMI->hasDebugInfo())
|
||||
if (MMI->hasDebugInfo() || MF->getTarget().Options.ForceDwarfFrameSection)
|
||||
return CFI_M_Debug;
|
||||
|
||||
return CFI_M_None;
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/FormattedStream.h"
|
||||
#include "llvm/Target/TargetLoweringObjectFile.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
using namespace llvm;
|
||||
|
||||
@ -133,6 +134,8 @@ void DwarfCFIException::beginFragment(const MachineBasicBlock *MBB,
|
||||
if (!hasEmittedCFISections) {
|
||||
if (Asm->needsOnlyDebugCFIMoves())
|
||||
Asm->OutStreamer->EmitCFISections(false, true);
|
||||
else if (Asm->TM.Options.ForceDwarfFrameSection)
|
||||
Asm->OutStreamer->EmitCFISections(true, true);
|
||||
hasEmittedCFISections = true;
|
||||
}
|
||||
|
||||
|
@ -48,8 +48,7 @@ class CFIInstrInserter : public MachineFunctionPass {
|
||||
}
|
||||
|
||||
bool runOnMachineFunction(MachineFunction &MF) override {
|
||||
if (!MF.getMMI().hasDebugInfo() &&
|
||||
!MF.getFunction().needsUnwindTableEntry())
|
||||
if (!MF.needsFrameMoves())
|
||||
return false;
|
||||
|
||||
MBBVector.resize(MF.getNumBlockIDs());
|
||||
|
@ -520,6 +520,13 @@ void MachineFunction::print(raw_ostream &OS, const SlotIndexes *Indexes) const {
|
||||
OS << "\n# End machine code for function " << getName() << ".\n\n";
|
||||
}
|
||||
|
||||
/// True if this function needs frame moves for debug or exceptions.
|
||||
bool MachineFunction::needsFrameMoves() const {
|
||||
return getMMI().hasDebugInfo() ||
|
||||
getTarget().Options.ForceDwarfFrameSection ||
|
||||
F.needsUnwindTableEntry();
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
|
||||
template<>
|
||||
|
@ -844,8 +844,8 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
|
||||
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
|
||||
MachineModuleInfo &MMI = MF.getMMI();
|
||||
AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
|
||||
bool needsFrameMoves = (MMI.hasDebugInfo() || F.needsUnwindTableEntry()) &&
|
||||
!MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
|
||||
bool needsFrameMoves =
|
||||
MF.needsFrameMoves() && !MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
|
||||
bool HasFP = hasFP(MF);
|
||||
bool NeedsWinCFI = needsWinCFI(MF);
|
||||
bool HasWinCFI = false;
|
||||
|
@ -128,7 +128,7 @@ static void ReplaceFrameIndex(MachineBasicBlock::iterator II,
|
||||
ARCRegisterInfo::ARCRegisterInfo() : ARCGenRegisterInfo(ARC::BLINK) {}
|
||||
|
||||
bool ARCRegisterInfo::needsFrameMoves(const MachineFunction &MF) {
|
||||
return MF.getMMI().hasDebugInfo() || MF.getFunction().needsUnwindTableEntry();
|
||||
return MF.needsFrameMoves();
|
||||
}
|
||||
|
||||
const MCPhysReg *
|
||||
|
@ -223,8 +223,7 @@ namespace {
|
||||
|
||||
bool HexagonCallFrameInformation::runOnMachineFunction(MachineFunction &MF) {
|
||||
auto &HFI = *MF.getSubtarget<HexagonSubtarget>().getFrameLowering();
|
||||
bool NeedCFI = MF.getMMI().hasDebugInfo() ||
|
||||
MF.getFunction().needsUnwindTableEntry();
|
||||
bool NeedCFI = MF.needsFrameMoves();
|
||||
|
||||
if (!NeedCFI)
|
||||
return false;
|
||||
|
@ -782,8 +782,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF,
|
||||
MachineModuleInfo &MMI = MF.getMMI();
|
||||
const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
|
||||
DebugLoc dl;
|
||||
bool needsCFI = MMI.hasDebugInfo() ||
|
||||
MF.getFunction().needsUnwindTableEntry();
|
||||
bool needsCFI = MF.needsFrameMoves();
|
||||
|
||||
// Get processor type.
|
||||
bool isPPC64 = Subtarget.isPPC64();
|
||||
|
@ -993,8 +993,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
|
||||
bool NeedsWinFPO =
|
||||
!IsFunclet && STI.isTargetWin32() && MMI.getModule()->getCodeViewFlag();
|
||||
bool NeedsWinCFI = NeedsWin64CFI || NeedsWinFPO;
|
||||
bool NeedsDwarfCFI =
|
||||
!IsWin64Prologue && (MMI.hasDebugInfo() || Fn.needsUnwindTableEntry());
|
||||
bool NeedsDwarfCFI = !IsWin64Prologue && MF.needsFrameMoves();
|
||||
Register FramePtr = TRI->getFrameRegister(MF);
|
||||
const Register MachineFramePtr =
|
||||
STI.isTarget64BitILP32()
|
||||
@ -1614,10 +1613,9 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
|
||||
bool HasFP = hasFP(MF);
|
||||
uint64_t NumBytes = 0;
|
||||
|
||||
bool NeedsDwarfCFI =
|
||||
(!MF.getTarget().getTargetTriple().isOSDarwin() &&
|
||||
!MF.getTarget().getTargetTriple().isOSWindows()) &&
|
||||
(MF.getMMI().hasDebugInfo() || MF.getFunction().needsUnwindTableEntry());
|
||||
bool NeedsDwarfCFI = (!MF.getTarget().getTargetTriple().isOSDarwin() &&
|
||||
!MF.getTarget().getTargetTriple().isOSWindows()) &&
|
||||
MF.needsFrameMoves();
|
||||
|
||||
if (IsFunclet) {
|
||||
assert(HasFP && "EH funclets without FP not yet implemented");
|
||||
@ -2812,11 +2810,9 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
|
||||
unsigned StackAlign = getStackAlignment();
|
||||
Amount = alignTo(Amount, StackAlign);
|
||||
|
||||
MachineModuleInfo &MMI = MF.getMMI();
|
||||
const Function &F = MF.getFunction();
|
||||
bool WindowsCFI = MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
|
||||
bool DwarfCFI = !WindowsCFI &&
|
||||
(MMI.hasDebugInfo() || F.needsUnwindTableEntry());
|
||||
bool DwarfCFI = !WindowsCFI && MF.needsFrameMoves();
|
||||
|
||||
// If we have any exception handlers in this function, and we adjust
|
||||
// the SP before calls, we may need to indicate this to the unwinder
|
||||
|
@ -3963,9 +3963,7 @@ static bool ExpandMOVImmSExti8(MachineInstrBuilder &MIB,
|
||||
MachineFunction &MF = *MBB.getParent();
|
||||
const X86FrameLowering *TFL = Subtarget.getFrameLowering();
|
||||
bool IsWin64Prologue = MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
|
||||
bool NeedsDwarfCFI =
|
||||
!IsWin64Prologue &&
|
||||
(MF.getMMI().hasDebugInfo() || MF.getFunction().needsUnwindTableEntry());
|
||||
bool NeedsDwarfCFI = !IsWin64Prologue && MF.needsFrameMoves();
|
||||
bool EmitCFI = !TFL->hasFP(MF) && NeedsDwarfCFI;
|
||||
if (EmitCFI) {
|
||||
TFL->BuildCFI(MBB, I, DL,
|
||||
|
@ -203,7 +203,7 @@ static void InsertSPConstInst(MachineBasicBlock::iterator II,
|
||||
}
|
||||
|
||||
bool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) {
|
||||
return MF.getMMI().hasDebugInfo() || MF.getFunction().needsUnwindTableEntry();
|
||||
return MF.needsFrameMoves();
|
||||
}
|
||||
|
||||
const MCPhysReg *
|
||||
|
38
llvm/test/CodeGen/ARM/dwarf-frame.ll
Normal file
38
llvm/test/CodeGen/ARM/dwarf-frame.ll
Normal file
@ -0,0 +1,38 @@
|
||||
; RUN: llc -mtriple armv7-unknown -frame-pointer=all -filetype=asm -o - %s | FileCheck %s --check-prefix=CHECK-NO-CFI
|
||||
; RUN: llc -mtriple armv7-unknown -frame-pointer=all -filetype=asm -force-dwarf-frame-section -o - %s | FileCheck %s --check-prefix=CHECK-ALWAYS-CFI
|
||||
|
||||
declare void @dummy_use(i32*, i32)
|
||||
|
||||
define void @test_basic() #0 {
|
||||
%mem = alloca i32, i32 10
|
||||
call void @dummy_use (i32* %mem, i32 10)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-NO-CFI-LABEL: test_basic:
|
||||
; CHECK-NO-CFI: .fnstart
|
||||
; CHECK-NO-CFI-NOT: .cfi_sections .debug_frame
|
||||
; CHECK-NO-CFI-NOT: .cfi_startproc
|
||||
; CHECK-NO-CFI: @ %bb.0:
|
||||
; CHECK-NO-CFI: push {r11, lr}
|
||||
; CHECK-NO-CFI-NOT: .cfi_def_cfa_offset 8
|
||||
; CHECK-NO-CFI-NOT: .cfi_offset lr, -4
|
||||
; CHECK-NO-CFI-NOT: .cfi_offset r11, -8
|
||||
; CHECK-NO-CFI: mov r11, sp
|
||||
; CHECK-NO-CFI-NOT: .cfi_def_cfa_register r11
|
||||
; CHECK-NO-CFI-NOT: .cfi_endproc
|
||||
; CHECK-NO-CFI: .fnend
|
||||
|
||||
; CHECK-ALWAYS-CFI-LABEL: test_basic:
|
||||
; CHECK-ALWAYS-CFI: .fnstart
|
||||
; CHECK-ALWAYS-CFI: .cfi_sections .debug_frame
|
||||
; CHECK-ALWAYS-CFI: .cfi_startproc
|
||||
; CHECK-ALWAYS-CFI: @ %bb.0:
|
||||
; CHECK-ALWAYS-CFI: push {r11, lr}
|
||||
; CHECK-ALWAYS-CFI: .cfi_def_cfa_offset 8
|
||||
; CHECK-ALWAYS-CFI: .cfi_offset lr, -4
|
||||
; CHECK-ALWAYS-CFI: .cfi_offset r11, -8
|
||||
; CHECK-ALWAYS-CFI: mov r11, sp
|
||||
; CHECK-ALWAYS-CFI: .cfi_def_cfa_register r11
|
||||
; CHECK-ALWAYS-CFI: .cfi_endproc
|
||||
; CHECK-ALWAYS-CFI: .fnend
|
Loading…
x
Reference in New Issue
Block a user