Emitting ptrauth intrinsics in rustc_codegen_llvm for function calls

I've been trying to develop a fork of the Rust compiler with an arm64e-apple-ios target, using the Apple LLVM.

However, this requires getting rustc_codegen_llvm to emit custom llvm.ptrauth intrinsics in certain areas, which I'm not sure how to do.

Examples from the PointerAuth documentation:

define void @f(void ()* %fp) {
  call void %fp() [ "ptrauth"(i32 <key>, i64 <data>) ]
  ret void
}

or

define void @f(void ()* %fp) {
  %fp_i = ptrtoint void ()* %fp to i64
  %fp_auth = call i64 @llvm.ptrauth.auth.i64(i64 %fp_i, i32 <key>, i64 <data>)
  %fp_auth_p = inttoptr i64 %fp_auth to void ()*
  call void %fp_auth_p()
  ret void
}

(both are functionally equivalent)

At bare minimum, this would likely need to be applied to EXTERNAL function calls - calling system functions or external library functions (as safe code likely makes ptrauth mostly redundant for Rust calls)

In addition, global initializers need to be signed too:

@fp.ptrauth = constant { i8*, i32, i64, i64 }
                       { i8* <value>,
                         i32 <key>,
                         i64 <address discriminator>,
                         i64 <integer discriminator>
                       }, section "llvm.ptrauth"

I'm curious as to where in rustc I could find the code that emits the LLVM function calls / globals, so I could insert the llvm.ptrauth.auth / llvm.ptrauth.sign instructions.

2 Likes

I'm not sure about globals, but invoke instructions are emitted here:

and call instructions are emitted here: