Skip to content

Commit f301c17

Browse files
pccgithub-actions[bot]
authored andcommitted
Automerge: 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: llvm/llvm-project#133537
2 parents ceaf705 + d2379ef commit f301c17

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)