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
|
#pragma once
#include "binaryninjaapi.h"
#include "sysregs_enum.h"
#include "disassembler/arm64dis.h"
#include "disassembler/encodings_dec.h"
#include "disassembler/encodings_fmt.h"
#include "disassembler/operations.h"
/* Do we lift pointer authentication instructions as intrinsics?
If no, the below define should be preceeded with "//"
If yes, the below define should start with "#define" and intrinsics are used.
This is read by il.cpp and arm64test.py */
//#define LIFT_PAC_AS_INTRINSIC 1
#define IL_FLAG_N 31
#define IL_FLAG_Z 30
#define IL_FLAG_C 29
#define IL_FLAG_V 28
#define IL_FLAG_WRITE_NONE 0
#define IL_FLAG_WRITE_ALL 1
#define IL_FLAG_WRITE_ALL_FLOAT 2
#define IL_FLAG_CLASS_INT 1
#define IL_FLAG_CLASS_FLOAT 2
#define IL_FLAG_GROUP_EQ 1
#define IL_FLAG_GROUP_NE 2
#define IL_FLAG_GROUP_CS 3
#define IL_FLAG_GROUP_CC 4
#define IL_FLAG_GROUP_MI 5
#define IL_FLAG_GROUP_PL 6
#define IL_FLAG_GROUP_VS 7
#define IL_FLAG_GROUP_VC 8
#define IL_FLAG_GROUP_HI 9
#define IL_FLAG_GROUP_LS 10
#define IL_FLAG_GROUP_GE 11
#define IL_FLAG_GROUP_LT 12
#define IL_FLAG_GROUP_GT 13
#define IL_FLAG_GROUP_LE 14
enum Arm64Intrinsic : uint32_t
{
ARM64_INTRIN_AUTDA,
ARM64_INTRIN_AUTDB,
ARM64_INTRIN_AUTIA,
ARM64_INTRIN_AUTIB,
ARM64_INTRIN_DC,
ARM64_INTRIN_DMB,
ARM64_INTRIN_DSB,
ARM64_INTRIN_ESB,
ARM64_INTRIN_HINT_BTI,
ARM64_INTRIN_HINT_CSDB,
ARM64_INTRIN_HINT_DGH,
ARM64_INTRIN_HINT_TSB,
ARM64_INTRIN_ISB,
ARM64_INTRIN_MRS,
ARM64_INTRIN_MSR,
ARM64_INTRIN_PACDA,
ARM64_INTRIN_PACDB,
ARM64_INTRIN_PACGA,
ARM64_INTRIN_PACIA,
ARM64_INTRIN_PACIB,
ARM64_INTRIN_PRFM,
ARM64_INTRIN_PSBCSYNC,
ARM64_INTRIN_SEV,
ARM64_INTRIN_SEVL,
ARM64_INTRIN_WFE,
ARM64_INTRIN_WFI,
ARM64_INTRIN_XPACD,
ARM64_INTRIN_XPACI,
ARM64_INTRIN_YIELD,
ARM64_INTRIN_ERET,
ARM64_INTRIN_CLZ,
ARM64_INTRIN_CNT,
ARM64_INTRIN_CTZ,
ARM64_INTRIN_CLREX,
ARM64_INTRIN_REV,
ARM64_INTRIN_RBIT,
ARM64_INTRIN_AESD,
ARM64_INTRIN_AESE,
ARM64_INTRIN_AESIMC,
ARM64_INTRIN_AESMC,
ARM64_INTRIN_LDXR,
ARM64_INTRIN_LDXRB,
ARM64_INTRIN_LDXRH,
ARM64_INTRIN_LDXP,
ARM64_INTRIN_LDAXR,
ARM64_INTRIN_LDAXRB,
ARM64_INTRIN_LDAXRH,
ARM64_INTRIN_STXR,
ARM64_INTRIN_STXRB,
ARM64_INTRIN_STXRH,
ARM64_INTRIN_STXP,
ARM64_INTRIN_STLXR,
ARM64_INTRIN_STLXRB,
ARM64_INTRIN_STLXRH,
ARM64_INTRIN_TLBI,
ARM64_INTRIN_TLBI_REG,
ARM64_INTRIN_AT,
ARM64_INTRIN_ADDG,
ARM64_INTRIN_CMPP,
ARM64_INTRIN_GMI,
ARM64_INTRIN_IRG,
ARM64_INTRIN_LDG,
ARM64_INTRIN_LDGM,
ARM64_INTRIN_ST2G,
ARM64_INTRIN_STG,
ARM64_INTRIN_STGM,
ARM64_INTRIN_STGP,
ARM64_INTRIN_STZ2G,
ARM64_INTRIN_STZG,
ARM64_INTRIN_STZGM,
ARM64_INTRIN_SUBG,
ARM64_INTRIN_SUBP,
ARM64_INTRIN_SUBPS,
ARM64_INTRIN_NORMAL_END, /* needed so intrinsics can be extended by other lists, like neon
intrinsics */
ARM64_INTRIN_INVALID = 0xFFFFFFFF,
};
enum Arm64FakeRegister : uint32_t
{
FAKEREG_SYSREG_UNKNOWN = SYSREG_END + 1,
FAKEREG_SYSCALL_INFO = SYSREG_END + 2
};
bool GetLowLevelILForInstruction(BinaryNinja::Architecture* arch, uint64_t addr,
BinaryNinja::LowLevelILFunction& il, Instruction& instr, size_t addrSize, bool alignmentRequired, std::function<bool()> preferIntrinsics);
BinaryNinja::ExprId ExtractRegister(BinaryNinja::LowLevelILFunction& il,
InstructionOperand& operand, size_t regNum, size_t extractSize, bool signExtend,
size_t resultSize);
|