llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: Jon Roelofs (jroelofs)

<details>
<summary>Changes</summary>

The new builtin behaves like __builtin_ptrauth_auth_and_resign, but 
incorporates the address of the signing instruction (i.e. the 
`pacibsppc`/`paciasppc`) when performing the auth side, and subsequently 
re-signs using a different scheme. Authenticating the re-signed value will fail 
if and only if authenticating the original value with the incorporated pc would 
have failed.

---

Patch is 29.92 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/202742.diff


14 Files Affected:

- (modified) clang/docs/PointerAuthentication.rst (+16) 
- (modified) clang/include/clang/Basic/Builtins.td (+6) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+3-1) 
- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+14) 
- (modified) clang/lib/Headers/ptrauth.h (+38) 
- (modified) clang/lib/Sema/SemaChecking.cpp (+39-2) 
- (modified) clang/test/CodeGen/ptrauth-intrinsics.c (+14) 
- (modified) clang/test/Sema/ptrauth-intrinsics-macro.c (+5) 
- (modified) clang/test/Sema/ptrauth.c (+27) 
- (modified) llvm/include/llvm/IR/Intrinsics.td (+13) 
- (modified) llvm/lib/IR/Verifier.cpp (+9) 
- (modified) llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp (+47) 
- (modified) llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp (+61) 
- (added) 
llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-with-pc-and-resign.ll (+93) 


``````````diff
diff --git a/clang/docs/PointerAuthentication.rst 
b/clang/docs/PointerAuthentication.rst
index bf2520b32a3a4..9f0a30caf5343 100644
--- a/clang/docs/PointerAuthentication.rst
+++ b/clang/docs/PointerAuthentication.rst
@@ -687,6 +687,22 @@ computations may still be attackable.  In the future, 
Clang should be enhanced
 to guarantee non-attackability if these expressions are
 :ref:`safely-derived<Safe derivation>`.
 
+``ptrauth_auth_with_pc_and_resign``
+
+.. code-block:: c
+
+  ptrauth_auth_with_pc_and_resign(pointer, oldKey, oldDiscriminator, oldPC, 
newKey, newDiscriminator)
+
+Similar to :ref:`ptrauth_auth_and_resign`, but additionally requires that the
+signature includes the address of the signing instruction (i.e. uses 
`paciasppc`
+/ `pacibsppc` instead of `paciasp` / `pacibsp`). This authenticates ``pointer``
+signed with ``oldKey`` and ``oldDiscriminator`` at ``oldPC``, then resigns the
+raw-pointer result with ``newKey`` and ``newDiscriminator``.
+
+Note: ``oldKey`` must be ``ptrauth_key_asia`` (IA) or ``ptrauth_key_asib`` 
(IB),
+as only these keys support PC-based authentication instructions. Data keys
+(``ptrauth_key_asda`` / ``ptrauth_key_asdb``) are not supported.
+
 ``ptrauth_auth_function``
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index e7fb43be8794e..d8a3215cd8627 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -5013,6 +5013,12 @@ def PtrauthAuthAndResign : Builtin {
   let Prototype = "void*(void*,int,void*,int,void*)";
 }
 
+def PtrauthAuthWithPCAndResign : Builtin {
+  let Spellings = ["__builtin_ptrauth_auth_with_pc_and_resign"];
+  let Attributes = [CustomTypeChecking, NoThrow];
+  let Prototype = "void*(void*,int,void*,void*,int,void*)";
+}
+
 def PtrauthAuthLoadRelativeAndSign : Builtin {
   let Spellings = ["__builtin_ptrauth_auth_load_relative_and_sign"];
   let Attributes = [CustomTypeChecking, NoThrow];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d3e2d616a8b80..224726d35f294 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1010,7 +1010,7 @@ def err_ptrauth_invalid_key :
         "the current target">;
 def err_ptrauth_value_bad_type :
   Error<"%select{signed value|extra discriminator|blended pointer|blended "
-        "integer}0 must have %select{pointer|integer|pointer or integer}1 "
+        "integer|blended pc}0 must have %select{pointer|integer|pointer or 
integer}1 "
         "type; type here is %2">;
 def err_ptrauth_bad_constant_pointer :
   Error<"argument to ptrauth_sign_constant must refer to a global variable "
