Skip to content

[C API] Support new ptrauth constant type #93909

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 17, 2024

Conversation

Benjins
Copy link
Contributor

@Benjins Benjins commented May 31, 2024

This is a new constant type that was added to the C++ API in 0edc97f. This adds the ability to create instances of this constant and get its values to the C API

This is a new constant type that was added to the C++ API in
0edc97f. This adds the ability to create
instances of this constant and get its values to the C API
@Benjins Benjins requested a review from nikic as a code owner May 31, 2024 00:50
@llvmbot
Copy link
Member

llvmbot commented May 31, 2024

@llvm/pr-subscribers-llvm-ir

Author: Benji Smith (Benjins)

Changes

This is a new constant type that was added to the C++ API in 0edc97f. This adds the ability to create instances of this constant and get its values to the C API


Full diff: https://github.com/llvm/llvm-project/pull/93909.diff

6 Files Affected:

  • (modified) llvm/docs/ReleaseNotes.rst (+8)
  • (modified) llvm/include/llvm-c/Core.h (+39)
  • (modified) llvm/include/llvm/IR/Value.def (+1-1)
  • (modified) llvm/lib/IR/Core.cpp (+23)
  • (modified) llvm/test/Bindings/llvm-c/echo.ll (+5)
  • (modified) llvm/tools/llvm-c-test/echo.cpp (+10)
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 1e1ccb495c366..398d2308e212d 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -186,6 +186,14 @@ Changes to the C API
   * ``LLVMGetCallBrNumIndirectDests``
   * ``LLVMGetCallBrIndirectDest``
 
