[llvm] e7e67c9 - Add Windows ehcont section support (/guard:ehcont).
via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 3 19:47:48 PST 2021
Author: Wang, Pengfei
Date: 2021-03-04T11:47:29+08:00
New Revision: e7e67c930ae59151affcd57bd49d650e4dac3468
URL: https://github.com/llvm/llvm-project/commit/e7e67c930ae59151affcd57bd49d650e4dac3468
DIFF: https://github.com/llvm/llvm-project/commit/e7e67c930ae59151affcd57bd49d650e4dac3468.diff
LOG: Add Windows ehcont section support (/guard:ehcont).
Add option /guard:ehcont
Reviewed By: rnk
Differential Revision: https://reviews.llvm.org/D96709
Added:
Modified:
clang/docs/UsersManual.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/lib/Driver/ToolChains/MSVC.cpp
clang/test/CodeGen/cfguardtable.c
clang/test/Driver/cl-options.c
llvm/docs/ReleaseNotes.rst
Removed:
################################################################################
diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index b762bf9a542b..c668645aaeca 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -3523,7 +3523,8 @@ Execute ``clang-cl /?`` to see a list of supported options:
/Gs Use stack probes (default)
/Gs<value> Set stack probe size (default 4096)
/guard:<value> Enable Control Flow Guard with /guard:cf,
- or only the table with /guard:cf,nochecks
+ or only the table with /guard:cf,nochecks.
+ Enable EH Continuation Guard with /guard:ehcont
/Gv Set __vectorcall as a default calling convention
/Gw- Don't put each data item in its own section
/Gw Put each data item in its own section
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 832f7fad3551..50503dbe4f84 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -42,6 +42,7 @@ CODEGENOPT(Backchain , 1, 0) ///< -mbackchain
CODEGENOPT(IgnoreXCOFFVisibility , 1, 0) ///< -mignore-xcoff-visibility
CODEGENOPT(ControlFlowGuardNoChecks , 1, 0) ///< -cfguard-no-checks
CODEGENOPT(ControlFlowGuard , 1, 0) ///< -cfguard
+CODEGENOPT(EHContGuard , 1, 0) ///< -ehcontguard
CODEGENOPT(CXAAtExit , 1, 1) ///< Use __cxa_atexit for calling destructors.
CODEGENOPT(RegisterGlobalDtorsWithAtExit, 1, 1) ///< Use atexit or __cxa_atexit to register global destructors.
CODEGENOPT(CXXCtorDtorAliases, 1, 0) ///< Emit complete ctors/dtors as linker
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 72213ed51ce2..2f57895d4c23 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4859,6 +4859,9 @@ def cfguard_no_checks : Flag<["-"], "cfguard-no-checks">,
def cfguard : Flag<["-"], "cfguard">,
HelpText<"Emit Windows Control Flow Guard tables and checks">,
MarshallingInfoFlag<CodeGenOpts<"ControlFlowGuard">>;
+def ehcontguard : Flag<["-"], "ehcontguard">,
+ HelpText<"Emit Windows EH Continuation Guard tables">,
+ MarshallingInfoFlag<CodeGenOpts<"EHContGuard">>;
def fdenormal_fp_math_f32_EQ : Joined<["-"], "fdenormal-fp-math-f32=">,
Group<f_Group>;
@@ -5857,7 +5860,8 @@ def _SLASH_Fo : CLCompileJoined<"Fo">,
HelpText<"Set output object file (with /c)">,
MetaVarName<"<file or dir/>">;
def _SLASH_guard : CLJoined<"guard:">,
- HelpText<"Enable Control Flow Guard with /guard:cf, or only the table with /guard:cf,nochecks">;
+ HelpText<"Enable Control Flow Guard with /guard:cf, or only the table with /guard:cf,nochecks. "
+ "Enable EH Continuation Guard with /guard:ehcont">;
def _SLASH_GX : CLFlag<"GX">,
HelpText<"Deprecated; use /EHsc">;
def _SLASH_GX_ : CLFlag<"GX-">,
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 802a13fb41fc..b23d995683bf 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -552,6 +552,10 @@ void CodeGenModule::Release() {
// Function ID tables for Control Flow Guard (cfguard=1).
getModule().addModuleFlag(llvm::Module::Warning, "cfguard", 1);
}
+ if (CodeGenOpts.EHContGuard) {
+ // Function ID tables for EH Continuation Guard.
+ getModule().addModuleFlag(llvm::Module::Warning, "ehcontguard", 1);
+ }
if (CodeGenOpts.OptimizationLevel > 0 && CodeGenOpts.StrictVTablePointers) {
// We don't support LTO with 2 with
diff erent StrictVTablePointers
// FIXME: we could support it by stripping all the information introduced
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index df2b20702efc..eb09d722d304 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7076,14 +7076,19 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
if (Arg *A = Args.getLastArg(options::OPT__SLASH_guard)) {
StringRef GuardArgs = A->getValue();
- // The only valid options are "cf", "cf,nochecks", and "cf-".
+ // The only valid options are "cf", "cf,nochecks", "cf-", "ehcont" and
+ // "ehcont-".
if (GuardArgs.equals_lower("cf")) {
// Emit CFG instrumentation and the table of address-taken functions.
CmdArgs.push_back("-cfguard");
} else if (GuardArgs.equals_lower("cf,nochecks")) {
// Emit only the table of address-taken functions.
CmdArgs.push_back("-cfguard-no-checks");
- } else if (GuardArgs.equals_lower("cf-")) {
+ } else if (GuardArgs.equals_lower("ehcont")) {
+ // Emit EH continuation table.
+ CmdArgs.push_back("-ehcontguard");
+ } else if (GuardArgs.equals_lower("cf-") ||
+ GuardArgs.equals_lower("ehcont-")) {
// Do nothing, but we might want to emit a security warning in future.
} else {
D.Diag(diag::err_drv_invalid_value) << A->getSpelling() << GuardArgs;
diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp
index c95c5b61d6ae..96de02378ca2 100644
--- a/clang/lib/Driver/ToolChains/MSVC.cpp
+++ b/clang/lib/Driver/ToolChains/MSVC.cpp
@@ -509,6 +509,10 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-guard:cf");
} else if (GuardArgs.equals_lower("cf-")) {
CmdArgs.push_back("-guard:cf-");
+ } else if (GuardArgs.equals_lower("ehcont")) {
+ CmdArgs.push_back("-guard:ehcont");
+ } else if (GuardArgs.equals_lower("ehcont-")) {
+ CmdArgs.push_back("-guard:ehcont-");
}
}
diff --git a/clang/test/CodeGen/cfguardtable.c b/clang/test/CodeGen/cfguardtable.c
index 05284f6d23a6..c0212aea89e2 100644
--- a/clang/test/CodeGen/cfguardtable.c
+++ b/clang/test/CodeGen/cfguardtable.c
@@ -1,8 +1,10 @@
-// RUN: %clang_cc1 -cfguard-no-checks -emit-llvm %s -o - | FileCheck %s -check-prefix=CFGUARDNOCHECKS
-// RUN: %clang_cc1 -cfguard -emit-llvm %s -o - | FileCheck %s -check-prefix=CFGUARD
-
-void f() {}
-
-// Check that the cfguard metadata flag gets correctly set on the module.
-// CFGUARDNOCHECKS: !"cfguard", i32 1}
-// CFGUARD: !"cfguard", i32 2}
+// RUN: %clang_cc1 -cfguard-no-checks -emit-llvm %s -o - | FileCheck %s -check-prefix=CFGUARDNOCHECKS
+// RUN: %clang_cc1 -cfguard -emit-llvm %s -o - | FileCheck %s -check-prefix=CFGUARD
+// RUN: %clang_cc1 -ehcontguard -emit-llvm %s -o - | FileCheck %s -check-prefix=EHCONTGUARD
+
+void f() {}
+
+// Check that the cfguard metadata flag gets correctly set on the module.
+// CFGUARDNOCHECKS: !"cfguard", i32 1}
+// CFGUARD: !"cfguard", i32 2}
+// EHCONTGUARD: !"ehcontguard", i32 1}
diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c
index 0e07ea49e4b8..7d83b3d60b1e 100644
--- a/clang/test/Driver/cl-options.c
+++ b/clang/test/Driver/cl-options.c
@@ -614,6 +614,13 @@
// RUN: %clang_cl /guard:nochecks -### -- %s 2>&1 | FileCheck -check-prefix=CFGUARDNOCHECKSINVALID %s
// CFGUARDNOCHECKSINVALID: invalid value 'nochecks' in '/guard:'
+// RUN: %clang_cl -### -- %s 2>&1 | FileCheck -check-prefix=NOEHCONTGUARD %s
+// RUN: %clang_cl /guard:ehcont- -### -- %s 2>&1 | FileCheck -check-prefix=NOEHCONTGUARD %s
+// NOEHCONTGUARD-NOT: -ehcontguard
+
+// RUN: %clang_cl /guard:ehcont -### -- %s 2>&1 | FileCheck -check-prefix=EHCONTGUARD %s
+// EHCONTGUARD: -ehcontguard
+
// RUN: %clang_cl /guard:foo -### -- %s 2>&1 | FileCheck -check-prefix=CFGUARDINVALID %s
// CFGUARDINVALID: invalid value 'foo' in '/guard:'
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 1de11f0c9c2c..411505c41c5c 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -51,6 +51,9 @@ Non-comprehensive list of changes in this release
Makes programs 10x faster by doing Special New Thing.
+* Windows Control-flow Enforcement Technology: the ``-ehcontguard`` option now
+ emits valid unwind entrypoints which are validated when the context is being
+ set during exception handling.
Changes to the LLVM IR
----------------------
More information about the llvm-commits
mailing list