Skip to content

Commit 6f867f9

Browse files
committed
[X86] Support -mindirect-branch-cs-prefix for call and jmp to indirect thunk
This is to address feature request from ClangBuiltLinux/linux#1665 Reviewed By: nickdesaulniers, MaskRay Differential Revision: https://reviews.llvm.org/D130754
1 parent 45bae1b commit 6f867f9

File tree

11 files changed

+80
-19
lines changed

11 files changed

+80
-19
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ CUDA Support in Clang
138138
X86 Support in Clang
139139
--------------------
140140

141+
- Support ``-mindirect-branch-cs-prefix`` for call and jmp to indirect thunk.
142+
141143
DWARF Support in Clang
142144
----------------------
143145

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ CODEGENOPT(CFProtectionBranch , 1, 0) ///< if -fcf-protection is
108108
///< set to full or branch.
109109
CODEGENOPT(IBTSeal, 1, 0) ///< set to optimize CFProtectionBranch.
110110
CODEGENOPT(FunctionReturnThunks, 1, 0) ///< -mfunction-return={keep|thunk-extern}
111+
CODEGENOPT(IndirectBranchCSPrefix, 1, 0) ///< if -mindirect-branch-cs-prefix
112+
///< is set.
111113

112114
CODEGENOPT(XRayInstrumentFunctions , 1, 0) ///< Set when -fxray-instrument is
113115
///< enabled.

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2025,6 +2025,10 @@ def mfunction_return_EQ : Joined<["-"], "mfunction-return=">,
20252025
NormalizedValues<["Keep", "Extern"]>,
20262026
NormalizedValuesScope<"llvm::FunctionReturnThunksKind">,
20272027
MarshallingInfoEnum<CodeGenOpts<"FunctionReturnThunks">, "Keep">;
2028+
def mindirect_branch_cs_prefix : Flag<["-"], "mindirect-branch-cs-prefix">,
2029+
Group<m_Group>, Flags<[CoreOption, CC1Option]>,
2030+
HelpText<"Add cs prefix to call and jmp to indirect thunk">,
2031+
MarshallingInfoFlag<CodeGenOpts<"IndirectBranchCSPrefix">>;
20282032

