retdec
llvmir_emul.h
Go to the documentation of this file.
1 
7 #ifndef RETDEC_LLVMIR_EMUL_LLVMIR_EMUL_H
8 #define RETDEC_LLVMIR_EMUL_LLVMIR_EMUL_H
9 
10 #include <list>
11 #include <map>
12 #include <set>
13 
14 #include <llvm/CodeGen/IntrinsicLowering.h>
15 #include <llvm/ExecutionEngine/GenericValue.h>
16 #include <llvm/IR/CallSite.h>
17 #include <llvm/IR/InstVisitor.h>
18 #include <llvm/IR/Module.h>
19 
21 
22 namespace retdec {
23 namespace llvmir_emul {
24 
31 {
32  public:
34  {
35 
36  }
37 
38  AllocaHolder(AllocaHolder &RHS) = default;
40  Allocations(std::move(RHS.Allocations))
41  {
42 
43  }
44 
47  {
48  Allocations = std::move(RHS.Allocations);
49  return *this;
50  }
51 
53  {
54  for (void *Allocation : Allocations)
55  free(Allocation);
56  }
57 
58  void add(void *Mem)
59  {
60  Allocations.push_back(Mem);
61  }
62 
63  private:
64  std::vector<void *> Allocations;
65 };
66 
68 
80 {
81  public:
82  GlobalExecutionContext(llvm::Module* m);
83  llvm::Module* getModule() const;
84 
85  llvm::GenericValue getMemory(uint64_t addr, bool log = true);
86  void setMemory(uint64_t addr, llvm::GenericValue val, bool log = true);
87 
88  llvm::GenericValue getGlobal(llvm::GlobalVariable* g, bool log = true);
89  void setGlobal(
90  llvm::GlobalVariable* g,
91  llvm::GenericValue val,
92  bool log = true);
93 
94  void setValue(llvm::Value* v, llvm::GenericValue val);
95  llvm::GenericValue getOperandValue(
96  llvm::Value* val,
98 
99  public:
100  llvm::Module* _module = nullptr;
101 
102  std::map<uint64_t, llvm::GenericValue> memory;
103  std::list<uint64_t> memoryLoads;
104  std::list<uint64_t> memoryStores;
105 
106  std::map<llvm::GlobalVariable*, llvm::GenericValue> globals;
107  std::list<llvm::GlobalVariable*> globalsLoads;
108  std::list<llvm::GlobalVariable*> globalsStores;
109 
116  std::map<llvm::Value*, llvm::GenericValue> values;
117 };
118 
120 {
121  public:
127 
128  llvm::Module* getModule() const;
129 
130  public:
132  llvm::Function* curFunction = nullptr;
134  llvm::BasicBlock* curBB = nullptr;
136  llvm::BasicBlock::iterator curInst;
139  llvm::CallSite caller;
142 };
143 
144 class LlvmIrEmulator : public llvm::InstVisitor<LlvmIrEmulator>
145 {
146  public:
147  struct CallEntry
148  {
149  llvm::Value* calledValue;
150  std::vector<llvm::GenericValue> calledArguments;
151  };
152 
153  public:
154  LlvmIrEmulator(llvm::Module* m);
155  ~LlvmIrEmulator();
156 
157  llvm::GenericValue runFunction(
158  llvm::Function* f,
159  const llvm::ArrayRef<llvm::GenericValue> argVals = {});
160 
161  // Emulation query methods.
162  //
163  public:
164  const std::list<llvm::Instruction*>& getVisitedInstructions() const;
165  const std::list<llvm::BasicBlock*>& getVisitedBasicBlocks() const;
166  bool wasInstructionVisited(llvm::Instruction* i) const;
167  bool wasBasicBlockVisited(llvm::BasicBlock* bb) const;
168 
169  llvm::GenericValue getExitValue() const;
170 
171  const std::list<CallEntry>& getCallEntries() const;
172  std::list<llvm::Value*> getCalledValues() const;
173  std::set<llvm::Value*> getCalledValuesSet() const;
174  bool wasValueCalled(llvm::Value* v) const;
175  const CallEntry* getCallEntry(llvm::Value* v, unsigned n = 0) const;
176 
177  bool wasGlobalVariableLoaded(llvm::GlobalVariable* gv);
178  bool wasGlobalVariableStored(llvm::GlobalVariable* gv);
179  std::list<llvm::GlobalVariable*> getLoadedGlobalVariables();
180  std::set<llvm::GlobalVariable*> getLoadedGlobalVariablesSet();
181  std::list<llvm::GlobalVariable*> getStoredGlobalVariables();
182  std::set<llvm::GlobalVariable*> getStoredGlobalVariablesSet();
183  llvm::GenericValue getGlobalVariableValue(llvm::GlobalVariable* gv);
185  llvm::GlobalVariable* gv,
186  llvm::GenericValue val);
187 
188  bool wasMemoryLoaded(uint64_t addr);
189  bool wasMemoryStored(uint64_t addr);
190  std::list<uint64_t> getLoadedMemory();
191  std::set<uint64_t> getLoadedMemorySet();
192  std::list<uint64_t> getStoredMemory();
193  std::set<uint64_t> getStoredMemorySet();
194  llvm::GenericValue getMemoryValue(uint64_t addr);
195  void setMemoryValue(uint64_t addr, llvm::GenericValue val);
196 
197  llvm::GenericValue getValueValue(llvm::Value* val);
198 
199  // This needs to be public for LLVM instruction visitor.
200  // However, users of this class SHOULD NOT call any of these.
201  //
202  public:
203  void visitReturnInst(llvm::ReturnInst& I);
204  void visitBranchInst(llvm::BranchInst& I);
205  void visitSwitchInst(llvm::SwitchInst& I);
206  void visitIndirectBrInst(llvm::IndirectBrInst& I);
207  void visitBinaryOperator(llvm::BinaryOperator& I);
208  void visitICmpInst(llvm::ICmpInst& I);
209  void visitFCmpInst(llvm::FCmpInst& I);
210  void visitAllocaInst(llvm::AllocaInst& I);
211  void visitLoadInst(llvm::LoadInst& I);
212  void visitStoreInst(llvm::StoreInst& I);
213  void visitGetElementPtrInst(llvm::GetElementPtrInst& I);
214  void visitPHINode(llvm::PHINode& PN);
215  void visitTruncInst(llvm::TruncInst& I);
216  void visitZExtInst(llvm::ZExtInst& I);
217  void visitSExtInst(llvm::SExtInst& I);
218  void visitFPTruncInst(llvm::FPTruncInst& I);
219  void visitFPExtInst(llvm::FPExtInst& I);
220  void visitUIToFPInst(llvm::UIToFPInst& I);
221  void visitSIToFPInst(llvm::SIToFPInst& I);
222  void visitFPToUIInst(llvm::FPToUIInst& I);
223  void visitFPToSIInst(llvm::FPToSIInst& I);
224  void visitPtrToIntInst(llvm::PtrToIntInst& I);
225  void visitIntToPtrInst(llvm::IntToPtrInst& I);
226  void visitBitCastInst(llvm::BitCastInst& I);
227  void visitSelectInst(llvm::SelectInst& I);
228  void visitCallInst(llvm::CallInst& I);
229  void visitInvokeInst(llvm::InvokeInst& I);
230  void visitUnreachableInst(llvm::UnreachableInst& I);
231  void visitShl(llvm::BinaryOperator& I);
232  void visitLShr(llvm::BinaryOperator& I);
233  void visitAShr(llvm::BinaryOperator& I);
234  void visitVAArgInst(llvm::VAArgInst& I);
235  void visitExtractElementInst(llvm::ExtractElementInst& I);
236  void visitInsertElementInst(llvm::InsertElementInst& I);
237  void visitShuffleVectorInst(llvm::ShuffleVectorInst& I);
238  void visitExtractValueInst(llvm::ExtractValueInst& I);
239  void visitInsertValueInst(llvm::InsertValueInst& I);
240  void visitInstruction(llvm::Instruction& I);
241 
242  private:
243  void run();
244  void callFunction(
245  llvm::Function* f,
246  llvm::ArrayRef<llvm::GenericValue> argVals);
247 
248  void logInstruction(llvm::Instruction* i);
249 
251  llvm::Type* retT,
252  llvm::GenericValue res);
253 
254  public:
255  std::vector<LocalExecutionContext> _ecStackRetired;
256 
257  private:
258  llvm::IntrinsicLowering *IL = nullptr;
259  llvm::Module* _module = nullptr;
260  llvm::GenericValue _exitValue;
261  std::vector<LocalExecutionContext> _ecStack;
263 
267  std::list<llvm::Instruction*> _visitedInsns;
271  std::list<llvm::BasicBlock*> _visitedBbs;
272 
274  std::list<CallEntry> _calls;
275 };
276 
277 } // llvmir_emul
278 } // retdec
279 
280 #endif
Definition: llvmir_emul.h:31
void add(void *Mem)
Definition: llvmir_emul.h:58
AllocaHolder(AllocaHolder &&RHS)
Definition: llvmir_emul.h:39
AllocaHolder & operator=(AllocaHolder &RHS)=default
std::vector< void * > Allocations
Definition: llvmir_emul.h:64
AllocaHolder()
Definition: llvmir_emul.h:33
~AllocaHolder()
Definition: llvmir_emul.h:52
AllocaHolder & operator=(AllocaHolder &&RHS)
Definition: llvmir_emul.h:46
AllocaHolder(AllocaHolder &RHS)=default
void setMemory(uint64_t addr, llvm::GenericValue val, bool log=true)
Definition: llvmir_emul.cpp:2214
std::map< uint64_t, llvm::GenericValue > memory
Definition: llvmir_emul.h:102
std::list< llvm::GlobalVariable * > globalsLoads
Definition: llvmir_emul.h:107
void setValue(llvm::Value *v, llvm::GenericValue val)
Definition: llvmir_emul.cpp:2254
std::list< uint64_t > memoryLoads
Definition: llvmir_emul.h:103
void setGlobal(llvm::GlobalVariable *g, llvm::GenericValue val, bool log=true)
Definition: llvmir_emul.cpp:2241
llvm::GenericValue getGlobal(llvm::GlobalVariable *g, bool log=true)
Definition: llvmir_emul.cpp:2227
std::map< llvm::Value *, llvm::GenericValue > values
Definition: llvmir_emul.h:116
llvm::GenericValue getMemory(uint64_t addr, bool log=true)
Definition: llvmir_emul.cpp:2203
llvm::GenericValue getOperandValue(llvm::Value *val, LocalExecutionContext &ec)
Definition: llvmir_emul.cpp:2259
std::map< llvm::GlobalVariable *, llvm::GenericValue > globals
Definition: llvmir_emul.h:106
std::list< uint64_t > memoryStores
Definition: llvmir_emul.h:104
llvm::Module * _module
Definition: llvmir_emul.h:100
GlobalExecutionContext(llvm::Module *m)
Definition: llvmir_emul.cpp:2192
llvm::Module * getModule() const
Definition: llvmir_emul.cpp:2198
std::list< llvm::GlobalVariable * > globalsStores
Definition: llvmir_emul.h:108
Definition: llvmir_emul.h:145
void popStackAndReturnValueToCaller(llvm::Type *retT, llvm::GenericValue res)
Definition: llvmir_emul.cpp:2636
const CallEntry * getCallEntry(llvm::Value *v, unsigned n=0) const
Definition: llvmir_emul.cpp:2498
void visitAShr(llvm::BinaryOperator &I)
Definition: llvmir_emul.cpp:3215
void visitSelectInst(llvm::SelectInst &I)
Definition: llvmir_emul.cpp:2968
std::set< llvm::GlobalVariable * > getLoadedGlobalVariablesSet()
Definition: llvmir_emul.cpp:2538
const std::list< CallEntry > & getCallEntries() const
Definition: llvmir_emul.cpp:2453
llvm::IntrinsicLowering * IL
Definition: llvmir_emul.h:258
std::set< llvm::GlobalVariable * > getStoredGlobalVariablesSet()
Definition: llvmir_emul.cpp:2549
void visitFCmpInst(llvm::FCmpInst &I)
Definition: llvmir_emul.cpp:2927
void run()
Definition: llvmir_emul.cpp:2389
llvm::GenericValue getGlobalVariableValue(llvm::GlobalVariable *gv)
Definition: llvmir_emul.cpp:2555
const std::list< llvm::Instruction * > & getVisitedInstructions() const
Definition: llvmir_emul.cpp:2414
void visitReturnInst(llvm::ReturnInst &I)
Definition: llvmir_emul.cpp:2680
void visitFPExtInst(llvm::FPExtInst &I)
Definition: llvmir_emul.cpp:3277
void visitInsertElementInst(llvm::InsertElementInst &I)
Definition: llvmir_emul.cpp:3347
void visitIntToPtrInst(llvm::IntToPtrInst &I)
Definition: llvmir_emul.cpp:3313
llvm::GenericValue _exitValue
Definition: llvmir_emul.h:260
void visitSExtInst(llvm::SExtInst &I)
Definition: llvmir_emul.cpp:3259
std::set< uint64_t > getStoredMemorySet()
Definition: llvmir_emul.cpp:2596
LlvmIrEmulator(llvm::Module *m)
Definition: llvmir_emul.cpp:2325
bool wasValueCalled(llvm::Value *v) const
Definition: llvmir_emul.cpp:2481
bool wasGlobalVariableLoaded(llvm::GlobalVariable *gv)
Definition: llvmir_emul.cpp:2521
llvm::GenericValue runFunction(llvm::Function *f, const llvm::ArrayRef< llvm::GenericValue > argVals={})
Definition: llvmir_emul.cpp:2343
void visitIndirectBrInst(llvm::IndirectBrInst &I)
Definition: llvmir_emul.cpp:2743
void visitUIToFPInst(llvm::UIToFPInst &I)
Definition: llvmir_emul.cpp:3283
void logInstruction(llvm::Instruction *i)
Definition: llvmir_emul.cpp:2405
void setGlobalVariableValue(llvm::GlobalVariable *gv, llvm::GenericValue val)
Definition: llvmir_emul.cpp:2561
void visitStoreInst(llvm::StoreInst &I)
Definition: llvmir_emul.cpp:3050
llvm::GenericValue getMemoryValue(uint64_t addr)
Definition: llvmir_emul.cpp:2602
void callFunction(llvm::Function *f, llvm::ArrayRef< llvm::GenericValue > argVals)
Definition: llvmir_emul.cpp:2365
void visitFPToSIInst(llvm::FPToSIInst &I)
Definition: llvmir_emul.cpp:3301
void setMemoryValue(uint64_t addr, llvm::GenericValue val)
Definition: llvmir_emul.cpp:2607
void visitFPToUIInst(llvm::FPToUIInst &I)
Definition: llvmir_emul.cpp:3295
bool wasMemoryStored(uint64_t addr)
Definition: llvmir_emul.cpp:2574
void visitExtractValueInst(llvm::ExtractValueInst &I)
Definition: llvmir_emul.cpp:3363
llvm::Module * _module
Definition: llvmir_emul.h:259
std::list< llvm::Instruction * > _visitedInsns
Definition: llvmir_emul.h:267
std::list< uint64_t > getStoredMemory()
Definition: llvmir_emul.cpp:2591
void visitICmpInst(llvm::ICmpInst &I)
Definition: llvmir_emul.cpp:2899
bool wasMemoryLoaded(uint64_t addr)
Definition: llvmir_emul.cpp:2568
std::vector< LocalExecutionContext > _ecStack
Definition: llvmir_emul.h:261
void visitVAArgInst(llvm::VAArgInst &I)
Definition: llvmir_emul.cpp:3331
void visitInstruction(llvm::Instruction &I)
Definition: llvmir_emul.cpp:3393
void visitTruncInst(llvm::TruncInst &I)
Definition: llvmir_emul.cpp:3253
llvm::GenericValue getExitValue() const
Definition: llvmir_emul.cpp:2448
void visitPHINode(llvm::PHINode &PN)
Definition: llvmir_emul.cpp:3375
void visitLoadInst(llvm::LoadInst &I)
Definition: llvmir_emul.cpp:3030
void visitShl(llvm::BinaryOperator &I)
Definition: llvmir_emul.cpp:3151
void visitInsertValueInst(llvm::InsertValueInst &I)
Definition: llvmir_emul.cpp:3369
void visitSIToFPInst(llvm::SIToFPInst &I)
Definition: llvmir_emul.cpp:3289
std::vector< LocalExecutionContext > _ecStackRetired
Definition: llvmir_emul.h:255
std::list< llvm::Value * > getCalledValues() const
Definition: llvmir_emul.cpp:2458
bool wasInstructionVisited(llvm::Instruction *i) const
Definition: llvmir_emul.cpp:2424
void visitZExtInst(llvm::ZExtInst &I)
Definition: llvmir_emul.cpp:3265
void visitBitCastInst(llvm::BitCastInst &I)
Definition: llvmir_emul.cpp:3319
void visitGetElementPtrInst(llvm::GetElementPtrInst &I)
Definition: llvmir_emul.cpp:3017
std::set< llvm::Value * > getCalledValuesSet() const
Definition: llvmir_emul.cpp:2468
void visitUnreachableInst(llvm::UnreachableInst &I)
Definition: llvmir_emul.cpp:2696
void visitCallInst(llvm::CallInst &I)
Definition: llvmir_emul.cpp:3074
void visitShuffleVectorInst(llvm::ShuffleVectorInst &I)
Definition: llvmir_emul.cpp:3353
std::list< uint64_t > getLoadedMemory()
Definition: llvmir_emul.cpp:2580
const std::list< llvm::BasicBlock * > & getVisitedBasicBlocks() const
Definition: llvmir_emul.cpp:2419
bool wasBasicBlockVisited(llvm::BasicBlock *bb) const
Definition: llvmir_emul.cpp:2436
std::list< llvm::GlobalVariable * > getStoredGlobalVariables()
Definition: llvmir_emul.cpp:2544
GlobalExecutionContext _globalEc
Definition: llvmir_emul.h:262
void visitLShr(llvm::BinaryOperator &I)
Definition: llvmir_emul.cpp:3183
void visitExtractElementInst(llvm::ExtractElementInst &I)
Definition: llvmir_emul.cpp:3341
~LlvmIrEmulator()
Definition: llvmir_emul.cpp:2338
void visitBinaryOperator(llvm::BinaryOperator &I)
Definition: llvmir_emul.cpp:2756
void visitFPTruncInst(llvm::FPTruncInst &I)
Definition: llvmir_emul.cpp:3271
std::list< llvm::GlobalVariable * > getLoadedGlobalVariables()
Definition: llvmir_emul.cpp:2533
llvm::GenericValue getValueValue(llvm::Value *val)
Definition: llvmir_emul.cpp:2618
void visitSwitchInst(llvm::SwitchInst &I)
Definition: llvmir_emul.cpp:2718
void visitPtrToIntInst(llvm::PtrToIntInst &I)
Definition: llvmir_emul.cpp:3307
void visitAllocaInst(llvm::AllocaInst &I)
Definition: llvmir_emul.cpp:2992
bool wasGlobalVariableStored(llvm::GlobalVariable *gv)
Definition: llvmir_emul.cpp:2527
void visitBranchInst(llvm::BranchInst &I)
Definition: llvmir_emul.cpp:2701
std::set< uint64_t > getLoadedMemorySet()
Definition: llvmir_emul.cpp:2585
std::list< CallEntry > _calls
Intrinsic calls are lowered and not logged here.
Definition: llvmir_emul.h:274
void visitInvokeInst(llvm::InvokeInst &I)
Definition: llvmir_emul.cpp:3125
std::list< llvm::BasicBlock * > _visitedBbs
Definition: llvmir_emul.h:271
Definition: llvmir_emul.h:120
LocalExecutionContext(LocalExecutionContext &o)=default
LocalExecutionContext & operator=(LocalExecutionContext &o)=default
llvm::Module * getModule() const
Definition: llvmir_emul.cpp:2314
llvm::Function * curFunction
The currently executing function.
Definition: llvmir_emul.h:132
llvm::CallSite caller
Definition: llvmir_emul.h:139
llvm::BasicBlock::iterator curInst
The next instruction to execute.
Definition: llvmir_emul.h:136
AllocaHolder allocas
Track memory allocated by alloca.
Definition: llvmir_emul.h:141
LocalExecutionContext()
Definition: llvmir_emul.cpp:2288
LocalExecutionContext & operator=(LocalExecutionContext &&o)
Definition: llvmir_emul.cpp:2304
llvm::BasicBlock * curBB
The currently executing BB.
Definition: llvmir_emul.h:134
Definitions of exceptions used in llvmir-emul library.
Definition: archive_wrapper.h:19
llvm::Value * calledValue
Definition: llvmir_emul.h:149
std::vector< llvm::GenericValue > calledArguments
Definition: llvmir_emul.h:150