@@ -1025,6 +1025,8 @@ def warn_ptrauth_sign_null_pointer :
 def warn_ptrauth_auth_null_pointer :
   Warning<"authenticating a null pointer will almost certainly trap">,
   InGroup<PtrAuthNullPointers>;
+def err_ptrauth_auth_with_pc_and_resign_invalid_key :
+  Error<"ptrauth_auth_with_pc_and_resign only supports auth with IA and IB 
keys, not %0">;
 def err_ptrauth_string_not_literal : Error<
   "argument must be a string literal%select{| of char type}0">;
 def err_ptrauth_type_disc_undiscriminated : Error<
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 682b125890fe1..5f2ba6412da78 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -6249,6 +6249,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
 
   case Builtin::BI__builtin_ptrauth_auth:
   case Builtin::BI__builtin_ptrauth_auth_and_resign:
+  case Builtin::BI__builtin_ptrauth_auth_with_pc_and_resign:
   case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
   case Builtin::BI__builtin_ptrauth_blend_discriminator:
   case Builtin::BI__builtin_ptrauth_sign_generic_data:
@@ -6265,6 +6266,17 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
       Args[0] = Builder.CreatePtrToInt(Args[0], IntPtrTy);
 
     switch (BuiltinID) {
+    case Builtin::BI__builtin_ptrauth_auth_with_pc_and_resign:
+      // Convert oldDiscriminator (arg 2), oldPC (arg 3) and newDiscriminator
+      // (arg 5) to intptr_t
+      if (Args[2]->getType()->isPointerTy())
+        Args[2] = Builder.CreatePtrToInt(Args[2], IntPtrTy);
+      if (Args[3]->getType()->isPointerTy())
+        Args[3] = Builder.CreatePtrToInt(Args[3], IntPtrTy);
+      if (Args[5]->getType()->isPointerTy())
+        Args[5] = Builder.CreatePtrToInt(Args[5], IntPtrTy);
+      break;
+
     case Builtin::BI__builtin_ptrauth_auth_and_resign:
     case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
       if (Args[4]->getType()->isPointerTy())
@@ -6294,6 +6306,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
         return Intrinsic::ptrauth_auth;
       case Builtin::BI__builtin_ptrauth_auth_and_resign:
         return Intrinsic::ptrauth_resign;
+      case Builtin::BI__builtin_ptrauth_auth_with_pc_and_resign:
+        return Intrinsic::ptrauth_auth_with_pc_and_resign;
       case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
         return Intrinsic::ptrauth_resign_load_relative;
       case Builtin::BI__builtin_ptrauth_blend_discriminator:
diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h
index cde1b3c4ebbe2..3b34c42b22fb3 100644
--- a/clang/lib/Headers/ptrauth.h
+++ b/clang/lib/Headers/ptrauth.h
@@ -178,6 +178,33 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
   __builtin_ptrauth_auth_and_resign(__value, __old_key, __old_data, __new_key, 
\
                                     __new_data)
 
+/* Authenticate a pointer using a PC-based signature scheme and resign
+   it using a different scheme.
+
+   If the result is subsequently authenticated using the new scheme, that
+   authentication is guaranteed to fail if and only if the initial
+   authentication failed.
+
+   The value must be an expression of pointer type.
+   The key must be a constant expression of type ptrauth_key.
+   The extra data must be an expression of pointer or integer type;
+   if an integer, it will be coerced to ptrauth_extra_data_t.
+   The oldpc must be an expression of pointer or integer type representing
+   the PC value where the original signature was created.
+   The result will have the same type as the original value.
+
+   This operation is guaranteed to not leave the intermediate value
+   available for attack before it is re-signed. The authentication is
+   performed using autia171615/autib171615 instructions which include the
+   PC value in the signature.
+
+   Do not pass a null pointer to this function. A null pointer
+   will not successfully authenticate. */
+#define ptrauth_auth_with_pc_and_resign(__value, __old_key, __old_data,        
\
+                                        __old_pc, __new_key, __new_data)       
\
+  __builtin_ptrauth_auth_with_pc_and_resign(__value, __old_key, __old_data,    
\
+                                            __old_pc, __new_key, __new_data)
+
 /* Authenticate a pointer using one scheme, load 32bit value at offset addend
    from the pointer, and add this value to the pointer, sign using specified
    scheme.
@@ -396,6 +423,17 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
     __value;                                                                   
\
   })
 
+#define ptrauth_auth_with_pc_and_resign(__value, __old_key, __old_data,        
\
+                                        __old_pc, __new_key, __new_data)       
\
+  ({                                                                           
\
+    (void)__old_key;                                                           
\
+    (void)__old_data;                                                          
\
+    (void)__old_pc;                                                            
\
+    (void)__new_key;                                                           
\
+    (void)__new_data;                                                          
\
+    __value;                                                                   
\
+  })
+
 #define ptrauth_auth_load_relative_and_sign(__value, __old_key, __old_data,    
\
                                             __new_key, __new_data, __offset)   
\
   __extension__({                                                              
\
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index b8a3f48a32f24..1d64f666d347e 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -1550,7 +1550,8 @@ enum PointerAuthOpKind {
   PAO_SignGeneric,
   PAO_Discriminator,
   PAO_BlendPointer,
-  PAO_BlendInteger
+  PAO_BlendInteger,
+  PAO_BlendPC
 };
 }
 
@@ -1676,7 +1677,7 @@ static bool checkPointerAuthValue(Sema &S, Expr *&Arg, 
PointerAuthOpKind OpKind,
   };
   auto AllowsInteger = [](PointerAuthOpKind OpKind) {
     return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
-           OpKind == PAO_SignGeneric;
+           OpKind == PAO_SignGeneric || OpKind == PAO_BlendPC;
   };
 
   // Require the value to have the right range of type.
@@ -1695,6 +1696,7 @@ static bool checkPointerAuthValue(Sema &S, Expr *&Arg, 
PointerAuthOpKind OpKind,
         << unsigned(OpKind == PAO_Discriminator  ? 1
                     : OpKind == PAO_BlendPointer ? 2
                     : OpKind == PAO_BlendInteger ? 3
+                    : OpKind == PAO_BlendPC      ? 4
                                                  : 0)
         << unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 
0)
         << Arg->getType() << Arg->getSourceRange();
@@ -1861,6 +1863,39 @@ static ExprResult PointerAuthAuthAndResign(Sema &S, 
CallExpr *Call) {
   return Call;
 }
 
+static ExprResult PointerAuthAuthWithPCAndResign(Sema &S, CallExpr *Call) {
+  if (S.checkArgCount(Call, 6))
+    return ExprError();
+  if (checkPointerAuthEnabled(S, Call))
+    return ExprError();
+  if (checkPointerAuthValue(S, Call->getArgs()[0], PAO_Auth) ||
+      checkPointerAuthKey(S, Call->getArgs()[1]) ||
+      checkPointerAuthValue(S, Call->getArgs()[2], PAO_Discriminator) ||
+      checkPointerAuthValue(S, Call->getArgs()[3], PAO_BlendPC) ||
+      checkPointerAuthKey(S, Call->getArgs()[4]) ||
+      checkPointerAuthValue(S, Call->getArgs()[5], PAO_Discriminator))
+    return ExprError();
+
+  // Validate that the oldKey is IA or IB, not DA or DB.
+  // This enforces the constraint that auth_with_pc_and_resign only supports
+  // IA/IB keys for authentication, as only those keys support the PC-based
+  // signing instructions (paciasppc/pacibsppc).
+  unsigned OldKey = 0;
+  if (!S.checkConstantPointerAuthKey(Call->getArgs()[1], OldKey)) {
+    using AK = PointerAuthSchema::ARM8_3Key;
+    if (OldKey != static_cast<unsigned>(AK::ASIA) &&
+        OldKey != static_cast<unsigned>(AK::ASIB)) {
+      S.Diag(Call->getArgs()[1]->getExprLoc(),
+             diag::err_ptrauth_auth_with_pc_and_resign_invalid_key)
+          << OldKey << Call->getArgs()[1]->getSourceRange();
+      return ExprError();
+    }
+  }
+
+  Call->setType(Call->getArgs()[0]->getType());
+  return Call;
+}
+
 static ExprResult PointerAuthAuthLoadRelativeAndSign(Sema &S, CallExpr *Call) {
   if (S.checkArgCount(Call, 6))
     return ExprError();
@@ -3498,6 +3533,8 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
     return PointerAuthSignGenericData(*this, TheCall);
   case Builtin::BI__builtin_ptrauth_auth_and_resign:
     return PointerAuthAuthAndResign(*this, TheCall);
+  case Builtin::BI__builtin_ptrauth_auth_with_pc_and_resign:
+    return PointerAuthAuthWithPCAndResign(*this, TheCall);
   case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
     return PointerAuthAuthLoadRelativeAndSign(*this, TheCall);
   case Builtin::BI__builtin_ptrauth_string_discriminator:
diff --git a/clang/test/CodeGen/ptrauth-intrinsics.c 
b/clang/test/CodeGen/ptrauth-intrinsics.c
index bd348f9b3551a..c98ce60dc9fc9 100644
--- a/clang/test/CodeGen/ptrauth-intrinsics.c
+++ b/clang/test/CodeGen/ptrauth-intrinsics.c
@@ -67,6 +67,20 @@ void test_auth_load_relative_and_sign() {
   fnptr = __builtin_ptrauth_auth_load_relative_and_sign(fnptr, 0, 
ptr_discriminator, 3, 15, 16L);
 }
 
+// CHECK-LABEL: define {{.*}}void @test_auth_with_pc_and_resign()
+void test_auth_with_pc_and_resign() {
+  // CHECK:      [[PTR:%.*]] = load ptr, ptr @fnptr,
+  // CHECK-NEXT: [[DISC0:%.*]] = load ptr, ptr @ptr_discriminator,
+  // CHECK-NEXT: [[PC:%.*]] = load ptr, ptr @ptr_discriminator,
+  // CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[PTR]] to i64
+  // CHECK-NEXT: [[DISC:%.*]] = ptrtoint ptr [[DISC0]] to i64
+  // CHECK-NEXT: [[PCVAL:%.*]] = ptrtoint ptr [[PC]] to i64
+  // CHECK-NEXT: [[T1:%.*]] = call i64 
@llvm.ptrauth.auth.with.pc.and.resign(i64 [[T0]], i32 0, i64 [[DISC]], i64 
[[PCVAL]], i32 3, i64 15)
+  // CHECK-NEXT: [[RESULT:%.*]] = inttoptr  i64 [[T1]] to ptr
+  // CHECK-NEXT: store ptr [[RESULT]], ptr @fnptr,
+  fnptr = __builtin_ptrauth_auth_with_pc_and_resign(fnptr, 0, 
ptr_discriminator, ptr_discriminator, 3, 15);
+}
+
 // CHECK-LABEL: define {{.*}}void @test_blend_discriminator()
 void test_blend_discriminator() {
   // CHECK:      [[PTR:%.*]] = load ptr, ptr @fnptr,
diff --git a/clang/test/Sema/ptrauth-intrinsics-macro.c 
b/clang/test/Sema/ptrauth-intrinsics-macro.c
index adbb71a9d6e50..fbe1149eec786 100644
--- a/clang/test/Sema/ptrauth-intrinsics-macro.c
+++ b/clang/test/Sema/ptrauth-intrinsics-macro.c
@@ -16,12 +16,17 @@ void test(int *dp, int value) {
   (void)t0;
   dp = ptrauth_sign_unauthenticated(dp, VALID_DATA_KEY, 0);
   dp = ptrauth_auth_and_resign(dp, VALID_DATA_KEY, dp, VALID_DATA_KEY, dp);
+  dp = ptrauth_auth_with_pc_and_resign(dp, VALID_CODE_KEY, dp, dp, 
VALID_DATA_KEY, dp);
   dp = ptrauth_auth_data(dp, VALID_DATA_KEY, 0);
   int pu0 = 0, pu1 = 0, pu2 = 0, pu3 = 0, pu4 = 0, pu5 = 0, pu6 = 0, pu7 = 0;
   ptrauth_blend_discriminator(&pu0, value);
   ptrauth_auth_and_resign(&pu1, VALID_DATA_KEY, dp, VALID_DATA_KEY, dp);
   ptrauth_auth_and_resign(dp, VALID_DATA_KEY, &pu2, VALID_DATA_KEY, dp);
   ptrauth_auth_and_resign(dp, VALID_DATA_KEY, dp, VALID_DATA_KEY, &pu3);
+  ptrauth_auth_with_pc_and_resign(&pu1, VALID_CODE_KEY, dp, dp, 
VALID_DATA_KEY, dp);
+  ptrauth_auth_with_pc_and_resign(dp, VALID_CODE_KEY, &pu2, dp, 
VALID_DATA_KEY, dp);
+  ptrauth_auth_with_pc_and_resign(dp, VALID_CODE_KEY, dp, &pu3, 
VALID_DATA_KEY, dp);
+  ptrauth_auth_with_pc_and_resign(dp, VALID_CODE_KEY, dp, dp, VALID_DATA_KEY, 
&pu4);
   ptrauth_sign_generic_data(pu4, dp);
   ptrauth_sign_generic_data(dp, pu5);
   ptrauth_auth_data(&pu6, VALID_DATA_KEY, value);
diff --git a/clang/test/Sema/ptrauth.c b/clang/test/Sema/ptrauth.c
index 59c18a3ef5e40..5aae042f50c96 100644
--- a/clang/test/Sema/ptrauth.c
+++ b/clang/test/Sema/ptrauth.c
@@ -145,6 +145,33 @@ void test_auth_load_relative_and_sign(int *dp, int 
(*fp)(int)) {
   float *mismatch = __builtin_ptrauth_auth_load_relative_and_sign(dp, 
VALID_DATA_KEY, 0, VALID_DATA_KEY, dp,0); // expected-error {{incompatible 
pointer types initializing 'float *' with an expression of type 'int *'}}
 }
 
+void test_auth_with_pc_and_resign(int *dp, int (*fp)(int), void *pc) {
+  __builtin_ptrauth_auth_with_pc_and_resign(dp, VALID_DATA_KEY, 0, pc, 
VALID_DATA_KEY); // expected-error {{too few arguments}}
+  __builtin_ptrauth_auth_with_pc_and_resign(dp, VALID_DATA_KEY, dp, pc, 
VALID_DATA_KEY, dp, 0); // expected-error {{too many arguments}}
+
+  __builtin_ptrauth_auth_with_pc_and_resign(mismatched_type, VALID_DATA_KEY, 
0, pc, VALID_DATA_KEY, dp); // expected-error {{signed value must have pointer 
type; type here is 'struct A'}}
+  __builtin_ptrauth_auth_with_pc_and_resign(dp, mismatched_type, 0, pc, 
VALID_DATA_KEY, dp); // expected-error {{passing 'struct A' to parameter of 
incompatible type 'int'}}
+  __builtin_ptrauth_auth_with_pc_and_resign(dp, VALID_DATA_KEY, 
mismatched_type, pc, VALID_DATA_KEY, dp); // expected-error {{extra 
discriminator must have pointer or integer type; type here is 'struct A'}}
+  __builtin_ptrauth_auth_with_pc_and_resign(dp, VALID_DATA_KEY, 0, 
mismatched_type, VALID_DATA_KEY, dp); // expected-error {{blended pc must have 
pointer or integer type; type here is 'struct A'}}
+  __builtin_ptrauth_auth_with_pc_and_resign(dp, VALID_DATA_KEY, 0, pc, 
mismatched_type, dp); // expected-error {{passing 'struct A' to parameter of 
incompatible type 'int'}}
+  __builtin_ptrauth_auth_with_pc_and_resign(dp, VALID_DATA_KEY, 0, pc, 
VALID_DATA_KEY, mismatched_type); // expected-error {{extra discriminator must 
have pointer or integer type; type here is 'struct A'}}
+
+  (void) __builtin_ptrauth_auth_with_pc_and_resign(NULL, VALID_DATA_KEY, 0, 
pc, VALID_DATA_KEY, dp); // expected-error {{ptrauth_auth_with_pc_and_resign 
only supports auth with IA and IB keys, not 2}} expected-warning 
{{authenticating a null pointer will almost certainly trap}}
+
+  // Test that data keys (DA/DB) are rejected for oldKey
+  int *dr = __builtin_ptrauth_auth_with_pc_and_resign(dp, VALID_DATA_KEY, 0, 
pc, VALID_DATA_KEY, dp); // expected-error {{ptrauth_auth_with_pc_and_resign 
only supports auth with IA and IB keys, not 2}}
+  dr = __builtin_ptrauth_auth_with_pc_and_resign(dp, 3, 0, pc, VALID_DATA_KEY, 
dp); // expected-error {{ptrauth_auth_with_pc_and_resign only supports auth 
with IA and IB keys, not 3}}
+  dr = __builtin_ptrauth_auth_with_pc_and_resign(dp, INVALID_KEY, 0, pc, 
VALID_DATA_KEY, dp); // expected-error {{does not identify a valid pointer 
authentication key for the current target}}
+  dr = __builtin_ptrauth_auth_with_pc_and_resign(dp, VALID_CODE_KEY, 0, pc, 
INVALID_KEY, dp); // expected-error {{does not identify a valid pointer 
authentication key for the current target}}
+
+  // Test with valid IA/IB keys
+  int (*fr)(int) = __builtin_ptrauth_auth_with_pc_and_resign(fp, 
VALID_CODE_KEY, 0, pc, VALID_CODE_KEY, dp);
+  fr = __builtin_ptrauth_auth_with_pc_and_resign(fp, INVALID_KEY, 0, pc, 
VALID_CODE_KEY, dp); // expected-error {{does not identify a valid pointer 
authentication key for the current target}}
+  fr = __builtin_ptrauth_auth_with_pc_and_resign(fp, VALID_CODE_KEY, 0, pc, 
INVALID_KEY, dp); // expected-error {{does not identify a valid pointer 
authentication key for the current target}}
+
+  float *mismatch = __builtin_ptrauth_auth_with_pc_and_resign(dp, 
VALID_CODE_KEY, 0, pc, VALID_DATA_KEY, dp); // expected-error {{incompatible 
pointer types initializing 'float *' with an expression of type 'int *'}}
+}
+
 void test_sign_generic_data(int *dp) {
   __builtin_ptrauth_sign_generic_data(dp); // expected-error {{too few 
arguments}}
   __builtin_ptrauth_sign_generic_data(dp, 0, 0); // expected-error {{too many 
arguments}}
diff --git a/llvm/include/llvm/IR/Intrinsics.td 
b/llvm/include/llvm/IR/Intrinsics.td
index b1b2bb2a72c65..b6d41fb543af9 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -1839,6 +1839,19 @@ def int_experimental_patchpoint : 
Intrinsic<[llvm_any_ty],
                                              ImmArg<ArgIndex<1>>,
                                              ImmArg<ArgIndex<3>>]>;
 
+// Authenticate a signed pointer using a PC-based signature and resign it.
+// The second (key) and third (discriminator) arguments specify the signing
+// schema used for authenticating.
+// The fourth argument specifies the signing PC value.
+// The fifth and sixth arguments specify the schema used for resigning.
+// The signature must be valid.
+// This uses autia171615/autib171615 for authentication with PC, then signs 
normally.
+def int_ptrauth_auth_with_pc_and_resign : Intrinsic<[llvm_i64_ty],
+                                                     [llvm_i64_ty, 
llvm_i32_ty, llvm_i64_ty,
+                                                      llvm_i64_ty, 
llvm_i32_ty, llvm_i64_ty],
+                                                     [IntrNoMem, 
ImmArg<ArgIndex<1>>,
+                                                      ImmArg<ArgIndex<4>>]>;
+
 
 //===------------------------ Garbage Collection Intrinsics 
---------------===//
 // These are documented in docs/Statepoint.rst
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index f0363b6553440..ca681cb4b572c 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -7458,6 +7458,15 @@ void Verifie...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/202742
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to