20
20
#include " llvm/Demangle/Demangle.h"
21
21
#include " llvm/Transforms/Instrumentation/RealtimeSanitizer.h"
22
22
23
+ #include < vector>
24
+
23
25
using namespace llvm ;
24
26
27
+ static std::vector<Type *> getArgTypes (ArrayRef<Value *> FunctionArgs) {
28
+ std::vector<Type *> Types;
29
+ for (Value *Arg : FunctionArgs)
30
+ Types.push_back (Arg->getType ());
31
+ return Types;
32
+ }
33
+
25
34
static void insertCallBeforeInstruction (Function &Fn, Instruction &Instruction,
26
- const char *FunctionName) {
35
+ const char *FunctionName,
36
+ ArrayRef<Value *> FunctionArgs) {
27
37
LLVMContext &Context = Fn.getContext ();
28
- FunctionType *FuncType = FunctionType::get (Type::getVoidTy (Context), false );
38
+ FunctionType *FuncType = FunctionType::get (Type::getVoidTy (Context),
39
+ getArgTypes (FunctionArgs), false );
29
40
FunctionCallee Func =
30
41
Fn.getParent ()->getOrInsertFunction (FunctionName, FuncType);
31
42
IRBuilder<> Builder{&Instruction};
32
- Builder.CreateCall (Func, {} );
43
+ Builder.CreateCall (Func, FunctionArgs );
33
44
}
34
45
35
46
static void insertCallAtFunctionEntryPoint (Function &Fn,
36
- const char *InsertFnName) {
37
-
38
- insertCallBeforeInstruction (Fn, Fn.front ().front (), InsertFnName);
47
+ const char *InsertFnName,
48
+ ArrayRef<Value *> FunctionArgs) {
49
+ insertCallBeforeInstruction (Fn, Fn.front ().front (), InsertFnName,
50
+ FunctionArgs);
39
51
}
40
52
41
53
static void insertCallAtAllFunctionExitPoints (Function &Fn,
42
- const char *InsertFnName) {
54
+ const char *InsertFnName,
55
+ ArrayRef<Value *> FunctionArgs) {
43
56
for (auto &BB : Fn)
44
57
for (auto &I : BB)
45
58
if (isa<ReturnInst>(&I))
46
- insertCallBeforeInstruction (Fn, I, InsertFnName);
59
+ insertCallBeforeInstruction (Fn, I, InsertFnName, FunctionArgs );
47
60
}
48
61
49
62
static PreservedAnalyses rtsanPreservedCFGAnalyses () {
@@ -52,35 +65,29 @@ static PreservedAnalyses rtsanPreservedCFGAnalyses() {
52
65
return PA;
53
66
}
54
67
55
- static void insertNotifyBlockingCallAtFunctionEntryPoint (Function &Fn) {
56
- IRBuilder<> Builder (&Fn.front ().front ());
57
- Value *NameArg = Builder.CreateGlobalString (demangle (Fn.getName ()));
58
-
59
- FunctionType *FuncType =
60
- FunctionType::get (Type::getVoidTy (Fn.getContext ()),
61
- {PointerType::getUnqual (Fn.getContext ())}, false );
62
-
63
- FunctionCallee Func = Fn.getParent ()->getOrInsertFunction (
64
- " __rtsan_notify_blocking_call" , FuncType);
68
+ static PreservedAnalyses runSanitizeRealtime (Function &Fn) {
69
+ insertCallAtFunctionEntryPoint (Fn, " __rtsan_realtime_enter" , {});
70
+ insertCallAtAllFunctionExitPoints (Fn, " __rtsan_realtime_exit" , {});
71
+ return rtsanPreservedCFGAnalyses ();
72
+ }
65
73
66
- Builder.CreateCall (Func, {NameArg});
74
+ static PreservedAnalyses runSanitizeRealtimeUnsafe (Function &Fn) {
75
+ IRBuilder<> Builder (&Fn.front ().front ());
76
+ Value *Name = Builder.CreateGlobalString (demangle (Fn.getName ()));
77
+ insertCallAtFunctionEntryPoint (Fn, " __rtsan_notify_blocking_call" , {Name});
78
+ return rtsanPreservedCFGAnalyses ();
67
79
}
68
80
69
81
RealtimeSanitizerPass::RealtimeSanitizerPass (
70
82
const RealtimeSanitizerOptions &Options) {}
71
83
72
84
PreservedAnalyses RealtimeSanitizerPass::run (Function &Fn,
73
85
AnalysisManager<Function> &AM) {
74
- if (Fn.hasFnAttribute (Attribute::SanitizeRealtime)) {
75
- insertCallAtFunctionEntryPoint (Fn, " __rtsan_realtime_enter" );
76
- insertCallAtAllFunctionExitPoints (Fn, " __rtsan_realtime_exit" );
77
- return rtsanPreservedCFGAnalyses ();
78
- }
86
+ if (Fn.hasFnAttribute (Attribute::SanitizeRealtime))
87
+ return runSanitizeRealtime (Fn);
79
88
80
- if (Fn.hasFnAttribute (Attribute::SanitizeRealtimeUnsafe)) {
81
- insertNotifyBlockingCallAtFunctionEntryPoint (Fn);
82
- return rtsanPreservedCFGAnalyses ();
83
- }
89
+ if (Fn.hasFnAttribute (Attribute::SanitizeRealtimeUnsafe))
90
+ return runSanitizeRealtimeUnsafe (Fn);
84
91
85
92
return PreservedAnalyses::all ();
86
93
}
0 commit comments