Skip to content

Commit c6638c7

Browse files
committed
Print disc/addrdisc optionally, and swap them in ops list.
We originally matched the llvm.ptrauth struct layout, but this is nicer because: - both are commonly 0/null, so we can omit them in the common case - other than qualifier usage, integer discriminator alone is more common than an address discriminator, so omitting the latter alone helps also. - key + integer discriminator looks like the bundle/intrinsics, which helps pattern matching when staring at IR. - the variable-length addrdisc GEP string hides the integer disc. This doesn't match the llvm.ptrauth struct, but that's relatively straightforward to macro-update. This doesn't match the C qualifier either, but there the address discriminator is only a boolean `1`, so it's hard to mix these up.
1 parent 48a946c commit c6638c7

18 files changed

+97
-80
lines changed

llvm/docs/LangRef.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4755,7 +4755,7 @@ need to refer to the actual function body.
47554755
Pointer Authentication Constants
47564756
--------------------------------
47574757

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

47604760
A '``ptrauth``' constant represents a pointer with a cryptographic
47614761
authentication signature embedded into some bits, as described in the
@@ -4765,6 +4765,9 @@ A '``ptrauth``' constant is simply a constant equivalent to the
47654765
``llvm.ptrauth.sign`` intrinsic, potentially fed by a discriminator
47664766
``llvm.ptrauth.blend`` if needed.
47674767

4768+
Its type is the same as the first argument. An integer constant discriminator
4769+
and an address discriminator may be optionally specified. Otherwise, they have
4770+
values ``i64 0`` and ``ptr null``.
47684771

47694772
If the address disciminator is ``null`` then the expression is equivalent to
47704773

llvm/docs/PointerAuth.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ The latter are represented using a
237237
which describes an authenticated relocation producing a signed pointer.
238238

239239
```llvm
240-
ptrauth (ptr CST, i32 KEY, ptr ADDRDISC, i64 DISC)
240+
ptrauth (ptr CST, i32 KEY, i64 DISC, ptr ADDRDISC)
241241
```
242242

243243
is equivalent to:

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_PTRAUTH = 32, // [ptr, key, addrdisc, disc]
415+
CST_CODE_PTRAUTH = 32, // [ptr, key, disc, addrdisc]
416416
};
417417

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

