Skip to content

Commit a9dd959

Browse files
rjmccallahmedbougacha
authored andcommitted
Add support for the new pointer authentication builtins.
Patch by Akira Hatanaka and me.
1 parent 4ec8ebf commit a9dd959

37 files changed

+1529
-3
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,6 +1147,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
11471147
/// space.
11481148
QualType removeAddrSpaceQualType(QualType T) const;
11491149

1150+
/// Return the "other" type-specific discriminator for the given type.
1151+
uint16_t getPointerAuthTypeDiscriminator(QualType T);
1152+
11501153
/// Apply Objective-C protocol qualifiers to the given type.
11511154
/// \param allowOnPointerType specifies if we can apply protocol
11521155
/// qualifiers on ObjCObjectPointerType. It can be set to true when

clang/include/clang/AST/StableHash.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ class StringRef;
2020
}
2121

2222
namespace clang {
23+
class ASTContext;
24+
2325
/// Compute a stable 64-bit hash of the given string.
2426
///
2527
/// The exact algorithm is the little-endian interpretation of the
@@ -30,6 +32,15 @@ namespace clang {
3032
/// the same across different compiler versions and target platforms.
3133
uint64_t getStableStringHash(llvm::StringRef string);
3234

35+
/// Compute a pointer-auth extra discriminator for the given string,
36+
/// suitable for both the blend operation and the __ptrauth qualifier.
37+
///
38+
/// The result of this hash will be the same across different compiler
39+
/// versions but may vary between targets due to differences in the
40+
/// range of discriminators desired by the target.
41+
uint64_t getPointerAuthStringDiscriminator(const ASTContext &ctx,
42+
llvm::StringRef string);
43+
3344
} // end namespace clang
3445

3546
#endif

clang/include/clang/Basic/Builtins.def

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,6 +1499,16 @@ BUILTIN(__builtin_coro_end, "bv*Ib", "n")
14991499
BUILTIN(__builtin_coro_suspend, "cIb", "n")
15001500
BUILTIN(__builtin_coro_param, "bv*v*", "n")
15011501

1502+
// Pointer authentication builtins.
1503+
BUILTIN(__builtin_ptrauth_strip, "v*v*i", "tnc")
1504+
BUILTIN(__builtin_ptrauth_blend_discriminator, "zv*i", "tnc")
1505+
BUILTIN(__builtin_ptrauth_sign_constant, "v*v*iv*", "tnc")
1506+
BUILTIN(__builtin_ptrauth_sign_unauthenticated, "v*v*iv*", "tnc")
1507+
BUILTIN(__builtin_ptrauth_sign_generic_data, "zv*v*", "tnc")
1508+
BUILTIN(__builtin_ptrauth_auth_and_resign, "v*v*iv*iv*", "tn")
1509+
BUILTIN(__builtin_ptrauth_auth, "v*v*iv*", "tn")
1510+
BUILTIN(__builtin_ptrauth_string_discriminator, "zcC*", "nc")
1511+
15021512
// OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions.
15031513
// We need the generic prototype, since the packet type could be anything.
15041514
LANGBUILTIN(read_pipe, "i.", "tn", OCLC20_LANG)

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,7 @@ def ZeroLengthArray : DiagGroup<"zero-length-array">;
690690
def GNUZeroLineDirective : DiagGroup<"gnu-zero-line-directive">;
691691
def GNUZeroVariadicMacroArguments : DiagGroup<"gnu-zero-variadic-macro-arguments">;
692692
def Fallback : DiagGroup<"fallback">;
693+
def PtrAuthNullPointers : DiagGroup<"ptrauth-null-pointers">;
693694

694695
// This covers both the deprecated case (in C++98)
695696
// and the extension case (in C++11 onwards).

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,36 @@ def warn_fortify_source_size_mismatch : Warning<
736736
"'%0' size argument is too large; destination buffer has size %1,"
737737
" but size argument is %2">, InGroup<FortifySource>;
738738

739+
def err_ptrauth_disabled_target :
740+
Error<"this target does not support pointer authentication">;
741+
def err_ptrauth_disabled :
742+
Error<"pointer authentication is disabled for the current target">;
743+
def err_ptrauth_invalid_key :
744+
Error<"%0 does not identify a valid pointer authentication key for "
745+
"the current target">;
746+
def err_ptrauth_value_bad_type :
747+
Error<"%select{signed value|extra discriminator|blended pointer|blended "
748+
"integer}0 must have %select{pointer|integer|pointer or integer}1 "
749+
"type; type here is %2">;
750+
def err_ptrauth_bad_constant_pointer :
751+
Error<"argument to ptrauth_sign_constant must refer to a global variable "
752+
"or function">;
753+
def err_ptrauth_bad_constant_discriminator :
754+
Error<"discriminator argument to ptrauth_sign_constant must be a constant "
755+
"integer, the address of the global variable where the result "
756+
"will be stored, or a blend of the two">;
757+
def warn_ptrauth_sign_null_pointer :
758+
Warning<"signing a null pointer will yield a non-null pointer">,
759+
InGroup<PtrAuthNullPointers>;
760+
def warn_ptrauth_auth_null_pointer :
761+
Warning<"authenticating a null pointer will almost certainly trap">,
762+
InGroup<PtrAuthNullPointers>;
763+
def err_ptrauth_string_not_literal : Error<
764+
"argument must be a string literal%select{| of char type}0">;
765+
def err_ptrauth_type_disc_variably_modified : Error<
766+
"cannot pass variably-modified type %0 to "
767+
"'__builtin_ptrauth_type_discriminator'">;
768+
739769
/// main()
740770
// static main() is not an error in C, just in C++.
741771
def warn_static_main : Warning<"'main' should not be declared static">,

clang/include/clang/Basic/TargetInfo.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,6 +1234,11 @@ class TargetInfo : public virtual TransferrableTargetInfo,
12341234

12351235
const LangASMap &getAddressSpaceMap() const { return *AddrSpaceMap; }
12361236

1237+
/// Determine whether the given pointer-authentication key is valid.
1238+
///
1239+
/// The value has been coerced to type 'int'.
1240+
virtual bool validatePointerAuthKey(const llvm::APSInt &value) const;
1241+
12371242
/// Map from the address space field in builtin description strings to the
12381243
/// language address space.
12391244
virtual LangAS getOpenCLBuiltinAddressSpace(unsigned AS) const {

clang/include/clang/Basic/TokenKinds.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,8 @@ KEYWORD(__array_extent , KEYCXX)
529529
KEYWORD(__private_extern__ , KEYALL)
530530
KEYWORD(__module_private__ , KEYALL)
531531

532+
KEYWORD(__builtin_ptrauth_type_discriminator, KEYALL)
533+
532534
// Extension that will be enabled for Microsoft, Borland and PS4, but can be
533535
// disabled via '-fno-declspec'.
534536
KEYWORD(__declspec , 0)

clang/include/clang/Basic/TypeTraits.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ namespace clang {
104104
/// __alignof returns the preferred alignment of a type, the alignment
105105
/// clang will attempt to give an object of the type if allowed by ABI.
106106
UETT_PreferredAlignOf,
107+
/// __builtin_ptrauth_type_discriminator
108+
UETT_PtrAuthTypeDiscriminator,
107109
};
108110
}
109111

clang/include/clang/CodeGen/CodeGenABITypes.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "clang/CodeGen/CGFunctionInfo.h"
2929

3030
namespace llvm {
31+
class Constant;
3132
class DataLayout;
3233
class Module;
3334
class Function;
@@ -84,6 +85,23 @@ llvm::Type *convertTypeForMemory(CodeGenModule &CGM, QualType T);
8485
unsigned getLLVMFieldNumber(CodeGenModule &CGM,
8586
const RecordDecl *RD, const FieldDecl *FD);
8687

88+
/// Compute a stable hash of the given string.
89+
///
90+
/// The exact algorithm is the little-endian interpretation of the
91+
/// non-doubled (i.e. 64-bit) result of applying a SipHash-2-4 using
92+
/// a specific key value which can be found in the source.
93+
uint64_t computeStableStringHash(StringRef string);
94+
95+
/// Return a type discriminator for the given function type.
96+
uint16_t getPointerAuthTypeDiscriminator(CodeGenModule &CGM, QualType fnType);
97+
98+
/// Return a signed constant pointer.
99+
llvm::Constant *getConstantSignedPointer(CodeGenModule &CGM,
100+
llvm::Constant *pointer,
101+
unsigned key,
102+
llvm::Constant *storageAddress,
103+
llvm::Constant *otherDiscriminator);
104+
87105
/// Returns the default constructor for a C struct with non-trivially copyable
88106
/// fields, generating it if necessary. The returned function uses the `cdecl`
89107
/// calling convention, returns void, and takes a single argument that is a

clang/include/clang/CodeGen/ConstantInitBuilder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,12 @@ class ConstantAggregateBuilderBase {
199199
add(llvm::ConstantInt::get(intTy, value, isSigned));
200200
}
201201

202+
/// Add a signed pointer using the given pointer authentication schema.
203+
void addSignedPointer(llvm::Constant *pointer,
204+
unsigned key,
205+
bool useAddressDiscrimination,
206+
llvm::Constant *otherDiscriminator);
207+
202208
/// Add a null pointer of a specific type.
203209
void addNullPointer(llvm::PointerType *ptrTy) {
204210
add(llvm::ConstantPointerNull::get(ptrTy));

0 commit comments

Comments
 (0)