+* Added the following functions for creating and accessing data for ConstantPtrAuth constants:
+
+  * ``LLVMConstantPtrAuth``
+  * ``LLVMGetConstantPtrAuthPointer``
+  * ``LLVMGetConstantPtrAuthKey``
+  * ``LLVMGetConstantPtrAuthDiscriminator``
+  * ``LLVMGetConstantPtrAuthAddrDiscriminator``
+
 Changes to the CodeGen infrastructure
 -------------------------------------
 
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index 9d09546513f0e..fdd81cd76299b 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -286,6 +286,7 @@ typedef enum {
   LLVMInstructionValueKind,
   LLVMPoisonValueValueKind,
   LLVMConstantTargetNoneValueKind,
+  LLVMConstantPtrAuthValueKind,
 } LLVMValueKind;
 
 typedef enum {
@@ -1652,6 +1653,35 @@ LLVMTypeRef LLVMScalableVectorType(LLVMTypeRef ElementType,
  */
 unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy);
 
+/**
+ * Get the pointer value for the associated ConstantPtrAuth constant.
+ *
+ * @see llvm::ConstantPtrAuth::getPointer
+ */
+LLVMValueRef LLVMGetConstantPtrAuthPointer(LLVMValueRef PtrAuth);
+
+/**
+ * Get the key value for the associated ConstantPtrAuth constant.
+ *
+ * @see llvm::ConstantPtrAuth::getKey
+ */
+LLVMValueRef LLVMGetConstantPtrAuthKey(LLVMValueRef PtrAuth);
+
+/**
+ * Get the discriminator value for the associated ConstantPtrAuth constant.
+ *
+ * @see llvm::ConstantPtrAuth::getDiscriminator
+ */
+LLVMValueRef LLVMGetConstantPtrAuthDiscriminator(LLVMValueRef PtrAuth);
+
+/**
+ * Get the address discriminator value for the associated ConstantPtrAuth
+ * constant.
+ *
+ * @see llvm::ConstantPtrAuth::getAddrDiscriminator
+ */
+LLVMValueRef LLVMGetConstantPtrAuthAddrDiscriminator(LLVMValueRef PtrAuth);
+
 /**
  * @}
  */
@@ -1758,6 +1788,7 @@ LLVMTypeRef LLVMTargetExtTypeInContext(LLVMContextRef C, const char *Name,
       macro(ConstantStruct)                 \
       macro(ConstantTokenNone)              \
       macro(ConstantVector)                 \
+      macro(ConstantPtrAuth)                \
       macro(GlobalValue)                    \
         macro(GlobalAlias)                  \
         macro(GlobalObject)                 \
@@ -2322,6 +2353,14 @@ LLVM_ATTRIBUTE_C_DEPRECATED(
  */
 LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size);
 
+/**
+ * Create a ConstantPtrAuth constant with the given values.
+ *
+ * @see llvm::ConstantPtrAuth::get()
+ */
+LLVMValueRef LLVMConstantPtrAuth(LLVMValueRef Ptr, LLVMValueRef Key,
+                                 LLVMValueRef Disc, LLVMValueRef AddrDisc);
+
 /**
  * @}
  */
diff --git a/llvm/include/llvm/IR/Value.def b/llvm/include/llvm/IR/Value.def
index 3ece66a529e12..160e0f8513e2a 100644
--- a/llvm/include/llvm/IR/Value.def
+++ b/llvm/include/llvm/IR/Value.def
@@ -81,7 +81,7 @@ HANDLE_CONSTANT(BlockAddress)
 HANDLE_CONSTANT(ConstantExpr)
 HANDLE_CONSTANT_EXCLUDE_LLVM_C_API(DSOLocalEquivalent)
 HANDLE_CONSTANT_EXCLUDE_LLVM_C_API(NoCFIValue)
-HANDLE_CONSTANT_EXCLUDE_LLVM_C_API(ConstantPtrAuth)
+HANDLE_CONSTANT(ConstantPtrAuth)
 
 // ConstantAggregate.
 HANDLE_CONSTANT(ConstantArray)
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index df90b88341123..40327b8ad578c 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -917,6 +917,22 @@ unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy) {
   return unwrap<VectorType>(VectorTy)->getElementCount().getKnownMinValue();
 }
 
+LLVMValueRef LLVMGetConstantPtrAuthPointer(LLVMValueRef PtrAuth) {
+  return wrap(unwrap<ConstantPtrAuth>(PtrAuth)->getPointer());
+}
+
+LLVMValueRef LLVMGetConstantPtrAuthKey(LLVMValueRef PtrAuth) {
+  return wrap(unwrap<ConstantPtrAuth>(PtrAuth)->getKey());
+}
+
+LLVMValueRef LLVMGetConstantPtrAuthDiscriminator(LLVMValueRef PtrAuth) {
+  return wrap(unwrap<ConstantPtrAuth>(PtrAuth)->getDiscriminator());
+}
+
+LLVMValueRef LLVMGetConstantPtrAuthAddrDiscriminator(LLVMValueRef PtrAuth) {
+  return wrap(unwrap<ConstantPtrAuth>(PtrAuth)->getAddrDiscriminator());
+}
+
 /*--.. Operations on other types ...........................................--*/
 
 LLVMTypeRef LLVMPointerTypeInContext(LLVMContextRef C, unsigned AddressSpace) {
@@ -1637,6 +1653,13 @@ LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size) {
       ArrayRef(unwrap<Constant>(ScalarConstantVals, Size), Size)));
 }
 
+LLVMValueRef LLVMConstantPtrAuth(LLVMValueRef Ptr, LLVMValueRef Key,
+                                 LLVMValueRef Disc, LLVMValueRef AddrDisc) {
+  return wrap(ConstantPtrAuth::get(
+      unwrap<Constant>(Ptr), unwrap<ConstantInt>(Key),
+      unwrap<ConstantInt>(Disc), unwrap<Constant>(AddrDisc)));
+}
+
 /*-- Opcode mapping */
 
 static LLVMOpcode map_to_llvmopcode(int opcode)
diff --git a/llvm/test/Bindings/llvm-c/echo.ll b/llvm/test/Bindings/llvm-c/echo.ll
index bb5fae0dcd12e..983853eaf163f 100644
--- a/llvm/test/Bindings/llvm-c/echo.ll
+++ b/llvm/test/Bindings/llvm-c/echo.ll
@@ -34,6 +34,11 @@ module asm "classical GAS"
 
 @ifunc = ifunc i32 (i32), ptr @ifunc_resolver
 
