Skip to content

Commit 11d6d21

Browse files
pcc丹治秀樹
authored andcommitted
Add IR and codegen support for deactivation symbols.
Deactivation symbols are a mechanism for allowing object files to disable specific instructions in other object files at link time. The initial use case is for pointer field protection. For more information, see the RFC: https://discourse.llvm.org/t/rfc-deactivation-symbols/85556 Reviewers: ojhunt, nikic, fmayer, arsenm, ahmedbougacha Reviewed By: fmayer Pull Request: llvm#133536
1 parent 1566851 commit 11d6d21

40 files changed

+441
-67
lines changed

llvm/docs/LangRef.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3234,6 +3234,22 @@ 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+
Deactivation Symbol Operand Bundles
3238+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3239+
3240+
A ``"deactivation-symbol"`` operand bundle is valid on the following
3241+
instructions (AArch64 only):
3242+
3243+
- Call to a normal function with ``notail`` attribute and a first argument and
3244+
return value of type ``ptr``.
3245+
- Call to ``llvm.ptrauth.sign`` or ``llvm.ptrauth.auth`` intrinsics.
3246+
3247+
This operand bundle specifies that if the deactivation symbol is defined
3248+
to a valid value for the target, the marked instruction will return the
3249+
value of its first argument instead of calling the specified function
3250+
or intrinsic. This is achieved with ``PATCHINST`` relocations on the
3251+
target instructions (see the AArch64 psABI for details).
3252+
32373253
.. _moduleasm:
32383254

32393255
Module-Level Inline Assembly

llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ class LLVM_ABI CallLowering {
159159

160160
/// True if this call results in convergent operations.
161161
bool IsConvergent = true;
162+
163+
GlobalValue *DeactivationSymbol = nullptr;
162164
};
163165

164166
/// Argument handling is mostly uniform between the four places that

llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ struct MachineIRBuilderState {
5656
MDNode *PCSections = nullptr;
5757
/// MMRA Metadata to be set on any instruction we create.
5858
MDNode *MMRA = nullptr;
59+
Value *DS = nullptr;
5960

6061
/// \name Fields describing the insertion point.
6162
/// @{
@@ -369,6 +370,7 @@ class LLVM_ABI MachineIRBuilder {
369370
State.II = MI.getIterator();
370371
setPCSections(MI.getPCSections());
371372
setMMRAMetadata(MI.getMMRAMetadata());
373+
setDeactivationSymbol(MI.getDeactivationSymbol());
372374
}
373375
/// @}
374376

@@ -405,6 +407,9 @@ class LLVM_ABI MachineIRBuilder {
405407
/// Set the PC sections metadata to \p MD for all the next build instructions.
406408
void setMMRAMetadata(MDNode *MMRA) { State.MMRA = MMRA; }
407409

410+
Value *getDeactivationSymbol() { return State.DS; }
411+
void setDeactivationSymbol(Value *DS) { State.DS = DS; }
412+
408413
/// Get the current instruction's MMRA metadata.
409414
MDNode *getMMRAMetadata() { return State.MMRA; }
410415

llvm/include/llvm/CodeGen/ISDOpcodes.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,6 +1579,10 @@ enum NodeType {
15791579
// Outputs: Output Chain
15801580
CLEAR_CACHE,
15811581

1582+
// Untyped node storing deactivation symbol reference
1583+
// (DeactivationSymbolSDNode).
1584+
DEACTIVATION_SYMBOL,
1585+
15821586
/// BUILTIN_OP_END - This must be the last enum value in this list.
15831587
/// The target-specific pre-isel opcode values start here.
15841588
BUILTIN_OP_END

llvm/include/llvm/CodeGen/MachineFunction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1207,7 +1207,7 @@ class LLVM_ABI MachineFunction {
12071207
ArrayRef<MachineMemOperand *> MMOs, MCSymbol *PreInstrSymbol = nullptr,
12081208
MCSymbol *PostInstrSymbol = nullptr, MDNode *HeapAllocMarker = nullptr,
12091209
MDNode *PCSections = nullptr, uint32_t CFIType = 0,
1210-
MDNode *MMRAs = nullptr);
1210+
MDNode *MMRAs = nullptr, Value *DS = nullptr);
12111211

12121212
/// Allocate a string and populate it with the given external symbol name.
12131213
const char *createExternalSymbolName(StringRef Name);

llvm/include/llvm/CodeGen/MachineInstr.h

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -160,29 +160,33 @@ class MachineInstr
160160
///
161161
/// This has to be defined eagerly due to the implementation constraints of
162162
/// `PointerSumType` where it is used.
163-
class ExtraInfo final : TrailingObjects<ExtraInfo, MachineMemOperand *,
164-
MCSymbol *, MDNode *, uint32_t> {
163+
class ExtraInfo final
164+
: TrailingObjects<ExtraInfo, MachineMemOperand *, MCSymbol *, MDNode *,
165+
uint32_t, Value *> {
165166
public:
166167
static ExtraInfo *create(BumpPtrAllocator &Allocator,
167168
ArrayRef<MachineMemOperand *> MMOs,
168169
MCSymbol *PreInstrSymbol = nullptr,
169170
MCSymbol *PostInstrSymbol = nullptr,
170171
MDNode *HeapAllocMarker = nullptr,
171172
MDNode *PCSections = nullptr, uint32_t CFIType = 0,
172-
MDNode *MMRAs = nullptr) {
173+
MDNode *MMRAs = nullptr, Value *DS = nullptr) {
173174
bool HasPreInstrSymbol = PreInstrSymbol != nullptr;
174175
bool HasPostInstrSymbol = PostInstrSymbol != nullptr;
175176
bool HasHeapAllocMarker = HeapAllocMarker != nullptr;
176177
bool HasMMRAs = MMRAs != nullptr;
177178
bool HasCFIType = CFIType != 0;
178179
bool HasPCSections = PCSections != nullptr;
180+
bool HasDS = DS != nullptr;
179181
auto *Result = new (Allocator.Allocate(
180-
totalSizeToAlloc<MachineMemOperand *, MCSymbol *, MDNode *, uint32_t>(
182+
totalSizeToAlloc<MachineMemOperand *, MCSymbol *, MDNode *, uint32_t,
183+
Value *>(
181184
MMOs.size(), HasPreInstrSymbol + HasPostInstrSymbol,
182-
HasHeapAllocMarker + HasPCSections + HasMMRAs, HasCFIType),
185+
HasHeapAllocMarker + HasPCSections + HasMMRAs, HasCFIType, HasDS),
183186
alignof(ExtraInfo)))
184187
ExtraInfo(MMOs.size(), HasPreInstrSymbol, HasPostInstrSymbol,
185-
HasHeapAllocMarker, HasPCSections, HasCFIType, HasMMRAs);
188+
HasHeapAllocMarker, HasPCSections, HasCFIType, HasMMRAs,
189+
HasDS);
186190

187191
// Copy the actual data into the trailing objects.
188192
llvm::copy(MMOs, Result->getTrailingObjects<MachineMemOperand *>());
@@ -202,6 +206,8 @@ class MachineInstr
202206
Result->getTrailingObjects<uint32_t>()[0] = CFIType;
203207
if (HasMMRAs)
204208
Result->getTrailingObjects<MDNode *>()[MDNodeIdx++] = MMRAs;
209+
if (HasDS)
210+
Result->getTrailingObjects<Value *>()[0] = DS;
205211

206212
return Result;
207213
}
@@ -240,6 +246,10 @@ class MachineInstr
240246
: nullptr;
241247
}
242248

249+
Value *getDeactivationSymbol() const {
250+
return HasDS ? getTrailingObjects<Value *>()[0] : 0;
251+
}
252+
243253
private:
244254
friend TrailingObjects;
245255

@@ -255,6 +265,7 @@ class MachineInstr
255265
const bool HasPCSections;
256266
const bool HasCFIType;
257267
const bool HasMMRAs;
268+
const bool HasDS;
258269

259270
// Implement the `TrailingObjects` internal API.
260271
size_t numTrailingObjects(OverloadToken<MachineMemOperand *>) const {
@@ -269,16 +280,17 @@ class MachineInstr
269280
size_t numTrailingObjects(OverloadToken<uint32_t>) const {
270281
return HasCFIType;
271282
}
283+
size_t numTrailingObjects(OverloadToken<Value *>) const { return HasDS; }
272284

273285
// Just a boring constructor to allow us to initialize the sizes. Always use
274286
// the `create` routine above.
275287
ExtraInfo(int NumMMOs, bool HasPreInstrSymbol, bool HasPostInstrSymbol,
276288
bool HasHeapAllocMarker, bool HasPCSections, bool HasCFIType,
277-
bool HasMMRAs)
289+
bool HasMMRAs, bool HasDS)
278290
: NumMMOs(NumMMOs), HasPreInstrSymbol(HasPreInstrSymbol),
279291
HasPostInstrSymbol(HasPostInstrSymbol),
280292
HasHeapAllocMarker(HasHeapAllocMarker), HasPCSections(HasPCSections),
281-
HasCFIType(HasCFIType), HasMMRAs(HasMMRAs) {}
293+
HasCFIType(HasCFIType), HasMMRAs(HasMMRAs), HasDS(HasDS) {}
282294
};
283295

284296
/// Enumeration of the kinds of inline extra info available. It is important
@@ -867,6 +879,14 @@ class MachineInstr
867879
return nullptr;
868880
}
869881