20292033
defm xray_instrument : BoolFOption<"xray-instrument",
20302034
LangOpts<"XRayInstrument">, DefaultFalse,

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,9 @@ void CodeGenModule::Release() {
775775
if (CodeGenOpts.FunctionReturnThunks)
776776
getModule().addModuleFlag(llvm::Module::Override, "function_return_thunk_extern", 1);
777777

778+
if (CodeGenOpts.IndirectBranchCSPrefix)
779+
getModule().addModuleFlag(llvm::Module::Override, "indirect_branch_cs_prefix", 1);
780+
778781
// Add module metadata for return address signing (ignoring
779782
// non-leaf/all) and stack tagging. These are actually turned on by function
780783
// attributes, but we use module metadata to emit build attributes. This is

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6359,6 +6359,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
63596359
CmdArgs.push_back(
63606360
Args.MakeArgString(Twine("-mfunction-return=") + A->getValue()));
63616361

6362+
Args.AddLastArg(CmdArgs, options::OPT_mindirect_branch_cs_prefix);
6363+
63626364
// Forward -f options with positive and negative forms; we translate these by
63636365
// hand. Do not propagate PGO options to the GPU-side compilations as the
63646366
// profile info is for the host-side compilation only.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// RUN: %clang -target i386-unknown-unknown -o - -emit-llvm -S -mindirect-branch-cs-prefix %s | FileCheck %s
2+
3+
// CHECK: !{i32 4, !"indirect_branch_cs_prefix", i32 1}
4+
void foo() {}

clang/test/Driver/x86_features.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66
// RUN: %clang -### %s -mieee-fp -S 2>&1 | FileCheck --check-prefix=IEEE %s
77
// IEEE-NOT: error: unknown argument
88

9-
// RUN: %clang -target i386-unknown-unknown -### %s -mskip-rax-setup -S 2>&1 | FileCheck --check-prefix=SRS %s
9+
// RUN: %clang --target=i386 -### %s -mskip-rax-setup -S 2>&1 | FileCheck --check-prefix=SRS %s
1010
// SRS: "-mskip-rax-setup"
1111

12-
// RUN: %clang -target i386-unknown-unknown -### %s -mno-skip-rax-setup -S 2>&1 | FileCheck --check-prefix=NO-SRS %s
12+
// RUN: %clang --target=i386 -### %s -mno-skip-rax-setup -S 2>&1 | FileCheck --check-prefix=NO-SRS %s
1313
// NO-SRS-NOT: "-mskip-rax-setup"
14+
15+
// RUN: %clang --target=i386 -### %s -mindirect-branch-cs-prefix -S 2>&1 | FileCheck --check-prefix=IND-CS %s
16+
// IND-CS: "-mindirect-branch-cs-prefix"

llvm/lib/Target/X86/X86MCInstLower.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2440,6 +2440,9 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
24402440
if (OutStreamer->isVerboseAsm())
24412441
addConstantComments(MI, *OutStreamer);
24422442

2443+
bool IndCS =
2444+
MF->getMMI().getModule()->getModuleFlag("indirect_branch_cs_prefix");
2445+
24432446
switch (MI->getOpcode()) {
24442447
case TargetOpcode::DBG_VALUE:
24452448
llvm_unreachable("Should be handled target independently");
@@ -2488,13 +2491,16 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
24882491
break;
24892492
}
24902493

2494+
case X86::TAILJMPd64:
2495+
if (IndCS && MI->hasRegisterImplicitUseOperand(X86::R11))
2496+
EmitAndCountInstruction(MCInstBuilder(X86::CS_PREFIX));
2497+
LLVM_FALLTHROUGH;
24912498
case X86::TAILJMPr:
24922499
case X86::TAILJMPm:
24932500
case X86::TAILJMPd:
24942501
case X86::TAILJMPd_CC:
24952502
case X86::TAILJMPr64:
24962503
case X86::TAILJMPm64:
2497-
case X86::TAILJMPd64:
24982504
case X86::TAILJMPd64_CC:
24992505
case X86::TAILJMPr64_REX:
25002506
case X86::TAILJMPm64_REX:
@@ -2668,6 +2674,10 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
26682674
.addImm(MI->getOperand(0).getImm())
26692675
.addReg(X86::NoRegister));
26702676
return;
2677+
case X86::CALL64pcrel32:
2678+
if (IndCS && MI->hasRegisterImplicitUseOperand(X86::R11))
2679+
EmitAndCountInstruction(MCInstBuilder(X86::CS_PREFIX));
2680+
break;
26712681
}
26722682

26732683
MCInst TmpInst;

llvm/lib/Target/X86/X86ReturnThunks.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "llvm/CodeGen/MachineFunctionPass.h"
3535
#include "llvm/CodeGen/MachineInstr.h"
3636
#include "llvm/CodeGen/MachineInstrBuilder.h"
37+
#include "llvm/CodeGen/MachineModuleInfo.h"
3738
#include "llvm/MC/MCInstrDesc.h"
3839
#include "llvm/Support/Debug.h"
3940

@@ -73,9 +74,14 @@ bool X86ReturnThunks::runOnMachineFunction(MachineFunction &MF) {
7374
if (Term.getOpcode() == RetOpc)
7475
Rets.push_back(&Term);
7576

77+
bool IndCS =
78+
MF.getMMI().getModule()->getModuleFlag("indirect_branch_cs_prefix");
79+
const MCInstrDesc &CS = ST.getInstrInfo()->get(X86::CS_PREFIX);
7680
const MCInstrDesc &JMP = ST.getInstrInfo()->get(X86::TAILJMPd);
7781

7882
for (MachineInstr *Ret : Rets) {
83+
if (IndCS)
84+
BuildMI(Ret->getParent(), Ret->getDebugLoc(), CS);
7985
BuildMI(Ret->getParent(), Ret->getDebugLoc(), JMP)
8086
.addExternalSymbol(ThunkName.data());
8187
Ret->eraseFromParent();

llvm/test/CodeGen/X86/attr-function-return.ll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
define void @x() fn_ret_thunk_extern {
77
; CHECK-LABEL: x:
88
; CHECK: # %bb.0:
9+
; CHECK-NEXT: cs
910
; CHECK-NEXT: jmp __x86_return_thunk
1011
ret void
1112
}
13+
14+
!llvm.module.flags = !{!0}
15+
16+
!0 = !{i32 4, !"indirect_branch_cs_prefix", i32 1}

0 commit comments

Comments
 (0)