MaggieYi updated this revision to Diff 553409.
MaggieYi edited the summary of this revision.
MaggieYi added a comment.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.
The changes include:
1. Added an ARM::supportedExecuteOnly function to avoid the duplicated code.
2. Modified the `isExecuteOnlyTarget` function to only deal with the
`-mexecute-only` option.
3. Added `SanitizerKind::KCFI` to the SanitizerMask of
NotAllowedWithExecuteOnly.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D158614/new/
https://reviews.llvm.org/D158614
Files:
clang/include/clang/Basic/DiagnosticCommonKinds.td
clang/include/clang/Basic/Sanitizers.h
clang/lib/Basic/CMakeLists.txt
clang/lib/Basic/Sanitizers.cpp
clang/lib/Driver/SanitizerArgs.cpp
clang/lib/Driver/ToolChains/Arch/ARM.cpp
clang/test/CodeGenObjCXX/crash-function-type.mm
clang/test/Driver/fsanitize.c
llvm/include/llvm/TargetParser/ARMTargetParser.h
llvm/lib/TargetParser/ARMTargetParser.cpp
Index: llvm/lib/TargetParser/ARMTargetParser.cpp
===================================================================
--- llvm/lib/TargetParser/ARMTargetParser.cpp
+++ llvm/lib/TargetParser/ARMTargetParser.cpp
@@ -598,3 +598,11 @@
llvm_unreachable("invalid arch name");
}
+
+bool ARM::supportedExecuteOnly(const Triple &TT) {
+ if (parseArchVersion(TT.getArchName()) < 7 &&
+ parseArch(TT.getArchName()) != ArchKind::ARMV6T2 &&
+ parseArch(TT.getArchName()) != ArchKind::ARMV6M)
+ return false;
+ return true;
+}
Index: llvm/include/llvm/TargetParser/ARMTargetParser.h
===================================================================
--- llvm/include/llvm/TargetParser/ARMTargetParser.h
+++ llvm/include/llvm/TargetParser/ARMTargetParser.h
@@ -259,6 +259,9 @@
/// string then the triple's arch name is used.
StringRef getARMCPUForArch(const llvm::Triple &Triple, StringRef MArch = {});
+/// Return true if the arch supports the execute-only output. Currently, the
+/// execute-only output is only supported on ARMv6T2 and ARMv7 and above.
+bool supportedExecuteOnly(const Triple &TT);
} // namespace ARM
} // namespace llvm
Index: clang/test/Driver/fsanitize.c
===================================================================
--- clang/test/Driver/fsanitize.c
+++ clang/test/Driver/fsanitize.c
@@ -970,3 +970,19 @@
// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=undefined,function -mcmodel=large %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION-CODE-MODEL
// CHECK-UBSAN-FUNCTION-CODE-MODEL: error: invalid argument '-fsanitize=function' only allowed with '-mcmodel=small'
+
+// RUN: not %clang --target=x86_64-sie-ps5 -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION
+// RUN: not %clang --target=x86_64-sie-ps5 -fsanitize=undefined -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION
+// RUN: not %clang --target=x86_64-sie-ps5 -fsanitize=kcfi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-KCFI
+// RUN: not %clang --target=x86_64-sie-ps5 -fsanitize=function -fsanitize=kcfi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-KCFI --check-prefix=CHECK-UBSAN-FUNCTION
+// RUN: %clang --target=x86_64-sie-ps5 -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-UNDEFINED
+
+// RUN: not %clang --target=armv6t2-eabi -mexecute-only -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION
+// RUN: not %clang --target=armv6t2-eabi -mexecute-only -fsanitize=undefined -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION
+// RUN: not %clang --target=armv6t2-eabi -mexecute-only -fsanitize=kcfi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-KCFI
+// RUN: not %clang --target=armv6t2-eabi -mexecute-only -fsanitize=function -fsanitize=kcfi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-KCFI --check-prefix=CHECK-UBSAN-FUNCTION
+// RUN: %clang --target=armv6t2-eabi -mexecute-only -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-UNDEFINED
+
+// CHECK-UBSAN-KCFI-DAG: error: unsupported option '-fsanitize=kcfi' for the execute only target {{('x86_64-sie-ps5'|'armv6t2-unknown-unknown-eabi')}}
+// CHECK-UBSAN-FUNCTION-DAG: error: unsupported option '-fsanitize=function' for the execute only target {{('x86_64-sie-ps5'|'armv6t2-unknown-unknown-eabi')}}
+// CHECK-UBSAN-UNDEFINED-NOT: error: unsupported option '-fsanitize=function' for the execute only target {{('x86_64-sie-ps5'|'armv6t2-unknown-unknown-eabi')}}
Index: clang/test/CodeGenObjCXX/crash-function-type.mm
===================================================================
--- clang/test/CodeGenObjCXX/crash-function-type.mm
+++ clang/test/CodeGenObjCXX/crash-function-type.mm
@@ -1,3 +1,6 @@
+// Mark test as unsupported on PS5 due to PS5 doesn't support function sanitizer.
+// UNSUPPORTED: target=x86_64-sie-ps5
+
// RUN: %clang_cc1 -fblocks -fsanitize=function -emit-llvm %s -o %t
void g(void (^)());
Index: clang/lib/Driver/ToolChains/Arch/ARM.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Arch/ARM.cpp
+++ clang/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -843,10 +843,9 @@
// Cannot be combined with -mno-movt.
if (Arg *A = Args.getLastArg(options::OPT_mexecute_only, options::OPT_mno_execute_only)) {
if (A->getOption().matches(options::OPT_mexecute_only)) {
- if (getARMSubArchVersionNumber(Triple) < 7 &&
- llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6T2 &&
- llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6M)
- D.Diag(diag::err_target_unsupported_execute_only) << Triple.getArchName();
+ if (!llvm::ARM::supportedExecuteOnly(Triple))
+ D.Diag(diag::err_target_unsupported_execute_only)
+ << Triple.getArchName();
else if (llvm::ARM::parseArch(Triple.getArchName()) == llvm::ARM::ArchKind::ARMV6M) {
if (Arg *PIArg = Args.getLastArg(options::OPT_fropi, options::OPT_frwpi,
options::OPT_fpic, options::OPT_fpie,
Index: clang/lib/Driver/SanitizerArgs.cpp
===================================================================
--- clang/lib/Driver/SanitizerArgs.cpp
+++ clang/lib/Driver/SanitizerArgs.cpp
@@ -37,6 +37,8 @@
SanitizerKind::Vptr | SanitizerKind::CFI;
static const SanitizerMask NotAllowedWithTrap = SanitizerKind::Vptr;
static const SanitizerMask NotAllowedWithMinimalRuntime = SanitizerKind::Vptr;
+static const SanitizerMask NotAllowedWithExecuteOnly =
+ SanitizerKind::Function | SanitizerKind::KCFI;
static const SanitizerMask RequiresPIE =
SanitizerKind::DataFlow | SanitizerKind::Scudo;
static const SanitizerMask NeedsUnwindTables =
@@ -395,6 +397,22 @@
DiagnosedKinds |= SanitizerKind::Function;
}
}
+ // -fsanitize=function and -fsanitize=kcfi instrument indirect function
+ // calls to load a type hash before the function label. Therefore, an
+ // execute-only target doesn't support the function and kcfi sanitizers.
+ const llvm::Triple &Triple = TC.getTriple();
+ if (isExecuteOnlyTarget(Triple, Args)) {
+ if (SanitizerMask KindsToDiagnose =
+ Add & NotAllowedWithExecuteOnly & ~DiagnosedKinds) {
+ if (DiagnoseErrors) {
+ std::string Desc = describeSanitizeArg(Arg, KindsToDiagnose);
+ D.Diag(diag::err_unsupported_opt_for_execute_only_target)
+ << Desc << Triple.str();
+ }
+ DiagnosedKinds |= KindsToDiagnose;
+ }
+ Add &= ~NotAllowedWithExecuteOnly;
+ }
// FIXME: Make CFI on member function calls compatible with cross-DSO CFI.
// There are currently two problems:
@@ -457,6 +475,11 @@
if (MinimalRuntime) {
Add &= ~NotAllowedWithMinimalRuntime;
}
+ // `-fsanitize=function` is silently discarded on an execute-only target
+ // if implicitly enabled through group expansion.
+ if (isExecuteOnlyTarget(Triple, Args)) {
+ Add &= ~NotAllowedWithExecuteOnly;
+ }
if (CfiCrossDso)
Add &= ~SanitizerKind::CFIMFCall;
Add &= Supported;
Index: clang/lib/Basic/Sanitizers.cpp
===================================================================
--- clang/lib/Basic/Sanitizers.cpp
+++ clang/lib/Basic/Sanitizers.cpp
@@ -11,10 +11,14 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/Sanitizers.h"
+#include "clang/Driver/Options.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Option/ArgList.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/TargetParser/ARMTargetParser.h"
+#include "llvm/TargetParser/Triple.h"
using namespace clang;
@@ -112,4 +116,22 @@
.Default(llvm::AsanDetectStackUseAfterReturnMode::Invalid);
}
+bool isExecuteOnlyTarget(const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args) {
+ if (Triple.isPS5())
+ return true;
+
+ // On Arm, the clang `-mexecute-only` option is used to generate the
+ // execute-only output (no data access to code sections).
+ if (const llvm::opt::Arg *A =
+ Args.getLastArg(clang::driver::options::OPT_mexecute_only,
+ clang::driver::options::OPT_mno_execute_only)) {
+ if (A->getOption().matches(clang::driver::options::OPT_mexecute_only) &&
+ llvm::ARM::supportedExecuteOnly(Triple)) {
+ return true;
+ }
+ }
+
+ return false;
+}
} // namespace clang
Index: clang/lib/Basic/CMakeLists.txt
===================================================================
--- clang/lib/Basic/CMakeLists.txt
+++ clang/lib/Basic/CMakeLists.txt
@@ -1,4 +1,5 @@
set(LLVM_LINK_COMPONENTS
+ Option
Support
TargetParser
)
Index: clang/include/clang/Basic/Sanitizers.h
===================================================================
--- clang/include/clang/Basic/Sanitizers.h
+++ clang/include/clang/Basic/Sanitizers.h
@@ -23,7 +23,11 @@
namespace llvm {
class hash_code;
+class Triple;
+namespace opt {
+class ArgList;
}
+} // namespace llvm
namespace clang {
@@ -205,6 +209,11 @@
llvm::AsanDetectStackUseAfterReturnMode
AsanDetectStackUseAfterReturnModeFromString(StringRef modeStr);
+/// Return true if an execute-only target disallows data access to code
+/// sections.
+bool isExecuteOnlyTarget(const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args);
+
} // namespace clang
#endif // LLVM_CLANG_BASIC_SANITIZERS_H
Index: clang/include/clang/Basic/DiagnosticCommonKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -323,6 +323,8 @@
def err_target_unsupported_abi_for_triple : Error<
"ABI '%0' is not supported for '%1'">;
def err_unsupported_abi_for_opt : Error<"'%0' can only be used with the '%1' ABI">;
+def err_unsupported_opt_for_execute_only_target
+ : Error<"unsupported option '%0' for the execute only target '%1'">;
def err_mips_fp64_req : Error<
"'%0' can only be used if the target supports the mfhc1 and mthc1 instructions">;
def err_target_unknown_fpmath : Error<"unknown FP unit '%0'">;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits