Skip to content

Commit 546da43

Browse files
This plumbs the option --gsframe through the various levels needed to support it in the assembler.
This is the final step in assembler-level sframe support for x86. With it in place, clang produces sframe-sections that successfully link with gnu-ld. LLD support is pending some discussion.
1 parent c46bfed commit 546da43

File tree

7 files changed

+55
-0
lines changed

7 files changed

+55
-0
lines changed

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ CODEGENOPT(StackSizeSection , 1, 0, Benign) ///< Set when -fstack-size-section
120120
///< Set when -femit-compact-unwind-non-canonical is enabled.
121121
CODEGENOPT(EmitCompactUnwindNonCanonical, 1, 0, Benign)
122122

123+
CODEGENOPT(EmitSFrameUnwind, 1, 0, Benign) ///< Set when -sframe is enabled.
124+
123125
///< Set when -fxray-always-emit-customevents is enabled.
124126
CODEGENOPT(XRayAlwaysEmitCustomEvents , 1, 0, Benign)
125127

clang/include/clang/Driver/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7729,6 +7729,11 @@ def massembler_fatal_warnings : Flag<["-"], "massembler-fatal-warnings">,
77297729
def crel : Flag<["--"], "crel">,
77307730
HelpText<"Enable CREL relocation format (ELF only)">,
77317731
MarshallingInfoFlag<CodeGenOpts<"Crel">>;
7732+
// The leading 'g' is misleading. This is an unwind tables option, not
7733+
// a debug option. But uses this name for gnu compatibility.
7734+
def gsframe : Flag<["--"], "gsframe">,
7735+
HelpText<"Generate .sframe unwind sections (ELF only)">,
7736+
MarshallingInfoFlag<CodeGenOpts<"EmitSFrameUnwind">>;
77327737
def mmapsyms_implicit : Flag<["-"], "mmapsyms=implicit">,
77337738
HelpText<"Allow mapping symbol at section beginning to be implicit, "
77347739
"lowering number of mapping symbols at the expense of some "

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,7 @@ static bool initTargetOptions(const CompilerInstance &CI,
500500
Options.MCOptions.EmitDwarfUnwind = CodeGenOpts.getEmitDwarfUnwind();
501501
Options.MCOptions.EmitCompactUnwindNonCanonical =
502502
CodeGenOpts.EmitCompactUnwindNonCanonical;
503+
Options.MCOptions.EmitSFrameUnwind = CodeGenOpts.EmitSFrameUnwind;
503504
Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
504505
Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
505506
Options.MCOptions.MCUseDwarfDirectory =

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2626,6 +2626,14 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
26262626
llvm::codegenoptions::DebugInfoConstructor,
26272627
DwarfVersion, llvm::DebuggerKind::Default);
26282628
}
2629+
} else if (Value == "--gsframe") {
2630+
if (Triple.isOSBinFormatELF() && Triple.isX86()) {
2631+
CmdArgs.push_back("--gsframe");
2632+
} else {
2633+
D.Diag(diag::err_drv_unsupported_opt_for_target)
2634+
<< Value << D.getTargetTriple();
2635+
break;
2636+
}
26292637
} else if (Value.starts_with("-mcpu") || Value.starts_with("-mfpu") ||
26302638
Value.starts_with("-mhwdiv") || Value.starts_with("-march")) {
26312639
// Do nothing, we'll validate it later.
@@ -5929,6 +5937,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
59295937
else if (UnwindTables)
59305938
CmdArgs.push_back("-funwind-tables=1");
59315939

5940+
// Sframe unwind tables are independent of the other types, and only defined
5941+
// for these two targets.
5942+
if (Arg *A = Args.getLastArg(options::OPT_gsframe)) {
5943+
if ((Triple.isAArch64() || Triple.isX86()) && Triple.isOSBinFormatELF())
5944+
CmdArgs.push_back("--gsframe");
5945+
else
5946+
D.Diag(diag::err_drv_unsupported_opt_for_target)
5947+
<< A->getOption().getName() << TripleStr;
5948+
}
5949+
59325950
// Prepare `-aux-target-cpu` and `-aux-target-feature` unless
59335951
// `--gpu-use-aux-triple-only` is specified.
59345952
if (!Args.getLastArg(options::OPT_gpu_use_aux_triple_only) &&

clang/test/Driver/sframe.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %clang -### -c --target=x86_64 -Wa,--gsframe %s -Werror 2>&1 | FileCheck %s
2+
// CHECK: "-cc1" {{.*}}"--gsframe"
3+
4+
// RUN: %clang -### -c --target=x86_64 %s 2>&1 | FileCheck %s --check-prefix=NO
5+
// NO: "-cc1"
6+
7+
// RUN: %clang -### -c --target=x86_64 -Werror -Wa,--gsframe -x assembler %s -Werror 2>&1 | FileCheck %s --check-prefix=ASM
8+
// ASM: "-cc1as" {{.*}}"--gsframe"
9+
10+
// RUN: not %clang -### -c --target=mips64 -Wa,--gsframe %s 2>&1 | FileCheck %s --check-prefix=NOTARGETC
11+
// NOTARGETC: error: unsupported option '--gsframe' for target '{{.*}}'
12+
13+
// RUN: not %clang -### -c --target=mips64 -Wa,--gsframe -x assembler %s 2>&1 | FileCheck %s --check-prefix=NOTARGETASM
14+
// NOTARGETASM: error: unsupported option '--gsframe' for target '{{.*}}'
15+

clang/test/Misc/cc1as-sframe.s

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// REQUIRES: x86-registered-target
2+
// RUN: %clang -cc1as -triple x86_64 %s -filetype obj --gsframe -o %t.o
3+
// RUN: llvm-readelf -S %t.o | FileCheck %s
4+
5+
// CHECK: .sframe
6+
.cfi_startproc
7+
call foo
8+
.cfi_endproc

clang/tools/driver/cc1as_main.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ struct AssemblerInvocation {
163163
LLVM_PREFERRED_TYPE(bool)
164164
unsigned EmitCompactUnwindNonCanonical : 1;
165165

166+
// Whether to emit sframe unwind sections.
167+
LLVM_PREFERRED_TYPE(bool)
168+
unsigned EmitSFrameUnwind : 1;
169+
166170
LLVM_PREFERRED_TYPE(bool)
167171
unsigned Crel : 1;
168172
LLVM_PREFERRED_TYPE(bool)
@@ -388,6 +392,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
388392

389393
Opts.EmitCompactUnwindNonCanonical =
390394
Args.hasArg(OPT_femit_compact_unwind_non_canonical);
395+
Opts.EmitSFrameUnwind = Args.hasArg(OPT_gsframe);
391396
Opts.Crel = Args.hasArg(OPT_crel);
392397
Opts.ImplicitMapsyms = Args.hasArg(OPT_mmapsyms_implicit);
393398
Opts.X86RelaxRelocations = !Args.hasArg(OPT_mrelax_relocations_no);
@@ -450,6 +455,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
450455
MCOptions.MCRelaxAll = Opts.RelaxAll;
451456
MCOptions.EmitDwarfUnwind = Opts.EmitDwarfUnwind;
452457
MCOptions.EmitCompactUnwindNonCanonical = Opts.EmitCompactUnwindNonCanonical;
458+
MCOptions.EmitSFrameUnwind = Opts.EmitSFrameUnwind;
453459
MCOptions.MCSaveTempLabels = Opts.SaveTemporaryLabels;
454460
MCOptions.Crel = Opts.Crel;
455461
MCOptions.ImplicitMapSyms = Opts.ImplicitMapsyms;

0 commit comments

Comments
 (0)