pengfei created this revision. pengfei added a reviewer: nickdesaulniers. Herald added a subscriber: hiraditya. Herald added a project: All. pengfei requested review of this revision. Herald added subscribers: llvm-commits, cfe-commits, MaskRay. Herald added projects: clang, LLVM.
This is to address feature request from https://github.com/ClangBuiltLinux/linux/issues/1665 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D130754 Files: clang/docs/ReleaseNotes.rst clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/test/CodeGen/X86/indirect-branch-cs-prefix.c llvm/lib/Target/X86/X86MCInstLower.cpp llvm/lib/Target/X86/X86ReturnThunks.cpp llvm/test/CodeGen/X86/attr-function-return.ll llvm/test/CodeGen/X86/lvi-hardening-indirectbr.ll
Index: llvm/test/CodeGen/X86/lvi-hardening-indirectbr.ll =================================================================== --- llvm/test/CodeGen/X86/lvi-hardening-indirectbr.ll +++ llvm/test/CodeGen/X86/lvi-hardening-indirectbr.ll @@ -22,18 +22,22 @@ ; X64: callq bar ; X64-DAG: movl %[[x]], %edi ; X64-DAG: movq %[[fp]], %r11 -; X64: callq __llvm_lvi_thunk_r11 +; X64: cs +; X64-NEXT: callq __llvm_lvi_thunk_r11 ; X64: movl %[[x]], %edi ; X64: callq bar ; X64-DAG: movl %[[x]], %edi ; X64-DAG: movq %[[fp]], %r11 -; X64: jmp __llvm_lvi_thunk_r11 # TAILCALL +; X64: cs +; X64-NEXT: jmp __llvm_lvi_thunk_r11 # TAILCALL ; X64FAST-LABEL: icall_reg: ; X64FAST: callq bar -; X64FAST: callq __llvm_lvi_thunk_r11 +; X64FAST: cs +; X64FAST-NEXT: callq __llvm_lvi_thunk_r11 ; X64FAST: callq bar -; X64FAST: jmp __llvm_lvi_thunk_r11 # TAILCALL +; X64FAST: cs +; X64FAST-NEXT: jmp __llvm_lvi_thunk_r11 # TAILCALL @global_fp = external dso_local global ptr @@ -50,16 +54,20 @@ ; X64-LABEL: icall_global_fp: ; X64-DAG: movl %edi, %[[x:[^ ]*]] ; X64-DAG: movq global_fp(%rip), %r11 -; X64: callq __llvm_lvi_thunk_r11 +; X64: cs +; X64-NEXT: callq __llvm_lvi_thunk_r11 ; X64-DAG: movl %[[x]], %edi ; X64-DAG: movq global_fp(%rip), %r11 -; X64: jmp __llvm_lvi_thunk_r11 # TAILCALL +; X64: cs +; X64-NEXT: jmp __llvm_lvi_thunk_r11 # TAILCALL ; X64FAST-LABEL: icall_global_fp: ; X64FAST: movq global_fp(%rip), %r11 -; X64FAST: callq __llvm_lvi_thunk_r11 +; X64FAST: cs +; X64FAST-NEXT: callq __llvm_lvi_thunk_r11 ; X64FAST: movq global_fp(%rip), %r11 -; X64FAST: jmp __llvm_lvi_thunk_r11 # TAILCALL +; X64FAST: cs +; X64FAST-NEXT: jmp __llvm_lvi_thunk_r11 # TAILCALL %struct.Foo = type { ptr } @@ -79,14 +87,18 @@ ; X64: movq (%rdi), %[[vptr:[^ ]*]] ; X64: movq 8(%[[vptr]]), %[[fp:[^ ]*]] ; X64: movq %[[fp]], %r11 -; X64: callq __llvm_lvi_thunk_r11 +; X64: cs +; X64-NEXT: callq __llvm_lvi_thunk_r11 ; X64-DAG: movq %[[obj]], %rdi ; X64-DAG: movq %[[fp]], %r11 -; X64: jmp __llvm_lvi_thunk_r11 # TAILCALL +; X64: cs +; X64-NEXT: jmp __llvm_lvi_thunk_r11 # TAILCALL ; X64FAST-LABEL: vcall: -; X64FAST: callq __llvm_lvi_thunk_r11 -; X64FAST: jmp __llvm_lvi_thunk_r11 # TAILCALL +; X64FAST: cs +; X64FAST-NEXT: callq __llvm_lvi_thunk_r11 +; X64FAST: cs +; X64FAST-NEXT: jmp __llvm_lvi_thunk_r11 # TAILCALL declare dso_local void @direct_callee() @@ -113,14 +125,18 @@ ; X64-LABEL: nonlazybind_caller: ; X64: movq nonlazybind_callee@GOTPCREL(%rip), %[[REG:.*]] ; X64: movq %[[REG]], %r11 -; X64: callq __llvm_lvi_thunk_r11 +; X64: cs +; X64-NEXT: callq __llvm_lvi_thunk_r11 ; X64: movq %[[REG]], %r11 -; X64: jmp __llvm_lvi_thunk_r11 # TAILCALL +; X64: cs +; X64-NEXT: jmp __llvm_lvi_thunk_r11 # TAILCALL ; X64FAST-LABEL: nonlazybind_caller: ; X64FAST: movq nonlazybind_callee@GOTPCREL(%rip), %r11 -; X64FAST: callq __llvm_lvi_thunk_r11 +; X64FAST: cs +; X64FAST-NEXT: callq __llvm_lvi_thunk_r11 ; X64FAST: movq nonlazybind_callee@GOTPCREL(%rip), %r11 -; X64FAST: jmp __llvm_lvi_thunk_r11 # TAILCALL +; X64FAST: cs +; X64FAST-NEXT: jmp __llvm_lvi_thunk_r11 # TAILCALL ; Check that a switch gets lowered using a jump table @@ -278,3 +294,7 @@ ; X64-NEXT: jmpq *%r11 attributes #1 = { nonlazybind } + +!llvm.module.flags = !{!0} + +!0 = !{i32 4, !"indirect_branch_cs_prefix", i32 1} Index: llvm/test/CodeGen/X86/attr-function-return.ll =================================================================== --- llvm/test/CodeGen/X86/attr-function-return.ll +++ llvm/test/CodeGen/X86/attr-function-return.ll @@ -6,6 +6,11 @@ define void @x() fn_ret_thunk_extern { ; CHECK-LABEL: x: ; CHECK: # %bb.0: +; CHECK-NEXT: cs ; CHECK-NEXT: jmp __x86_return_thunk ret void } + +!llvm.module.flags = !{!0} + +!0 = !{i32 4, !"indirect_branch_cs_prefix", i32 1} Index: llvm/lib/Target/X86/X86ReturnThunks.cpp =================================================================== --- llvm/lib/Target/X86/X86ReturnThunks.cpp +++ llvm/lib/Target/X86/X86ReturnThunks.cpp @@ -34,6 +34,7 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/MC/MCInstrDesc.h" #include "llvm/Support/Debug.h" @@ -73,9 +74,14 @@ if (Term.getOpcode() == RetOpc) Rets.push_back(&Term); + bool IndCS = + MF.getMMI().getModule()->getModuleFlag("indirect_branch_cs_prefix"); + const MCInstrDesc &CS = ST.getInstrInfo()->get(X86::CS_PREFIX); const MCInstrDesc &JMP = ST.getInstrInfo()->get(X86::TAILJMPd); for (MachineInstr *Ret : Rets) { + if (IndCS) + BuildMI(Ret->getParent(), Ret->getDebugLoc(), CS); BuildMI(Ret->getParent(), Ret->getDebugLoc(), JMP) .addExternalSymbol(ThunkName.data()); Ret->eraseFromParent(); Index: llvm/lib/Target/X86/X86MCInstLower.cpp =================================================================== --- llvm/lib/Target/X86/X86MCInstLower.cpp +++ llvm/lib/Target/X86/X86MCInstLower.cpp @@ -2441,6 +2441,9 @@ if (OutStreamer->isVerboseAsm()) addConstantComments(MI, *OutStreamer); + bool IndCS = + MF->getMMI().getModule()->getModuleFlag("indirect_branch_cs_prefix"); + switch (MI->getOpcode()) { case TargetOpcode::DBG_VALUE: llvm_unreachable("Should be handled target independently"); @@ -2489,13 +2492,16 @@ break; } + case X86::TAILJMPd64: + if (IndCS && MI->hasRegisterImplicitUseOperand(X86::R11)) + EmitAndCountInstruction(MCInstBuilder(X86::CS_PREFIX)); + LLVM_FALLTHROUGH; case X86::TAILJMPr: case X86::TAILJMPm: case X86::TAILJMPd: case X86::TAILJMPd_CC: case X86::TAILJMPr64: case X86::TAILJMPm64: - case X86::TAILJMPd64: case X86::TAILJMPd64_CC: case X86::TAILJMPr64_REX: case X86::TAILJMPm64_REX: @@ -2669,6 +2675,10 @@ .addImm(MI->getOperand(0).getImm()) .addReg(X86::NoRegister)); return; + case X86::CALL64pcrel32: + if (IndCS && MI->hasRegisterImplicitUseOperand(X86::R11)) + EmitAndCountInstruction(MCInstBuilder(X86::CS_PREFIX)); + break; } MCInst TmpInst; Index: clang/test/CodeGen/X86/indirect-branch-cs-prefix.c =================================================================== --- /dev/null +++ clang/test/CodeGen/X86/indirect-branch-cs-prefix.c @@ -0,0 +1,4 @@ +// RUN: %clang -target i386-unknown-unknown -o - -emit-llvm -S -mindirect-branch-cs-prefix %s | FileCheck %s + +// CHECK: !{i32 4, !"indirect_branch_cs_prefix", i32 1} +void foo() {} Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -6347,6 +6347,9 @@ CmdArgs.push_back( Args.MakeArgString(Twine("-mfunction-return=") + A->getValue())); + if (Args.hasArg(options::OPT_mindirect_branch_cs_prefix)) + CmdArgs.push_back("-mindirect-branch-cs-prefix"); + // Forward -f options with positive and negative forms; we translate these by // hand. Do not propagate PGO options to the GPU-side compilations as the // profile info is for the host-side compilation only. Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -775,6 +775,9 @@ if (CodeGenOpts.FunctionReturnThunks) getModule().addModuleFlag(llvm::Module::Override, "function_return_thunk_extern", 1); + if (CodeGenOpts.IndirectBranchCSPrefix) + getModule().addModuleFlag(llvm::Module::Override, "indirect_branch_cs_prefix", 1); + // Add module metadata for return address signing (ignoring // non-leaf/all) and stack tagging. These are actually turned on by function // attributes, but we use module metadata to emit build attributes. This is Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -2028,6 +2028,10 @@ NormalizedValues<["Keep", "Extern"]>, NormalizedValuesScope<"llvm::FunctionReturnThunksKind">, MarshallingInfoEnum<CodeGenOpts<"FunctionReturnThunks">, "Keep">; +def mindirect_branch_cs_prefix : Flag<["-"], "mindirect-branch-cs-prefix">, + Group<m_Group>, Flags<[CoreOption, CC1Option]>, + HelpText<"Add cs prefix to call and jmp to indirect thunk">, + MarshallingInfoFlag<CodeGenOpts<"IndirectBranchCSPrefix">>; defm xray_instrument : BoolFOption<"xray-instrument", LangOpts<"XRayInstrument">, DefaultFalse, Index: clang/include/clang/Basic/CodeGenOptions.def =================================================================== --- clang/include/clang/Basic/CodeGenOptions.def +++ clang/include/clang/Basic/CodeGenOptions.def @@ -108,6 +108,8 @@ ///< set to full or branch. CODEGENOPT(IBTSeal, 1, 0) ///< set to optimize CFProtectionBranch. CODEGENOPT(FunctionReturnThunks, 1, 0) ///< -mfunction-return={keep|thunk-extern} +CODEGENOPT(IndirectBranchCSPrefix, 1, 0) ///< if -mindirect-branch-cs-prefix + ///< is set. CODEGENOPT(XRayInstrumentFunctions , 1, 0) ///< Set when -fxray-instrument is ///< enabled. Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -131,6 +131,8 @@ X86 Support in Clang -------------------- +- Support ``-mindirect-branch-cs-prefix`` for call and jmp to indirect thunk. + DWARF Support in Clang ----------------------
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits