Skip to content

Commit 0d4640a

Browse files
committed
fixup! address reviewer comments
Created using spr 1.3.8-beta.1
1 parent d77f2c0 commit 0d4640a

File tree

12 files changed

+104
-80
lines changed

12 files changed

+104
-80
lines changed

llvm/docs/LangRef.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2428,7 +2428,7 @@ For example:
24282428
attributed with ``sanitize_realtime``.
24292429
This attribute is incompatible with the ``sanitize_realtime`` attribute.
24302430
``sanitize_alloc_token``
2431-
This attributes indicates that implicit allocation token instrumentation
2431+
This attribute indicates that implicit allocation token instrumentation
24322432
is enabled for this function.
24332433
``speculative_load_hardening``
24342434
This attribute indicates that
@@ -8392,6 +8392,13 @@ Example:
83928392
The ``nofree`` metadata indicates the memory pointed by the pointer will not be
83938393
freed after the attached instruction.
83948394

8395+
'``alloc_token``' Metadata
8396+
^^^^^^^^^^^^^^^^^^^^^^^^^^
8397+
8398+
The ``alloc_token`` metadata may be attached to calls to memory allocation
8399+
functions, and contains richer semantic information about the type of the
8400+
allocation. This information is consumed by the ``alloc-token`` pass to
8401+
instrument such calls with allocation token IDs.
83958402

83968403
Module Flags Metadata
83978404
=====================

llvm/docs/ReleaseNotes.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,9 @@ Changes to Sanitizers
166166
Other Changes
167167
-------------
168168

169-
* Introduces the `AllocToken` pass, an instrumentation pass designed to provide
170-
tokens to memory allocators enabling various heap organization strategies,
171-
such as heap partitioning.
169+
* Introduces the `AllocToken` pass, an instrumentation pass providing tokens to
170+
memory allocators enabling various heap organization strategies, such as heap
171+
partitioning.
172172

173173
External Open Source Projects Using LLVM {{env.config.release}}
174174
===============================================================

llvm/include/llvm/IR/FixedMetadataKinds.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,4 @@ LLVM_FIXED_MD_KIND(MD_mmra, "mmra", 40)
5555
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)
58-
LLVM_FIXED_MD_KIND(MD_alloc_token_hint, "alloc_token_hint", 44)
58+
LLVM_FIXED_MD_KIND(MD_alloc_token, "alloc_token", 44)

llvm/lib/Transforms/Instrumentation/AllocToken.cpp

Lines changed: 48 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -69,27 +69,19 @@ enum class TokenMode : unsigned {
6969

7070
/// Token ID based on allocated type hash.
7171
TypeHash = 2,
72-
73-
// Mode count - keep last
74-
ModeCount
7572
};
7673

7774
//===--- Command-line options ---------------------------------------------===//
7875

79-
struct ModeParser : public cl::parser<unsigned> {
80-
ModeParser(cl::Option &O) : cl::parser<unsigned>(O) {}
81-
bool parse(cl::Option &O, StringRef ArgName, StringRef Arg, unsigned &Value) {
82-
if (cl::parser<unsigned>::parse(O, ArgName, Arg, Value))
83-
return true;
84-
if (Value >= static_cast<unsigned>(TokenMode::ModeCount))
85-
return O.error("'" + Arg + "' value invalid");
86-
return false;
87-
}
88-
};
89-
90-
cl::opt<unsigned, false, ModeParser>
91-
ClMode("alloc-token-mode", cl::desc("Token assignment mode"), cl::Hidden,
92-
cl::init(static_cast<unsigned>(TokenMode::TypeHash)));
76+
cl::opt<TokenMode>
77+
ClMode("alloc-token-mode", cl::Hidden, cl::desc("Token assignment mode"),
78+
cl::init(TokenMode::TypeHash),
79+
cl::values(clEnumValN(TokenMode::Increment, "increment",
80+
"Incrementally increasing token ID"),
81+
clEnumValN(TokenMode::Random, "random",
82+
"Statically-assigned random token ID"),
83+
clEnumValN(TokenMode::TypeHash, "typehash",
84+
"Token ID based on allocated type hash")));
9385

