Skip to content

Commit 1e5cc6a

Browse files
committed
[AArch64][PAC] Error out early if missing PAuth support is needed
adjustTargetOptions() was only used by AMDGCN until ce2258c and has no in-tree users now. Let's add Diag argument like it was done in aaba371.
1 parent 62ce88f commit 1e5cc6a

File tree

9 files changed

+124
-2
lines changed

9 files changed

+124
-2
lines changed

clang/include/clang/Basic/DiagnosticDriverKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,9 @@ def err_stack_tagging_requires_hardware_feature : Error<
532532
"'-fsanitize=memtag-stack' requires hardware support (+memtag). For Armv8 or "
533533
"Armv9, try compiling with -march=armv8a+memtag or -march=armv9a+memtag">;
534534

535+
def err_pauth_cpu_feature_missing : Error<
536+
"A feature is requested that needs CPU with Pointer Authentication support">;
537+
535538
def err_cmse_pi_are_incompatible : Error<
536539
"cmse is not compatible with %select{RWPI|ROPI}0">;
537540

clang/include/clang/Basic/PointerAuthOptions.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,14 @@ struct PointerAuthOptions {
234234
/// Should return addresses be authenticated?
235235
bool ReturnAddresses = false;
236236

237+
/// Returns all schemas being used.
238+
///
239+
/// Returns all schemas that are mentioned by this instance of
240+
/// PointerAuthOptions (possibly with duplicates).
241+
///
242+
/// FIXME: Handle ReturnAddresses here.
243+
std::vector<PointerAuthSchema> getAllUsedSchemas() const;
244+
237245
/// The ABI for C function pointers.
238246
PointerAuthSchema FunctionPointers;
239247

clang/include/clang/Basic/TargetInfo.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1262,7 +1262,8 @@ class TargetInfo : public TransferrableTargetInfo,
12621262
virtual void adjust(DiagnosticsEngine &Diags, LangOptions &Opts);
12631263

12641264
/// Adjust target options based on codegen options.
1265-
virtual void adjustTargetOptions(const CodeGenOptions &CGOpts,
1265+
virtual void adjustTargetOptions(DiagnosticsEngine &Diags,
1266+
const CodeGenOptions &CGOpts,
12661267
TargetOptions &TargetOpts) const {}
12671268

12681269
/// Initialize the map with the default set of target features for the

clang/lib/Basic/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ add_clang_library(clangBasic
7676
OpenMPKinds.cpp
7777
OperatorPrecedence.cpp
7878
ParsedAttrInfo.cpp
79+
PointerAuthOptions.cpp
7980
ProfileList.cpp
8081
NoSanitizeList.cpp
8182
SanitizerSpecialCaseList.cpp
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===- PointerAuthOptions.cpp -----------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "clang/Basic/PointerAuthOptions.h"
10+
11+
using namespace clang;
12+
13+
std::vector<PointerAuthSchema>
14+
clang::PointerAuthOptions::getAllUsedSchemas() const {
15+
std::vector<PointerAuthSchema> Result;
16+
Result.push_back(FunctionPointers);
17+
Result.push_back(BlockInvocationFunctionPointers);
18+
Result.push_back(BlockHelperFunctionPointers);
19+
Result.push_back(BlockByrefHelperFunctionPointers);
20+
Result.push_back(BlockDescriptorPointers);
21+
Result.push_back(ObjCMethodListFunctionPointers);
22+
Result.push_back(ObjCMethodListPointer);
23+
Result.push_back(CXXVTablePointers);
24+
Result.push_back(CXXTypeInfoVTablePointer);
25+
Result.push_back(CXXVTTVTablePointers);
26+
Result.push_back(CXXVirtualFunctionPointers);
27+
Result.push_back(CXXVirtualVariadicFunctionPointers);
28+
Result.push_back(CXXMemberFunctionPointers);
29+
Result.push_back(ObjCIsaPointers);
30+
Result.push_back(ObjCSuperPointers);
31+
Result.push_back(InitFiniPointers);
32+
assert(sizeof(Result[0]) * Result.size() + 4 == sizeof(PointerAuthOptions));
33+
return Result;
34+
}

clang/lib/Basic/Targets/AArch64.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "AArch64.h"
14+
#include "clang/Basic/DiagnosticDriver.h"
1415
#include "clang/Basic/LangOptions.h"
16+
#include "clang/Basic/PointerAuthOptions.h"
1517
#include "clang/Basic/TargetBuiltins.h"
1618
#include "clang/Basic/TargetInfo.h"
1719
#include "llvm/ADT/APSInt.h"
@@ -197,6 +199,34 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
197199
Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount";
198200
}
199201

202+
void AArch64TargetInfo::validatePAuthOptions(
203+
DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts) const {
204+
auto NeedsHWSupport = [](const PointerAuthSchema &Schema) {
205+
switch (Schema.getKind()) {
206+
case PointerAuthSchema::Kind::None:
207+
case PointerAuthSchema::Kind::Soft:
208+
return false;
209+
case PointerAuthSchema::Kind::ARM8_3:
210+
return true;
211+
}
212+
llvm_unreachable("Unexpected authentication kind");
213+
};
214+
215+
bool NeedsFeatPAuth = false;
216+
NeedsFeatPAuth |= CGOpts.PointerAuth.ReturnAddresses;
217+
for (auto Schema : CGOpts.PointerAuth.getAllUsedSchemas())
218+
NeedsFeatPAuth |= NeedsHWSupport(Schema);
219+
220+
if (NeedsFeatPAuth && !HasPAuth)
221+
Diags.Report(diag::err_pauth_cpu_feature_missing);
222+
}
223+
224+
void AArch64TargetInfo::adjustTargetOptions(DiagnosticsEngine &Diags,
225+
const CodeGenOptions &CGOpts,
226+
TargetOptions &TargetOpts) const {
227+
validatePAuthOptions(Diags, CGOpts);
228+
}
229+
200230
StringRef AArch64TargetInfo::getABI() const { return ABI; }
201231

202232
bool AArch64TargetInfo::setABI(const std::string &Name) {

clang/lib/Basic/Targets/AArch64.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
9191
public:
9292
AArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
9393

94+
void validatePAuthOptions(DiagnosticsEngine &Diags,
95+
const CodeGenOptions &CGOpts) const;
96+
void adjustTargetOptions(DiagnosticsEngine &Diags,
97+
const CodeGenOptions &CGOpts,
98+
TargetOptions &TargetOpts) const override;
99+
94100
StringRef getABI() const override;
95101
bool setABI(const std::string &Name) override;
96102

clang/lib/Frontend/CompilerInstance.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ bool CompilerInstance::createTarget() {
152152
getTarget().adjust(getDiagnostics(), getLangOpts());
153153

154154
// Adjust target options based on codegen options.
155-
getTarget().adjustTargetOptions(getCodeGenOpts(), getTargetOpts());
155+
getTarget().adjustTargetOptions(getDiagnostics(), getCodeGenOpts(),
156+
getTargetOpts());
156157

157158
if (auto *Aux = getAuxTarget())
158159
getTarget().setAuxTarget(Aux);
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Test that features requiring FEAT_PAuth fail early:
2+
// RUN: not %clang %s -S -o - -target aarch64-linux-gnu -mcpu=cortex-a72 -mbranch-protection=pauthabi 2>&1 | FileCheck %s --check-prefix=FAIL
3+
// RUN: not %clang %s -S -o - -target aarch64-linux-gnu -mcpu=cortex-a72 -fptrauth-calls 2>&1 | FileCheck %s --check-prefix=FAIL
4+
// RUN: not %clang %s -S -o - -target aarch64-linux-gnu -mcpu=cortex-a72 -fptrauth-returns 2>&1 | FileCheck %s --check-prefix=FAIL
5+
// RUN: not %clang %s -S -o - -target aarch64-linux-gnu -mcpu=cortex-a72 -fptrauth-objc-isa 2>&1 | FileCheck %s --check-prefix=FAIL
6+
//
7+
// Note: at the time of writing, the following options are gated on -fptrauth-calls:
8+
// -fptrauth-init-fini
9+
// -fptrauth-function-pointer-type-discrimination
10+
// -fptrauth-vtable-pointer-address-discrimination
11+
// -fptrauth-vtable-pointer-type-discrimination
12+
// -fptrauth-block-descriptor-pointers
13+
14+
// Test that v8.2-compatible code is generated, if possible:
15+
// RUN: %clang %s -S -o - -target aarch64-linux-gnu -mcpu=cortex-a72 -mbranch-protection=pac-ret 2>&1 | FileCheck %s --check-prefix=COMPAT
16+
17+
// Several targets imply +pauth:
18+
// RUN: %clang %s -S -o - -target arm64e-apple-ios 2>&1 | FileCheck %s --check-prefix=PAUTH
19+
20+
void ext(void);
21+
22+
int f(void) {
23+
ext();
24+
return 0;
25+
}
26+
27+
// FAIL: error: A feature is requested that needs CPU with Pointer Authentication support
28+
29+
// COMPAT: f:
30+
// COMPAT: hint #25
31+
//
32+
// COMPAT: hint #29
33+
// COMPAT: ret
34+
35+
// PAUTH: f:
36+
// PAUTH: paci{{[ab]}}sp
37+
//
38+
// PAUTH: reta{{[ab]}}

0 commit comments

Comments
 (0)