forked from OSchip/llvm-project
[clang][MinGW] Add `-mguard=cf` and `-mguard=cf-nochecks`
This option can be used to enable Control Flow Guard checks and generation of address-taken function table. They are equivalent to `/guard:cf` and `/guard:cf,nochecks` in clang-cl. Passing this flag to the Clang driver will also pass `--guard-cf` to the MinGW linker. This feature is disabled by default. The option `-mguard=none` is also available to explicitly disable this feature. Reviewed By: rnk Differential Revision: https://reviews.llvm.org/D132810
This commit is contained in:
parent
bf7c5f1fae
commit
a3a8bd00c8
|
@ -178,6 +178,10 @@ Attribute Changes in Clang
|
||||||
|
|
||||||
Windows Support
|
Windows Support
|
||||||
---------------
|
---------------
|
||||||
|
- For the MinGW driver, added the options ``-mguard=none``, ``-mguard=cf`` and
|
||||||
|
``-mguard=cf-nochecks`` (equivalent to ``/guard:cf-``, ``/guard:cf`` and
|
||||||
|
``/guard:cf,nochecks`` in clang-cl) for enabling Control Flow Guard checks
|
||||||
|
and generation of address-taken function table.
|
||||||
|
|
||||||
AIX Support
|
AIX Support
|
||||||
-----------
|
-----------
|
||||||
|
|
|
@ -3367,6 +3367,9 @@ def mwindows : Joined<["-"], "mwindows">, Group<m_Group>, Flags<[NoXarchOption]>
|
||||||
def mdll : Joined<["-"], "mdll">, Group<m_Group>, Flags<[NoXarchOption]>;
|
def mdll : Joined<["-"], "mdll">, Group<m_Group>, Flags<[NoXarchOption]>;
|
||||||
def municode : Joined<["-"], "municode">, Group<m_Group>, Flags<[NoXarchOption]>;
|
def municode : Joined<["-"], "municode">, Group<m_Group>, Flags<[NoXarchOption]>;
|
||||||
def mthreads : Joined<["-"], "mthreads">, Group<m_Group>, Flags<[NoXarchOption]>;
|
def mthreads : Joined<["-"], "mthreads">, Group<m_Group>, Flags<[NoXarchOption]>;
|
||||||
|
def mguard_EQ : Joined<["-"], "mguard=">, Group<m_Group>, Flags<[NoXarchOption]>,
|
||||||
|
HelpText<"Enable or disable Control Flow Guard checks and guard tables emission">,
|
||||||
|
Values<"none,cf,cf-nochecks">;
|
||||||
def mcpu_EQ : Joined<["-"], "mcpu=">, Group<m_Group>;
|
def mcpu_EQ : Joined<["-"], "mcpu=">, Group<m_Group>;
|
||||||
def mmcu_EQ : Joined<["-"], "mmcu=">, Group<m_Group>;
|
def mmcu_EQ : Joined<["-"], "mmcu=">, Group<m_Group>;
|
||||||
def msim : Flag<["-"], "msim">, Group<m_Group>;
|
def msim : Flag<["-"], "msim">, Group<m_Group>;
|
||||||
|
|
|
@ -169,6 +169,17 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
|
||||||
if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
|
if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
|
||||||
CmdArgs.push_back("--no-demangle");
|
CmdArgs.push_back("--no-demangle");
|
||||||
|
|
||||||
|
if (Arg *A = Args.getLastArg(options::OPT_mguard_EQ)) {
|
||||||
|
StringRef GuardArgs = A->getValue();
|
||||||
|
if (GuardArgs == "none")
|
||||||
|
CmdArgs.push_back("--no-guard-cf");
|
||||||
|
else if (GuardArgs == "cf" || GuardArgs == "cf-nochecks")
|
||||||
|
CmdArgs.push_back("--guard-cf");
|
||||||
|
else
|
||||||
|
D.Diag(diag::err_drv_unsupported_option_argument)
|
||||||
|
<< A->getSpelling() << GuardArgs;
|
||||||
|
}
|
||||||
|
|
||||||
CmdArgs.push_back("-o");
|
CmdArgs.push_back("-o");
|
||||||
const char *OutputFile = Output.getFilename();
|
const char *OutputFile = Output.getFilename();
|
||||||
// GCC implicitly adds an .exe extension if it is given an output file name
|
// GCC implicitly adds an .exe extension if it is given an output file name
|
||||||
|
@ -607,6 +618,26 @@ void toolchains::MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
||||||
addSystemInclude(DriverArgs, CC1Args, Base + "include");
|
addSystemInclude(DriverArgs, CC1Args, Base + "include");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void toolchains::MinGW::addClangTargetOptions(
|
||||||
|
const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
|
||||||
|
Action::OffloadKind DeviceOffloadKind) const {
|
||||||
|
if (Arg *A = DriverArgs.getLastArg(options::OPT_mguard_EQ)) {
|
||||||
|
StringRef GuardArgs = A->getValue();
|
||||||
|
if (GuardArgs == "none") {
|
||||||
|
// Do nothing.
|
||||||
|
} else if (GuardArgs == "cf") {
|
||||||
|
// Emit CFG instrumentation and the table of address-taken functions.
|
||||||
|
CC1Args.push_back("-cfguard");
|
||||||
|
} else if (GuardArgs == "cf-nochecks") {
|
||||||
|
// Emit only the table of address-taken functions.
|
||||||
|
CC1Args.push_back("-cfguard-no-checks");
|
||||||
|
} else {
|
||||||
|
getDriver().Diag(diag::err_drv_unsupported_option_argument)
|
||||||
|
<< A->getSpelling() << GuardArgs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void toolchains::MinGW::AddClangCXXStdlibIncludeArgs(
|
void toolchains::MinGW::AddClangCXXStdlibIncludeArgs(
|
||||||
const ArgList &DriverArgs, ArgStringList &CC1Args) const {
|
const ArgList &DriverArgs, ArgStringList &CC1Args) const {
|
||||||
if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
|
if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
|
||||||
|
|
|
@ -79,6 +79,10 @@ public:
|
||||||
void
|
void
|
||||||
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
|
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
|
||||||
llvm::opt::ArgStringList &CC1Args) const override;
|
llvm::opt::ArgStringList &CC1Args) const override;
|
||||||
|
void
|
||||||
|
addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
|
||||||
|
llvm::opt::ArgStringList &CC1Args,
|
||||||
|
Action::OffloadKind DeviceOffloadKind) const override;
|
||||||
void AddClangCXXStdlibIncludeArgs(
|
void AddClangCXXStdlibIncludeArgs(
|
||||||
const llvm::opt::ArgList &DriverArgs,
|
const llvm::opt::ArgList &DriverArgs,
|
||||||
llvm::opt::ArgStringList &CC1Args) const override;
|
llvm::opt::ArgStringList &CC1Args) const override;
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
// RUN: %clang --target=x86_64-w64-windows-gnu -### %s 2>&1 | FileCheck -check-prefixes=NO_CF,DEFAULT %s
|
||||||
|
// RUN: %clang --target=x86_64-w64-windows-gnu -### %s -mguard=none 2>&1 | FileCheck -check-prefixes=NO_CF,GUARD_NONE %s
|
||||||
|
// NO_CF: "-cc1"
|
||||||
|
// NO_CF-NOT: "-cfguard"
|
||||||
|
// NO_CF-NOT: "-cfguard-no-checks"
|
||||||
|
// NO_CF-NEXT: ld"
|
||||||
|
// NO_CF-NOT: "--guard-cf"
|
||||||
|
// DEFAULT-NOT: "--no-guard-cf"
|
||||||
|
// GUARD_NONE-SAME: "--no-guard-cf"
|
||||||
|
|
||||||
|
// RUN: %clang --target=x86_64-w64-windows-gnu -### %s -mguard=cf 2>&1 | FileCheck -check-prefix=GUARD_CF %s
|
||||||
|
// GUARD_CF: "-cc1"
|
||||||
|
// GUARD_CF-SAME: "-cfguard"
|
||||||
|
// GUARD_CF-NEXT: ld"
|
||||||
|
// GUARD_CF-SAME: "--guard-cf"
|
||||||
|
// GUARD_CF-NOT: "--no-guard-cf"
|
||||||
|
|
||||||
|
// RUN: %clang --target=x86_64-w64-windows-gnu -### %s -mguard=cf-nochecks 2>&1 | FileCheck -check-prefix=GUARD_NOCHECKS %s
|
||||||
|
// GUARD_NOCHECKS: "-cc1"
|
||||||
|
// GUARD_NOCHECKS-NOT: "-cfguard"
|
||||||
|
// GUARD_NOCHECKS-SAME: "-cfguard-no-checks"
|
||||||
|
// GUARD_NOCHECKS-NOT: "-cfguard"
|
||||||
|
// GUARD_NOCHECKS-NEXT: ld"
|
||||||
|
// GUARD_NOCHECKS-SAME: "--guard-cf"
|
||||||
|
// GUARD_NOCHECKS-NOT: "--no-guard-cf"
|
||||||
|
|
||||||
|
// RUN: %clang --target=x86_64-w64-windows-gnu -### %s -mguard=xxx 2>&1 | FileCheck -check-prefix=GUARD_UNKNOWN %s
|
||||||
|
// GUARD_UNKNOWN: error: unsupported argument 'xxx' to option '--mguard='
|
Loading…
Reference in New Issue