Skip to content

Commit d157a9b

Browse files
ajpaverddavidchisnall
authored andcommitted
Add Windows Control Flow Guard checks (/guard:cf).
Summary: A new function pass (Transforms/CFGuard/CFGuard.cpp) inserts CFGuard checks on indirect function calls, using either the check mechanism (X86, ARM, AArch64) or or the dispatch mechanism (X86-64). The check mechanism requires a new calling convention for the supported targets. The dispatch mechanism adds the target as an operand bundle, which is processed by SelectionDAG. Another pass (CodeGen/CFGuardLongjmp.cpp) identifies and emits valid longjmp targets, as required by /guard:cf. This feature is enabled using the `cfguard` CC1 option. Reviewers: thakis, rnk, theraven, pcc Subscribers: ychen, hans, metalcanine, dmajor, tomrittervg, alex, mehdi_amini, mgorny, javed.absar, kristof.beyls, hiraditya, steven_wu, dexonsmith, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D65761
1 parent a233e7d commit d157a9b

File tree

77 files changed

+1514
-62
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+1514
-62
lines changed

clang/docs/ClangCommandLineReference.rst

+5-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,11 @@ Output path for the plist report
124124

125125
.. option:: -cfguard
126126

127-
Emit tables required for Windows Control Flow Guard.
127+
Emit tables and checks for Windows Control Flow Guard.
128+
129+
.. option:: -cfguard-no-checks
130+
131+
Emit tables required for Windows Control Flow Guard without checks.
128132

129133
.. option:: -client\_name<arg>
130134

clang/include/clang/Basic/CodeGenOptions.def

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ CODEGENOPT(AssumeSaneOperatorNew , 1, 1) ///< implicit __attribute__((malloc)) o
3737
CODEGENOPT(Autolink , 1, 1) ///< -fno-autolink
3838
CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe.
3939
CODEGENOPT(Backchain , 1, 0) ///< -mbackchain
40+
CODEGENOPT(ControlFlowGuardNoChecks , 1, 0) ///< -cfguard-no-checks
4041
CODEGENOPT(ControlFlowGuard , 1, 0) ///< -cfguard
4142
CODEGENOPT(CoverageExtraChecksum, 1, 0) ///< Whether we need a second checksum for functions in GCNO files.
4243
CODEGENOPT(CoverageNoFunctionNamesInData, 1, 0) ///< Do not include function names in GCDA files.

clang/include/clang/Driver/CC1Options.td

+4
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,10 @@ def msign_return_address_key_EQ : Joined<["-"], "msign-return-address-key=">,
400400
Values<"a_key,b_key">;
401401
def mbranch_target_enforce : Flag<["-"], "mbranch-target-enforce">;
402402
def fno_dllexport_inlines : Flag<["-"], "fno-dllexport-inlines">;
403+
def cfguard_no_checks : Flag<["-"], "cfguard-no-checks">,
404+
HelpText<"Emit Windows Control Flow Guard tables only (no checks)">;
405+
def cfguard : Flag<["-"], "cfguard">,
406+
HelpText<"Emit Windows Control Flow Guard tables and checks">;
403407

404408
//===----------------------------------------------------------------------===//
405409
// Dependency Output Options

clang/include/clang/Driver/Options.td

-2
Original file line numberDiff line numberDiff line change
@@ -503,8 +503,6 @@ def bind__at__load : Flag<["-"], "bind_at_load">;
503503
def bundle__loader : Separate<["-"], "bundle_loader">;
504504
def bundle : Flag<["-"], "bundle">;
505505
def b : JoinedOrSeparate<["-"], "b">, Flags<[Unsupported]>;
506-
def cfguard : Flag<["-"], "cfguard">, Flags<[CC1Option]>,
507-
HelpText<"Emit tables required for Windows Control Flow Guard.">;
508506
def cl_opt_disable : Flag<["-"], "cl-opt-disable">, Group<opencl_Group>, Flags<[CC1Option]>,
509507
HelpText<"OpenCL only. This option disables all optimizations. By default optimizations are enabled.">;
510508
def cl_strict_aliasing : Flag<["-"], "cl-strict-aliasing">, Group<opencl_Group>, Flags<[CC1Option]>,

clang/lib/CodeGen/CodeGenModule.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -482,8 +482,11 @@ void CodeGenModule::Release() {
482482
getModule().addModuleFlag(llvm::Module::Warning, "CodeViewGHash", 1);
483483
}
484484
if (CodeGenOpts.ControlFlowGuard) {
485-
// We want function ID tables for Control Flow Guard.
486-
getModule().addModuleFlag(llvm::Module::Warning, "cfguardtable", 1);
485+
// Function ID tables and checks for Control Flow Guard (cfguard=2).
486+
getModule().addModuleFlag(llvm::Module::Warning, "cfguard", 2);
487+
} else if (CodeGenOpts.ControlFlowGuardNoChecks) {
488+
// Function ID tables for Control Flow Guard (cfguard=1).
489+
getModule().addModuleFlag(llvm::Module::Warning, "cfguard", 1);
487490
}
488491
if (CodeGenOpts.OptimizationLevel > 0 && CodeGenOpts.StrictVTablePointers) {
489492
// We don't support LTO with 2 with different StrictVTablePointers

clang/lib/Driver/ToolChains/Clang.cpp

+12-19
Original file line numberDiff line numberDiff line change
@@ -5975,26 +5975,19 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
59755975
}
59765976

59775977
if (Arg *A = Args.getLastArg(options::OPT__SLASH_guard)) {
5978-
SmallVector<StringRef, 1> SplitArgs;
5979-
StringRef(A->getValue()).split(SplitArgs, ",");
5980-
bool Instrument = false;
5981-
bool NoChecks = false;
5982-
for (StringRef Arg : SplitArgs) {
5983-
if (Arg.equals_lower("cf"))
5984-
Instrument = true;
5985-
else if (Arg.equals_lower("cf-"))
5986-
Instrument = false;
5987-
else if (Arg.equals_lower("nochecks"))
5988-
NoChecks = true;
5989-
else if (Arg.equals_lower("nochecks-"))
5990-
NoChecks = false;
5991-
else
5992-
D.Diag(diag::err_drv_invalid_value) << A->getSpelling() << Arg;
5993-
}
5994-
// Currently there's no support emitting CFG instrumentation; the flag only
5995-
// emits the table of address-taken functions.
5996-
if (Instrument || NoChecks)
5978+
StringRef GuardArgs = A->getValue();
5979+
// The only valid options are "cf", "cf,nochecks", and "cf-".
5980+
if (GuardArgs.equals_lower("cf")) {
5981+
// Emit CFG instrumentation and the table of address-taken functions.
59975982
CmdArgs.push_back("-cfguard");
5983+
} else if (GuardArgs.equals_lower("cf,nochecks")) {
5984+
// Emit only the table of address-taken functions.
5985+
CmdArgs.push_back("-cfguard-no-checks");
5986+
} else if (GuardArgs.equals_lower("cf-")) {
5987+
// Do nothing, but we might want to emit a security warning in future.
5988+
} else {
5989+
D.Diag(diag::err_drv_invalid_value) << A->getSpelling() << GuardArgs;
5990+
}
59985991
}
59995992
}
60005993

clang/lib/Driver/ToolChains/MSVC.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,17 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
422422

423423
Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
424424

425+
// Control Flow Guard checks
426+
if (Arg *A = Args.getLastArg(options::OPT__SLASH_guard)) {
427+
StringRef GuardArgs = A->getValue();
428+
if (GuardArgs.equals_lower("cf") || GuardArgs.equals_lower("cf,nochecks")) {
429+
// MSVC doesn't yet support the "nochecks" modifier.
430+
CmdArgs.push_back("-guard:cf");
431+
} else if (GuardArgs.equals_lower("cf-")) {
432+
CmdArgs.push_back("-guard:cf-");
433+
}
434+
}
435+
425436
if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
426437
options::OPT_fno_openmp, false)) {
427438
CmdArgs.push_back("-nodefaultlib:vcomp.lib");
@@ -679,6 +690,17 @@ std::unique_ptr<Command> visualstudio::Compiler::GetCommand(
679690
: "/Zc:threadSafeInit-");
680691
}
681692

693+
// Control Flow Guard checks
694+
if (Arg *A = Args.getLastArg(options::OPT__SLASH_guard)) {
695+
StringRef GuardArgs = A->getValue();
696+
if (GuardArgs.equals_lower("cf") || GuardArgs.equals_lower("cf,nochecks")) {
697+
// MSVC doesn't yet support the "nochecks" modifier.
698+
CmdArgs.push_back("/guard:cf");
699+
} else if (GuardArgs.equals_lower("cf-")) {
700+
CmdArgs.push_back("/guard:cf-");
701+
}
702+
}
703+
682704
// Pass through all unknown arguments so that the fallback command can see
683705
// them too.
684706
Args.AddAllArgs(CmdArgs, options::OPT_UNKNOWN);

clang/lib/Frontend/CompilerInvocation.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
10031003
Opts.MainFileName = Args.getLastArgValue(OPT_main_file_name);
10041004
Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier);
10051005

1006+
Opts.ControlFlowGuardNoChecks = Args.hasArg(OPT_cfguard_no_checks);
10061007
Opts.ControlFlowGuard = Args.hasArg(OPT_cfguard);
10071008

10081009
Opts.DisableGCov = Args.hasArg(OPT_test_coverage);

clang/test/CodeGen/cfguardtable.c

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
// RUN: %clang_cc1 -cfguard -emit-llvm %s -o - | FileCheck %s
2-
3-
void f() {}
4-
5-
// Check that the cfguardtable metadata flag gets set on the module.
6-
// CHECK: !"cfguardtable", i32 1}
1+
// RUN: %clang_cc1 -cfguard-no-checks -emit-llvm %s -o - | FileCheck %s -check-prefix=CFGUARDNOCHECKS
2+
// RUN: %clang_cc1 -cfguard -emit-llvm %s -o - | FileCheck %s -check-prefix=CFGUARD
3+
4+
void f() {}
5+
6+
// Check that the cfguard metadata flag gets correctly set on the module.
7+
// CFGUARDNOCHECKS: !"cfguard", i32 1}
8+
// CFGUARD: !"cfguard", i32 2}

clang/test/Driver/cl-fallback.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// command-line option, e.g. on Mac where %s is commonly under /Users.
33

44
// RUN: %clang_cl --target=i686-pc-win32 /fallback /Dfoo=bar /Ubaz /Ifoo /O0 /Ox /GR /GR- /GS /GS- /Gy /Gy- \
5-
// RUN: /Gw /Gw- /LD /LDd /EHs /EHs- /Zl /MD /MDd /MTd /MT /FImyheader.h /Zi \
5+
// RUN: /Gw /Gw- /LD /LDd /EHs /EHs- /Zl /MD /MDd /MTd /MT /guard:cf /guard:cf- /FImyheader.h /Zi \
66
// RUN: -garbage -moregarbage \
77
// RUN: -### -- %s 2>&1 \
88
// RUN: | FileCheck %s
@@ -33,6 +33,7 @@
3333
// CHECK: "/EHs-"
3434
// CHECK: "/Zl"
3535
// CHECK: "/MT"
36+
// CHECK: "/guard:cf-"
3637
// CHECK: "-garbage"
3738
// CHECK: "-moregarbage"
3839
// CHECK: "/Tc" "{{.*cl-fallback.c}}"

clang/test/Driver/cl-options.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -597,9 +597,14 @@
597597
// NOCFGUARD-NOT: -cfguard
598598

599599
// RUN: %clang_cl /guard:cf -### -- %s 2>&1 | FileCheck -check-prefix=CFGUARD %s
600-
// RUN: %clang_cl /guard:cf,nochecks -### -- %s 2>&1 | FileCheck -check-prefix=CFGUARD %s
601-
// RUN: %clang_cl /guard:nochecks -### -- %s 2>&1 | FileCheck -check-prefix=CFGUARD %s
602600
// CFGUARD: -cfguard
601+
// CFGUARD-NOT: -cfguard-no-checks
602+
603+
// RUN: %clang_cl /guard:cf,nochecks -### -- %s 2>&1 | FileCheck -check-prefix=CFGUARDNOCHECKS %s
604+
// CFGUARDNOCHECKS: -cfguard-no-checks
605+
606+
// RUN: %clang_cl /guard:nochecks -### -- %s 2>&1 | FileCheck -check-prefix=CFGUARDNOCHECKSINVALID %s
607+
// CFGUARDNOCHECKSINVALID: invalid value 'nochecks' in '/guard:'
603608

604609
// RUN: %clang_cl /guard:foo -### -- %s 2>&1 | FileCheck -check-prefix=CFGUARDINVALID %s
605610
// CFGUARDINVALID: invalid value 'foo' in '/guard:'

llvm/docs/LangRef.rst

+11
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,17 @@ added in the future:
444444
the GHC or the HiPE convention is used. <CodeGenerator.html#id80>`_ This
445445
calling convention does not support varargs and requires the prototype of
446446
all callees to exactly match the prototype of the function definition.
447+
"``cfguard_checkcc``" - Windows Control Flow Guard (Check mechanism)
448+
This calling convention is used for the Control Flow Guard check function,
449+
calls to which can be inserted before indirect calls to check that the call
450+
target is a valid function address. The check function has no return value,
451+
but it will trigger an OS-level error if the address is not a valid target.
452+
The set of registers preserved by the check function, and the register
453+
containing the target address are architecture-specific.
454+
455+
- On X86 the target address is passed in ECX.
456+
- On ARM the target address is passed in R0.
457+
- On AArch64 the target address is passed in X15.
447458
"``cc <n>``" - Numbered convention
448459
Any calling convention may be specified by number, allowing
449460
target-specific calling conventions to be used. Target specific

llvm/docs/ReleaseNotes.rst

+5
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ Non-comprehensive list of changes in this release
8383
``bcmp`` pattern, and convert it into a call to ``bcmp`` (or ``memcmp``)
8484
function.
8585

86+
* Windows Control Flow Guard: the ``-cfguard`` option now emits CFG checks on
87+
indirect function calls. The previous behavior is still available with the
88+
``-cfguard-nochecks`` option. Note that this feature should always be used
89+
with optimizations enabled.
90+
8691
Changes to the LLVM IR
8792
----------------------
8893

llvm/include/llvm/CodeGen/MachineFunction.h

