@@ -30,13 +30,30 @@ CFFunctionInstrumentationPass::run(Module &M, ModuleAnalysisManager &AM) {
3030 continue ;
3131 }
3232
33+ // print the function name and the module name to traced_functions.txt
34+ std::ofstream out;
35+ out.open (" traced_functions.txt" , std::ios::app);
36+
37+ if (!out) {
38+ errs () << " Error: cannot open file traced_functions.txt \n " ;
39+ return PreservedAnalyses::none ();
40+ }
41+ out << F.getName ().str () << " instrumented in " << M.getName ().str ()
42+ << " \n " ;
43+ out.close ();
44+
3345 std::string outputString = F.getName ().str () + " %lld\n " ;
3446 StringRef funcFormatStr = StringRef (outputString);
3547 std::string fileName = " function_trace.txt" ;
3648 StringRef funcFileName = StringRef (fileName);
3749 // for all return instructions, print the return value to a file with the
3850 // name of the function
3951
52+ auto GV = new GlobalVariable (
53+ M, Type::getInt32Ty (M.getContext ()), true ,
54+ GlobalValue::LinkageTypes::PrivateLinkage,
55+ ConstantInt::get (IntegerType::getInt32Ty (M.getContext ()), 0 ),
56+ " init" + F.getName ());
4057 // store already handled blocks
4158 std::set<BasicBlock *> HandledBlocks;
4259 for (auto &BB : F) {
@@ -46,7 +63,7 @@ CFFunctionInstrumentationPass::run(Module &M, ModuleAnalysisManager &AM) {
4663 // Do NOT reinstrument the inserted blocks
4764 if (BB.getName () == " return" || BB.getName () == " print" ||
4865 BB.getName () == " open" ) {
49- HandledBlocks.insert (&BB);
66+ HandledBlocks.insert (&BB);
5067 continue ;
5168 }
5269 if (auto *RI = dyn_cast<ReturnInst>(BB.getTerminator ())) {
@@ -76,10 +93,44 @@ CFFunctionInstrumentationPass::run(Module &M, ModuleAnalysisManager &AM) {
7693 // split at return
7794 BasicBlock *ReturnBB = BB.splitBasicBlock (RI, " return" , false );
7895
96+ BasicBlock *CheckBB =
97+ BasicBlock::Create (M.getContext (), " access_check" , &F);
98+ BasicBlock *Check2BB =
99+ BasicBlock::Create (M.getContext (), " no_init_check" , &F);
79100 BasicBlock *AccessBB =
80101 BasicBlock::Create (M.getContext (), " access" , &F);
102+ BasicBlock *UpdateGVBB =
103+ BasicBlock::Create (M.getContext (), " update" , &F);
104+ BasicBlock *NoAccessBB =
105+ BasicBlock::Create (M.getContext (), " no_access" , &F);
106+
81107 BasicBlock *PrintBB = BasicBlock::Create (M.getContext (), " print" , &F);
82108
109+ LLVM_DEBUG (dbgs () << " Created BBs\n " );
110+
111+ IRBuilder<> CheckBuilder (CheckBB);
112+
113+ Value *GV_value = CheckBuilder.CreateLoad (
114+ IntegerType::getInt32Ty (M.getContext ()), GV);
115+
116+ // check if GV is 0 (not yet accessed) or -1 (no access) or 1 (access)
117+ Value *CmpGV = CheckBuilder.CreateICmpEQ (
118+ GV_value,
119+ ConstantInt::get (IntegerType::getInt32Ty (M.getContext ()), 1 ));
120+
121+ CheckBuilder.CreateCondBr (CmpGV, PrintBB, Check2BB);
122+
123+ LLVM_DEBUG (dbgs () << " Created check BB\n " );
124+
125+ IRBuilder<> Check2Builder (Check2BB);
126+ Value *CmpGV2 = Check2Builder.CreateICmpEQ (
127+ GV_value,
128+ ConstantInt::get (IntegerType::getInt32Ty (M.getContext ()), -1 ));
129+
130+ Check2Builder.CreateCondBr (CmpGV2, ReturnBB, AccessBB);
131+
132+ LLVM_DEBUG (dbgs () << " Created check2 BB\n " );
133+
83134 IRBuilder<> AccessBuilder (AccessBB);
84135 // insert call to access function with filename and 0
85136 Value *status = AccessBuilder.CreateCall (
@@ -88,7 +139,25 @@ CFFunctionInstrumentationPass::run(Module &M, ModuleAnalysisManager &AM) {
88139 Value *Cmp = AccessBuilder.CreateICmpEQ (
89140 status,
90141 ConstantInt::get (IntegerType::getInt32Ty (M.getContext ()), 0 ));
91- AccessBuilder.CreateCondBr (Cmp, PrintBB, ReturnBB);
142+ AccessBuilder.CreateCondBr (Cmp, UpdateGVBB, NoAccessBB);
143+
144+ LLVM_DEBUG (dbgs () << " Created access BB\n " );
145+
146+ IRBuilder<> NoAccessBuilder (NoAccessBB);
147+ NoAccessBuilder.CreateStore (
148+ ConstantInt::get (IntegerType::getInt32Ty (M.getContext ()), -1 ),
149+ GV);
150+ NoAccessBuilder.CreateBr (ReturnBB);
151+
152+ LLVM_DEBUG (dbgs () << " Created no access BB\n " );
153+
154+ IRBuilder<> UpdateGVBuilder (UpdateGVBB);
155+ UpdateGVBuilder.CreateStore (
156+ ConstantInt::get (IntegerType::getInt32Ty (M.getContext ()), 1 ), GV);
157+
158+ UpdateGVBuilder.CreateBr (PrintBB);
159+
160+ LLVM_DEBUG (dbgs () << " Created update BB\n " );
92161
93162 IRBuilder<> PrintBuilder (PrintBB);
94163 FunctionCallee PrintFunc = M.getOrInsertFunction (
@@ -119,14 +188,18 @@ CFFunctionInstrumentationPass::run(Module &M, ModuleAnalysisManager &AM) {
119188 PrintBuilder.CreateCall (CloseFunc, write_fptr);
120189 PrintBuilder.CreateBr (ReturnBB);
121190
122- BB.getTerminator ()->setSuccessor (0 , AccessBB );
191+ BB.getTerminator ()->setSuccessor (0 , CheckBB );
123192
124193 // place new BBs in the correct order
125194 ReturnBB->moveAfter (PrintBB);
126195
127196 HandledBlocks.insert (AccessBB);
128197 HandledBlocks.insert (PrintBB);
129198 HandledBlocks.insert (ReturnBB);
199+ HandledBlocks.insert (CheckBB);
200+ HandledBlocks.insert (Check2BB);
201+ HandledBlocks.insert (UpdateGVBB);
202+ HandledBlocks.insert (NoAccessBB);
130203 }
131204 }
132205 HandledBlocks.insert (&BB);
0 commit comments