Skip to content

Commit 48a946c

Browse files
committed
Refine patch a bit.
- signed_ptr/SP -> ptrauth/CPA - Verifier.cpp: check CPA type == base ptr type - C API: exclude ConstantPtrAuth until needed - BitcodeAnalyzer.cpp: print CST_CODE_PTRAUTH - IR: refine test a bit, add addrspace for base/disc - docs: refine a bit, remove stale overload - docs: add to PointerAuth.md
1 parent e47a75a commit 48a946c

File tree

11 files changed

+85
-41
lines changed

11 files changed

+85
-41
lines changed

llvm/docs/LangRef.rst

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4750,29 +4750,35 @@ reference to the CFI jump table in the ``LowerTypeTests`` pass. These constants
47504750
may be useful in low-level programs, such as operating system kernels, which
47514751
need to refer to the actual function body.
47524752

4753-
.. _ptrauth:
4753+
.. _ptrauth_constant:
47544754

4755-
Authenticated Pointers
4756-
----------------------
4755+
Pointer Authentication Constants
4756+
--------------------------------
47574757

4758-
``ptrauth (ptr CST, i32 KEY, ptr ADDRDISC, i16 DISC)
4758+
``ptrauth (ptr CST, i32 KEY, ptr ADDRDISC, i64 DISC)``
47594759

47604760
A '``ptrauth``' constant represents a pointer with a cryptographic
4761-
authentication signature embedded into some bits. Its type is the same as the
4762-
first argument.
4761+
authentication signature embedded into some bits, as described in the
4762+
`Pointer Authentication <PointerAuth.html>`__ document.
4763+
4764+
A '``ptrauth``' constant is simply a constant equivalent to the
4765+
``llvm.ptrauth.sign`` intrinsic, potentially fed by a discriminator
4766+
``llvm.ptrauth.blend`` if needed.
47634767

47644768

47654769
If the address disciminator is ``null`` then the expression is equivalent to
47664770

4767-
.. code-block:llvm
4768-
%tmp = call i64 @llvm.ptrauth.sign.i64(i64 ptrtoint (ptr CST to i64), i32 KEY, i64 DISC)
4771+
.. code-block:: llvm
4772+
4773+
%tmp = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr CST to i64), i32 KEY, i64 DISC)
47694774
%val = inttoptr i64 %tmp to ptr
47704775

4771-
If the address discriminator is present, then it is
4776+
Otherwise, the expression is equivalent to:
4777+
4778+
.. code-block:: llvm
47724779

4773-
.. code-block:llvm
4774-
%tmp1 = call i64 @llvm.ptrauth.blend.i64(i64 ptrtoint (ptr ADDRDISC to i64), i64 DISC)
4775-
%tmp2 = call i64 @llvm.ptrauth.sign.i64(i64 ptrtoint (ptr CST to i64), i64 %tmp1)
4780+
%tmp1 = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr ADDRDISC to i64), i64 DISC)
4781+
%tmp2 = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr CST to i64), i32 KEY, i64 %tmp1)
47764782
%val = inttoptr i64 %tmp2 to ptr
47774783

47784784
.. _constantexprs:

llvm/docs/PointerAuth.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ For more details, see the clang documentation page for
1616
At the IR level, it is represented using:
1717

