Skip to content

Commit 224873d

Browse files
authored
[AllocToken] Introduce sanitize_alloc_token attribute and alloc_token metadata (#160131)
In preparation of adding the "AllocToken" pass, add the pre-requisite `sanitize_alloc_token` function attribute and `alloc_token` metadata. --- This change is part of the following series: 1. #160131 2. #156838 3. #162098 4. #162099 5. #156839 6. #156840 7. #156841 8. #156842
1 parent ed113e7 commit 224873d

File tree

17 files changed

+207
-3
lines changed

17 files changed

+207
-3
lines changed

llvm/docs/LangRef.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2529,6 +2529,9 @@ For example:
25292529
if the attributed function is called during invocation of a function
25302530
attributed with ``sanitize_realtime``.
25312531
This attribute is incompatible with the ``sanitize_realtime`` attribute.
2532+
``sanitize_alloc_token``
2533+
This attribute indicates that implicit allocation token instrumentation
2534+
is enabled for this function.
25322535
``speculative_load_hardening``
25332536
This attribute indicates that
25342537
`Speculative Load Hardening <https://llvm.org/docs/SpeculativeLoadHardening.html>`_
@@ -8577,6 +8580,21 @@ Example:
85778580
The ``nofree`` metadata indicates the memory pointed by the pointer will not be
85788581
freed after the attached instruction.
85798582

8583+
'``alloc_token``' Metadata
8584+
^^^^^^^^^^^^^^^^^^^^^^^^^^
8585+
8586+
The ``alloc_token`` metadata may be attached to calls to memory allocation
8587+
functions, and contains richer semantic information about the type of the
8588+
allocation. This information is consumed by the ``alloc-token`` pass to
8589+
instrument such calls with allocation token IDs.
8590+
8591+
The metadata contains a string with the type of an allocation.
8592+
8593+
.. code-block:: none
8594+
8595+
call ptr @malloc(i64 64), !alloc_token !0
8596+
8597+
!0 = !{!"<type-name>"}
85808598

85818599
Module Flags Metadata
85828600
=====================

llvm/include/llvm/Bitcode/LLVMBitCodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,7 @@ enum AttributeKindCodes {
800800
ATTR_KIND_SANITIZE_TYPE = 101,
801801
ATTR_KIND_CAPTURES = 102,
802802
ATTR_KIND_DEAD_ON_RETURN = 103,
803+
ATTR_KIND_SANITIZE_ALLOC_TOKEN = 104,
803804
};
804805

805806
enum ComdatSelectionKindCodes {

llvm/include/llvm/IR/Attributes.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,9 @@ def SanitizeRealtime : EnumAttr<"sanitize_realtime", IntersectPreserve, [FnAttr]
342342
/// during a real-time sanitized function (see `sanitize_realtime`).
343343
def SanitizeRealtimeBlocking : EnumAttr<"sanitize_realtime_blocking", IntersectPreserve, [FnAttr]>;
344344

345+
/// Allocation token instrumentation is on.
346+
def SanitizeAllocToken : EnumAttr<"sanitize_alloc_token", IntersectPreserve, [FnAttr]>;
347+
345348
/// Speculative Load Hardening is enabled.
346349
///
347350
/// Note that this uses the default compatibility (always compatible during

llvm/include/llvm/IR/FixedMetadataKinds.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,4 @@ LLVM_FIXED_MD_KIND(MD_noalias_addrspace, "noalias.addrspace", 41)
5656
LLVM_FIXED_MD_KIND(MD_callee_type, "callee_type", 42)
5757
LLVM_FIXED_MD_KIND(MD_nofree, "nofree", 43)
5858
LLVM_FIXED_MD_KIND(MD_captures, "captures", 44)
59+
LLVM_FIXED_MD_KIND(MD_alloc_token, "alloc_token", 45)

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2203,6 +2203,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
22032203
return Attribute::SanitizeRealtime;
22042204
case bitc::ATTR_KIND_SANITIZE_REALTIME_BLOCKING:
22052205
return Attribute::SanitizeRealtimeBlocking;
2206+
case bitc::ATTR_KIND_SANITIZE_ALLOC_TOKEN:
2207+
return Attribute::SanitizeAllocToken;
22062208
case bitc::ATTR_KIND_SPECULATIVE_LOAD_HARDENING:
22072209
return Attribute::SpeculativeLoadHardening;
22082210
case bitc::ATTR_KIND_SWIFT_ERROR:

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
883883
return bitc::ATTR_KIND_STRUCT_RET;
884884
case Attribute::SanitizeAddress:
885885
return bitc::ATTR_KIND_SANITIZE_ADDRESS;
886+
case Attribute::SanitizeAllocToken:
887+
return bitc::ATTR_KIND_SANITIZE_ALLOC_TOKEN;
886888
case Attribute::SanitizeHWAddress:
887889
return bitc::ATTR_KIND_SANITIZE_HWADDRESS;
888890
case Attribute::SanitizeThread:

llvm/lib/IR/Verifier.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
543543
void visitAliasScopeListMetadata(const MDNode *MD);
544544
void visitAccessGroupMetadata(const MDNode *MD);
545545
void visitCapturesMetadata(Instruction &I, const MDNode *Captures);
546+
void visitAllocTokenMetadata(Instruction &I, MDNode *MD);
546547

547548
template <class Ty> bool isValidMetadataArray(const MDTuple &N);
548549
#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N);
@@ -5395,6 +5396,12 @@ void Verifier::visitCapturesMetadata(Instruction &I, const MDNode *Captures) {
53955396
}
53965397
}
53975398

5399+
void Verifier::visitAllocTokenMetadata(Instruction &I, MDNode *MD) {
5400+
Check(isa<CallBase>(I), "!alloc_token should only exist on calls", &I);
5401+
Check(MD->getNumOperands() == 1, "!alloc_token must have 1 operand", MD);
5402+
Check(isa<MDString>(MD->getOperand(0)), "expected string", MD);
5403+
}
5404+
53985405
/// verifyInstruction - Verify that an instruction is well formed.
53995406
///
54005407
void Verifier::visitInstruction(Instruction &I) {
@@ -5625,6 +5632,9 @@ void Verifier::visitInstruction(Instruction &I) {
56255632
if (MDNode *Captures = I.getMetadata(LLVMContext::MD_captures))
56265633
visitCapturesMetadata(I, Captures);
56275634

5635+
if (MDNode *MD = I.getMetadata(LLVMContext::MD_alloc_token))
5636+
visitAllocTokenMetadata(I, MD);
5637+
56285638
if (MDNode *N = I.getDebugLoc().getAsMDNode()) {
56295639
CheckDI(isa<DILocation>(N), "invalid !dbg metadata attachment", &I, N);
56305640
visitMDNode(*N, AreDebugLocsAllowed::Yes);

llvm/lib/Transforms/Utils/CodeExtractor.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,7 @@ Function *CodeExtractor::constructFunctionDeclaration(
970970
case Attribute::SanitizeMemTag:
971971
case Attribute::SanitizeRealtime:
972972
case Attribute::SanitizeRealtimeBlocking:
973+
case Attribute::SanitizeAllocToken:
973974
case Attribute::SpeculativeLoadHardening:
974975
case Attribute::StackProtect:
975976
case Attribute::StackProtectReq:

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3031,6 +3031,13 @@ static void combineMetadata(Instruction *K, const Instruction *J,
30313031
K->getContext(), MDNode::toCaptureComponents(JMD) |
30323032
MDNode::toCaptureComponents(KMD)));
30333033
break;
3034+
case LLVMContext::MD_alloc_token:
3035+
// Preserve !alloc_token if both K and J have it, and they are equal.
3036+
if (KMD == JMD)
3037+
K->setMetadata(Kind, JMD);
3038+
else
3039+
K->setMetadata(Kind, nullptr);
3040+
break;
30343041
}
30353042
}
30363043
// Set !invariant.group from J if J has it. If both instructions have it

llvm/test/Bitcode/attributes.ll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,11 @@ define void @f93() sanitize_realtime_blocking {
516516
ret void;
517517
}
518518

519+
; CHECK: define void @f_sanitize_alloc_token() #55
520+
define void @f_sanitize_alloc_token() sanitize_alloc_token {
521+
ret void;
522+
}
523+
519524
; CHECK: define void @f87() [[FNRETTHUNKEXTERN:#[0-9]+]]
520525
define void @f87() fn_ret_thunk_extern { ret void }
521526

@@ -627,6 +632,7 @@ define void @dead_on_return(ptr dead_on_return %p) {
627632
; CHECK: attributes #52 = { nosanitize_bounds }
628633
; CHECK: attributes #53 = { sanitize_realtime }
629634
; CHECK: attributes #54 = { sanitize_realtime_blocking }
635+
; CHECK: attributes #55 = { sanitize_alloc_token }
630636
; CHECK: attributes [[FNRETTHUNKEXTERN]] = { fn_ret_thunk_extern }
631637
; CHECK: attributes [[SKIPPROFILE]] = { skipprofile }
632638
; CHECK: attributes [[OPTDEBUG]] = { optdebug }

0 commit comments

Comments
 (0)