2020#include " llvm/Demangle/Demangle.h"
2121#include " llvm/Transforms/Instrumentation/RealtimeSanitizer.h"
2222
23+ #include < vector>
24+
2325using namespace llvm ;
2426
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+
2534static void insertCallBeforeInstruction (Function &Fn, Instruction &Instruction,
26- const char *FunctionName) {
35+ const char *FunctionName,
36+ ArrayRef<Value *> FunctionArgs) {
2737 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 );
2940 FunctionCallee Func =
3041 Fn.getParent ()->getOrInsertFunction (FunctionName, FuncType);
3142 IRBuilder<> Builder{&Instruction};
32- Builder.CreateCall (Func, {} );
43+ Builder.CreateCall (Func, FunctionArgs );
3344}
3445
3546static 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);
3951}
4052
4153static void insertCallAtAllFunctionExitPoints (Function &Fn,
42- const char *InsertFnName) {
54+ const char *InsertFnName,
55+ ArrayRef<Value *> FunctionArgs) {
4356 for (auto &BB : Fn)
4457 for (auto &I : BB)
4558 if (isa<ReturnInst>(&I))
46- insertCallBeforeInstruction (Fn, I, InsertFnName);
59+ insertCallBeforeInstruction (Fn, I, InsertFnName, FunctionArgs );
4760}
4861
4962static PreservedAnalyses rtsanPreservedCFGAnalyses () {
@@ -52,35 +65,29 @@ static PreservedAnalyses rtsanPreservedCFGAnalyses() {
5265 return PA;
5366}
5467
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+ }
6573
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 ();
6779}
6880
6981RealtimeSanitizerPass::RealtimeSanitizerPass (
7082 const RealtimeSanitizerOptions &Options) {}
7183
7284PreservedAnalyses RealtimeSanitizerPass::run (Function &Fn,
7385 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);
7988
80- if (Fn.hasFnAttribute (Attribute::SanitizeRealtimeUnsafe)) {
81- insertNotifyBlockingCallAtFunctionEntryPoint (Fn);
82- return rtsanPreservedCFGAnalyses ();
83- }
89+ if (Fn.hasFnAttribute (Attribute::SanitizeRealtimeUnsafe))
90+ return runSanitizeRealtimeUnsafe (Fn);
8491
8592 return PreservedAnalyses::all ();
8693}
0 commit comments