1818
* a [set of intrinsics](#intrinsics) (to sign/authenticate pointers)
19+
* a [signed pointer constant](#constant) (to sign globals)
1920
* a [call operand bundle](#operand-bundle) (to authenticate called pointers)
2021

2122
The current implementation leverages the
@@ -225,6 +226,27 @@ with a pointer address discriminator, in a way that is specified by the target
225226
implementation.
226227

227228

229+
### Constant
230+
231+
[Intrinsics](#intrinsics) can be used to produce signed pointers dynamically,
232+
in code, but not for signed pointers referenced by constants, in, e.g., global
233+
initializers.
234+
235+
The latter are represented using a
236+
[``ptrauth`` constant](https://llvm.org/docs/LangRef.html#ptrauth-constant),
237+
which describes an authenticated relocation producing a signed pointer.
238+
239+
```llvm
240+
ptrauth (ptr CST, i32 KEY, ptr ADDRDISC, i64 DISC)
241+
```
242+
243+
is equivalent to:
244+
245+
```llvm
246+
%disc = call i64 @llvm.ptrauth.blend(i64 ptrtoint(ptr ADDRDISC to i64), i64 DISC)
247+
%signedval = call i64 @llvm.ptrauth.sign(ptr CST, i32 KEY, i64 %disc)
248+
```
249+
228250
### Operand Bundle
229251

230252
Function pointers used as indirect call targets can be signed when materialized,

llvm/include/llvm-c/Core.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,6 @@ typedef enum {
286286
LLVMInstructionValueKind,
287287
LLVMPoisonValueValueKind,
288288
LLVMConstantTargetNoneValueKind,
289-
LLVMConstantPtrAuthValueKind,
290289
} LLVMValueKind;
291290

292291
typedef enum {

llvm/include/llvm/Bitcode/LLVMBitCodes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ enum ConstantsCodes {
412412
// asmdialect|unwind,
413413
// asmstr,conststr]
414414
CST_CODE_CE_GEP_WITH_INRANGE = 31, // [opty, flags, range, n x operands]
415-
CST_CODE_SIGNED_PTR = 32, // [ptr, key, addrdisc, disc]
415+
CST_CODE_PTRAUTH = 32, // [ptr, key, addrdisc, disc]
416416
};
417417

418418
/// CastOpcodes - These are values used in the bitcode files to encode which

llvm/include/llvm/IR/Value.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,10 @@ HANDLE_GLOBAL_VALUE(GlobalAlias)
7878
HANDLE_GLOBAL_VALUE(GlobalIFunc)
7979
HANDLE_GLOBAL_VALUE(GlobalVariable)
8080
HANDLE_CONSTANT(BlockAddress)
81-
HANDLE_CONSTANT(ConstantPtrAuth)
8281
HANDLE_CONSTANT(ConstantExpr)
8382
HANDLE_CONSTANT_EXCLUDE_LLVM_C_API(DSOLocalEquivalent)
8483
HANDLE_CONSTANT_EXCLUDE_LLVM_C_API(NoCFIValue)
84+
HANDLE_CONSTANT_EXCLUDE_LLVM_C_API(ConstantPtrAuth)
8585

8686
// ConstantAggregate.
8787
HANDLE_CONSTANT(ConstantArray)

llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ GetCodeName(unsigned CodeID, unsigned BlockID,
222222
STRINGIFY_CODE(CST_CODE, CE_UNOP)
223223
STRINGIFY_CODE(CST_CODE, DSO_LOCAL_EQUIVALENT)
224224
STRINGIFY_CODE(CST_CODE, NO_CFI_VALUE)
225+
STRINGIFY_CODE(CST_CODE, PTRAUTH)
225226
case bitc::CST_CODE_BLOCKADDRESS:
226227
return "CST_CODE_BLOCKADDRESS";
227228
STRINGIFY_CODE(CST_CODE, DATA)

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3642,7 +3642,7 @@ Error BitcodeReader::parseConstants() {
36423642
Record[1]);
36433643
break;
36443644
}
3645-
case bitc::CST_CODE_SIGNED_PTR: {
3645+
case bitc::CST_CODE_PTRAUTH: {
36463646
if (Record.size() < 4)
36473647
return error("Invalid ptrauth record");
36483648
// Ptr, Key, AddrDisc, Disc

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2831,7 +2831,7 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
28312831
Record.push_back(VE.getTypeID(NC->getGlobalValue()->getType()));
28322832
Record.push_back(VE.getValueID(NC->getGlobalValue()));
28332833
} else if (const auto *CPA = dyn_cast<ConstantPtrAuth>(C)) {
2834-
Code = bitc::CST_CODE_SIGNED_PTR;
2834+
Code = bitc::CST_CODE_PTRAUTH;
28352835
Record.push_back(VE.getValueID(CPA->getPointer()));
28362836
Record.push_back(VE.getValueID(CPA->getKey()));
28372837
Record.push_back(VE.getValueID(CPA->getAddrDiscriminator()));

llvm/lib/IR/AsmWriter.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,14 +1590,14 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
15901590
return;
15911591
}
15921592

1593-
if (const ConstantPtrAuth *SP = dyn_cast<ConstantPtrAuth>(CV)) {
1593+
if (const ConstantPtrAuth *CPA = dyn_cast<ConstantPtrAuth>(CV)) {
15941594
Out << "ptrauth (";
15951595
ListSeparator LS;
1596-
for (unsigned i = 0; i < SP->getNumOperands(); ++i) {
1596+
for (auto *Op : CPA->operand_values()) {
15971597
Out << LS;
1598-
WriterCtx.TypePrinter->print(SP->getOperand(i)->getType(), Out);
1598+
WriterCtx.TypePrinter->print(Op->getType(), Out);
15991599
Out << ' ';
1600-
WriteAsOperandInternal(Out, SP->getOperand(i), WriterCtx);
1600+
WriteAsOperandInternal(Out, Op, WriterCtx);
16011601
}
16021602
Out << ')';
16031603
return;

llvm/lib/IR/Verifier.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
629629

630630
void visitConstantExprsRecursively(const Constant *EntryC);
631631
void visitConstantExpr(const ConstantExpr *CE);
632-
void visitConstantPtrAuth(const ConstantPtrAuth *SP);
632+
void visitConstantPtrAuth(const ConstantPtrAuth *CPA);
633633
void verifyInlineAsmCall(const CallBase &Call);
634634
void verifyStatepoint(const CallBase &Call);
635635
void verifyFrameRecoverIndices();
@@ -2423,8 +2423,8 @@ void Verifier::visitConstantExprsRecursively(const Constant *EntryC) {
24232423
if (const auto *CE = dyn_cast<ConstantExpr>(C))
24242424
visitConstantExpr(CE);
24252425

2426-
if (const auto *SP = dyn_cast<ConstantPtrAuth>(C))
2427-
visitConstantPtrAuth(SP);
2426+
if (const auto *CPA = dyn_cast<ConstantPtrAuth>(C))
2427+
visitConstantPtrAuth(CPA);
24282428

24292429
if (const auto *GV = dyn_cast<GlobalValue>(C)) {
24302430
// Global Values get visited separately, but we do need to make sure
@@ -2453,18 +2453,21 @@ void Verifier::visitConstantExpr(const ConstantExpr *CE) {
24532453
"Invalid bitcast", CE);
24542454
}
24552455

2456-
void Verifier::visitConstantPtrAuth(const ConstantPtrAuth *SP) {
2457-
Check(SP->getPointer()->getType()->isPointerTy(),
2458-
"signed pointer must be a pointer");
2456+
void Verifier::visitConstantPtrAuth(const ConstantPtrAuth *CPA) {
2457+
Check(CPA->getPointer()->getType()->isPointerTy(),
2458+
"signed ptrauth constant base pointer must have pointer type");
24592459

2460-
Check(SP->getKey()->getBitWidth() == 32,
2461-
"signed pointer key must be i32 constant integer");
2460+
Check(CPA->getType() == CPA->getPointer()->getType(),
2461+
"signed ptrauth constant must have same type as its base pointer");
24622462

2463-
Check(SP->getAddrDiscriminator()->getType()->isPointerTy(),
2464-
"signed pointer address discriminator must be a pointer");
2463+
Check(CPA->getKey()->getBitWidth() == 32,
2464+
"signed ptrauth constant key must be i32 constant integer");
24652465

2466-
Check(SP->getDiscriminator()->getBitWidth() == 64,
2467-
"signed pointer discriminator must be i64 constant integer");
2466+
Check(CPA->getAddrDiscriminator()->getType()->isPointerTy(),
2467+
"signed ptrauth constant address discriminator must be a pointer");
2468+
2469+
Check(CPA->getDiscriminator()->getBitWidth() == 64,
2470+
"signed ptrauth constant discriminator must be i64 constant integer");
24682471
}
24692472

24702473
bool Verifier::verifyAttributeCount(AttributeList Attrs, unsigned Params) {
@@ -5108,8 +5111,8 @@ void Verifier::visitInstruction(Instruction &I) {
51085111
} else if (isa<InlineAsm>(I.getOperand(i))) {
51095112
Check(CBI && &CBI->getCalledOperandUse() == &I.getOperandUse(i),
51105113
"Cannot take the address of an inline asm!", &I);
5111-
} else if (auto SP = dyn_cast<ConstantPtrAuth>(I.getOperand(i))) {
5112-
visitConstantExprsRecursively(SP);
5114+
} else if (auto *CPA = dyn_cast<ConstantPtrAuth>(I.getOperand(i))) {
5115+
visitConstantExprsRecursively(CPA);
51135116
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(I.getOperand(i))) {
51145117
if (CE->getType()->isPtrOrPtrVectorTy()) {
51155118
// If we have a ConstantExpr pointer, we need to see if it came from an

llvm/test/Assembler/ptrauth-const.ll

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,25 @@
22

33
@var = global i32 0
44

5-
; CHECK: @auth_var = global ptr ptrauth (ptr @var, i32 0, ptr null, i64 -1)
6-
@auth_var = global ptr ptrauth (ptr @var, i32 0, ptr null, i64 -1)
5+
; CHECK: @basic = global ptr ptrauth (ptr @var, i32 0, ptr null, i64 0)
6+
@basic = global ptr ptrauth (ptr @var, i32 0, ptr null, i64 0)
77

8+
; CHECK: @keyed = global ptr ptrauth (ptr @var, i32 3, ptr null, i64 0)
9+
@keyed = global ptr ptrauth (ptr @var, i32 3, ptr null, i64 0)
810

9-
; CHECK: @addrdisc_var = global ptr ptrauth (ptr @var, i32 0, ptr @addrdisc_var, i64 1234)
10-
@addrdisc_var = global ptr ptrauth (ptr @var, i32 0, ptr @addrdisc_var, i64 1234)
11+
; CHECK: @intdisc = global ptr ptrauth (ptr @var, i32 0, ptr null, i64 -1)
12+
@intdisc = global ptr ptrauth (ptr @var, i32 0, ptr null, i64 -1)
1113

12-
; CHECK: @keyed_var = global ptr ptrauth (ptr @var, i32 3, ptr null, i64 0)
13-
@keyed_var = global ptr ptrauth (ptr @var, i32 3, ptr null, i64 0)
14+
@addrdisc_storage = global ptr null
15+
; CHECK: @addrdisc = global ptr ptrauth (ptr @var, i32 2, ptr @addrdisc_storage, i64 1234)
16+
@addrdisc = global ptr ptrauth (ptr @var, i32 2, ptr @addrdisc_storage, i64 1234)
17+
18+
19+
@var1 = addrspace(1) global i32 0
20+
21+
; CHECK: @addrspace = global ptr addrspace(1) ptrauth (ptr addrspace(1) @var1, i32 0, ptr null, i64 0)
22+
@addrspace = global ptr addrspace(1) ptrauth (ptr addrspace(1) @var1, i32 0, ptr null, i64 0)
23+
24+
@addrspace_addrdisc_storage = addrspace(2) global ptr addrspace(1) null
25+
; CHECK: @addrspace_addrdisc = global ptr addrspace(1) ptrauth (ptr addrspace(1) @var1, i32 2, ptr addrspace(2) @addrspace_addrdisc_storage, i64 1234)
26+
@addrspace_addrdisc = global ptr addrspace(1) ptrauth (ptr addrspace(1) @var1, i32 2, ptr addrspace(2) @addrspace_addrdisc_storage, i64 1234)

0 commit comments

Comments
 (0)