9486
cl::opt<std::string> ClFuncPrefix("alloc-token-prefix",
9587
cl::desc("The allocation function prefix"),
@@ -106,7 +98,7 @@ cl::opt<bool>
10698

10799
// Instrument libcalls only by default - compatible allocators only need to take
108100
// care of providing standard allocation functions. With extended coverage, also
109-
// instrument non-libcall allocation function calls with !alloc_token_hint
101+
// instrument non-libcall allocation function calls with !alloc_token
110102
// metadata.
111103
cl::opt<bool>
112104
ClExtended("alloc-token-extended",
@@ -140,14 +132,14 @@ STATISTIC(NumAllocations, "Allocations found");
140132

141133
//===----------------------------------------------------------------------===//
142134

143-
/// Returns the !alloc_token_hint metadata if available.
135+
/// Returns the !alloc_token metadata if available.
144136
///
145137
/// Expected format is: !{<type-name>}
146-
MDNode *getAllocTokenHintMetadata(const CallBase &CB) {
147-
MDNode *Ret = CB.getMetadata(LLVMContext::MD_alloc_token_hint);
138+
MDNode *getAllocTokenMetadata(const CallBase &CB) {
139+
MDNode *Ret = CB.getMetadata(LLVMContext::MD_alloc_token);
148140
if (!Ret)
149141
return nullptr;
150-
assert(Ret->getNumOperands() == 1 && "bad !alloc_token_hint");
142+
assert(Ret->getNumOperands() == 1 && "bad !alloc_token");
151143
assert(isa<MDString>(Ret->getOperand(0)));
152144
return Ret;
153145
}
@@ -198,7 +190,7 @@ class TypeHashMode : public ModeBase {
198190
using ModeBase::ModeBase;
199191

200192
uint64_t operator()(const CallBase &CB, OptimizationRemarkEmitter &ORE) {
201-
if (MDNode *N = getAllocTokenHintMetadata(CB)) {
193+
if (MDNode *N = getAllocTokenMetadata(CB)) {
202194
MDString *S = cast<MDString>(N->getOperand(0));
203195
return boundedToken(xxHash64(S->getString()));
204196
}
@@ -212,7 +204,7 @@ class TypeHashMode : public ModeBase {
212204
ore::NV FuncNV("Function", CB.getParent()->getParent());
213205
const Function *Callee = CB.getCalledFunction();
214206
ore::NV CalleeNV("Callee", Callee ? Callee->getName() : "<unknown>");
215-
return OptimizationRemark(DEBUG_TYPE, "NoAllocTokenHint", &CB)
207+
return OptimizationRemark(DEBUG_TYPE, "NoAllocToken", &CB)
216208
<< "Call to '" << CalleeNV << "' in '" << FuncNV
217209
<< "' without source-level type token";
218210
});
@@ -235,7 +227,7 @@ class AllocToken {
235227
: Options(transformOptionsFromCl(std::move(Opts))), Mod(M),
236228
FAM(MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager()),
237229
Mode(IncrementMode(*Options.MaxTokens)) {
238-
switch (static_cast<TokenMode>(ClMode.getValue())) {
230+
switch (ClMode.getValue()) {
239231
case TokenMode::Increment:
240232
break;
241233
case TokenMode::Random:
@@ -244,9 +236,6 @@ class AllocToken {
244236
case TokenMode::TypeHash:
245237
Mode.emplace<TypeHashMode>(*Options.MaxTokens);
246238
break;
247-
case TokenMode::ModeCount:
248-
llvm_unreachable("");
249-
break;
250239
}
251240
}
252241

@@ -255,10 +244,11 @@ class AllocToken {
255244
private:
256245
/// Returns true for !isAllocationFn() functions that are also eligible for
257246
/// instrumentation.
258-
bool isInstrumentableLibFunc(LibFunc Func) const;
247+
static bool isInstrumentableLibFunc(LibFunc Func, const Value *V,
248+
const TargetLibraryInfo *TLI);
259249

260250
/// Returns true for isAllocationFn() functions that we should ignore.
261-
bool ignoreInstrumentableLibFunc(LibFunc Func) const;
251+
static bool ignoreInstrumentableLibFunc(LibFunc Func);
262252

263253
/// Replace a call/invoke with a call/invoke to the allocation function
264254
/// with token ID.
@@ -277,6 +267,7 @@ class AllocToken {
277267

278268
const AllocTokenOptions Options;
279269
Module &Mod;
270+
IntegerType *IntPtrTy = Mod.getDataLayout().getIntPtrType(Mod.getContext());
280271
FunctionAnalysisManager &FAM;
281272
// Cache for replacement functions.
282273
DenseMap<std::pair<LibFunc, uint64_t>, FunctionCallee> TokenAllocFunctions;
@@ -316,28 +307,29 @@ bool AllocToken::instrumentFunction(Function &F) {
316307
if (TLI.getLibFunc(*Callee, Func)) {
317308
if (ignoreInstrumentableLibFunc(Func))
318309
continue;
319-
if (isInstrumentableLibFunc(Func) || isAllocationFn(CB, &TLI))
310+
if (isInstrumentableLibFunc(Func, CB, &TLI))
320311
AllocCalls.emplace_back(CB, Func);
321-
} else if (Options.Extended && getAllocTokenHintMetadata(*CB)) {
312+
} else if (Options.Extended && getAllocTokenMetadata(*CB)) {
322313
AllocCalls.emplace_back(CB, NotLibFunc);
323314
}
324315
}
325316

326-
bool Modified = false;
317+
if (AllocCalls.empty())
318+
return false;
327319

328-
if (!AllocCalls.empty()) {
329-
for (auto &[CB, Func] : AllocCalls) {
330-
replaceAllocationCall(CB, Func, ORE, TLI);
331-
}
332-
NumAllocations += AllocCalls.size();
333-
NumFunctionsInstrumented++;
334-
Modified = true;
335-
}
320+
for (auto &[CB, Func] : AllocCalls)
321+
replaceAllocationCall(CB, Func, ORE, TLI);
322+
NumAllocations += AllocCalls.size();
323+
NumFunctionsInstrumented++;
336324

337-
return Modified;
325+
return true;
338326
}
339327

340-
bool AllocToken::isInstrumentableLibFunc(LibFunc Func) const {
328+
bool AllocToken::isInstrumentableLibFunc(LibFunc Func, const Value *V,
329+
const TargetLibraryInfo *TLI) {
330+
if (isAllocationFn(V, TLI))
331+
return true;
332+
341333
switch (Func) {
342334
case LibFunc_posix_memalign:
343335
case LibFunc_size_returning_new:
@@ -375,7 +367,7 @@ bool AllocToken::isInstrumentableLibFunc(LibFunc Func) const {
375367
}
376368
}
377369

378-
bool AllocToken::ignoreInstrumentableLibFunc(LibFunc Func) const {
370+
bool AllocToken::ignoreInstrumentableLibFunc(LibFunc Func) {
379371
switch (Func) {
380372
case LibFunc_strdup:
381373
case LibFunc_dunder_strdup:
@@ -395,16 +387,17 @@ void AllocToken::replaceAllocationCall(CallBase *CB, LibFunc Func,
395387
FunctionCallee TokenAlloc = getTokenAllocFunction(*CB, TokenID, Func);
396388
if (!TokenAlloc)
397389
return;
390+
if (Options.FastABI) {
391+
assert(TokenAlloc.getFunctionType()->getNumParams() == CB->arg_size());
392+
CB->setCalledFunction(TokenAlloc);
393+
return;
394+
}
398395

399396
IRBuilder<> IRB(CB);
400-
401397
// Original args.
402398
SmallVector<Value *, 4> NewArgs{CB->args()};
403-
if (!Options.FastABI) {
404-
// Add token ID.
405-
NewArgs.push_back(
406-
ConstantInt::get(Type::getInt64Ty(Mod.getContext()), TokenID));
407-
}
399+
// Add token ID.
400+
NewArgs.push_back(ConstantInt::get(IntPtrTy, TokenID));
408401
assert(TokenAlloc.getFunctionType()->getNumParams() == NewArgs.size());
409402

410403
// Preserve invoke vs call semantics for exception handling.
@@ -443,15 +436,13 @@ FunctionCallee AllocToken::getTokenAllocFunction(const CallBase &CB,
443436
if (OldFTy->isVarArg())
444437
return FunctionCallee();
445438
// Copy params, and append token ID type.
446-
LLVMContext &C = Mod.getContext();
447439
Type *RetTy = OldFTy->getReturnType();
448440
SmallVector<Type *, 4> NewParams{OldFTy->params()};
449441
std::string TokenAllocName = ClFuncPrefix;
450-
if (Options.FastABI) {
442+
if (Options.FastABI)
451443
TokenAllocName += utostr(TokenID) + "_";
452-
} else {
453-
NewParams.push_back(Type::getInt64Ty(C)); // token ID
454-
}
444+
else
445+
NewParams.push_back(IntPtrTy); // token ID
455446
FunctionType *NewFTy = FunctionType::get(RetTy, NewParams, false);
456447
// Remove leading '_' - we add our own.
457448
StringRef No_ = Callee->getName().drop_while([](char C) { return C == '_'; });
@@ -480,5 +471,6 @@ PreservedAnalyses AllocTokenPass::run(Module &M, ModuleAnalysisManager &MAM) {
480471
Modified |= Pass.instrumentFunction(F);
481472
}
482473

483-
return Modified ? PreservedAnalyses::none() : PreservedAnalyses::all();
474+
return Modified ? PreservedAnalyses::none().preserveSet<CFGAnalyses>()
475+
: PreservedAnalyses::all();
484476
}

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3025,8 +3025,8 @@ static void combineMetadata(Instruction *K, const Instruction *J,
30253025
// Preserve !nosanitize if both K and J have it.
30263026
K->setMetadata(Kind, JMD);
30273027
break;
3028-
case LLVMContext::MD_alloc_token_hint:
3029-
// Preserve !alloc_token_hint if both K and J have it.
3028+
case LLVMContext::MD_alloc_token:
3029+
// Preserve !alloc_token if both K and J have it.
30303030
K->setMetadata(Kind, JMD);
30313031
break;
30323032
}

llvm/test/Instrumentation/AllocToken/basic.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt < %s -passes=inferattrs,alloc-token -alloc-token-mode=0 -S | FileCheck %s
1+
; RUN: opt < %s -passes=inferattrs,alloc-token -alloc-token-mode=increment -S | FileCheck %s
22

33
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
44
target triple = "x86_64-unknown-linux-gnu"
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
; RUN: opt < %s -passes=inferattrs,alloc-token -alloc-token-mode=increment -S | FileCheck %s
2+
3+
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
4+
target triple = "i386-pc-linux-gnu"
5+
6+
declare ptr @malloc(i32)
7+
declare ptr @_Znwm(i32)
8+
9+
; CHECK-LABEL: @test_basic_rewriting
10+
define ptr @test_basic_rewriting() sanitize_alloc_token {
11+
entry:
12+
; CHECK: [[PTR1:%[0-9]]] = call ptr @__alloc_token_malloc(i32 64, i32 0)
13+
; CHECK-NOT: call ptr @malloc(
14+
%ptr1 = call ptr @malloc(i32 64)
15+
ret ptr %ptr1
16+
}
17+
18+
; CHECK-LABEL: @test_cpp_operators
19+
define ptr @test_cpp_operators() sanitize_alloc_token {
20+
entry:
21+
; CHECK: call ptr @__alloc_token_Znwm(i32 32, i32 1)
22+
; CHECK-NOT: call ptr @_Znwm(
23+
%ptr1 = call ptr @_Znwm(i32 32)
24+
ret ptr %ptr1
25+
}

llvm/test/Instrumentation/AllocToken/extralibfuncs.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ declare {ptr, i64} @__size_returning_new(i64)
1111
define ptr @test_extra_libfuncs() sanitize_alloc_token {
1212
entry:
1313
; CHECK: call {{.*}} @__alloc_token_size_returning_new(
14-
%srn = call {ptr, i64} @__size_returning_new(i64 10), !alloc_token_hint !0
14+
%srn = call {ptr, i64} @__size_returning_new(i64 10), !alloc_token !0
1515
%ptr1 = extractvalue {ptr, i64} %srn, 0
1616
ret ptr %ptr1
1717
}
@@ -23,9 +23,9 @@ declare ptr @_Znam(i64) nobuiltin allocsize(0)
2323
define ptr @test_replaceable_new() sanitize_alloc_token {
2424
entry:
2525
; CHECK: call ptr @__alloc_token_Znwm(
26-
%ptr1 = call ptr @_Znwm(i64 32), !alloc_token_hint !0
26+
%ptr1 = call ptr @_Znwm(i64 32), !alloc_token !0
2727
; CHECK: call ptr @__alloc_token_Znam(
28-
%ptr2 = call ptr @_Znam(i64 64), !alloc_token_hint !0
28+
%ptr2 = call ptr @_Znam(i64 64), !alloc_token !0
2929
ret ptr %ptr1
3030
}
3131

llvm/test/Instrumentation/AllocToken/fast.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt < %s -passes=inferattrs,alloc-token -alloc-token-mode=0 -alloc-token-fast-abi -alloc-token-max=3 -S | FileCheck %s
1+
; RUN: opt < %s -passes=inferattrs,alloc-token -alloc-token-mode=increment -alloc-token-fast-abi -alloc-token-max=3 -S | FileCheck %s
22

33
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
44
target triple = "x86_64-unknown-linux-gnu"
@@ -13,7 +13,7 @@ declare ptr @_Znam(i64)
1313
; CHECK-LABEL: @test_basic_rewriting
1414
define ptr @test_basic_rewriting() sanitize_alloc_token {
1515
entry:
16-
; CHECK: [[PTR1:%[0-9]]] = call ptr @__alloc_token_0_malloc(i64 64)
16+
; CHECK: [[PTR1:%ptr[0-9]]] = call ptr @__alloc_token_0_malloc(i64 64)
1717
; CHECK: call ptr @__alloc_token_1_calloc(i64 8, i64 8)
1818
; CHECK: call ptr @__alloc_token_2_realloc(ptr [[PTR1]], i64 128)
1919
; CHECK-NOT: call ptr @malloc(

llvm/test/Instrumentation/AllocToken/invoke.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt < %s -passes=inferattrs,alloc-token -alloc-token-mode=0 -S | FileCheck %s
1+
; RUN: opt < %s -passes=inferattrs,alloc-token -alloc-token-mode=increment -S | FileCheck %s
22

33
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
44
target triple = "x86_64-unknown-linux-gnu"

0 commit comments

Comments
 (0)