llvm/include/llvm/IR/Constants.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,8 +1013,8 @@ class ConstantPtrAuth final : public Constant {
10131013
friend struct ConstantPtrAuthKeyType;
10141014
friend class Constant;
10151015

1016-
ConstantPtrAuth(Constant *Ptr, ConstantInt *Key, Constant *AddrDisc,
1017-
ConstantInt *Disc);
1016+
ConstantPtrAuth(Constant *Ptr, ConstantInt *Key, ConstantInt *Disc,
1017+
Constant *AddrDisc);
10181018

10191019
void *operator new(size_t s) { return User::operator new(s, 4); }
10201020

@@ -1024,7 +1024,7 @@ class ConstantPtrAuth final : public Constant {
10241024
public:
10251025
/// Return a pointer authenticated with the specified parameters.
10261026
static ConstantPtrAuth *get(Constant *Ptr, ConstantInt *Key,
1027-
Constant *AddrDisc, ConstantInt *Disc);
1027+
ConstantInt *Disc, Constant *AddrDisc);
10281028

10291029
/// Produce a new ptrauth expression signing the given value using
10301030
/// the same schema as is stored in one.
@@ -1039,16 +1039,16 @@ class ConstantPtrAuth final : public Constant {
10391039
/// The Key ID, an i32 constant.
10401040
ConstantInt *getKey() const { return cast<ConstantInt>(Op<1>().get()); }
10411041

1042+
/// The discriminator.
1043+
ConstantInt *getDiscriminator() const {
1044+
return cast<ConstantInt>(Op<2>().get());
1045+
}
1046+
10421047
/// The address discriminator if any, or the null constant.
10431048
/// If present, this must be a value equivalent to the storage location of
10441049
/// the only user of the authenticated ptrauth global.
10451050
Constant *getAddrDiscriminator() const {
1046-
return cast<Constant>(Op<2>().get());
1047-
}
1048-
1049-
/// The discriminator.
1050-
ConstantInt *getDiscriminator() const {
1051-
return cast<ConstantInt>(Op<3>().get());
1051+
return cast<Constant>(Op<3>().get());
10521052
}
10531053

10541054
/// Whether there is any non-null address discriminator.

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4045,44 +4045,56 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
40454045
return false;
40464046
}
40474047
case lltok::kw_ptrauth: {
4048-
// ValID ::= 'ptrauth' '(' ptr @foo ',' i32 <key> ','
4049-
// ptr addrdisc ',' i64 <disc> ')'
4048+
// ValID ::= 'ptrauth' '(' ptr @foo ',' i32 <key>
4049+
// (',' i64 <disc> (',' ptr addrdisc)? )? ')'
40504050
Lex.Lex();
40514051

4052-
Constant *Ptr, *Key, *AddrDisc, *Disc;
4052+
Constant *Ptr, *Key;
4053+
Constant *Disc = nullptr, *AddrDisc = nullptr;
40534054

40544055
if (parseToken(lltok::lparen,
4055-
"expected '(' in signed pointer expression") ||
4056+
"expected '(' in constant ptrauth expression") ||
40564057
parseGlobalTypeAndValue(Ptr) ||
40574058
parseToken(lltok::comma,
4058-
"expected comma in signed pointer expression") ||
4059-
parseGlobalTypeAndValue(Key) ||
4060-
parseToken(lltok::comma,
4061-
"expected comma in signed pointer expression") ||
4062-
parseGlobalTypeAndValue(AddrDisc) ||
4063-
parseToken(lltok::comma,
4064-
"expected comma in signed pointer expression") ||
4065-
parseGlobalTypeAndValue(Disc) ||
4066-
parseToken(lltok::rparen, "expected ')' in signed pointer expression"))
4059+
"expected comma in constant ptrauth expression") ||
4060+
parseGlobalTypeAndValue(Key))
4061+
return true;
4062+
// If present, parse the optional disc/addrdisc.
4063+
if (EatIfPresent(lltok::comma))
4064+
if (parseGlobalTypeAndValue(Disc) ||
4065+
(EatIfPresent(lltok::comma) && parseGlobalTypeAndValue(AddrDisc)))
4066+
return true;
4067+
if (parseToken(lltok::rparen,
4068+
"expected ')' in constant ptrauth expression"))
40674069
return true;
40684070

40694071
if (!Ptr->getType()->isPointerTy())
4070-
return error(ID.Loc, "signed pointer must be a pointer");
4072+
return error(ID.Loc, "constant ptrauth base pointer must be a pointer");
40714073

40724074
auto *KeyC = dyn_cast<ConstantInt>(Key);
40734075
if (!KeyC || KeyC->getBitWidth() != 32)
4074-
return error(ID.Loc, "signed pointer key must be i32 constant integer");
4076+
return error(ID.Loc, "constant ptrauth key must be i32 constant");
40754077

4076-
if (!AddrDisc->getType()->isPointerTy())
4077-
return error(ID.Loc,
4078-
"signed pointer address discriminator must be a pointer");
4078+
ConstantInt *DiscC = nullptr;
4079+
if (Disc) {
4080+
DiscC = dyn_cast<ConstantInt>(Disc);
4081+
if (!DiscC || DiscC->getBitWidth() != 64)
4082+
return error(
4083+
ID.Loc,
4084+
"constant ptrauth integer discriminator must be i64 constant");
4085+
} else {
4086+
DiscC = ConstantInt::get(Type::getInt64Ty(Context), 0);
4087+
}
40794088

4080-
auto *DiscC = dyn_cast<ConstantInt>(Disc);
4081-
if (!DiscC || DiscC->getBitWidth() != 64)
4082-
return error(ID.Loc,
4083-
"signed pointer discriminator must be i64 constant integer");
4089+
if (AddrDisc) {
4090+
if (!AddrDisc->getType()->isPointerTy())
4091+
return error(
4092+
ID.Loc, "constant ptrauth address discriminator must be a pointer");
4093+
} else {
4094+
AddrDisc = ConstantPointerNull::get(PointerType::get(Context, 0));
4095+
}
40844096

4085-
ID.ConstantVal = ConstantPtrAuth::get(Ptr, KeyC, AddrDisc, DiscC);
4097+
ID.ConstantVal = ConstantPtrAuth::get(Ptr, KeyC, DiscC, AddrDisc);
40864098
ID.Kind = ValID::t_Constant;
40874099
return false;
40884100
}

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,11 +1556,11 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID,
15561556
if (!Key)
15571557
return error("ptrauth key operand must be ConstantInt");
15581558

1559-
auto *Disc = dyn_cast<ConstantInt>(ConstOps[3]);
1559+
auto *Disc = dyn_cast<ConstantInt>(ConstOps[2]);
15601560
if (!Disc)
15611561
return error("ptrauth disc operand must be ConstantInt");
15621562

1563-
C = ConstantPtrAuth::get(ConstOps[0], Key, ConstOps[2], Disc);
1563+
C = ConstantPtrAuth::get(ConstOps[0], Key, Disc, ConstOps[3]);
15641564
break;
15651565
}
15661566
case BitcodeConstant::NoCFIOpcode: {
@@ -3645,7 +3645,7 @@ Error BitcodeReader::parseConstants() {
36453645
case bitc::CST_CODE_PTRAUTH: {
36463646
if (Record.size() < 4)
36473647
return error("Invalid ptrauth record");
3648-
// Ptr, Key, AddrDisc, Disc
3648+
// Ptr, Key, Disc, AddrDisc
36493649
V = BitcodeConstant::create(
36503650
Alloc, CurTy, BitcodeConstant::ConstantPtrAuthOpcode,
36513651
{(unsigned)Record[0], (unsigned)Record[1], (unsigned)Record[2],

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2834,8 +2834,8 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
28342834
Code = bitc::CST_CODE_PTRAUTH;
28352835
Record.push_back(VE.getValueID(CPA->getPointer()));
28362836
Record.push_back(VE.getValueID(CPA->getKey()));
2837-
Record.push_back(VE.getValueID(CPA->getAddrDiscriminator()));
28382837
Record.push_back(VE.getValueID(CPA->getDiscriminator()));
2838+
Record.push_back(VE.getValueID(CPA->getAddrDiscriminator()));
28392839
} else {
28402840
#ifndef NDEBUG
28412841
C->dump();

llvm/lib/IR/AsmWriter.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,12 +1592,20 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
15921592

15931593
if (const ConstantPtrAuth *CPA = dyn_cast<ConstantPtrAuth>(CV)) {
15941594
Out << "ptrauth (";
1595+
1596+
// ptrauth (ptr CST, i32 KEY[, i64 DISC[, ptr ADDRDISC]?]?)
1597+
unsigned NumOpsToWrite = 2;
1598+
if (!CPA->getOperand(2)->isNullValue())
1599+
NumOpsToWrite = 3;
1600+
if (!CPA->getOperand(3)->isNullValue())
1601+
NumOpsToWrite = 4;
1602+
15951603
ListSeparator LS;
1596-
for (auto *Op : CPA->operand_values()) {
1604+
for (unsigned i = 0, e = NumOpsToWrite; i != e; ++i) {
15971605
Out << LS;
1598-
WriterCtx.TypePrinter->print(Op->getType(), Out);
1606+
WriterCtx.TypePrinter->print(CPA->getOperand(i)->getType(), Out);
15991607
Out << ' ';
1600-
WriteAsOperandInternal(Out, Op, WriterCtx);
1608+
WriteAsOperandInternal(Out, CPA->getOperand(i), WriterCtx);
16011609
}
16021610
Out << ')';
16031611
return;

llvm/lib/IR/Constants.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2071,28 +2071,28 @@ bool ConstantPtrAuth::isCompatibleWith(const Value *Key,
20712071
}
20722072

20732073
ConstantPtrAuth *ConstantPtrAuth::getWithSameSchema(Constant *Pointer) const {
2074-
return get(Pointer, getKey(), getAddrDiscriminator(), getDiscriminator());
2074+
return get(Pointer, getKey(), getDiscriminator(), getAddrDiscriminator());
20752075
}
20762076

20772077
ConstantPtrAuth *ConstantPtrAuth::get(Constant *Ptr, ConstantInt *Key,
2078-
Constant *AddrDisc, ConstantInt *Disc) {
2079-
Constant *ArgVec[] = {Ptr, Key, AddrDisc, Disc};
2078+
ConstantInt *Disc, Constant *AddrDisc) {
2079+
Constant *ArgVec[] = {Ptr, Key, Disc, AddrDisc};
20802080
ConstantPtrAuthKeyType MapKey(ArgVec);
20812081
LLVMContextImpl *pImpl = Ptr->getContext().pImpl;
20822082
return pImpl->ConstantPtrAuths.getOrCreate(Ptr->getType(), MapKey);
20832083
}
20842084

20852085
ConstantPtrAuth::ConstantPtrAuth(Constant *Ptr, ConstantInt *Key,
2086-
Constant *AddrDisc, ConstantInt *Disc)
2086+
ConstantInt *Disc, Constant *AddrDisc)
20872087
: Constant(Ptr->getType(), Value::ConstantPtrAuthVal, &Op<0>(), 4) {
20882088
assert(Ptr->getType()->isPointerTy());
20892089
assert(Key->getBitWidth() == 32);
2090-
assert(AddrDisc->getType()->isPointerTy());
20912090
assert(Disc->getBitWidth() == 64);
2091+
assert(AddrDisc->getType()->isPointerTy());
20922092
setOperand(0, Ptr);
20932093
setOperand(1, Key);
2094-
setOperand(2, AddrDisc);
2095-
setOperand(3, Disc);
2094+
setOperand(2, Disc);
2095+
setOperand(3, AddrDisc);
20962096
}
20972097

20982098
/// Remove the constant from the constant table.

llvm/lib/IR/ConstantsContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ struct ConstantPtrAuthKeyType {
579579

580580
ConstantPtrAuth *create(TypeClass *Ty) const {
581581
return new ConstantPtrAuth(Operands[0], cast<ConstantInt>(Operands[1]),
582-
Operands[2], cast<ConstantInt>(Operands[3]));
582+
cast<ConstantInt>(Operands[2]), Operands[3]);
583583
}
584584
};
585585

llvm/test/Assembler/invalid-ptrauth-const1.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
@var = global i32 0
44

5-
; CHECK: error: signed pointer must be a pointer
6-
@auth_var = global ptr ptrauth (i32 42, i32 0, ptr null, i64 65535)
5+
; CHECK: error: constant ptrauth base pointer must be a pointer
6+
@auth_var = global ptr ptrauth (i32 42, i32 0)

llvm/test/Assembler/invalid-ptrauth-const2.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
@var = global i32 0
44

5-
; CHECK: error: signed pointer key must be i32 constant integer
6-
@auth_var = global ptr ptrauth (ptr @var, i32 ptrtoint (ptr @var to i32), ptr null, i64 65535)
5+
; CHECK: error: constant ptrauth key must be i32 constant
6+
@auth_var = global ptr ptrauth (ptr @var, i32 ptrtoint (ptr @var to i32))

llvm/test/Assembler/invalid-ptrauth-const3.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
@var = global i32 0
44

5-
; CHECK: error: signed pointer address discriminator must be a pointer
6-
@auth_var = global ptr ptrauth (ptr @var, i32 2, i8 0, i64 65535)
5+
; CHECK: error: constant ptrauth address discriminator must be a pointer
6+
@auth_var = global ptr ptrauth (ptr @var, i32 2, i64 65535, i8 0)

llvm/test/Assembler/invalid-ptrauth-const4.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
@var = global i32 0
44

5-
; CHECK: error: signed pointer address discriminator must be a pointer
6-
@auth_var = global ptr ptrauth (ptr @var, i32 2, i8 0, i64 65535)
5+
; CHECK: error: constant ptrauth integer discriminator must be i64 constant
6+
@auth_var = global ptr ptrauth (ptr @var, i32 2, ptr null, i64 ptrtoint (ptr @var to i64))

llvm/test/Assembler/invalid-ptrauth-const5.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
@var = global i32 0
44

5-
; CHECK: error: signed pointer discriminator must be i64 constant integer
6-
@auth_var = global ptr ptrauth (ptr @var, i32 2, ptr null, i64 ptrtoint (ptr @var to i64))
5+
; CHECK: error: constant ptrauth integer discriminator must be i64 constant
6+
@auth_var = global ptr ptrauth (ptr @var, i32 2, ptr @var))

llvm/test/Assembler/invalid-ptrauth-const6.ll

Lines changed: 0 additions & 6 deletions
This file was deleted.

llvm/test/Assembler/ptrauth-const.ll

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

33
@var = global i32 0
44

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)
5+
; CHECK: @basic = global ptr ptrauth (ptr @var, i32 0)
6+
@basic = global ptr ptrauth (ptr @var, i32 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)
8+
; CHECK: @keyed = global ptr ptrauth (ptr @var, i32 3)
9+
@keyed = global ptr ptrauth (ptr @var, i32 3)
1010

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)
11+
; CHECK: @intdisc = global ptr ptrauth (ptr @var, i32 0, i64 -1)
12+
@intdisc = global ptr ptrauth (ptr @var, i32 0, i64 -1)
1313

1414
@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)
15+
; CHECK: @addrdisc = global ptr ptrauth (ptr @var, i32 2, i64 1234, ptr @addrdisc_storage)
16+
@addrdisc = global ptr ptrauth (ptr @var, i32 2, i64 1234, ptr @addrdisc_storage)
1717

1818

1919
@var1 = addrspace(1) global i32 0
2020

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)
21+
; CHECK: @addrspace = global ptr addrspace(1) ptrauth (ptr addrspace(1) @var1, i32 0)
22+
@addrspace = global ptr addrspace(1) ptrauth (ptr addrspace(1) @var1, i32 0)
2323

2424
@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)
25+
; CHECK: @addrspace_addrdisc = global ptr addrspace(1) ptrauth (ptr addrspace(1) @var1, i32 2, i64 1234, ptr addrspace(2) @addrspace_addrdisc_storage)
26+
@addrspace_addrdisc = global ptr addrspace(1) ptrauth (ptr addrspace(1) @var1, i32 2, i64 1234, ptr addrspace(2) @addrspace_addrdisc_storage)

llvm/test/Bitcode/compatibility.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,8 @@ declare void @g.f1()
218218
; CHECK: @g.sanitize_multiple = global i32 0, sanitize_memtag, sanitize_address_dyninit
219219

220220
; ptrauth constant
221-
@auth_var = global ptr ptrauth (ptr @g1, i32 0, ptr null, i64 65535)
222-
; CHECK: @auth_var = global ptr ptrauth (ptr @g1, i32 0, ptr null, i64 65535)
221+
@auth_var = global ptr ptrauth (ptr @g1, i32 0, i64 65535, ptr null)
222+
; CHECK: @auth_var = global ptr ptrauth (ptr @g1, i32 0, i64 65535)
223223

224224
;; Aliases
225225
; Format: @<Name> = [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal]

0 commit comments

Comments
 (0)