[clang] a3a8bd0 - [clang][MinGW] Add `-mguard=cf` and `-mguard=cf-nochecks`
Martin Storsjö via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 8 23:56:22 PDT 2022
Author: Alvin Wong
Date: 2022-09-09T09:55:40+03:00
New Revision: a3a8bd00c8f1e094967a80e56485c421e312dd2e
URL: https://github.com/llvm/llvm-project/commit/a3a8bd00c8f1e094967a80e56485c421e312dd2e
DIFF: https://github.com/llvm/llvm-project/commit/a3a8bd00c8f1e094967a80e56485c421e312dd2e.diff
LOG: [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
Added:
clang/test/Driver/mingw-cfguard.c
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Driver/Options.td
clang/lib/Driver/ToolChains/MinGW.cpp
clang/lib/Driver/ToolChains/MinGW.h
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5bd812aca97f4..155eababa81e6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -178,6 +178,10 @@ Attribute Changes in Clang
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
-----------
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 3b8c2a99178fb..b9be33396fdfe 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3367,6 +3367,9 @@ def mwindows : Joined<["-"], "mwindows">, Group<m_Group>, Flags<[NoXarchOption]>
def mdll : Joined<["-"], "mdll">, Group<m_Group>, Flags<[NoXarchOption]>;
def municode : Joined<["-"], "municode">, 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 mmcu_EQ : Joined<["-"], "mmcu=">, Group<m_Group>;
def msim : Flag<["-"], "msim">, Group<m_Group>;
diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp
index ae7c4c56bf9e7..e7710bf12c080 100644
--- a/clang/lib/Driver/ToolChains/MinGW.cpp
+++ b/clang/lib/Driver/ToolChains/MinGW.cpp
@@ -169,6 +169,17 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_Z_Xlinker__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");
const char *OutputFile = Output.getFilename();
// 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");
}
+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(
const ArgList &DriverArgs, ArgStringList &CC1Args) const {
if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
diff --git a/clang/lib/Driver/ToolChains/MinGW.h b/clang/lib/Driver/ToolChains/MinGW.h
index f15f99dc8a8c0..531b2b9eabf3a 100644
--- a/clang/lib/Driver/ToolChains/MinGW.h
+++ b/clang/lib/Driver/ToolChains/MinGW.h
@@ -79,6 +79,10 @@ class LLVM_LIBRARY_VISIBILITY MinGW : public ToolChain {
void
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
+ void
+ addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args,
+ Action::OffloadKind DeviceOffloadKind) const override;
void AddClangCXXStdlibIncludeArgs(
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
diff --git a/clang/test/Driver/mingw-cfguard.c b/clang/test/Driver/mingw-cfguard.c
new file mode 100644
index 0000000000000..f88fd59098b8b
--- /dev/null
+++ b/clang/test/Driver/mingw-cfguard.c
@@ -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='
More information about the cfe-commits
mailing list