+@ptrauth_addr_disc = global i32 0
+@ptrauth_data = global i32 0
+@ptrauth_ptr_01 = global ptr ptrauth (ptr @ptrauth_data, i32 77, i64 1001, ptr @ptrauth_addr_disc)
+@ptrauth_ptr_02 = global ptr ptrauth (ptr @ptrauth_data, i32 11, i64 99, ptr null)
+
 define ptr @ifunc_resolver() {
 entry:
   ret ptr null
diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp
index 518716168c423..0b8675350f994 100644
--- a/llvm/tools/llvm-c-test/echo.cpp
+++ b/llvm/tools/llvm-c-test/echo.cpp
@@ -373,6 +373,16 @@ static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M) {
     return LLVMConstVector(Elts.data(), EltCount);
   }
 
+  if (LLVMIsAConstantPtrAuth(Cst)) {
+    LLVMValueRef Ptr = clone_constant(LLVMGetConstantPtrAuthPointer(Cst), M);
+    LLVMValueRef Key = clone_constant(LLVMGetConstantPtrAuthKey(Cst), M);
+    LLVMValueRef Disc =
+        clone_constant(LLVMGetConstantPtrAuthDiscriminator(Cst), M);
+    LLVMValueRef AddrDisc =
+        clone_constant(LLVMGetConstantPtrAuthAddrDiscriminator(Cst), M);
+    return LLVMConstantPtrAuth(Ptr, Key, Disc, AddrDisc);
+  }
+
   // At this point, if it's not a constant expression, it's a kind of constant
   // which is not supported
   if (!LLVMIsAConstantExpr(Cst))

Copy link

github-actions bot commented May 31, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@Benjins
Copy link
Contributor Author

Benjins commented May 31, 2024

The clang-format diff is on the LLVM_FOR_EACH_VALUE_SUBCLASS macro, which it tries to indent weirdly. If there's a preferred way of dealing with it I can push changes, but I assume the naive auto-formatted output isn't what we want

@nikic
Copy link
Contributor

nikic commented May 31, 2024

The clang-format diff is on the LLVM_FOR_EACH_VALUE_SUBCLASS macro, which it tries to indent weirdly. If there's a preferred way of dealing with it I can push changes, but I assume the naive auto-formatted output isn't what we want

You could add some // clang-format off // clang-format on annotations. Agree that this formatting is ... wild.

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me.

@ahmedbougacha @asl Is there any risk that something about ptrauth constants will change in the near future (in ways that would affect stability of the C API)?

@asl
Copy link
Collaborator

asl commented May 31, 2024

@ahmedbougacha @asl Is there any risk that something about ptrauth constants will change in the near future (in ways that would affect stability of the C API)?

Given the stability guarantees of C API, I would wait until we will have end-to-end implementation from frontend to backend just in case.

@Benjins
Copy link
Contributor Author

Benjins commented Jul 16, 2024

Merged from main and added some annotations to skip clang formatting on the macro it had trouble with

Given the stability guarantees of C API, I would wait until we will have end-to-end implementation from frontend to backend just in case.

@asl From the commit history, it seems like ptrauth constants are now used in Clang and the AArch64 backend. It seems like the fields for ConstantPtrAuth are the same as before. Does this PR seem good to land now?

static ConstantPtrAuth *get(Constant *Ptr, ConstantInt *Key,
ConstantInt *Disc, Constant *AddrDisc);

@asl
Copy link
Collaborator

asl commented Jul 16, 2024

Merged from main and added some annotations to skip clang formatting on the macro it had trouble with

Given the stability guarantees of C API, I would wait until we will have end-to-end implementation from frontend to backend just in case.

@asl From the commit history, it seems like ptrauth constants are now used in Clang and the AArch64 backend. It seems like the fields for ConstantPtrAuth are the same as before. Does this PR seem good to land now?

static ConstantPtrAuth *get(Constant *Ptr, ConstantInt *Key,
ConstantInt *Disc, Constant *AddrDisc);

Yes, I think we can consider these to be stable now. Thanks!

@nikic nikic merged commit f56db78 into llvm:main Jul 17, 2024
6 of 8 checks passed
yuxuanchen1997 pushed a commit that referenced this pull request Jul 25, 2024
Summary:
This is a new constant type that was added to the C++ API in
0edc97f. This adds the ability to
create instances of this constant and get its values to the C API.

Test Plan: 

Reviewers: 

Subscribers: 

Tasks: 

Tags: 


Differential Revision: https://phabricator.intern.facebook.com/D60250977
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants