Rizin
unix-like reverse engineering framework and cli tools
arch_54.h
Go to the documentation of this file.
1 // SPDX-License-Identifier: LGPL-3.0-only
2 // SPDX-FileCopyrightText: 2021 Heersin <teablearcher@gmail.com>
3 
4 #ifndef BUILD_ARCH_54_H
5 #define BUILD_ARCH_54_H
6 
7 #include <rz_types.h>
8 #include <rz_asm.h>
10 
11 /*===========================================================================
12  We assume that instructions are unsigned 32-bit integers.
13  All instructions have an opcode in the first 7 bits.
14  Instructions can have the following formats:
15 
16  3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
17  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
18 iABC C(8) | B(8) |k| A(8) | Op(7) |
19 iABx Bx(17) | A(8) | Op(7) |
20 iAsBx sBx (signed)(17) | A(8) | Op(7) |
21 iAx Ax(25) | Op(7) |
22 isJ sJ(25) | Op(7) |
23 
24  A signed argument is represented in excess K: the represented value is
25  the written unsigned value minus K, where K is half the maximum for the
26  corresponding unsigned argument.
27 ===========================================================================*/
28 
29 typedef enum {
33  iAx,
34  isJ
36 
37 /* Offset and size of opcode arguments */
38 #define LUAOP_A_SIZE 8
39 #define LUAOP_B_SIZE 8
40 #define LUAOP_C_SIZE 8
41 #define LUAOP_Bx_SIZE (LUAOP_C_SIZE + LUAOP_B_SIZE + 1)
42 #define LUAOP_Ax_SIZE (LUAOP_Bx_SIZE + LUAOP_A_SIZE)
43 #define LUAOP_sJ_SIZE (LUAOP_Bx_SIZE + LUAOP_A_SIZE)
44 #define LUAOP_OP_SIZE 7
45 
46 #define LUAOP_OP_OFFSET 0
47 #define LUAOP_A_OFFSET (LUAOP_OP_OFFSET + LUAOP_OP_SIZE)
48 #define LUAOP_k_OFFSET (LUAOP_A_OFFSET + LUAOP_A_SIZE)
49 #define LUAOP_B_OFFSET (LUAOP_k_OFFSET + 1)
50 #define LUAOP_C_OFFSET (LUAOP_B_OFFSET + LUAOP_B_SIZE)
51 #define LUAOP_Bx_OFFSET LUAOP_k_OFFSET
52 #define LUAOP_Ax_OFFSET LUAOP_A_OFFSET
53 #define LUAOP_sJ_OFFSET LUAOP_A_OFFSET
54 
55 /* max value of these args */
56 #define LUAOP_MAXARG_Bx ((1 << LUAOP_Bx_SIZE) - 1)
57 #define LUAOP_MAXARG_Ax ((1 << LUAOP_Ax_SIZE) - 1)
58 #define LUAOP_MAXARG_sJ ((1 << LUAOP_sJ_SIZE) - 1)
59 #define LUAOP_MAXARG_A ((1 << LUAOP_A_SIZE) - 1)
60 #define LUAOP_MAXARG_B ((1 << LUAOP_B_SIZE) - 1)
61 #define LUAOP_MAXARG_C ((1 << LUAOP_C_SIZE) - 1)
62 
63 /* fix value of signed args */
64 #define LUAOP_FIX_sBx (LUAOP_MAXARG_Bx >> 1)
65 #define LUAOP_FIX_sJ (LUAOP_MAXARG_sJ >> 1)
66 #define LUAOP_FIX_sC (LUAOP_MAXARG_C >> 1)
67 
68 typedef enum {
69  /*----------------------------------------------------------------------
70  name args description
71 ------------------------------------------------------------------------*/
72  OP_MOVE, /* A B R[A] := R[B] */
73  OP_LOADI, /* A sBx R[A] := sBx */
74  OP_LOADF, /* A sBx R[A] := (lua_Number)sBx */
75  OP_LOADK, /* A Bx R[A] := K[Bx] */
76  OP_LOADKX, /* A R[A] := K[extra arg] */
77  OP_LOADFALSE, /* A R[A] := false */
78  OP_LFALSESKIP, /*A R[A] := false; pc++ */
79  OP_LOADTRUE, /* A R[A] := true */
80  OP_LOADNIL, /* A B R[A], R[A+1], ..., R[A+B] := nil */
81  OP_GETUPVAL, /* A B R[A] := UpValue[B] */
82  OP_SETUPVAL, /* A B UpValue[B] := R[A] */
83 
84  OP_GETTABUP, /* A B C R[A] := UpValue[B][K[C]:string] */
85  OP_GETTABLE, /* A B C R[A] := R[B][R[C]] */
86  OP_GETI, /* A B C R[A] := R[B][C] */
87  OP_GETFIELD, /* A B C R[A] := R[B][K[C]:string] */
88 
89  OP_SETTABUP, /* A B C UpValue[A][K[B]:string] := RK(C) */
90  OP_SETTABLE, /* A B C R[A][R[B]] := RK(C) */
91  OP_SETI, /* A B C R[A][B] := RK(C) */
92  OP_SETFIELD, /* A B C R[A][K[B]:string] := RK(C) */
93 
94  OP_NEWTABLE, /* A B C k R[A] := {} */
95 
96  OP_SELF, /* A B C R[A+1] := R[B]; R[A] := R[B][RK(C):string] */
97 
98  OP_ADDI, /* A B sC R[A] := R[B] + sC */
99 
100  OP_ADDK, /* A B C R[A] := R[B] + K[C] */
101  OP_SUBK, /* A B C R[A] := R[B] - K[C] */
102  OP_MULK, /* A B C R[A] := R[B] * K[C] */
103  OP_MODK, /* A B C R[A] := R[B] % K[C] */
104  OP_POWK, /* A B C R[A] := R[B] ^ K[C] */
105  OP_DIVK, /* A B C R[A] := R[B] / K[C] */
106  OP_IDIVK, /* A B C R[A] := R[B] // K[C] */
107 
108  OP_BANDK, /* A B C R[A] := R[B] & K[C]:integer */
109  OP_BORK, /* A B C R[A] := R[B] | K[C]:integer */
110  OP_BXORK, /* A B C R[A] := R[B] ~ K[C]:integer */
111 
112  OP_SHRI, /* A B sC R[A] := R[B] >> sC */
113  OP_SHLI, /* A B sC R[A] := sC << R[B] */
114 
115  OP_ADD, /* A B C R[A] := R[B] + R[C] */
116  OP_SUB, /* A B C R[A] := R[B] - R[C] */
117  OP_MUL, /* A B C R[A] := R[B] * R[C] */
118  OP_MOD, /* A B C R[A] := R[B] % R[C] */
119  OP_POW, /* A B C R[A] := R[B] ^ R[C] */
120  OP_DIV, /* A B C R[A] := R[B] / R[C] */
121  OP_IDIV, /* A B C R[A] := R[B] // R[C] */
122 
123  OP_BAND, /* A B C R[A] := R[B] & R[C] */
124  OP_BOR, /* A B C R[A] := R[B] | R[C] */
125  OP_BXOR, /* A B C R[A] := R[B] ~ R[C] */
126  OP_SHL, /* A B C R[A] := R[B] << R[C] */
127  OP_SHR, /* A B C R[A] := R[B] >> R[C] */
128 
129  OP_MMBIN, /* A B C call C metamethod over R[A] and R[B] */
130  OP_MMBINI, /* A sB C k call C metamethod over R[A] and sB */
131  OP_MMBINK, /* A B C k call C metamethod over R[A] and K[B] */
132 
133  OP_UNM, /* A B R[A] := -R[B] */
134  OP_BNOT, /* A B R[A] := ~R[B] */
135  OP_NOT, /* A B R[A] := not R[B] */
136  OP_LEN, /* A B R[A] := #R[B] (length operator) */
137 
138  OP_CONCAT, /* A B R[A] := R[A].. ... ..R[A + B - 1] */
139 
140  OP_CLOSE, /* A close all upvalues >= R[A] */
141  OP_TBC, /* A mark variable A "to be closed" */
142  OP_JMP, /* sJ pc += sJ */
143  OP_EQ, /* A B k if ((R[A] == R[B]) ~= k) then pc++ */
144  OP_LT, /* A B k if ((R[A] < R[B]) ~= k) then pc++ */
145  OP_LE, /* A B k if ((R[A] <= R[B]) ~= k) then pc++ */
146 
147  OP_EQK, /* A B k if ((R[A] == K[B]) ~= k) then pc++ */
148  OP_EQI, /* A sB k if ((R[A] == sB) ~= k) then pc++ */
149  OP_LTI, /* A sB k if ((R[A] < sB) ~= k) then pc++ */
150  OP_LEI, /* A sB k if ((R[A] <= sB) ~= k) then pc++ */
151  OP_GTI, /* A sB k if ((R[A] > sB) ~= k) then pc++ */
152  OP_GEI, /* A sB k if ((R[A] >= sB) ~= k) then pc++ */
153 
154  OP_TEST, /* A k if (not R[A] == k) then pc++ */
155  OP_TESTSET, /* A B k if (not R[B] == k) then pc++ else R[A] := R[B] */
156 
157  OP_CALL, /* A B C R[A], ... ,R[A+C-2] := R[A](R[A+1], ... ,R[A+B-1]) */
158  OP_TAILCALL, /* A B C k return R[A](R[A+1], ... ,R[A+B-1]) */
159 
160  OP_RETURN, /* A B C k return R[A], ... ,R[A+B-2] (see note) */
161  OP_RETURN0, /* return */
162  OP_RETURN1, /* A return R[A] */
163 
164  OP_FORLOOP, /* A Bx update counters; if loop continues then pc-=Bx; */
165  OP_FORPREP, /* A Bx <check values and prepare counters>;
166  if not to run then pc+=Bx+1; */
167 
168  OP_TFORPREP, /* A Bx create upvalue for R[A + 3]; pc+=Bx */
169  OP_TFORCALL, /* A C R[A+4], ... ,R[A+3+C] := R[A](R[A+1], R[A+2]); */
170  OP_TFORLOOP, /* A Bx if R[A+2] ~= nil then { R[A]=R[A+2]; pc -= Bx } */
171 
172  OP_SETLIST, /* A B C k R[A][C+i] := R[A+i], 1 <= i <= B */
173 
174  OP_CLOSURE, /* A Bx R[A] := closure(KPROTO[Bx]) */
175 
176  OP_VARARG, /* A C R[A], R[A+1], ..., R[A+C-2] = vararg */
177 
178  OP_VARARGPREP, /*A (adjust vararg parameters) */
179 
180  OP_EXTRAARG /* Ax extra (larger) argument for previous opcode */
182 #define LUA_NUM_OPCODES ((int)(OP_EXTRAARG) + 1)
183 
184 /* ===========================================
185  * Operation Method Macros
186  * =========================================== */
187 
188 /* Macros Highlight the cast */
189 #define LUA_CAST(x, y) ((x)y)
190 #define int2sC(i) ((i) + LUAOP_FIX_sC)
191 #define sC2int(i) ((i)-LUAOP_FIX_sC)
192 
193 /* creates a mask with 'n' 1/0 bits at position 'p' */
194 #define LUA_MASK1(n, p) ((~((~(LuaInstruction)0) << (n))) << (p))
195 #define LUA_MASK0(n, p) (~LUA_MASK1(n, p))
196 
197 /* OPCODE getter */
198 #define LUA_GET_OPCODE(i) (LUA_CAST(LuaOpCode, ((i) >> LUAOP_OP_OFFSET) & LUA_MASK1(LUAOP_OP_SIZE, 0)))
199 #define LUA_SET_OPCODE(i, o) ((i) = (((i)&LUA_MASK0(LUAOP_OP_SIZE, LUAOP_OP_OFFSET)) | \
200  ((LUA_CAST(LuaInstruction, o) << LUAOP_OP_OFFSET) & LUA_MASK1(LUAOP_OP_SIZE, LUAOP_OP_OFFSET))))
201 
202 /* Arguments getter */
203 #define LUA_GETARG(i, offset, size) (LUA_CAST(int, ((i) >> (offset)) & LUA_MASK1(size, 0)))
204 #define LUA_SETARG(i, v, pos, size) ((i) = (((i)&LUA_MASK0(size, pos)) | \
205  ((LUA_CAST(LuaInstruction, v) << (pos)) & LUA_MASK1(size, pos))))
206 
207 #define LUA_GETARG_A(i) LUA_GETARG(i, LUAOP_A_OFFSET, LUAOP_A_SIZE)
208 #define LUA_GETARG_B(i) LUA_GETARG(i, LUAOP_B_OFFSET, LUAOP_B_SIZE)
209 #define LUA_GETARG_C(i) LUA_GETARG(i, LUAOP_C_OFFSET, LUAOP_C_SIZE)
210 #define LUA_GETARG_Bx(i) LUA_GETARG(i, LUAOP_Bx_OFFSET, LUAOP_Bx_SIZE)
211 #define LUA_GETARG_Ax(i) LUA_GETARG(i, LUAOP_Ax_OFFSET, LUAOP_Ax_SIZE)
212 #define LUA_GETARG_sBx(i) (LUA_GETARG_Bx(i) - LUAOP_FIX_sBx)
213 #define LUA_GETARG_sJ(i) (LUA_GETARG(i, LUAOP_sJ_OFFSET, LUAOP_sJ_SIZE) - LUAOP_FIX_sJ)
214 #define LUA_GETARG_sC(i) sC2int(LUA_GETARG_C(i))
215 #define LUA_GETARG_sB(i) sC2int(LUA_GETARG_B(i))
216 
217 #define LUA_GETARG_k(i) LUA_GETARG(i, LUAOP_k_OFFSET, 1)
218 
219 #define SETARG_A(i, v) LUA_SETARG(i, v, LUAOP_A_OFFSET, LUAOP_A_SIZE)
220 #define SETARG_B(i, v) LUA_SETARG(i, v, LUAOP_B_OFFSET, LUAOP_B_SIZE)
221 #define SETARG_C(i, v) LUA_SETARG(i, v, LUAOP_C_OFFSET, LUAOP_C_SIZE)
222 #define SETARG_Bx(i, v) LUA_SETARG(i, v, LUAOP_Bx_OFFSET, LUAOP_Bx_SIZE)
223 #define SETARG_Ax(i, v) LUA_SETARG(i, v, LUAOP_Ax_OFFSET, LUAOP_Ax_SIZE)
224 #define SETARG_sBx(i, b) SETARG_Bx((i), LUA_CAST(ut32, (b) + LUAOP_FIX_sBx))
225 #define SETARG_sJ(i, j) \
226  LUA_SETARG((i), LUA_CAST(ut32, (j) + LUAOP_FIX_sJ), LUAOP_sJ_OFFSET, LUAOP_sJ_SIZE)
227 #define SETARG_sC(i, v) SETARG_C((i), int2sC(v))
228 #define SETARG_sB(i, v) SETARG_B((i), int2sC(v))
229 
230 #define SETARG_k(i, v) LUA_SETARG(i, v, LUAOP_k_OFFSET, 1)
231 
232 /* parameter flags */
233 #define PARAM_A 1
234 #define PARAM_B 2
235 #define PARAM_C 4
236 #define PARAM_Ax 8
237 #define PARAM_Bx 16
238 #define PARAM_sBx 32
239 #define PARAM_sJ 64
240 #define PARAM_sC 128
241 #define PARAM_sB 256
242 #define PARAM_k 512
243 
244 #define has_param_flag(flag, bit) ((flag) & (bit)) ? true : false
245 
246 #define ISK(isk) ((isk) ? "#CONST" : "#R")
247 #define ISFLIP(isk) ((isk) ? "#FLIP" : "")
248 
249 #endif // BUILD_ARCH_54_H
LuaOpCode
Definition: arch_54.h:68
@ OP_SETLIST
Definition: arch_54.h:172
@ OP_MMBINK
Definition: arch_54.h:131
@ OP_EQI
Definition: arch_54.h:148
@ OP_CALL
Definition: arch_54.h:157
@ OP_VARARGPREP
Definition: arch_54.h:178
@ OP_LFALSESKIP
Definition: arch_54.h:78
@ OP_EQ
Definition: arch_54.h:143
@ OP_VARARG
Definition: arch_54.h:176
@ OP_MMBINI
Definition: arch_54.h:130
@ OP_POWK
Definition: arch_54.h:104
@ OP_BANDK
Definition: arch_54.h:108
@ OP_MMBIN
Definition: arch_54.h:129
@ OP_CONCAT
Definition: arch_54.h:138
@ OP_MULK
Definition: arch_54.h:102
@ OP_BOR
Definition: arch_54.h:124
@ OP_SETFIELD
Definition: arch_54.h:92
@ OP_SETTABLE
Definition: arch_54.h:90
@ OP_POW
Definition: arch_54.h:119
@ OP_NOT
Definition: arch_54.h:135
@ OP_TESTSET
Definition: arch_54.h:155
@ OP_MOD
Definition: arch_54.h:118
@ OP_CLOSURE
Definition: arch_54.h:174
@ OP_TBC
Definition: arch_54.h:141
@ OP_SETUPVAL
Definition: arch_54.h:82
@ OP_GTI
Definition: arch_54.h:151
@ OP_SETI
Definition: arch_54.h:91
@ OP_FORPREP
Definition: arch_54.h:165
@ OP_LEN
Definition: arch_54.h:136
@ OP_BORK
Definition: arch_54.h:109
@ OP_LOADNIL
Definition: arch_54.h:80
@ OP_LOADI
Definition: arch_54.h:73
@ OP_BAND
Definition: arch_54.h:123
@ OP_SELF
Definition: arch_54.h:96
@ OP_SUB
Definition: arch_54.h:116
@ OP_DIV
Definition: arch_54.h:120
@ OP_LTI
Definition: arch_54.h:149
@ OP_SHR
Definition: arch_54.h:127
@ OP_LT
Definition: arch_54.h:144
@ OP_TFORLOOP
Definition: arch_54.h:170
@ OP_LOADF
Definition: arch_54.h:74
@ OP_SHL
Definition: arch_54.h:126
@ OP_RETURN1
Definition: arch_54.h:162
@ OP_LOADFALSE
Definition: arch_54.h:77
@ OP_TEST
Definition: arch_54.h:154
@ OP_TFORCALL
Definition: arch_54.h:169
@ OP_DIVK
Definition: arch_54.h:105
@ OP_SHRI
Definition: arch_54.h:112
@ OP_ADD
Definition: arch_54.h:115
@ OP_GETI
Definition: arch_54.h:86
@ OP_IDIVK
Definition: arch_54.h:106
@ OP_CLOSE
Definition: arch_54.h:140
@ OP_FORLOOP
Definition: arch_54.h:164
@ OP_MUL
Definition: arch_54.h:117
@ OP_ADDK
Definition: arch_54.h:100
@ OP_TFORPREP
Definition: arch_54.h:168
@ OP_SHLI
Definition: arch_54.h:113
@ OP_GETTABLE
Definition: arch_54.h:85
@ OP_LOADK
Definition: arch_54.h:75
@ OP_GETUPVAL
Definition: arch_54.h:81
@ OP_GETFIELD
Definition: arch_54.h:87
@ OP_LOADTRUE
Definition: arch_54.h:79
@ OP_EQK
Definition: arch_54.h:147
@ OP_SETTABUP
Definition: arch_54.h:89
@ OP_IDIV
Definition: arch_54.h:121
@ OP_GETTABUP
Definition: arch_54.h:84
@ OP_MODK
Definition: arch_54.h:103
@ OP_LE
Definition: arch_54.h:145
@ OP_RETURN
Definition: arch_54.h:160
@ OP_BNOT
Definition: arch_54.h:134
@ OP_MOVE
Definition: arch_54.h:72
@ OP_GEI
Definition: arch_54.h:152
@ OP_RETURN0
Definition: arch_54.h:161
@ OP_UNM
Definition: arch_54.h:133
@ OP_ADDI
Definition: arch_54.h:98
@ OP_EXTRAARG
Definition: arch_54.h:180
@ OP_LOADKX
Definition: arch_54.h:76
@ OP_LEI
Definition: arch_54.h:150
@ OP_BXORK
Definition: arch_54.h:110
@ OP_NEWTABLE
Definition: arch_54.h:94
@ OP_BXOR
Definition: arch_54.h:125
@ OP_JMP
Definition: arch_54.h:142
@ OP_TAILCALL
Definition: arch_54.h:158
@ OP_SUBK
Definition: arch_54.h:101
LuaOpMode
Definition: arch_54.h:29
@ iAx
Definition: arch_54.h:33
@ iABC
Definition: arch_54.h:30
@ iAsBx
Definition: arch_54.h:32
@ isJ
Definition: arch_54.h:34
@ iABx
Definition: arch_54.h:31