[RFC] Adding ptrauth constants

We’ve been gradually implementing more support for pointer authentication (targeting the PAC AArch64 feature), and now have various @llvm.ptrauth. intrinsics to sign and authenticate pointers. However, we also need to allow global initializers to contain signed pointers.

Proposal

We’re proposing adding a Constant:

ptrauth(ptr base_pointer, i32 key, i64 discriminator, ptr address_discriminator)

Which signs (in the ptrauth sense, as in @llvm.ptrauth.sign) the base pointer using the specified key, and, if present, the specified integer and address discriminators.

It is then lowered to the “authenticated” relocations on ELF (in the AArch64 PAuth ABI being specified) and MachO.

For more details on signing and discriminators, we have the clang and llvm docs pages.

But the short version is: the proposed ptrauth constant is simply a way to represent a full sign operation in Constant form:

    %tmp1 = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr addrdisc to i64), i64 disc)
    %tmp2 = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr base to i64), i32 key, i64 %tmp1)
    %val = inttoptr i64 %tmp2 to ptr

We had some discussion previously on the list, and we’re now iterating on a pull request:
[PAC][IR][AArch64] Add "ptrauth(...)" Constant to represent signed pointers. by ahmedbougacha · Pull Request #85738 · llvm/llvm-project · GitHub

Please comment here or there if you have feedback!

Alternatives

Our initial implementation was based on a wrapper global variable in a special llvm section, using a struct type that resembles the operands of the ptrauth Constant we’re proposing. But I don’t think we want to live with that any more than we absolutely have to, as I consider it only a way to avoid bitcode divergence on the original implementation branches.

In previous discussions, the specifics of the operands came up. AArch64 PAC only has a handful of keys, but we initially tried to avoid representing ptrauth constructs in IR in ways that mimic the AArch64 ISA. For instance, we have an architecture-agnostic software-only ptrauth implementation that uses many more keys than the ISA restricts us to. I don’t know that genericity beyond AArch64 is a hard requirement at this point though.

Finally, the ConstantExpr vs. top-level Constant question also was a topic of past discussion, and there were issues with the instruction/constantexpr mapping. With the recent ConstantExpr changes I imagine that’s not an interesting question anymore, but more generally there might be a better fit in the Constant hierarchy; I don’t think there is.

ptrauth beyond the Constant

Beyond this proposal, we’re actively working on many changes for ptrauth support, and have a regular sync-up on mondays that all interested folks are welcome to join.

5 Likes

We are aiming to provide more or less complete pauh support in LLVM 19 release. The constants representation is one of the things on the critical path here. So, unless there will be any objections, etc. we are going to proceed with this approach.

That said, I encourage everyone to provide feedback on this RFC, if any :slight_smile: