Skip to content

Commit 92aa0c2

Browse files
committed
[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
1 parent 9c73925 commit 92aa0c2

File tree

21 files changed

+95
-24
lines changed

21 files changed

+95
-24
lines changed

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ CODEGENOPT(CFProtectionBranch , 1, 0) ///< if -fcf-protection is
9797
CODEGENOPT(XRayInstrumentFunctions , 1, 0) ///< Set when -fxray-instrument is
9898
///< enabled.
9999
CODEGENOPT(StackSizeSection , 1, 0) ///< Set when -fstack-size-section is enabled.
100+
CODEGENOPT(ForceDwarfFrameSection , 1, 0) ///< Set when -fforce-dwarf-frame is
101+
///< enabled.
100102

101103
///< Set when -fxray-always-emit-customevents is enabled.
102104
CODEGENOPT(XRayAlwaysEmitCustomEvents , 1, 0)

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1950,6 +1950,10 @@ def fdebug_prefix_map_EQ
19501950
: Joined<["-"], "fdebug-prefix-map=">, Group<f_Group>,
19511951
Flags<[CC1Option,CC1AsOption]>,
19521952
HelpText<"remap file source paths in debug info">;
1953+
def fforce_dwarf_frame : Flag<["-"], "fforce-dwarf-frame">, Group<f_Group>, Flags<[CC1Option]>,
1954+
HelpText<"Always emit a debug frame section">;
1955+
def fno_force_dwarf_frame : Flag<["-"], "fno-force-dwarf-frame">, Group<f_Group>, Flags<[CC1Option]>,
1956+
HelpText<"Don't always emit a debug frame section">;
19531957
def g_Flag : Flag<["-"], "g">, Group<g_Group>,
19541958
HelpText<"Generate source-level debug information">;
19551959
def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<gN_Group>,

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ static void initTargetOptions(llvm::TargetOptions &Options,
485485
Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection;
486486
Options.EmitAddrsig = CodeGenOpts.Addrsig;
487487
Options.EnableDebugEntryValues = CodeGenOpts.EnableDebugEntryValues;
488+
Options.ForceDwarfFrameSection = CodeGenOpts.ForceDwarfFrameSection;
488489

489490
Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;
490491
Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3339,6 +3339,10 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
33393339
CmdArgs.push_back("-generate-arange-section");
33403340
}
33413341

3342+
if (Args.hasFlag(options::OPT_fforce_dwarf_frame,
3343+
options::OPT_fno_force_dwarf_frame, false))
3344+
CmdArgs.push_back("-fforce-dwarf-frame");
3345+
33423346
if (Args.hasFlag(options::OPT_fdebug_types_section,
33433347
options::OPT_fno_debug_types_section, false)) {
33443348
if (!T.isOSBinFormatELF()) {

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,9 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
769769
Opts.DebugFwdTemplateParams = Args.hasArg(OPT_debug_forward_template_params);
770770
Opts.EmbedSource = Args.hasArg(OPT_gembed_source);
771771

772+
Opts.ForceDwarfFrameSection =
773+
Args.hasFlag(OPT_fforce_dwarf_frame, OPT_fno_force_dwarf_frame, false);
774+
772775
for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ))
773776
Opts.DebugPrefixMap.insert(StringRef(Arg).split('='));
774777

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: %clang -target arm -c -### %s -fforce-dwarf-frame 2>&1 | FileCheck --check-prefix=CHECK-ALWAYS %s
2+
// RUN: %clang -target arm -c -### %s -fno-force-dwarf-frame 2>&1 | FileCheck --check-prefix=CHECK-NO-ALWAYS %s
3+
// RUN: %clang -target arm -c -### %s 2>&1 | FileCheck --check-prefix=CHECK-NO-ALWAYS %s
4+
5+
// CHECK-ALWAYS: -fforce-dwarf-frame
6+
// CHECK-NO-ALWAYS-NOT: -fforce-dwarf-frame

llvm/include/llvm/CodeGen/CommandFlags.inc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,11 @@ static cl::opt<bool>
276276
cl::desc("Emit debug info about parameter's entry values"),
277277
cl::init(false));
278278

279+
static cl::opt<bool>
280+
ForceDwarfFrameSection("force-dwarf-frame-section",
281+
cl::desc("Always emit a debug frame section."),
282+
cl::init(false));
283+
279284
// Common utility function tightly tied to the options listed here. Initializes
280285
// a TargetOptions object with CodeGen flags and returns it.
281286
static TargetOptions InitTargetOptionsFromCodeGenFlags() {
@@ -306,6 +311,7 @@ static TargetOptions InitTargetOptionsFromCodeGenFlags() {
306311
Options.EmitStackSizeSection = EnableStackSizeSection;
307312
Options.EmitAddrsig = EnableAddrsig;
308313
Options.EnableDebugEntryValues = EnableDebugEntryValues;
314+
Options.ForceDwarfFrameSection = ForceDwarfFrameSection;
309315

310316
Options.MCOptions = InitMCTargetOptionsFromFlags();
311317

llvm/include/llvm/CodeGen/MachineFunction.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,9 @@ class MachineFunction {
560560
}
561561
void setHasWinCFI(bool v) { HasWinCFI = v; }
562562

563+
/// True if this function needs frame moves for debug or exceptions.
564+
bool needsFrameMoves() const;
565+
563566
/// Get the function properties
564567
const MachineFunctionProperties &getProperties() const { return Properties; }
565568
MachineFunctionProperties &getProperties() { return Properties; }

llvm/include/llvm/Target/TargetOptions.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ namespace llvm {
119119
ExplicitEmulatedTLS(false), EnableIPRA(false),
120120
EmitStackSizeSection(false), EnableMachineOutliner(false),
121121
SupportsDefaultOutlining(false), EmitAddrsig(false),
122-
EnableDebugEntryValues(false) {}
122+
EnableDebugEntryValues(false), ForceDwarfFrameSection(false) {}
123123

124124
/// PrintMachineCode - This flag is enabled when the -print-machineinstrs
125125
/// option is specified on the command line, and should enable debugging
@@ -256,6 +256,9 @@ namespace llvm {
256256
/// Emit debug info about parameter's entry values.
257257
unsigned EnableDebugEntryValues : 1;
258258

259+
/// Emit DWARF debug frame section.
260+
unsigned ForceDwarfFrameSection : 1;
261+
259262
/// FloatABIType - This setting is set by -float-abi=xxx option is specfied
260263
/// on the command line. This setting may either be Default, Soft, or Hard.
261264
/// Default selects the target's default behavior. Soft selects the ABI for

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -935,7 +935,7 @@ AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() const {
935935
MF->getFunction().needsUnwindTableEntry())
936936
return CFI_M_EH;
937937

938-
if (MMI->hasDebugInfo())
938+
if (MMI->hasDebugInfo() || MF->getTarget().Options.ForceDwarfFrameSection)
939939
return CFI_M_Debug;
940940

941941
return CFI_M_None;

llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "llvm/Support/ErrorHandling.h"
3030
#include "llvm/Support/FormattedStream.h"
3131
#include "llvm/Target/TargetLoweringObjectFile.h"
32+
#include "llvm/Target/TargetMachine.h"
3233
#include "llvm/Target/TargetOptions.h"
3334
using namespace llvm;
3435

@@ -133,6 +134,8 @@ void DwarfCFIException::beginFragment(const MachineBasicBlock *MBB,
133134
if (!hasEmittedCFISections) {
134135
if (Asm->needsOnlyDebugCFIMoves())
135136
Asm->OutStreamer->EmitCFISections(false, true);
137+
else if (Asm->TM.Options.ForceDwarfFrameSection)
138+
Asm->OutStreamer->EmitCFISections(true, true);
136139
hasEmittedCFISections = true;
137140
}
138141

llvm/lib/CodeGen/CFIInstrInserter.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ class CFIInstrInserter : public MachineFunctionPass {
4848
}
4949

5050
bool runOnMachineFunction(MachineFunction &MF) override {
51-
if (!MF.getMMI().hasDebugInfo() &&
52-
!MF.getFunction().needsUnwindTableEntry())
51+
if (!MF.needsFrameMoves())
5352
return false;
5453

5554
MBBVector.resize(MF.getNumBlockIDs());

llvm/lib/CodeGen/MachineFunction.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,13 @@ void MachineFunction::print(raw_ostream &OS, const SlotIndexes *Indexes) const {
520520
OS << "\n# End machine code for function " << getName() << ".\n\n";
521521
}
522522

523+
/// True if this function needs frame moves for debug or exceptions.
524+
bool MachineFunction::needsFrameMoves() const {
525+
return getMMI().hasDebugInfo() ||
526+
getTarget().Options.ForceDwarfFrameSection ||
527+
F.needsUnwindTableEntry();
528+
}
529+
523530
namespace llvm {
524531

525532
template<>

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -844,8 +844,8 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
844844
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
845845
MachineModuleInfo &MMI = MF.getMMI();
846846
AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
847-
bool needsFrameMoves = (MMI.hasDebugInfo() || F.needsUnwindTableEntry()) &&
848-
!MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
847+
bool needsFrameMoves =
848+
MF.needsFrameMoves() && !MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
849849
bool HasFP = hasFP(MF);
850850
bool NeedsWinCFI = needsWinCFI(MF);
851851
bool HasWinCFI = false;

llvm/lib/Target/ARC/ARCRegisterInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ static void ReplaceFrameIndex(MachineBasicBlock::iterator II,
128128
ARCRegisterInfo::ARCRegisterInfo() : ARCGenRegisterInfo(ARC::BLINK) {}
129129

130130
bool ARCRegisterInfo::needsFrameMoves(const MachineFunction &MF) {
131-
return MF.getMMI().hasDebugInfo() || MF.getFunction().needsUnwindTableEntry();
131+
return MF.needsFrameMoves();
132132
}
133133

134134
const MCPhysReg *

llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,7 @@ namespace {
223223

224224
bool HexagonCallFrameInformation::runOnMachineFunction(MachineFunction &MF) {
225225
auto &HFI = *MF.getSubtarget<HexagonSubtarget>().getFrameLowering();
226-
bool NeedCFI = MF.getMMI().hasDebugInfo() ||
227-
MF.getFunction().needsUnwindTableEntry();
226+
bool NeedCFI = MF.needsFrameMoves();
228227

229228
if (!NeedCFI)
230229
return false;

llvm/lib/Target/PowerPC/PPCFrameLowering.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -782,8 +782,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF,
782782
MachineModuleInfo &MMI = MF.getMMI();
783783
const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
784784
DebugLoc dl;
785-
bool needsCFI = MMI.hasDebugInfo() ||
786-
MF.getFunction().needsUnwindTableEntry();
785+
bool needsCFI = MF.needsFrameMoves();
787786

788787
// Get processor type.
789788
bool isPPC64 = Subtarget.isPPC64();

llvm/lib/Target/X86/X86FrameLowering.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -993,8 +993,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
993993
bool NeedsWinFPO =
994994
!IsFunclet && STI.isTargetWin32() && MMI.getModule()->getCodeViewFlag();
995995
bool NeedsWinCFI = NeedsWin64CFI || NeedsWinFPO;
996-
bool NeedsDwarfCFI =
997-
!IsWin64Prologue && (MMI.hasDebugInfo() || Fn.needsUnwindTableEntry());
996+
bool NeedsDwarfCFI = !IsWin64Prologue && MF.needsFrameMoves();
998997
Register FramePtr = TRI->getFrameRegister(MF);
999998
const Register MachineFramePtr =
1000999
STI.isTarget64BitILP32()
@@ -1614,10 +1613,9 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
16141613
bool HasFP = hasFP(MF);
16151614
uint64_t NumBytes = 0;
16161615

1617-
bool NeedsDwarfCFI =
1618-
(!MF.getTarget().getTargetTriple().isOSDarwin() &&
1619-
!MF.getTarget().getTargetTriple().isOSWindows()) &&
1620-
(MF.getMMI().hasDebugInfo() || MF.getFunction().needsUnwindTableEntry());
1616+
bool NeedsDwarfCFI = (!MF.getTarget().getTargetTriple().isOSDarwin() &&
1617+
!MF.getTarget().getTargetTriple().isOSWindows()) &&
1618+
MF.needsFrameMoves();
16211619

16221620
if (IsFunclet) {
16231621
assert(HasFP && "EH funclets without FP not yet implemented");
@@ -2812,11 +2810,9 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
28122810
unsigned StackAlign = getStackAlignment();
28132811
Amount = alignTo(Amount, StackAlign);
28142812

2815-
MachineModuleInfo &MMI = MF.getMMI();
28162813
const Function &F = MF.getFunction();
28172814
bool WindowsCFI = MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
2818-
bool DwarfCFI = !WindowsCFI &&
2819-
(MMI.hasDebugInfo() || F.needsUnwindTableEntry());
2815+
bool DwarfCFI = !WindowsCFI && MF.needsFrameMoves();
28202816

28212817
// If we have any exception handlers in this function, and we adjust
28222818
// the SP before calls, we may need to indicate this to the unwinder

llvm/lib/Target/X86/X86InstrInfo.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3963,9 +3963,7 @@ static bool ExpandMOVImmSExti8(MachineInstrBuilder &MIB,
39633963
MachineFunction &MF = *MBB.getParent();
39643964
const X86FrameLowering *TFL = Subtarget.getFrameLowering();
39653965
bool IsWin64Prologue = MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
3966-
bool NeedsDwarfCFI =
3967-
!IsWin64Prologue &&
3968-
(MF.getMMI().hasDebugInfo() || MF.getFunction().needsUnwindTableEntry());
3966+
bool NeedsDwarfCFI = !IsWin64Prologue && MF.needsFrameMoves();
39693967
bool EmitCFI = !TFL->hasFP(MF) && NeedsDwarfCFI;
39703968
if (EmitCFI) {
39713969
TFL->BuildCFI(MBB, I, DL,

llvm/lib/Target/XCore/XCoreRegisterInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ static void InsertSPConstInst(MachineBasicBlock::iterator II,
203203
}
204204

205205
bool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) {
206-
return MF.getMMI().hasDebugInfo() || MF.getFunction().needsUnwindTableEntry();
206+
return MF.needsFrameMoves();
207207
}
208208

209209
const MCPhysReg *

llvm/test/CodeGen/ARM/dwarf-frame.ll

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; RUN: llc -mtriple armv7-unknown -frame-pointer=all -filetype=asm -o - %s | FileCheck %s --check-prefix=CHECK-NO-CFI
2+
; RUN: llc -mtriple armv7-unknown -frame-pointer=all -filetype=asm -force-dwarf-frame-section -o - %s | FileCheck %s --check-prefix=CHECK-ALWAYS-CFI
3+
4+
declare void @dummy_use(i32*, i32)
5+
6+
define void @test_basic() #0 {
7+
%mem = alloca i32, i32 10
8+
call void @dummy_use (i32* %mem, i32 10)
9+
ret void
10+
}
11+
12+
; CHECK-NO-CFI-LABEL: test_basic:
13+
; CHECK-NO-CFI: .fnstart
14+
; CHECK-NO-CFI-NOT: .cfi_sections .debug_frame
15+
; CHECK-NO-CFI-NOT: .cfi_startproc
16+
; CHECK-NO-CFI: @ %bb.0:
17+
; CHECK-NO-CFI: push {r11, lr}
18+
; CHECK-NO-CFI-NOT: .cfi_def_cfa_offset 8
19+
; CHECK-NO-CFI-NOT: .cfi_offset lr, -4
20+
; CHECK-NO-CFI-NOT: .cfi_offset r11, -8
21+
; CHECK-NO-CFI: mov r11, sp
22+
; CHECK-NO-CFI-NOT: .cfi_def_cfa_register r11
23+
; CHECK-NO-CFI-NOT: .cfi_endproc
24+
; CHECK-NO-CFI: .fnend
25+
26+
; CHECK-ALWAYS-CFI-LABEL: test_basic:
27+
; CHECK-ALWAYS-CFI: .fnstart
28+
; CHECK-ALWAYS-CFI: .cfi_sections .debug_frame
29+
; CHECK-ALWAYS-CFI: .cfi_startproc
30+
; CHECK-ALWAYS-CFI: @ %bb.0:
31+
; CHECK-ALWAYS-CFI: push {r11, lr}
32+
; CHECK-ALWAYS-CFI: .cfi_def_cfa_offset 8
33+
; CHECK-ALWAYS-CFI: .cfi_offset lr, -4
34+
; CHECK-ALWAYS-CFI: .cfi_offset r11, -8
35+
; CHECK-ALWAYS-CFI: mov r11, sp
36+
; CHECK-ALWAYS-CFI: .cfi_def_cfa_register r11
37+
; CHECK-ALWAYS-CFI: .cfi_endproc
38+
; CHECK-ALWAYS-CFI: .fnend

0 commit comments

Comments
 (0)