882+
Value *getDeactivationSymbol() const {
883+
if (!Info)
884+
return nullptr;
885+
if (ExtraInfo *EI = Info.get<EIIK_OutOfLine>())
886+
return EI->getDeactivationSymbol();
887+
return nullptr;
888+
}
889+
870890
/// Helper to extract a CFI type hash if one has been added.
871891
uint32_t getCFIType() const {
872892
if (!Info)
@@ -1969,6 +1989,8 @@ class MachineInstr
19691989
/// Set the CFI type for the instruction.
19701990
LLVM_ABI void setCFIType(MachineFunction &MF, uint32_t Type);
19711991

1992+
LLVM_ABI void setDeactivationSymbol(MachineFunction &MF, Value *DS);
1993+
19721994
/// Return the MIFlags which represent both MachineInstrs. This
19731995
/// should be used when merging two MachineInstrs into one. This routine does
19741996
/// not modify the MIFlags of this MachineInstr.
@@ -2088,7 +2110,7 @@ class MachineInstr
20882110
void setExtraInfo(MachineFunction &MF, ArrayRef<MachineMemOperand *> MMOs,
20892111
MCSymbol *PreInstrSymbol, MCSymbol *PostInstrSymbol,
20902112
MDNode *HeapAllocMarker, MDNode *PCSections,
2091-
uint32_t CFIType, MDNode *MMRAs);
2113+
uint32_t CFIType, MDNode *MMRAs, Value *DS);
20922114
};
20932115

20942116
/// Special DenseMapInfo traits to compare MachineInstr* by *value* of the

llvm/include/llvm/CodeGen/MachineInstrBuilder.h

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,29 +70,44 @@ enum {
7070
} // end namespace RegState
7171