+15
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,10 @@ class MachineFunction {
304304
/// by debug and exception handling consumers.
305305
std::vector<MCCFIInstruction> FrameInstructions;
306306

307+
/// List of basic blocks immediately following calls to _setjmp. Used to
308+
/// construct a table of valid longjmp targets for Windows Control Flow Guard.
309+
std::vector<MCSymbol *> LongjmpTargets;
310+
307311
/// \name Exception Handling
308312
/// \{
309313

@@ -830,6 +834,17 @@ class MachineFunction {
830834

831835
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst);
832836

837+
/// Returns a reference to a list of symbols immediately following calls to
838+
/// _setjmp in the function. Used to construct the longjmp target table used
839+
/// by Windows Control Flow Guard.
840+
const std::vector<MCSymbol *> &getLongjmpTargets() const {
841+
return LongjmpTargets;
842+
}
843+
844+
/// Add the specified symbol to the list of valid longjmp targets for Windows
845+
/// Control Flow Guard.
846+
void addLongjmpTarget(MCSymbol *Target) { LongjmpTargets.push_back(Target); }
847+
833848
/// \name Exception Handling
834849
/// \{
835850

llvm/include/llvm/CodeGen/Passes.h

+4
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,10 @@ namespace llvm {
451451
/// Creates CFI Instruction Inserter pass. \see CFIInstrInserter.cpp
452452
FunctionPass *createCFIInstrInserter();
453453

454+
/// Creates CFGuard longjmp target identification pass.
455+
/// \see CFGuardLongjmp.cpp
456+
FunctionPass *createCFGuardLongjmpPass();
457+
454458
/// Create Hardware Loop pass. \see HardwareLoops.cpp
455459
FunctionPass *createHardwareLoopsPass();
456460

llvm/include/llvm/CodeGen/TargetCallingConv.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ namespace ISD {
3838
unsigned IsSplitEnd : 1; ///< Last part of a split
3939
unsigned IsSwiftSelf : 1; ///< Swift self parameter
4040
unsigned IsSwiftError : 1; ///< Swift error parameter
41+
unsigned IsCFGuardTarget : 1; ///< Control Flow Guard target
4142
unsigned IsHva : 1; ///< HVA field for
4243
unsigned IsHvaStart : 1; ///< HVA structure start
4344
unsigned IsSecArgPass : 1; ///< Second argument
@@ -56,8 +57,8 @@ namespace ISD {
5657
ArgFlagsTy()
5758
: IsZExt(0), IsSExt(0), IsInReg(0), IsSRet(0), IsByVal(0), IsNest(0),
5859
IsReturned(0), IsSplit(0), IsInAlloca(0), IsSplitEnd(0),
59-
IsSwiftSelf(0), IsSwiftError(0), IsHva(0), IsHvaStart(0),
60-
IsSecArgPass(0), ByValAlign(0), OrigAlign(0),
60+
IsSwiftSelf(0), IsSwiftError(0), IsCFGuardTarget(0), IsHva(0),
61+
IsHvaStart(0), IsSecArgPass(0), ByValAlign(0), OrigAlign(0),
6162
IsInConsecutiveRegsLast(0), IsInConsecutiveRegs(0),
6263
IsCopyElisionCandidate(0), IsPointer(0), ByValSize(0),
6364
PointerAddrSpace(0) {
@@ -88,6 +89,9 @@ namespace ISD {
8889
bool isSwiftError() const { return IsSwiftError; }
8990
void setSwiftError() { IsSwiftError = 1; }
9091

92+
bool isCFGuardTarget() const { return IsCFGuardTarget; }
93+
void setCFGuardTarget() { IsCFGuardTarget = 1; }
94+
9195
bool isHva() const { return IsHva; }
9296
void setHva() { IsHva = 1; }
9397

llvm/include/llvm/CodeGen/TargetLowering.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,14 @@ class TargetLoweringBase {
188188
bool IsReturned : 1;
189189
bool IsSwiftSelf : 1;
190190
bool IsSwiftError : 1;
191+
bool IsCFGuardTarget : 1;
191192
uint16_t Alignment = 0;
192193
Type *ByValType = nullptr;
193194

194195
ArgListEntry()
195196
: IsSExt(false), IsZExt(false), IsInReg(false), IsSRet(false),
196197
IsNest(false), IsByVal(false), IsInAlloca(false), IsReturned(false),
197-
IsSwiftSelf(false), IsSwiftError(false) {}
198+
IsSwiftSelf(false), IsSwiftError(false), IsCFGuardTarget(false) {}
198199

199200
void setAttributes(const CallBase *Call, unsigned ArgIdx);
200201

llvm/include/llvm/IR/CallingConv.h

+6
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ namespace CallingConv {
8080
/// be performed.
8181
Tail = 18,
8282

83+
/// Special calling convention on Windows for calling the Control
84+
/// Guard Check ICall funtion. The function takes exactly one argument
85+
/// (address of the target function) passed in the first argument register,
86+
/// and has no return value. All register values are preserved.
87+
CFGuard_Check = 19,
88+
8389
// Target - This is the start of the target-specific calling conventions,
8490
// e.g. fastcall and thiscall on X86.
8591
FirstTargetCC = 64,

llvm/include/llvm/IR/InstrTypes.h

+5
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,11 @@ struct OperandBundleUse {
10391039
return getTagID() == LLVMContext::OB_funclet;
10401040
}
10411041

1042+
/// Return true if this is a "cfguardtarget" operand bundle.
1043+
bool isCFGuardTargetOperandBundle() const {
1044+
return getTagID() == LLVMContext::OB_cfguardtarget;
1045+
}
1046+
10421047
private:
10431048
/// Pointer to an entry in LLVMContextImpl::getOrInsertBundleTag.
10441049
StringMapEntry<uint32_t> *Tag;

llvm/include/llvm/IR/LLVMContext.h

+1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class LLVMContext {
8585
OB_deopt = 0, // "deopt"
8686
OB_funclet = 1, // "funclet"
8787
OB_gc_transition = 2, // "gc-transition"
88+
OB_cfguardtarget = 3, // "cfguardtarget"
8889
};
8990

9091
/// getMDKindID - Return a unique non-zero ID for the specified metadata kind.

llvm/include/llvm/InitializePasses.h

+2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ void initializeCFGOnlyPrinterLegacyPassPass(PassRegistry&);
9191
void initializeCFGOnlyViewerLegacyPassPass(PassRegistry&);
9292
void initializeCFGPrinterLegacyPassPass(PassRegistry&);
9393
void initializeCFGSimplifyPassPass(PassRegistry&);
94+
void initializeCFGuardPass(PassRegistry&);
95+
void initializeCFGuardLongjmpPass(PassRegistry&);
9496
void initializeCFGViewerLegacyPassPass(PassRegistry&);
9597
void initializeCFIInstrInserterPass(PassRegistry&);
9698
void initializeCFLAndersAAWrapperPassPass(PassRegistry&);

llvm/include/llvm/MC/MCObjectFileInfo.h

+2
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ class MCObjectFileInfo {
211211
MCSection *XDataSection;
212212
MCSection *SXDataSection;
213213
MCSection *GFIDsSection;
214+
MCSection *GLJMPSection;
214215

215216
public:
216217
void InitMCObjectFileInfo(const Triple &TT, bool PIC, MCContext &ctx,
@@ -379,6 +380,7 @@ class MCObjectFileInfo {
379380
MCSection *getXDataSection() const { return XDataSection; }
380381
MCSection *getSXDataSection() const { return SXDataSection; }
381382
MCSection *getGFIDsSection() const { return GFIDsSection; }
383+
MCSection *getGLJMPSection() const { return GLJMPSection; }
382384

383385
MCSection *getEHFrameSection() {
384386
return EHFrameSection;

llvm/include/llvm/Target/TargetCallingConv.td

+5
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ class CCIfSwiftSelf<CCAction A> : CCIf<"ArgFlags.isSwiftSelf()", A> {
5151
class CCIfSwiftError<CCAction A> : CCIf<"ArgFlags.isSwiftError()", A> {
5252
}
5353

54+
/// CCIfCFGuardTarget - If the current argument has cfguardtarget parameter
55+
/// attribute, apply Action A.
56+
class CCIfCFGuardTarget<CCAction A> : CCIf<"ArgFlags.isCFGuardTarget()", A> {
57+
}
58+
5459
/// CCIfConsecutiveRegs - If the current argument has InConsecutiveRegs
5560
/// parameter attribute, apply Action A.
5661
class CCIfConsecutiveRegs<CCAction A> : CCIf<"ArgFlags.isInConsecutiveRegs()", A> {
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===-- CFGuard.h - CFGuard Transformations ---------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===---------------------------------------------------------------------===//
8+
// Windows Control Flow Guard passes (/guard:cf).
9+
//===---------------------------------------------------------------------===//
10+
11+
#ifndef LLVM_TRANSFORMS_CFGUARD_H
12+
#define LLVM_TRANSFORMS_CFGUARD_H
13+
14+
namespace llvm {
15+
16+
class FunctionPass;
17+
18+
/// Insert Control FLow Guard checks on indirect function calls.
19+
FunctionPass *createCFGuardCheckPass();
20+
21+
/// Insert Control FLow Guard dispatches on indirect function calls.
22+
FunctionPass *createCFGuardDispatchPass();
23+
24+
} // namespace llvm
25+
26+
#endif

0 commit comments

Comments
 (0)