forked from revng/revng
-
Notifications
You must be signed in to change notification settings - Fork 0
/
revamb.h
134 lines (115 loc) · 4.09 KB
/
revamb.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
#ifndef _REVAMB_H
#define _REVAMB_H
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
// Standard includes
#include <cstdint>
#include <iterator>
#include <string>
#include <vector>
// LLVM includes
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
namespace llvm {
class GlobalVariable;
};
/// \brief Type of debug information to produce
enum class DebugInfoType {
None, ///< no debug information.
OriginalAssembly, ///< produce a file containing the assembly code of the
/// input binary.
PTC, ///< produce the PTC as translated by libtinycode.
LLVMIR ///< produce an LLVM IR with debug metadata referring to itself.
};
// TODO: move me to another header file
/// \brief Classification of the various basic blocks we are creating
enum BlockType {
UntypedBlock, ///< A basic block generated during translation that it's not a
/// jump target.
DispatcherBlock, ///< Basic block representing the dispatcher.
AnyPCBlock, ///< Basic block used to handle an expectedly unknown jump target.
UnexpectedPCBlock, ///< Basic block used to handle an unexpectedly unknown
/// jump target.
JumpTargetBlock ///< A basic block generated during translation representing a
/// jump target.
};
/// \brief Basic information about an input/output architecture
class Architecture {
public:
enum EndianessType {
LittleEndian,
BigEndian
};
public:
Architecture() :
InstructionAlignment(1),
DefaultAlignment(1),
Endianess(LittleEndian),
PointerSize(64),
DelaySlotSize(0) { }
Architecture(unsigned Type,
unsigned InstructionAlignment,
unsigned DefaultAlignment,
bool IsLittleEndian,
unsigned PointerSize,
llvm::StringRef SyscallHelper,
llvm::StringRef SyscallNumberRegister,
llvm::ArrayRef<uint64_t> NoReturnSyscalls,
unsigned DelaySlotSize) :
Type(static_cast<llvm::Triple::ArchType>(Type)),
InstructionAlignment(InstructionAlignment),
DefaultAlignment(DefaultAlignment),
Endianess(IsLittleEndian ? LittleEndian : BigEndian),
PointerSize(PointerSize),
SyscallHelper(SyscallHelper),
SyscallNumberRegister(SyscallNumberRegister),
NoReturnSyscalls(NoReturnSyscalls),
DelaySlotSize(DelaySlotSize) { }
unsigned instructionAlignment() const { return InstructionAlignment; }
unsigned defaultAlignment() const { return DefaultAlignment; }
EndianessType endianess() const { return Endianess; }
unsigned pointerSize() const { return PointerSize; }
bool isLittleEndian() const { return Endianess == LittleEndian; }
llvm::StringRef syscallHelper() const { return SyscallHelper; }
llvm::StringRef syscallNumberRegister() const {
return SyscallNumberRegister;
}
llvm::ArrayRef<uint64_t> noReturnSyscalls() const { return NoReturnSyscalls; }
unsigned delaySlotSize() const { return DelaySlotSize; }
const char *name() const { return llvm::Triple::getArchTypeName(Type); }
private:
llvm::Triple::ArchType Type;
unsigned InstructionAlignment;
unsigned DefaultAlignment;
EndianessType Endianess;
unsigned PointerSize;
llvm::StringRef SyscallHelper;
llvm::StringRef SyscallNumberRegister;
llvm::ArrayRef<uint64_t> NoReturnSyscalls;
unsigned DelaySlotSize;
};
// TODO: this requires C++14
template<typename FnTy, FnTy Ptr>
struct GenericFunctor {
template<typename... Args>
auto operator()(Args... args) -> decltype(Ptr(args...)) {
return Ptr(args...);
}
};
// TODO: move me somewhere more appropriate
static inline bool startsWith(std::string String, std::string Prefix) {
return String.substr(0, Prefix.size()) == Prefix;
}
/// \brief Simple helper function asserting a pointer is not a `nullptr`
template<typename T>
static inline T *notNull(T *Pointer) {
assert(Pointer != nullptr);
return Pointer;
}
template<typename T>
static inline bool contains(T Range, typename T::value_type V) {
return std::find(std::begin(Range), std::end(Range), V) != std::end(Range);
}
#endif // _REVAMB_H