Skip to content

Commit 7a53f4f

Browse files
committed
5.2 disasm and asm change bx and ax interpretation
1 parent 70c3020 commit 7a53f4f

File tree

5 files changed

+102
-113
lines changed

5 files changed

+102
-113
lines changed

librz/arch/isa/luac/v52/arch_52.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@ enum OpArgMask {
195195
OpArgK /* argument is a constant or register/constant */
196196
};
197197

198+
extern const ut8 luaP_opmodes[LUA_NUM_OPCODES];
199+
200+
#define opmode(t, a, b, c, m) (((t) << 7) | ((a) << 6) | ((b) << 4) | ((c) << 2) | (m))
201+
198202
#define getOpMode(m) (cast(LuaOpMode, luaP_opmodes[m] & 3))
199203
#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
200204
#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))

librz/arch/isa/luac/v52/assembly_52.c

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,15 @@
55

66
#include "arch_52.h"
77

8-
static LuaInstruction encode_instruction(ut8 opcode, const char *arg_start, ut16 flag, ut8 arg_num) {
8+
static LuaInstruction encode_instruction(const ut8 opcode, const char *arg_start, const ut16 flag, const ut8 arg_num) {
99
LuaInstruction instruction = 0;
1010
int args[3];
1111
char buffer[64]; // buffer for digits
1212
int cur_cnt = 0;
13-
int delta_offset;
1413
int temp;
1514

16-
if (arg_num > sizeof(args)) {
17-
return -1;
18-
}
19-
2015
for (int i = 0; i < arg_num; ++i) {
21-
delta_offset = lua_load_next_arg_start(arg_start, buffer);
16+
const int delta_offset = lua_load_next_arg_start(arg_start, buffer);
2217
if (delta_offset == 0) {
2318
return -1;
2419
}
@@ -30,6 +25,27 @@ static LuaInstruction encode_instruction(ut8 opcode, const char *arg_start, ut16
3025
}
3126
}
3227

28+
switch (getOpMode(opcode)) {
29+
case iABC:
30+
if (getBMode(opcode) != OpArgN) {
31+
args[1] = ISK(args[1]) ? (MYK(INDEXK(args[1]))) : args[1];
32+
}
33+
if (getCMode(opcode) != OpArgN) {
34+
args[2] = ISK(args[2]) ? (MYK(INDEXK(args[2]))) : args[2];
35+
}
36+
break;
37+
case iABx:
38+
if (getBMode(opcode) == OpArgK) {
39+
args[1] = MYK(args[1]);
40+
}
41+
break;
42+
case iAsBx:
43+
break;
44+
case iAx:
45+
args[0] = MYK(args[0]);
46+
break;
47+
}
48+
3349
SET_OPCODE(instruction, opcode);
3450
if (has_param_flag(flag, PARAM_A)) {
3551
SETARG_A(instruction, args[cur_cnt++]);
@@ -54,32 +70,26 @@ static LuaInstruction encode_instruction(ut8 opcode, const char *arg_start, ut16
5470
SETARG_Bx(instruction, args[cur_cnt++]);
5571
}
5672
rz_return_val_if_fail(cur_cnt == arg_num, -1);
57-
5873
return instruction;
5974
}
6075

6176
bool lua52_assembly(const char *input, st32 input_size, LuaInstruction *instruction_p) {
62-
const char *opcode_start; // point to the header
63-
const char *opcode_end; // point to the first white space
64-
int opcode_len;
65-
66-
const char *arg_start;
67-
68-
ut8 opcode;
6977
LuaInstruction instruction = 0x00;
7078

7179
/* Find the opcode */
72-
opcode_start = input;
73-
opcode_end = strchr(input, ' ');
80+
// point to the header
81+
const char *opcode_start = input;
82+
// point to the first white space
83+
const char *opcode_end = strchr(input, ' ');
7484
if (opcode_end == NULL) {
7585
opcode_end = input + input_size;
7686
}
7787

78-
opcode_len = opcode_end - opcode_start;
79-
opcode = get_lua52_opcode_by_name(opcode_start, opcode_len);
88+
int opcode_len = opcode_end - opcode_start;
89+
ut8 opcode = get_lua52_opcode_by_name(opcode_start, opcode_len);
8090

8191
/* Find the arguments */
82-
arg_start = rz_str_trim_head_ro(opcode_end);
92+
const char *arg_start = rz_str_trim_head_ro(opcode_end);
8393

8494
/* Encode opcode and args */
8595
switch (opcode) {

librz/arch/isa/luac/v52/disassembly_52.c

Lines changed: 0 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -5,91 +5,6 @@
55

66
#include "arch_52.h"
77

8-
#define opmode(t, a, b, c, m) (((t) << 7) | ((a) << 6) | ((b) << 4) | ((c) << 2) | (m))
9-
10-
const ut8 luaP_opmodes[LUA_NUM_OPCODES] = {
11-
/* T A B C mode opcode */
12-
opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
13-
,
14-
opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
15-
,
16-
opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */
17-
,
18-
opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
19-
,
20-
opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */
21-
,
22-
opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
23-
,
24-
opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */
25-
,
26-
opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
27-
,
28-
opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */
29-
,
30-
opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
31-
,
32-
opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
33-
,
34-
opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
35-
,
36-
opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
37-
,
38-
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
39-
,
40-
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
41-
,
42-
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
43-
,
44-
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
45-
,
46-
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
47-
,
48-
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
49-
,
50-
opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
51-
,
52-
opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
53-
,
54-
opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
55-
,
56-
opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
57-
,
58-
opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
59-
,
60-
opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
61-
,
62-
opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
63-
,
64-
opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
65-
,
66-
opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */
67-
,
68-
opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
69-
,
70-
opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
71-
,
72-
opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
73-
,
74-
opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
75-
,
76-
opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
77-
,
78-
opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
79-
,
80-
opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */
81-
,
82-
opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */
83-
,
84-
opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
85-
,
86-
opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
87-
,
88-
opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
89-
,
90-
opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */
91-
};
92-
938
int lua52_disasm(RzAsmOp *op, const ut8 *buf, int len, LuaOpNameList opnames) {
949
if (len < 4) {
9510
RZ_LOG_DEBUG("Cannot disassemble lua52 opcode (truncated).\n");

librz/arch/isa/luac/v52/opcode_52.c

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,57 @@
44
// SPDX-FileCopyrightText: 2025-2026 Sergey Sharshunov <s.sharshunov@gmail.com>
55

66
#include "arch_52.h"
7+
8+
const ut8 luaP_opmodes[LUA_NUM_OPCODES] = {
9+
/* T A B C mode opcode */
10+
opmode(0, 1, OpArgR, OpArgN, iABC), /* OP_MOVE */
11+
opmode(0, 1, OpArgK, OpArgN, iABx), /* OP_LOADK */
12+
opmode(0, 1, OpArgN, OpArgN, iABx), /* OP_LOADKX */
13+
opmode(0, 1, OpArgU, OpArgU, iABC), /* OP_LOADBOOL */
14+
opmode(0, 1, OpArgU, OpArgN, iABC), /* OP_LOADNIL */
15+
opmode(0, 1, OpArgU, OpArgN, iABC), /* OP_GETUPVAL */
16+
opmode(0, 1, OpArgU, OpArgK, iABC), /* OP_GETTABUP */
17+
opmode(0, 1, OpArgR, OpArgK, iABC), /* OP_GETTABLE */
18+
opmode(0, 0, OpArgK, OpArgK, iABC), /* OP_SETTABUP */
19+
opmode(0, 0, OpArgU, OpArgN, iABC), /* OP_SETUPVAL */
20+
opmode(0, 0, OpArgK, OpArgK, iABC), /* OP_SETTABLE */
21+
opmode(0, 1, OpArgU, OpArgU, iABC), /* OP_NEWTABLE */
22+
opmode(0, 1, OpArgR, OpArgK, iABC), /* OP_SELF */
23+
opmode(0, 1, OpArgK, OpArgK, iABC), /* OP_ADD */
24+
opmode(0, 1, OpArgK, OpArgK, iABC), /* OP_SUB */
25+
opmode(0, 1, OpArgK, OpArgK, iABC), /* OP_MUL */
26+
opmode(0, 1, OpArgK, OpArgK, iABC), /* OP_DIV */
27+
opmode(0, 1, OpArgK, OpArgK, iABC), /* OP_MOD */
28+
opmode(0, 1, OpArgK, OpArgK, iABC), /* OP_POW */
29+
opmode(0, 1, OpArgR, OpArgN, iABC), /* OP_UNM */
30+
opmode(0, 1, OpArgR, OpArgN, iABC), /* OP_NOT */
31+
opmode(0, 1, OpArgR, OpArgN, iABC), /* OP_LEN */
32+
opmode(0, 1, OpArgR, OpArgR, iABC), /* OP_CONCAT */
33+
opmode(0, 0, OpArgR, OpArgN, iAsBx), /* OP_JMP */
34+
opmode(1, 0, OpArgK, OpArgK, iABC), /* OP_EQ */
35+
opmode(1, 0, OpArgK, OpArgK, iABC), /* OP_LT */
36+
opmode(1, 0, OpArgK, OpArgK, iABC), /* OP_LE */
37+
opmode(1, 0, OpArgN, OpArgU, iABC), /* OP_TEST */
38+
opmode(1, 1, OpArgR, OpArgU, iABC), /* OP_TESTSET */
39+
opmode(0, 1, OpArgU, OpArgU, iABC), /* OP_CALL */
40+
opmode(0, 1, OpArgU, OpArgU, iABC), /* OP_TAILCALL */
41+
opmode(0, 0, OpArgU, OpArgN, iABC), /* OP_RETURN */
42+
opmode(0, 1, OpArgR, OpArgN, iAsBx), /* OP_FORLOOP */
43+
opmode(0, 1, OpArgR, OpArgN, iAsBx), /* OP_FORPREP */
44+
opmode(0, 0, OpArgN, OpArgU, iABC), /* OP_TFORCALL */
45+
opmode(0, 1, OpArgR, OpArgN, iAsBx), /* OP_TFORLOOP */
46+
opmode(0, 0, OpArgU, OpArgU, iABC), /* OP_SETLIST */
47+
opmode(0, 1, OpArgU, OpArgN, iABx), /* OP_CLOSURE */
48+
opmode(0, 1, OpArgU, OpArgN, iABC), /* OP_VARARG */
49+
opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */
50+
};
51+
752
#define lua_strcase(case_str) if ( \
853
((limit) <= sizeof(case_str) - 1) && \
954
rz_str_ncasecmp((name), (case_str), sizeof(case_str) - 1) == 0)
1055

1156
LuaOpNameList get_lua52_opnames(void) {
12-
LuaOpNameList list = RZ_NEWS(char *, LUA_NUM_OPCODES + 1);
57+
const LuaOpNameList list = RZ_NEWS(char *, LUA_NUM_OPCODES + 1);
1358
if (list == NULL) {
1459
RZ_LOG_ERROR("Cannot allocate lua52 opcode list.\n");
1560
return NULL;
@@ -32,9 +77,9 @@ LuaOpNameList get_lua52_opnames(void) {
3277
list[OP_ADD] = "add";
3378
list[OP_SUB] = "sub";
3479
list[OP_MUL] = "mul";
80+
list[OP_DIV] = "div";
3581
list[OP_MOD] = "mod";
3682
list[OP_POW] = "pow";
37-
list[OP_DIV] = "div";
3883
list[OP_UNM] = "unm";
3984
list[OP_NOT] = "not";
4085
list[OP_LEN] = "len";
@@ -78,14 +123,15 @@ ut8 get_lua52_opcode_by_name(const char *name, int limit) {
78123
lua_strcase("add") return OP_ADD;
79124
lua_strcase("sub") return OP_SUB;
80125
lua_strcase("mul") return OP_MUL;
126+
lua_strcase("div") return OP_DIV;
81127
lua_strcase("mod") return OP_MOD;
82128
lua_strcase("pow") return OP_POW;
83-
lua_strcase("div") return OP_DIV;
84129
lua_strcase("unm") return OP_UNM;
85130
lua_strcase("not") return OP_NOT;
86-
87131
lua_strcase("len") return OP_LEN;
132+
88133
lua_strcase("concat") return OP_CONCAT;
134+
89135
lua_strcase("jmp") return OP_JMP;
90136
lua_strcase("eq") return OP_EQ;
91137
lua_strcase("lt") return OP_LT;

test/db/asm/luac_5.2_0

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ ad "forloop 0 -130806" 20404200
33
ad "tailcall 0 -1 3" 1ec00080
44
ad "gettabup 0 0 -1" 06004000
55
ad "setlist 0 2 1" 24400001
6-
ad "loadk 1 -14" 41400300
76
ad "gettable 0 0 -16" 07c04300
87
ad "call 2 2 3" 9dc00001
98
ad "move 3 0" c0000000
@@ -13,10 +12,25 @@ d "invalid" ec400200
1312
ad "settable 2 -92 3" 8ac080ad
1413
ad "self 2 2 -93" 8c005701
1514
d "invalid" a9800000
16-
ad "extraarg 33552898" a780fe7f
1715
ad "vararg 0 1" 26008000
1816
ad "self 0 0 -3" 0c804000
19-
ad "loadk 2 -6" 81400100
2017
ad "self 0 0 -4" 0cc04000
18+
ad "return 0 1" 1f008000
19+
ad "gettabup 0 0 0" 06000000
20+
ad "gettable 0 0 0" 07000000
21+
ad "settabup 1 0 0" 48000000
22+
ad "self 0 0 0" 0c000000
23+
ad "self 1 0 5" 4c400100
24+
ad "tailcall 0 0 0" 1e000000
25+
ad "tailcall 1 0 0" 5e000000
26+
ad "vararg 0 0" 26000000
27+
ad "vararg 2 0" a6000000
28+
ad "tforcall 0 0" 22000000
29+
ad "tforcall 0 4" 22000100
30+
ad "loadk 1 -14" 41400300
2131
ad "loadk 2 -7" 81800100
22-
ad "return 0 1" 1f008071
32+
ad "loadk 2 -6" 81400100
33+
ad "loadk 1 -1" 41000000
34+
ad "loadk 3 -1" c1000000
35+
ad "loadk 0 -1" 01000000
36+
ad "loadk 1 -6" 41400100

0 commit comments

Comments
 (0)