1
+ // ===-- PCC.cpp - Probabilistic Calling Context ---------------------------===//
2
+ //
3
+ // The LLVM Compiler Infrastructure
4
+ //
5
+ // This file is distributed under the University of Illinois Open Source
6
+ // License. See LICENSE.TXT for details.
7
+ //
8
+ // ===----------------------------------------------------------------------===//
9
+ // /
10
+ // / \file
11
+ // / This file contains an implementation of Michael Bond's "probabilistic
12
+ // / calling context" (PCC) for maintaining runtime calling context information.
13
+ // /
14
+ // ===----------------------------------------------------------------------===//
15
+
1
16
#include < stdint.h>
2
17
#include < stdlib.h>
3
18
@@ -15,8 +30,10 @@ using namespace llvm;
15
30
namespace {
16
31
17
32
static const char *const PCCCalculateName = " __pcc_calculate" ;
18
- static const char *const PCCVName = " __pcc_V" ;
33
+ static const char *const PCCVarName = " __pcc_V" ;
19
34
35
+ // / ProbabilisticCallingContext: instrument the code in a module to maintain a
36
+ // / probabilistic unique value representing the current calling context.
20
37
class ProbabilisticCallingContext : public ModulePass {
21
38
public:
22
39
static char ID;
@@ -27,7 +44,8 @@ class ProbabilisticCallingContext : public ModulePass {
27
44
28
45
} // namespace
29
46
30
- static Function *getPCCFunction (Constant *FuncOrBitcast) {
47
+ // Adapted from llvm::checkSanitizerInterfaceFunction
48
+ static Function *checkPCCInterfaceFunction (Constant *FuncOrBitcast) {
31
49
if (isa<Function>(FuncOrBitcast)) {
32
50
return cast<Function>(FuncOrBitcast);
33
51
}
@@ -46,29 +64,38 @@ bool ProbabilisticCallingContext::runOnModule(Module &M) {
46
64
LLVMContext &C = M.getContext ();
47
65
const DataLayout &DL = M.getDataLayout ();
48
66
67
+ // Either 32 or 64 bit depending on the target
49
68
IntegerType *IntTy = DL.getIntPtrType (C);
50
69
51
- Function *PCCFunc = getPCCFunction (
70
+ // PCCCalculate is the function `__pcc_calculate` that (funny enough)
71
+ // calculates the probabilistic calling context
72
+ Function *PCCCalculate = checkPCCInterfaceFunction (
52
73
M.getOrInsertFunction (PCCCalculateName, IntTy, IntTy, IntTy));
74
+ // PCCVar is the variable `__pcc_V` that stores the probabilistic calling
75
+ // context
53
76
GlobalVariable *PCCVar = new GlobalVariable (
54
- M, IntTy, false , GlobalValue::ExternalLinkage, nullptr , PCCVName, nullptr ,
55
- GlobalVariable::GeneralDynamicTLSModel, 0 , false );
77
+ M, IntTy, false , GlobalValue::ExternalLinkage, nullptr , PCCVarName ,
78
+ nullptr , GlobalVariable::GeneralDynamicTLSModel, 0 , false );
56
79
57
80
for (auto &F : M.functions ()) {
81
+ // We can only instrument functions that we have an implementation of
58
82
if (F.isDeclaration ()) {
59
83
continue ;
60
84
}
61
85
86
+ // Load the current PCC value into a local variable (temp)
62
87
BasicBlock::iterator IP = F.getEntryBlock ().getFirstInsertionPt ();
63
88
IRBuilder<> EntryIRB (&*IP);
64
89
LoadInst *Temp = EntryIRB.CreateLoad (PCCVar);
65
90
66
91
for (auto I = inst_begin (F); I != inst_end (F); ++I) {
92
+ // At each call site, compute the next calling context with `f` and
93
+ // update the global variable `V`
67
94
if (auto *Call = dyn_cast<CallInst>(&*I)) {
68
95
ConstantInt *CS = ConstantInt::get (IntTy, random ());
69
96
70
97
IRBuilder<> CallSiteIRB (Call);
71
- CallInst *CallF = CallSiteIRB.CreateCall (PCCFunc , {Temp, CS});
98
+ CallInst *CallF = CallSiteIRB.CreateCall (PCCCalculate , {Temp, CS});
72
99
CallSiteIRB.CreateStore (CallF, PCCVar);
73
100
}
74
101
}
0 commit comments