diff options
author | Ahmed Bougacha <ahmed@bougacha.org> | 2024-05-28 16:39:09 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-28 16:39:09 -0700 |
commit | 0edc97f119f3ac3ff96b11183fe5c001a48a9a8d (patch) | |
tree | 381f97ed82e28f48672f05e138ba9bb17104beff /llvm/lib/IR/Verifier.cpp | |
parent | 60bce6eab4d734b86f49b7638856eb8899bc89e8 (diff) | |
download | llvm-0edc97f119f3ac3ff96b11183fe5c001a48a9a8d.zip llvm-0edc97f119f3ac3ff96b11183fe5c001a48a9a8d.tar.gz llvm-0edc97f119f3ac3ff96b11183fe5c001a48a9a8d.tar.bz2 |
[IR][AArch64][PAC] Add "ptrauth(...)" Constant to represent signed pointers. (#85738)
This defines a new kind of IR Constant that represents a ptrauth signed
pointer, as used in AArch64 PAuth.
It allows representing most kinds of signed pointer constants used thus
far in the llvm ptrauth implementations, notably those used in the
Darwin and ELF ABIs being implemented for c/c++. These signed pointer
constants are then lowered to ELF/MachO relocations.
These can be simply thought of as a constant `llvm.ptrauth.sign`, with
the interesting addition of discriminator computation: the `ptrauth`
constant can also represent a combined blend, when both address and
integer discriminator operands are used. Both operands are otherwise
optional, with default values 0/null.
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 50f8d6ec..684e544 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -629,6 +629,7 @@ private: void visitConstantExprsRecursively(const Constant *EntryC); void visitConstantExpr(const ConstantExpr *CE); + void visitConstantPtrAuth(const ConstantPtrAuth *CPA); void verifyInlineAsmCall(const CallBase &Call); void verifyStatepoint(const CallBase &Call); void verifyFrameRecoverIndices(); @@ -2422,6 +2423,9 @@ void Verifier::visitConstantExprsRecursively(const Constant *EntryC) { if (const auto *CE = dyn_cast<ConstantExpr>(C)) visitConstantExpr(CE); + if (const auto *CPA = dyn_cast<ConstantPtrAuth>(C)) + visitConstantPtrAuth(CPA); + if (const auto *GV = dyn_cast<GlobalValue>(C)) { // Global Values get visited separately, but we do need to make sure // that the global value is in the correct module @@ -2449,6 +2453,23 @@ void Verifier::visitConstantExpr(const ConstantExpr *CE) { "Invalid bitcast", CE); } +void Verifier::visitConstantPtrAuth(const ConstantPtrAuth *CPA) { + Check(CPA->getPointer()->getType()->isPointerTy(), + "signed ptrauth constant base pointer must have pointer type"); + + Check(CPA->getType() == CPA->getPointer()->getType(), + "signed ptrauth constant must have same type as its base pointer"); + + Check(CPA->getKey()->getBitWidth() == 32, + "signed ptrauth constant key must be i32 constant integer"); + + Check(CPA->getAddrDiscriminator()->getType()->isPointerTy(), + "signed ptrauth constant address discriminator must be a pointer"); + + Check(CPA->getDiscriminator()->getBitWidth() == 64, + "signed ptrauth constant discriminator must be i64 constant integer"); +} + bool Verifier::verifyAttributeCount(AttributeList Attrs, unsigned Params) { // There shouldn't be more attribute sets than there are parameters plus the // function and return value. @@ -5090,6 +5111,8 @@ void Verifier::visitInstruction(Instruction &I) { } else if (isa<InlineAsm>(I.getOperand(i))) { Check(CBI && &CBI->getCalledOperandUse() == &I.getOperandUse(i), "Cannot take the address of an inline asm!", &I); + } else if (auto *CPA = dyn_cast<ConstantPtrAuth>(I.getOperand(i))) { + visitConstantExprsRecursively(CPA); } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(I.getOperand(i))) { if (CE->getType()->isPtrOrPtrVectorTy()) { // If we have a ConstantExpr pointer, we need to see if it came from an |