7272
/// Set of metadata that should be preserved when using BuildMI(). This provides
73-
/// a more convenient way of preserving DebugLoc, PCSections and MMRA.
73+
/// a more convenient way of preserving certain data from the original
74+
/// instruction.
7475
class MIMetadata {
7576
public:
7677
MIMetadata() = default;
77-
MIMetadata(DebugLoc DL, MDNode *PCSections = nullptr, MDNode *MMRA = nullptr)
78-
: DL(std::move(DL)), PCSections(PCSections), MMRA(MMRA) {}
78+
MIMetadata(DebugLoc DL, MDNode *PCSections = nullptr, MDNode *MMRA = nullptr,
79+
Value *DeactivationSymbol = nullptr)
80+
: DL(std::move(DL)), PCSections(PCSections), MMRA(MMRA),
81+
DeactivationSymbol(DeactivationSymbol) {}
7982
MIMetadata(const DILocation *DI, MDNode *PCSections = nullptr,
8083
MDNode *MMRA = nullptr)
8184
: DL(DI), PCSections(PCSections), MMRA(MMRA) {}
8285
explicit MIMetadata(const Instruction &From)
8386
: DL(From.getDebugLoc()),
84-
PCSections(From.getMetadata(LLVMContext::MD_pcsections)) {}
87+
PCSections(From.getMetadata(LLVMContext::MD_pcsections)),
88+
DeactivationSymbol(getDeactivationSymbol(&From)) {}
8589
explicit MIMetadata(const MachineInstr &From)
86-
: DL(From.getDebugLoc()), PCSections(From.getPCSections()) {}
90+
: DL(From.getDebugLoc()), PCSections(From.getPCSections()),
91+
DeactivationSymbol(From.getDeactivationSymbol()) {}
8792

8893
const DebugLoc &getDL() const { return DL; }
8994
MDNode *getPCSections() const { return PCSections; }
9095
MDNode *getMMRAMetadata() const { return MMRA; }
96+
Value *getDeactivationSymbol() const { return DeactivationSymbol; }
9197

9298
private:
9399
DebugLoc DL;
94100
MDNode *PCSections = nullptr;
95101
MDNode *MMRA = nullptr;
102+
Value *DeactivationSymbol = nullptr;
103+
104+
static inline Value *getDeactivationSymbol(const Instruction *I) {
105+
if (auto *CB = dyn_cast<CallBase>(I))
106+
if (auto Bundle =
107+
CB->getOperandBundle(llvm::LLVMContext::OB_deactivation_symbol))
108+
return Bundle->Inputs[0].get();
109+
return nullptr;
110+
}
96111
};
97112

98113
class MachineInstrBuilder {
@@ -348,6 +363,8 @@ class MachineInstrBuilder {
348363
MI->setPCSections(*MF, MIMD.getPCSections());
349364
if (MIMD.getMMRAMetadata())
350365
MI->setMMRAMetadata(*MF, MIMD.getMMRAMetadata());
366+
if (MIMD.getDeactivationSymbol())
367+
MI->setDeactivationSymbol(*MF, MIMD.getDeactivationSymbol());
351368
return *this;
352369
}
353370

llvm/include/llvm/CodeGen/SelectionDAG.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,7 @@ class SelectionDAG {
759759
int64_t offset = 0, unsigned TargetFlags = 0) {
760760
return getGlobalAddress(GV, DL, VT, offset, true, TargetFlags);
761761
}
762+
LLVM_ABI SDValue getDeactivationSymbol(const GlobalValue *GV);
762763
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget = false);
763764
SDValue getTargetFrameIndex(int FI, EVT VT) {
764765
return getFrameIndex(FI, VT, true);

llvm/include/llvm/CodeGen/SelectionDAGISel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ class SelectionDAGISel {
151151
OPC_RecordChild7,
152152
OPC_RecordMemRef,
153153
OPC_CaptureGlueInput,
154+
OPC_CaptureDeactivationSymbol,
154155
OPC_MoveChild,
155156
OPC_MoveChild0,
156157
OPC_MoveChild1,

llvm/include/llvm/CodeGen/SelectionDAGNodes.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2005,6 +2005,22 @@ class GlobalAddressSDNode : public SDNode {
20052005
}
20062006
};
20072007

2008+
class DeactivationSymbolSDNode : public SDNode {
2009+
friend class SelectionDAG;
2010+
2011+
const GlobalValue *TheGlobal;
2012+
2013+
DeactivationSymbolSDNode(const GlobalValue *GV, SDVTList VTs)
2014+
: SDNode(ISD::DEACTIVATION_SYMBOL, 0, DebugLoc(), VTs), TheGlobal(GV) {}
2015+
2016+
public:
2017+
const GlobalValue *getGlobal() const { return TheGlobal; }
2018+
2019+
static bool classof(const SDNode *N) {
2020+
return N->getOpcode() == ISD::DEACTIVATION_SYMBOL;
2021+
}
2022+
};
2023+
20082024
class FrameIndexSDNode : public SDNode {
20092025
friend class SelectionDAG;
20102026

0 commit comments

Comments
 (0)