alvinhochun created this revision. Herald added a subscriber: mstorsjo. Herald added a project: All. alvinhochun published this revision for review. alvinhochun added reviewers: rnk, ajpaverd, mstorsjo, aaron.ballman. Herald added subscribers: cfe-commits, MaskRay. Herald added a project: clang.
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. Depends on D132808 <https://reviews.llvm.org/D132808> Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D132810 Files: clang/docs/ReleaseNotes.rst clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/MinGW.cpp clang/lib/Driver/ToolChains/MinGW.h clang/test/Driver/mingw-cfguard.c
Index: clang/test/Driver/mingw-cfguard.c =================================================================== --- /dev/null +++ clang/test/Driver/mingw-cfguard.c @@ -0,0 +1,34 @@ +// RUN: %clang -v -target x86_64-w64-windows-gnu -### %s 2>&1 | FileCheck -check-prefixes=NO_CF,DEFAULT %s +// RUN: %clang -v -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-SAME: {{$}} +// NO_CF-NEXT: ld" +// NO_CF-NOT: "--guard-cf" +// DEFAULT-NOT: "--no-guard-cf" +// GUARD_NONE-SAME: "--no-guard-cf" +// NO_CF-SAME: {{$}} + +// RUN: %clang -v -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-SAME: {{$}} +// GUARD_CF-NEXT: ld" +// GUARD_CF-SAME: "--guard-cf" +// GUARD_CF-NOT: "--no-guard-cf" +// GUARD_CF-SAME: {{$}} + +// RUN: %clang -v -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-SAME: {{$}} +// GUARD_NOCHECKS-NEXT: ld" +// GUARD_NOCHECKS-SAME: "--guard-cf" +// GUARD_NOCHECKS-NOT: "--no-guard-cf" +// GUARD_NOCHECKS-SAME: {{$}} + +// RUN: %clang -v -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=' Index: clang/lib/Driver/ToolChains/MinGW.h =================================================================== --- clang/lib/Driver/ToolChains/MinGW.h +++ clang/lib/Driver/ToolChains/MinGW.h @@ -79,6 +79,10 @@ 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; Index: clang/lib/Driver/ToolChains/MinGW.cpp =================================================================== --- clang/lib/Driver/ToolChains/MinGW.cpp +++ clang/lib/Driver/ToolChains/MinGW.cpp @@ -169,6 +169,18 @@ 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.equals_insensitive("none")) + CmdArgs.push_back("--no-guard-cf"); + else if (GuardArgs.equals_insensitive("cf") || + GuardArgs.equals_insensitive("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 +619,26 @@ 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.equals_insensitive("none")) { + // Do nothing. + } else if (GuardArgs.equals_insensitive("cf")) { + // Emit CFG instrumentation and the table of address-taken functions. + CC1Args.push_back("-cfguard"); + } else if (GuardArgs.equals_insensitive("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) || Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -3363,6 +3363,9 @@ 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>; Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -137,6 +137,10 @@ 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 -----------
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits