-
Notifications
You must be signed in to change notification settings - Fork 2
/
asm_e2k.c
148 lines (134 loc) · 3.23 KB
/
asm_e2k.c
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
/*
E2K disassembler by uis
Distributed under MIT
*/
#include <stdio.h>
#include <string.h>
#include <r_types.h>
#include <r_lib.h>
#include <r_asm.h>
//Syllables order:
//HS
//SS (12)
//ALS{0-5} (26..31)
//CS0 (14)
//ALES{2,5} (22,25)
//CS1 (15)
//ALES{0,1,3,4} (20,21,23,24)
//AAS{0..5} (SS)
//LTS{3..0} {readed}[len-readed-cdscnt-plscnt]
//PLS{2..0} {end-cdscnt-plscnt}[plscnt]
//CDS{2..0} {end-cdscnt}[cdscnt]
//HS format
//{31..26} |{25..20} |{19:18} |{17:16}
//ALS{5..0} |ALES{5..0} |PLS count |CDS count
//
//|{15..14} |13 |12 |11 |10 |{9..7} |{6:4} |{3:0}
//|CS{1..0} |set_mark? |SS |rsrvd |loop_mode? |nop? |payload length |middle ptr?
//SS format
//{31:30} |29 |28 |27 |26 |25 |24
//ipd |eap |bap |srp |vfdi |crp(?) |abgi
//
//23 |22 |21 |20 |19 |18 |17 |16
//abgd |abnf |abnt |type=0 |abpf |abpt |alcf |alct
//
//15 |14 |13 |12 |{11:10} |{8:0}
//ASS02 |AASS03 |AASS14 |AASS15 |ctop(%ctpr) |ctcond
//SSv2 format
//{31:30} |{29:28} |27 |26 |25 |20 |{5:0}
//ipd |invush_hi |srp(?) |invush_lo |crp(?) |type=1 |prednum(%pred)
//More info at https://github.com/nrdmn/elbrus-docs
struct hs_bits {
const char *name;
unsigned int size;
int bit;
};
static struct hs_bits hs_bits[] = {
{"SS", 4, 12},
{"ALS0", 4, 26},
{"ALS1", 4, 27},
{"ALS2", 4, 28},
{"ALS3", 4, 29},
{"ALS4", 4, 30},
{"ALS5", 4, 31},
{"CS0", 4, 14},
{"ALES2", 2, 22},
{"ALES5", 2, 25},
{"CS1", 4, 15},
{"ALES0", 2, 20},
{"ALES1", 2, 21},
{"ALES3", 2, 23},
{"ALES4", 2, 24},
};
static int inslen(const ut8 *buf) {
ut32 hs = r_read_le32(buf);
int len = (hs & 0x70) >> 4;
return (len+1)*8;
}
static bool addSyll(const ut32 hs, const int bit, const char *name, RStrBuf *sb) {
if(hs & (1<<bit)) {
r_strbuf_appendf(sb, " %s;", name);
return true;
}
return false;
}
static void parseHS(const ut8 *buf, int oplen, RStrBuf *sb) {
int pos = 4;
ut32 hs = r_read_le32(buf)/*, opcode = r_read_le32(buf+4)*/;
for(size_t i = 0; i < (sizeof(hs_bits)/sizeof(hs_bits[0])); i++) {
if(pos == oplen)
break;
if(addSyll(hs, hs_bits[i].bit, hs_bits[i].name, sb))
pos += hs_bits[i].size;
}
//FIXME
if(pos%4)
pos+=2;
int plscnt, cdscnt;
cdscnt = (hs>>16)&3;
plscnt = (hs>>18)&3;
for(int i = (oplen-(pos+cdscnt+plscnt))/4; i > 0; i--) {
r_strbuf_appendf(sb, " LTS%u;", i);
pos += 4;
}
for(int i = plscnt; i > 0; i--) {
r_strbuf_appendf(sb, " PLS%u;", i);
pos += 4;
}
for(int i = cdscnt; i > 0; i--) {
r_strbuf_appendf(sb, " CDS%u;", i);
pos += 4;
}
if((hs>>7)&7)
r_strbuf_appendf(sb, " nop %u;", (hs>>7)&7);
}
static int disassemble(RAsm *as, RAsmOp *op, const ut8 *buf, int len) {
if(len < 4)
return -1;
int ilen = op->size = inslen(buf);
if(ilen > len)
return -1;
// sprintf(op->buf_asm.buf, "Len: %d:", ilen);
r_strbuf_setf(&op->buf_asm, "; %d bytes: {", ilen);
parseHS(buf, ilen, &op->buf_asm);
r_strbuf_append(&op->buf_asm, " }");
return ilen;
}
RAsmPlugin r_asm_plugin_e2k = {
.name = "elbrus",
.license = "MIT",
.author = "uis",
.desc = "ELBRUS disassembly plugin",
.arch = "elbrus",
.bits = 32|64,
.endian = R_SYS_ENDIAN_LITTLE,
.disassemble = &disassemble
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_e2k,
.version = R2_VERSION,
.pkgname = "RE2K decompiler"
};
#endif