retdec
asm_instruction.h
Go to the documentation of this file.
1 
7 #ifndef RETDEC_BIN2LLVMIR_PROVIDERS_ASM_INSTRUCTION_H
8 #define RETDEC_BIN2LLVMIR_PROVIDERS_ASM_INSTRUCTION_H
9 
10 #include <capstone/capstone.h>
15 
16 #include <llvm/IR/Instructions.h>
17 #include <llvm/IR/Module.h>
18 
20 #include "retdec/common/address.h"
21 
22 namespace retdec {
23 namespace bin2llvmir {
24 
25 using Llvm2CapstoneInsnMap = typename std::map<llvm::StoreInst*, cs_insn*>;
26 
34 {
35  // Constructors.
36  //
37  public:
39  AsmInstruction(llvm::Instruction* inst);
40  AsmInstruction(llvm::BasicBlock* bb);
41  AsmInstruction(llvm::Function* f);
42  AsmInstruction(llvm::Module* m, retdec::common::Address addr);
43 
44  // Operators.
45  //
46  public:
47  bool operator<(const AsmInstruction& o) const;
48  bool operator==(const AsmInstruction& o) const;
49  bool operator!=(const AsmInstruction& o) const;
50  explicit operator bool() const;
51 
52  // Iterators.
53  //
54  public:
55  template<
56  typename Category,
57  typename Type,
58  typename Reference = Type&,
59  typename Pointer = Type*,
60  typename Distance = std::ptrdiff_t>
61  class iterator_impl;
62 
64  std::bidirectional_iterator_tag,
65  llvm::Instruction>;
67  std::bidirectional_iterator_tag,
68  const llvm::Instruction>;
69  using reverse_iterator = std::reverse_iterator<iterator>;
70  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
71 
72  iterator begin();
73  iterator end();
76  const_iterator begin() const;
77  const_iterator end() const;
80 
81  // Other methods.
82  //
83  public:
84  bool isValid() const;
85  bool isInvalid() const;
86  cs_insn* getCapstoneInsn() const;
87 
88  std::string getDsm() const;
91  std::size_t getByteSize() const;
92  std::size_t getBitSize() const;
93  bool contains(retdec::common::Address addr) const;
94 
95  AsmInstruction getNext() const;
96  AsmInstruction getPrev() const;
97 
99  bool eraseInstructions();
100  llvm::Instruction* makeTerminal();
101  llvm::BasicBlock* makeStart(const std::string& name = "");
102 
103  llvm::BasicBlock* getBasicBlock() const;
104  llvm::Function* getFunction() const;
105  llvm::Module* getModule() const;
106  llvm::LLVMContext& getContext() const;
107  std::vector<llvm::Instruction*> getInstructions();
108  std::vector<llvm::BasicBlock*> getBasicBlocks();
109 
110  bool empty();
111  llvm::Instruction* front();
112  llvm::Instruction* back();
113  llvm::StoreInst* getLlvmToAsmInstruction() const;
114 
115  llvm::Instruction* insertBack(llvm::Instruction* i);
116  llvm::Instruction* insertBackSafe(llvm::Instruction* i);
117 
118  bool storesValue(llvm::Value* val) const;
119 
120  std::string dump() const;
121  friend std::ostream& operator<<(
122  std::ostream& out,
123  const AsmInstruction &a);
124 
125  // Templates.
126  //
127  public:
128  template<typename T>
130  {
131  for (auto& i : *this)
132  {
133  if (llvm::isa<T>(&i))
134  {
135  return true;
136  }
137  }
138  return false;
139  }
140 
141  template<typename T>
143  {
144  for (auto& i : *this)
145  {
146  if (auto* ret = llvm::dyn_cast<T>(&i))
147  {
148  return ret;
149  }
150  }
151  return nullptr;
152  }
153 
154  public:
156  const llvm::Module* m);
157  static llvm::GlobalVariable* getLlvmToAsmGlobalVariable(
158  const llvm::Module* m);
159  static void setLlvmToAsmGlobalVariable(
160  const llvm::Module* m,
161  llvm::GlobalVariable* gv);
163  llvm::Instruction* inst);
165  llvm::Instruction* inst);
167  llvm::BasicBlock* bb);
169  llvm::BasicBlock* bb);
171  llvm::BasicBlock* bb);
173  llvm::Function* f);
175  llvm::Function* f);
176  static bool isLlvmToAsmInstruction(const llvm::Value* inst);
177  static void clear();
178 
179  private:
180  const llvm::GlobalVariable* getLlvmToAsmGlobalVariablePrivate(
181  llvm::Module* m) const;
182  bool isLlvmToAsmInstructionPrivate(llvm::Value* inst) const;
183 
184  private:
185  using ModuleGlobalPair = std::pair<
186  const llvm::Module*,
187  llvm::GlobalVariable*>;
188  using ModuleInstructionMap = std::pair<
189  const llvm::Module*,
190  std::map<llvm::StoreInst*, cs_insn*>>;
191 
192  private:
193  llvm::StoreInst* _llvmToAsmInstr = nullptr;
194  static std::vector<ModuleGlobalPair> _module2global;
195  static std::vector<ModuleInstructionMap> _module2instMap;
196 
197  public:
198  template<
199  typename Category,
200  typename Type,
201  typename Reference,
202  typename Pointer,
203  typename Distance>
205  {
206  public:
207  using difference_type = Distance;
208  using value_type = Type;
209  using reference = Reference;
210  using pointer = Pointer;
211  using iterator_category = Category;
212 
213  public:
214  iterator_impl(llvm::StoreInst* s, bool end = false)
215  {
216  _first = s;
217  _last = s;
218  if (s == nullptr)
219  {
220  return;
221  }
222  llvm::Instruction* i = s;
223 
224  auto* bb = i->getParent();
225  while (i && (i == _first
226  || !isLlvmToAsmInstruction(i)))
227  {
228  if (i != _first)
229  {
230  _last = i;
231  if (_current == nullptr)
232  {
233  _current = i;
234  }
235  }
236 
237  if (&bb->back() == i)
238  {
239  if (&bb->getParent()->back() == bb)
240  {
241  break;
242  }
243  else
244  {
245  bb = bb->getNextNode();
246  i = &bb->front();
247  }
248  }
249  else
250  {
251  i = i->getNextNode();
252  }
253  }
254 
255  if (end)
256  {
257  _current = nullptr;
258  }
259  }
260  iterator_impl() = default;
261  iterator_impl(const iterator_impl& itr) = default;
263  {
264  _first = rhs._first;
265  _last = rhs._last;
266  _current = rhs._current;
267  return *this;
268  }
269 
271  {
272  if (_current == nullptr)
273  {
274  return *this;
275  }
276 
277  auto* bb = _current->getParent()->getNextNode();
278  _current = _current->getNextNode();
279  if (_current == nullptr)
280  {
281  if (bb)
282  {
283  _current = &bb->front();
284  }
285  }
287  {
288  _current = nullptr;
289  }
290  return *this;
291  }
292 
294  {
295  if (_current == nullptr)
296  {
297  return *this;
298  }
299 
300  iterator_impl tmp(*this);
301  auto* bb = _current->getParent()->getNextNode();
302  _current = _current->getNextNode();
303  if (_current == nullptr)
304  {
305  if (bb)
306  {
307  _current = &bb->front();
308  }
309  }
311  {
312  _current = nullptr;
313  }
314  return tmp;
315  }
316 
318  {
319  if (_current == _first)
320  {
321  return *this;
322  }
323  if (_current == nullptr)
324  {
325  _current = _last;
326  return *this;
327  }
328 
329  auto* bb = _current->getParent()->getPrevNode();
330  _current = _current->getPrevNode();
331  if (_current == nullptr)
332  {
333  if (bb)
334  {
335  _current = &bb->back();
336  }
337  }
338  return *this;
339  }
340 
342  {
343  if (_current == _first)
344  {
345  return *this;
346  }
347 
348  iterator_impl tmp(*this);
349 
350  if (_current == nullptr)
351  {
352  _current = _last;
353  return tmp;
354  }
355 
356  auto* bb = _current->getParent()->getPrevNode();
357  _current = _current->getPrevNode();
358  if (_current == nullptr)
359  {
360  if (bb)
361  {
362  _current = &bb->back();
363  }
364  }
365  return tmp;
366  }
367 
369  {
370  assert(_first != _current);
371  return *_current;
372  }
373 
375  {
376  assert(_first != _current);
377  return &(*_current);
378  }
379 
380  bool operator==(const iterator_impl& rhs) const
381  {
382  return (_current == nullptr && rhs._current == nullptr)
383  || (_first == rhs._first
384  && _last == rhs._last
385  && _current == rhs._current);
386  }
387 
388  bool operator!=(const iterator_impl& rhs) const
389  {
390  return !(*this == rhs);
391  }
392 
393  private:
394  bool isLlvmToAsmInstruction(const llvm::Instruction* i) const
395  {
396  auto* s = llvm::dyn_cast_or_null<llvm::StoreInst>(i);
397  return s &&
398  s->getPointerOperand() == _first->getPointerOperand();
399  }
400 
401  private:
402  llvm::StoreInst* _first = nullptr;
403  llvm::Instruction* _last = nullptr;
404  llvm::Instruction* _current = nullptr;
405  };
406 };
407 
408 } // namespace bin2llvmir
409 } // namespace retdec
410 
411 #endif
Additional (on top of Capstone) definitions for ARM translator.
Definition: asm_instruction.h:205
iterator_impl operator++(int)
Definition: asm_instruction.h:293
reference operator*()
Definition: asm_instruction.h:368
Reference reference
Definition: asm_instruction.h:209
iterator_impl operator--(int)
Definition: asm_instruction.h:341
iterator_impl & operator--()
Definition: asm_instruction.h:317
iterator_impl(llvm::StoreInst *s, bool end=false)
Definition: asm_instruction.h:214
iterator_impl & operator++()
Definition: asm_instruction.h:270
pointer operator->()
Definition: asm_instruction.h:374
bool isLlvmToAsmInstruction(const llvm::Instruction *i) const
Definition: asm_instruction.h:394
llvm::StoreInst * _first
Definition: asm_instruction.h:402
Pointer pointer
Definition: asm_instruction.h:210
llvm::Instruction * _last
Definition: asm_instruction.h:403
Category iterator_category
Definition: asm_instruction.h:211
iterator_impl(const iterator_impl &itr)=default
iterator_impl & operator=(iterator_impl rhs)
Definition: asm_instruction.h:262
bool operator!=(const iterator_impl &rhs) const
Definition: asm_instruction.h:388
Distance difference_type
Definition: asm_instruction.h:207
bool operator==(const iterator_impl &rhs) const
Definition: asm_instruction.h:380
llvm::Instruction * _current
Definition: asm_instruction.h:404
Type value_type
Definition: asm_instruction.h:208
Definition: asm_instruction.h:34
std::vector< llvm::Instruction * > getInstructions()
Definition: asm_instruction.cpp:683
std::pair< const llvm::Module *, std::map< llvm::StoreInst *, cs_insn * > > ModuleInstructionMap
Definition: asm_instruction.h:190
bool isInvalid() const
Definition: asm_instruction.cpp:340
llvm::Instruction * front()
Definition: asm_instruction.cpp:712
bool operator==(const AsmInstruction &o) const
Definition: asm_instruction.cpp:122
bool containsInstruction()
Definition: asm_instruction.h:129
static std::vector< ModuleInstructionMap > _module2instMap
Definition: asm_instruction.h:195
llvm::LLVMContext & getContext() const
Definition: asm_instruction.cpp:678
friend std::ostream & operator<<(std::ostream &out, const AsmInstruction &a)
Definition: asm_instruction.cpp:820
bool operator!=(const AsmInstruction &o) const
Definition: asm_instruction.cpp:127
T * getInstructionFirst()
Definition: asm_instruction.h:142
std::reverse_iterator< iterator > reverse_iterator
Definition: asm_instruction.h:69
static retdec::common::Address getBasicBlockAddress(llvm::BasicBlock *bb)
Definition: asm_instruction.cpp:247
llvm::Instruction * back()
Definition: asm_instruction.cpp:729
bool instructionsCanBeErased()
Definition: asm_instruction.cpp:477
bool operator<(const AsmInstruction &o) const
Definition: asm_instruction.cpp:117
bool isValid() const
Definition: asm_instruction.cpp:335
static retdec::common::Address getBasicBlockEndAddress(llvm::BasicBlock *bb)
Definition: asm_instruction.cpp:283
llvm::Instruction * insertBack(llvm::Instruction *i)
Definition: asm_instruction.cpp:743
std::size_t getBitSize() const
Definition: asm_instruction.cpp:384
std::string dump() const
Definition: asm_instruction.cpp:792
reverse_iterator rbegin()
Definition: asm_instruction.cpp:148
llvm::Instruction * makeTerminal()
Definition: asm_instruction.cpp:589
bool isLlvmToAsmInstructionPrivate(llvm::Value *inst) const
Definition: asm_instruction.cpp:307
retdec::common::Address getEndAddress() const
Definition: asm_instruction.cpp:378
llvm::StoreInst * _llvmToAsmInstr
Definition: asm_instruction.h:193
bool contains(retdec::common::Address addr) const
Definition: asm_instruction.cpp:390
static retdec::common::Address getFunctionEndAddress(llvm::Function *f)
Definition: asm_instruction.cpp:299
llvm::BasicBlock * makeStart(const std::string &name="")
Definition: asm_instruction.cpp:630
static Llvm2CapstoneInsnMap & getLlvmToCapstoneInsnMap(const llvm::Module *m)
Definition: asm_instruction.cpp:186
std::string getDsm() const
Definition: asm_instruction.cpp:359
AsmInstruction getNext() const
Definition: asm_instruction.cpp:404
llvm::BasicBlock * getBasicBlock() const
Definition: asm_instruction.cpp:651
iterator end()
Definition: asm_instruction.cpp:144
AsmInstruction()
Definition: asm_instruction.cpp:26
static bool isLlvmToAsmInstruction(const llvm::Value *inst)
Definition: asm_instruction.cpp:318
bool empty()
Definition: asm_instruction.cpp:718
static void clear()
Definition: asm_instruction.cpp:329
retdec::common::Address getAddress() const
Definition: asm_instruction.cpp:370
static retdec::common::Address getTrueBasicBlockAddress(llvm::BasicBlock *bb)
Definition: asm_instruction.cpp:265
std::size_t getByteSize() const
Definition: asm_instruction.cpp:365
bool storesValue(llvm::Value *val) const
Definition: asm_instruction.cpp:776
llvm::Module * getModule() const
Definition: asm_instruction.cpp:669
cs_insn * getCapstoneInsn() const
Definition: asm_instruction.cpp:345
iterator begin()
Definition: asm_instruction.cpp:140
llvm::Instruction * insertBackSafe(llvm::Instruction *i)
Definition: asm_instruction.cpp:758
AsmInstruction getPrev() const
Definition: asm_instruction.cpp:440
bool eraseInstructions()
Definition: asm_instruction.cpp:517
reverse_iterator rend()
Definition: asm_instruction.cpp:152
static std::vector< ModuleGlobalPair > _module2global
Definition: asm_instruction.h:194
static void setLlvmToAsmGlobalVariable(const llvm::Module *m, llvm::GlobalVariable *gv)
Definition: asm_instruction.cpp:216
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: asm_instruction.h:70
llvm::StoreInst * getLlvmToAsmInstruction() const
Definition: asm_instruction.cpp:395
static retdec::common::Address getInstructionEndAddress(llvm::Instruction *inst)
Definition: asm_instruction.cpp:235
const llvm::GlobalVariable * getLlvmToAsmGlobalVariablePrivate(llvm::Module *m) const
Definition: asm_instruction.cpp:173
static llvm::GlobalVariable * getLlvmToAsmGlobalVariable(const llvm::Module *m)
Definition: asm_instruction.cpp:203
static retdec::common::Address getFunctionAddress(llvm::Function *f)
Definition: asm_instruction.cpp:291
std::pair< const llvm::Module *, llvm::GlobalVariable * > ModuleGlobalPair
Definition: asm_instruction.h:187
llvm::Function * getFunction() const
Definition: asm_instruction.cpp:660
std::vector< llvm::BasicBlock * > getBasicBlocks()
Definition: asm_instruction.cpp:693
static retdec::common::Address getInstructionAddress(llvm::Instruction *inst)
Definition: asm_instruction.cpp:223
Definition: address.h:21
Address, address pair and other derived class representation.
LLVM Utility functions.
Additional (on top of Capstone) definitions for MIPS translator.
The frontend-end part of the decompiler.
typename std::map< llvm::StoreInst *, cs_insn * > Llvm2CapstoneInsnMap
Definition: asm_instruction.h:25
Definition: archive_wrapper.h:19
Additional (on top of Capstone) definitions for PowerPC translator.
Additional (on top of Capstone) definitions for x86 translator.