1+ // ===----------------------------------------------------------------------===//
2+ //
3+ // LLVM Fault Injection Tool
4+ //
5+ // ===----------------------------------------------------------------------===//
6+ //
7+ // Copyright (C) 2019. rollrat. All Rights Reserved.
8+ //
9+ // ===----------------------------------------------------------------------===//
10+
11+ #include " llvm/ADT/SmallVector.h"
12+ #include " llvm/Analysis/LoopInfo.h"
13+ #include " llvm/Demangle/Demangle.h"
14+ #include " llvm/IR/CFG.h"
15+ #include " llvm/IR/Constants.h"
16+ #include " llvm/IR/DebugInfoMetadata.h"
17+ #include " llvm/IR/Function.h"
18+ #include " llvm/IR/InstIterator.h"
19+ #include " llvm/IR/Instructions.h"
20+ #include " llvm/Pass.h"
21+ #include " llvm/Support/Casting.h"
22+ #include " llvm/Support/raw_ostream.h"
23+ #include " llvm/Transforms/Utils/InjectFault.h"
24+ #include < map>
25+ #include < random>
26+ #include < set>
27+ #include < sstream>
28+ #include < string>
29+
30+ #define MARK_FUNCTION_NAME " faultinjectmarked"
31+ #define IGNORE_ZERO_SIZE 1
32+ #define USE_RAW_INJECT 1
33+
34+ using namespace llvm ;
35+
36+ std::map<int , std::string> mgrs;
37+ std::string llvm::getInformation (int index)
38+ {
39+ return mgrs[index];
40+ }
41+
42+ namespace {
43+
44+ static LLVMContext cnt;
45+ static MDNode *md;
46+
47+ class DependencyDebugLocHelper {
48+ public:
49+ static void Initialize () {
50+ md = MDNode::get (
51+ cnt, DILocation::get (cnt, 100 , 100 , DIScope::get (cnt, nullptr )));
52+ }
53+
54+ static DebugLoc getDebugLoc (int magic) {
55+ return DebugLoc::get (magic, (uint16_t )-1 , md);
56+ }
57+
58+ static void setDebugLoc (Instruction *I) {
59+ // if (I->getDebugLoc()) {
60+ int magic = mgrs.size () + 30000 ;
61+ I->setDebugLoc (getDebugLoc (magic));
62+ mgrs.insert ({ magic, " ### FAULT INJECTED" });
63+ // }
64+ }
65+ };
66+
67+ struct LLVMInjectFaultPass : public FunctionPass {
68+ static char ID;
69+
70+ LLVMInjectFaultPass () : FunctionPass(ID) {
71+ DependencyDebugLocHelper::Initialize ();
72+ }
73+
74+ ~LLVMInjectFaultPass () {}
75+
76+ bool runOnFunction (Function &F) override {
77+
78+ // DependencyDebugLocHelper::setDebugLoc(resetter);
79+ std::vector<CallInst *> cis;
80+ for (auto &bb : F)
81+ for (auto &inst : bb)
82+ {
83+ if (CallInst *CI = dyn_cast<CallInst>(&inst))
84+ {
85+ CallInst *call = (CallInst *)(void *)&inst;
86+ if (call->getCalledFunction () &&
87+ call->getCalledFunction ()->getName ().contains (MARK_FUNCTION_NAME))
88+ {
89+ DependencyDebugLocHelper::setDebugLoc (cast<Instruction>(call->getOperand (0 )));
90+ cis.push_back (call);
91+ }
92+ }
93+ }
94+
95+ for (auto &CI : cis)
96+ CI->eraseFromParent ();
97+
98+ return true ;
99+ }
100+ };
101+
102+ }
103+
104+ char LLVMInjectFaultPass::ID = 0 ;
105+
106+ static RegisterPass<LLVMInjectFaultPass> X (" injectfault" ,
107+ " Inject Fault Pass" ,
108+ false /* Only looks at CFG */ ,
109+ false /* Analysis Pass */ );
110+
111+ FunctionPass *myPassx = nullptr ;
112+
113+ FunctionPass *llvm::createInjectFaultProcPass () {
114+ if (myPassx == nullptr )
115+ myPassx = new LLVMInjectFaultPass ();
116+ return myPassx;
117+ }
0 commit comments