Skip to content

Commit d2379ef

Browse files
authored
Add deactivation symbol operand to ConstantPtrAuth.
Deactivation symbol operands are supported in the code generator by building on the previously added support for IRELATIVE relocations. Reviewers: ojhunt, fmayer, ahmedbougacha, nikic, efriedma-quic Reviewed By: fmayer Pull Request: #133537
1 parent 6227eb9 commit d2379ef

File tree

24 files changed

+218
-48
lines changed

24 files changed

+218
-48
lines changed

clang/lib/CodeGen/CGPointerAuth.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -440,9 +440,10 @@ CodeGenModule::getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key,
440440
IntegerDiscriminator = llvm::ConstantInt::get(Int64Ty, 0);
441441
}
442442

443-
return llvm::ConstantPtrAuth::get(Pointer,
444-
llvm::ConstantInt::get(Int32Ty, Key),
445-
IntegerDiscriminator, AddressDiscriminator);
443+
return llvm::ConstantPtrAuth::get(
444+
Pointer, llvm::ConstantInt::get(Int32Ty, Key), IntegerDiscriminator,
445+
AddressDiscriminator,
446+
/*DeactivationSymbol=*/llvm::Constant::getNullValue(DefaultPtrTy));
446447
}
447448

448449
/// Does a given PointerAuthScheme require us to sign a value

llvm/docs/LangRef.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3234,6 +3234,8 @@ A "convergencectrl" operand bundle is only valid on a ``convergent`` operation.
32343234
When present, the operand bundle must contain exactly one value of token type.
32353235
See the :doc:`ConvergentOperations` document for details.
32363236

3237+
.. _deactivationsymbol:
3238+
32373239
Deactivation Symbol Operand Bundles
32383240
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
32393241

@@ -5300,7 +5302,7 @@ need to refer to the actual function body.
53005302
Pointer Authentication Constants
53015303
--------------------------------
53025304

5303-
``ptrauth (ptr CST, i32 KEY[, i64 DISC[, ptr ADDRDISC]?]?)``
5305+
``ptrauth (ptr CST, i32 KEY[, i64 DISC[, ptr ADDRDISC[, ptr DS]?]?]?)``
53045306

53055307
A '``ptrauth``' constant represents a pointer with a cryptographic
53065308
authentication signature embedded into some bits, as described in the
@@ -5329,6 +5331,11 @@ Otherwise, the expression is equivalent to:
53295331
%tmp2 = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr CST to i64), i32 KEY, i64 %tmp1)
53305332
%val = inttoptr i64 %tmp2 to ptr
53315333

5334+
If the deactivation symbol operand ``DS`` has a non-null value,
5335+
the semantics are as if a :ref:`deactivation-symbol operand bundle
5336+
<deactivationsymbol>` were added to the ``llvm.ptrauth.sign`` intrinsic
5337+
calls above, with ``DS`` as the only operand.
5338+
53325339
.. _constantexprs:
53335340

53345341
Constant Expressions

llvm/include/llvm/Bitcode/LLVMBitCodes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,8 @@ enum ConstantsCodes {
437437
CST_CODE_CE_GEP_WITH_INRANGE = 31, // [opty, flags, range, n x operands]
438438
CST_CODE_CE_GEP = 32, // [opty, flags, n x operands]
439439
CST_CODE_PTRAUTH = 33, // [ptr, key, disc, addrdisc]
440+
CST_CODE_PTRAUTH2 = 34, // [ptr, key, disc, addrdisc,
441+
// deactivation_symbol]
440442
};
441443

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

llvm/include/llvm/IR/Constants.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,10 +1033,10 @@ class ConstantPtrAuth final : public Constant {
10331033
friend struct ConstantPtrAuthKeyType;
10341034
friend class Constant;
10351035

1036-
constexpr static IntrusiveOperandsAllocMarker AllocMarker{4};
1036+
constexpr static IntrusiveOperandsAllocMarker AllocMarker{5};
10371037

10381038
ConstantPtrAuth(Constant *Ptr, ConstantInt *Key, ConstantInt *Disc,
1039-
Constant *AddrDisc);
1039+
Constant *AddrDisc, Constant *DeactivationSymbol);
10401040

10411041
void *operator new(size_t s) { return User::operator new(s, AllocMarker); }
10421042

@@ -1046,7 +1046,8 @@ class ConstantPtrAuth final : public Constant {
10461046
public:
10471047
/// Return a pointer signed with the specified parameters.
10481048
LLVM_ABI static ConstantPtrAuth *get(Constant *Ptr, ConstantInt *Key,
1049-
ConstantInt *Disc, Constant *AddrDisc);
1049+
ConstantInt *Disc, Constant *AddrDisc,
1050+
Constant *DeactivationSymbol);
10501051

10511052
/// Produce a new ptrauth expression signing the given value using
10521053
/// the same schema as is stored in one.
@@ -1078,6 +1079,10 @@ class ConstantPtrAuth final : public Constant {
10781079
return !getAddrDiscriminator()->isNullValue();
10791080
}
10801081

1082+
Constant *getDeactivationSymbol() const {
1083+
return cast<Constant>(Op<4>().get());
1084+
}
1085+
10811086
/// A constant value for the address discriminator which has special
10821087
/// significance to ctors/dtors lowering. Regular address discrimination can't
10831088
/// be applied for them since uses of llvm.global_{c|d}tors are disallowed
@@ -1106,7 +1111,7 @@ class ConstantPtrAuth final : public Constant {
11061111

11071112
template <>
11081113
struct OperandTraits<ConstantPtrAuth>
1109-
: public FixedNumOperandTraits<ConstantPtrAuth, 4> {};
1114+
: public FixedNumOperandTraits<ConstantPtrAuth, 5> {};
11101115

11111116
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPtrAuth, Constant)
11121117

llvm/include/llvm/SandboxIR/Constant.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1363,7 +1363,8 @@ class ConstantPtrAuth final : public Constant {
13631363
public:
13641364
/// Return a pointer signed with the specified parameters.
13651365
LLVM_ABI static ConstantPtrAuth *get(Constant *Ptr, ConstantInt *Key,
1366-
ConstantInt *Disc, Constant *AddrDisc);
1366+
ConstantInt *Disc, Constant *AddrDisc,
1367+
Constant *DeactivationSymbol);
13671368
/// The pointer that is signed in this ptrauth signed pointer.
13681369
LLVM_ABI Constant *getPointer() const;
13691370

@@ -1378,6 +1379,8 @@ class ConstantPtrAuth final : public Constant {
13781379
/// the only global-initializer user of the ptrauth signed pointer.
13791380
LLVM_ABI Constant *getAddrDiscriminator() const;
13801381

1382+
Constant *getDeactivationSymbol() const;
1383+
13811384
/// Whether there is any non-null address discriminator.
13821385
bool hasAddressDiscriminator() const {
13831386
return cast<llvm::ConstantPtrAuth>(Val)->hasAddressDiscriminator();

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4250,11 +4250,13 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
42504250
}
42514251
case lltok::kw_ptrauth: {
42524252
// ValID ::= 'ptrauth' '(' ptr @foo ',' i32 <key>
4253-
// (',' i64 <disc> (',' ptr addrdisc)? )? ')'
4253+
// (',' i64 <disc> (',' ptr addrdisc (',' ptr ds)?
4254+
// )? )? ')'
42544255
Lex.Lex();
42554256

42564257
Constant *Ptr, *Key;
4257-
Constant *Disc = nullptr, *AddrDisc = nullptr;
4258+
Constant *Disc = nullptr, *AddrDisc = nullptr,
4259+
*DeactivationSymbol = nullptr;
42584260

42594261
if (parseToken(lltok::lparen,
42604262
"expected '(' in constant ptrauth expression") ||
@@ -4263,11 +4265,14 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
42634265
"expected comma in constant ptrauth expression") ||
42644266
parseGlobalTypeAndValue(Key))
42654267
return true;
4266-
// If present, parse the optional disc/addrdisc.
4267-
if (EatIfPresent(lltok::comma))
4268-
if (parseGlobalTypeAndValue(Disc) ||
4269-
(EatIfPresent(lltok::comma) && parseGlobalTypeAndValue(AddrDisc)))
4270-
return true;
4268+
// If present, parse the optional disc/addrdisc/ds.
4269+
if (EatIfPresent(lltok::comma) && parseGlobalTypeAndValue(Disc))
4270+
return true;
4271+
if (EatIfPresent(lltok::comma) && parseGlobalTypeAndValue(AddrDisc))
4272+
return true;
4273+
if (EatIfPresent(lltok::comma) &&
4274+
parseGlobalTypeAndValue(DeactivationSymbol))
4275+
return true;
42714276
if (parseToken(lltok::rparen,
42724277
"expected ')' in constant ptrauth expression"))
42734278
return true;
@@ -4298,7 +4303,15 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
42984303
AddrDisc = ConstantPointerNull::get(PointerType::get(Context, 0));
42994304
}
43004305

