forked from revng/revng
-
Notifications
You must be signed in to change notification settings - Fork 0
/
instructiontranslator.h
150 lines (129 loc) · 5.23 KB
/
instructiontranslator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#ifndef _INSTRUCTIONTRANSLATOR_H
#define _INSTRUCTIONTRANSLATOR_H
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
// Standard includes
#include <cstdint>
#include <map>
#include <vector>
// LLVM includes
#include "llvm/IR/IRBuilder.h"
#include "llvm/Pass.h"
#include "llvm/Support/ErrorOr.h"
// Local includes
#include "revamb.h"
#include "ptcdump.h"
#include "jumptargetmanager.h"
// Forward declarations
namespace llvm {
class BasicBlock;
class CallInst;
class Function;
class MDNode;
class Module;
}
class JumpTargetManager;
class VariableManager;
/// \brief Expands a PTC instruction to LLVM IR
class InstructionTranslator {
public:
using LabeledBlocksMap = std::map<std::string, llvm::BasicBlock *>;
/// \param Builder the IRBuilder to be used to create the translated
/// code.
/// \param Variables reference to the VariableManager.
/// \param JumpTargets reference to the JumpTargetManager.
/// \param Blocks reference to a `vector` of `BasicBlock`s used to keep track
/// on which `BasicBlock`s the InstructionTranslator worked on, for
/// further processing.
/// \param SourceArchitecture the input architecture.
/// \param TargetArchitecture the output architecture.
InstructionTranslator(llvm::IRBuilder<>& Builder,
VariableManager& Variables,
JumpTargetManager& JumpTargets,
std::vector<llvm::BasicBlock *> Blocks,
const Architecture &SourceArchitecture,
const Architecture &TargetArchitecture);
/// \brief Result status of the translation of a PTC opcode
enum TranslationResult {
Abort, ///< An error occurred during translation, call abort and stop
Stop, ///< Do not proceed with translation
Success, ///< The translation was successful
ForceNewPC ///< Successful, but force a new basic block for the next PC
};
/// \brief Handle a new instruction from the input code
///
/// \param Instr the newly met PTCInstruction;
/// \param Next the PTCInstruction immediately following \p Instr,
/// or `nullptr` if \p Instr is the last instruction
/// translated by libtinycode.
/// \param EndPC PC of the instruction coming after the next
/// instruction after the last translated by
/// libtinycode.
/// \param IsFirst true, if \p Instr is the first instruction
/// translated by libtinycode.
/// \param ForceNew true if a new jump target (and therefore basic
/// block should be created from the PC associate to
/// \p Instr.
///
/// \return a tuple with 4 entries: the
/// InstructionTranslator::TranslationResult, an `MDNode` containing
/// the disassembled instruction and the value of the PC and two
/// `uint64_t` representing the current and next PC.
// TODO: rename to newPC
// TODO: the signature of this function is ugly
std::tuple<TranslationResult,
llvm::MDNode *,
uint64_t,
uint64_t> newInstruction(PTCInstruction *Instr,
PTCInstruction *Next,
uint64_t EndPC,
bool IsFirst,
bool ForceNew);
/// \brief Translate an ordinary instruction
///
/// \param Instr the instruction to translate.
/// \param PC the PC associated to \p Instr.
/// \param NextPC the PC associated to instruction after \p Instr.
///
/// \return see InstructionTranslator::TranslationResult.
TranslationResult translate(PTCInstruction *Instr,
uint64_t PC,
uint64_t NextPC);
/// \brief Translate a call to an helper
///
/// \param Instr the PTCInstruction of the call to the helper.
///
/// \return see InstructionTranslator::TranslationResult.
TranslationResult translateCall(PTCInstruction *Instr);
/// \brief Handle calls to `newPC` marker and emit coverage information
///
/// \param CoveragePath path where the coverage information should be stored.
void finalizeNewPCMarkers(std::string &CoveragePath);
/// \brief Notifies InstructionTranslator about a new PTC translation
void reset() { LabeledBasicBlocks.clear(); }
/// \brief Preprocess the translated instructions
///
/// Check if the translated code contains a delay slot and return a blacklist
/// of the PTC_INSTRUCTION_op_debug_insn_start instructions that have to be
/// ignored to merge the delay slot into the branch instruction.
llvm::SmallSet<unsigned, 1> preprocess(PTCInstructionList *Instructions);
private:
llvm::ErrorOr<std::vector<llvm::Value *>>
translateOpcode(PTCOpcode Opcode,
std::vector<uint64_t> ConstArguments,
std::vector<llvm::Value *> InArguments);
private:
llvm::IRBuilder<>& Builder;
VariableManager& Variables;
JumpTargetManager& JumpTargets;
std::map<std::string, llvm::BasicBlock *> LabeledBasicBlocks;
std::vector<llvm::BasicBlock *> Blocks;
llvm::Module &TheModule;
llvm::Function *TheFunction;
const Architecture &SourceArchitecture;
const Architecture &TargetArchitecture;
llvm::Function *NewPCMarker;
uint64_t LastPC;
};
#endif // _INSTRUCTIONTRANSLATOR_H