4301-
ID.ConstantVal = ConstantPtrAuth::get(Ptr, KeyC, DiscC, AddrDisc);
4306+
if (!DeactivationSymbol)
4307+
DeactivationSymbol =
4308+
ConstantPointerNull::get(PointerType::get(Context, 0));
4309+
if (!DeactivationSymbol->getType()->isPointerTy())
4310+
return error(ID.Loc,
4311+
"constant ptrauth deactivation symbol must be a pointer");
4312+
4313+
ID.ConstantVal =
4314+
ConstantPtrAuth::get(Ptr, KeyC, DiscC, AddrDisc, DeactivationSymbol);
43024315
ID.Kind = ValID::t_Constant;
43034316
return false;
43044317
}

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1609,7 +1609,16 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID,
16091609
if (!Disc)
16101610
return error("ptrauth disc operand must be ConstantInt");
16111611

1612-
C = ConstantPtrAuth::get(ConstOps[0], Key, Disc, ConstOps[3]);
1612+
Constant *DeactivationSymbol =
1613+
ConstOps.size() > 4 ? ConstOps[4]
1614+
: ConstantPointerNull::get(cast<PointerType>(
1615+
ConstOps[3]->getType()));
1616+
if (!DeactivationSymbol->getType()->isPointerTy())
1617+
return error(
1618+
"ptrauth deactivation symbol operand must be a pointer");
1619+
1620+
C = ConstantPtrAuth::get(ConstOps[0], Key, Disc, ConstOps[3],
1621+
DeactivationSymbol);
16131622
break;
16141623
}
16151624
case BitcodeConstant::NoCFIOpcode: {
@@ -3813,6 +3822,16 @@ Error BitcodeReader::parseConstants() {
38133822
(unsigned)Record[2], (unsigned)Record[3]});
38143823
break;
38153824
}
3825+
case bitc::CST_CODE_PTRAUTH2: {
3826+
if (Record.size() < 5)
3827+
return error("Invalid ptrauth record");
3828+
// Ptr, Key, Disc, AddrDisc, DeactivationSymbol
3829+
V = BitcodeConstant::create(
3830+
Alloc, CurTy, BitcodeConstant::ConstantPtrAuthOpcode,
3831+
{(unsigned)Record[0], (unsigned)Record[1], (unsigned)Record[2],
3832+
(unsigned)Record[3], (unsigned)Record[4]});
3833+
break;
3834+
}
38163835
}
38173836

38183837
assert(V->getType() == getTypeByID(CurTyID) && "Incorrect result type ID");

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3030,11 +3030,12 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
30303030
Record.push_back(VE.getTypeID(NC->getGlobalValue()->getType()));
30313031
Record.push_back(VE.getValueID(NC->getGlobalValue()));
30323032
} else if (const auto *CPA = dyn_cast<ConstantPtrAuth>(C)) {
3033-
Code = bitc::CST_CODE_PTRAUTH;
3033+
Code = bitc::CST_CODE_PTRAUTH2;
30343034
Record.push_back(VE.getValueID(CPA->getPointer()));
30353035
Record.push_back(VE.getValueID(CPA->getKey()));
30363036
Record.push_back(VE.getValueID(CPA->getDiscriminator()));
30373037
Record.push_back(VE.getValueID(CPA->getAddrDiscriminator()));
3038+
Record.push_back(VE.getValueID(CPA->getDeactivationSymbol()));
30383039
} else {
30393040
#ifndef NDEBUG
30403041
C->dump();

llvm/lib/IR/AsmWriter.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1674,12 +1674,14 @@ static void writeConstantInternal(raw_ostream &Out, const Constant *CV,
16741674
if (const auto *CPA = dyn_cast<ConstantPtrAuth>(CV)) {
16751675
Out << "ptrauth (";
16761676

1677-
// ptrauth (ptr CST, i32 KEY[, i64 DISC[, ptr ADDRDISC]?]?)
1677+
// ptrauth (ptr CST, i32 KEY[, i64 DISC[, ptr ADDRDISC[, ptr DS]?]?]?)
16781678
unsigned NumOpsToWrite = 2;
16791679
if (!CPA->getOperand(2)->isNullValue())
16801680
NumOpsToWrite = 3;
16811681
if (!CPA->getOperand(3)->isNullValue())
16821682
NumOpsToWrite = 4;
1683+
if (!CPA->getOperand(4)->isNullValue())
1684+
NumOpsToWrite = 5;
16831685

16841686
ListSeparator LS;
16851687
for (unsigned i = 0, e = NumOpsToWrite; i != e; ++i) {

llvm/lib/IR/Constants.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2081,28 +2081,33 @@ Value *NoCFIValue::handleOperandChangeImpl(Value *From, Value *To) {
20812081
//
20822082

20832083
ConstantPtrAuth *ConstantPtrAuth::get(Constant *Ptr, ConstantInt *Key,
2084-
ConstantInt *Disc, Constant *AddrDisc) {
2085-
Constant *ArgVec[] = {Ptr, Key, Disc, AddrDisc};
2084+
ConstantInt *Disc, Constant *AddrDisc,
2085+
Constant *DeactivationSymbol) {
2086+
Constant *ArgVec[] = {Ptr, Key, Disc, AddrDisc, DeactivationSymbol};
20862087
ConstantPtrAuthKeyType MapKey(ArgVec);
20872088
LLVMContextImpl *pImpl = Ptr->getContext().pImpl;
20882089
return pImpl->ConstantPtrAuths.getOrCreate(Ptr->getType(), MapKey);
20892090
}
20902091

20912092
ConstantPtrAuth *ConstantPtrAuth::getWithSameSchema(Constant *Pointer) const {
2092-
return get(Pointer, getKey(), getDiscriminator(), getAddrDiscriminator());
2093+
return get(Pointer, getKey(), getDiscriminator(), getAddrDiscriminator(),
2094+
getDeactivationSymbol());
20932095
}
20942096

20952097
ConstantPtrAuth::ConstantPtrAuth(Constant *Ptr, ConstantInt *Key,
2096-
ConstantInt *Disc, Constant *AddrDisc)
2098+
ConstantInt *Disc, Constant *AddrDisc,
2099+
Constant *DeactivationSymbol)
20972100
: Constant(Ptr->getType(), Value::ConstantPtrAuthVal, AllocMarker) {
20982101
assert(Ptr->getType()->isPointerTy());
20992102
assert(Key->getBitWidth() == 32);
21002103
assert(Disc->getBitWidth() == 64);
21012104
assert(AddrDisc->getType()->isPointerTy());
2105+
assert(DeactivationSymbol->getType()->isPointerTy());
21022106
setOperand(0, Ptr);
21032107
setOperand(1, Key);
21042108
setOperand(2, Disc);
21052109
setOperand(3, AddrDisc);
2110+
setOperand(4, DeactivationSymbol);
21062111
}
21072112

21082113
/// Remove the constant from the constant table.
@@ -2150,6 +2155,11 @@ bool ConstantPtrAuth::hasSpecialAddressDiscriminator(uint64_t Value) const {
21502155
bool ConstantPtrAuth::isKnownCompatibleWith(const Value *Key,
21512156
const Value *Discriminator,
21522157
const DataLayout &DL) const {
2158+
// This function may only be validly called to analyze a ptrauth operation
2159+
// with no deactivation symbol, so if we have one it isn't compatible.
2160+
if (!getDeactivationSymbol()->isNullValue())
2161+
return false;
2162+
21532163
// If the keys are different, there's no chance for this to be compatible.
21542164
if (getKey() != Key)
21552165
return false;

0 commit comments

Comments
 (0)