mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-27 09:35:49 +00:00
Initial implementation of the MIPS assembler
This commit is contained in:
parent
5c236fa0e3
commit
a395c8d6c8
@ -120,6 +120,7 @@ static int mips_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len) {
|
||||
} else
|
||||
if ((optype & 0x3e) == 2) {
|
||||
#if 0
|
||||
// J-TYPE
|
||||
|--[0]--| |--[1]--| |--[2]--| |--[3]--|
|
||||
1111 1111 1111 1111 1111 1111 1111 1111
|
||||
\_op__/\______address____________________/
|
||||
|
132
libr/asm/arch/mips/mipsasm.c
Normal file
132
libr/asm/arch/mips/mipsasm.c
Normal file
@ -0,0 +1,132 @@
|
||||
/* radare - Copyright 2012 - pancake */
|
||||
|
||||
#include <r_types.h>
|
||||
|
||||
static const char * const regs[32] = {
|
||||
"zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
|
||||
"a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
|
||||
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
|
||||
"t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct {
|
||||
const char *name;
|
||||
int type;
|
||||
int args;
|
||||
int n;
|
||||
} ops[] = {
|
||||
{ "nop", 'N', 0, NULL },
|
||||
{ "lui", 'I', 2, 15 },
|
||||
{ "sw", 'I', 3, 43 },
|
||||
{ "sh", 'I', 3, 41 },
|
||||
{ "sb", 'I', 3, 40 },
|
||||
{ "lw", 'I', 3, 35 },
|
||||
{ "lh", 'I', 3, 33 },
|
||||
{ "lb", 'I', 3, 32 },
|
||||
{ "ori", 'I', 3, 13 },
|
||||
{ "andi", 'I', 3, 12 },
|
||||
{ "xori", 'I', 3, 14 },
|
||||
{ "addi", 'I', 3, 8 },
|
||||
{ "addiu", 'I', 3, 9 },
|
||||
{ "bnez", 'I', 2, 5 },
|
||||
{ "jalr", 'R', 1, 9 },
|
||||
{ "jr", 'R', 1, 8 },
|
||||
{ "jal", 'J', 1, 3 },
|
||||
{ "j", 'J', 1, 2 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static int mips_r (ut8 *b, int op, int rs, int rt, int rd, int sa, int fun) {
|
||||
if (rs == -1 || rt == -1) return -1;
|
||||
b[3] = ((op<<2)&0xfc) | ((rs>>3)&3);
|
||||
b[2] = (rs<<5) | (rt&0x1f);
|
||||
b[1] = ((rd<<3)&0xff) | (sa>>2);
|
||||
b[0] = (fun&0x3f) | ((sa&3)<<5);
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int mips_i (ut8 *b, int op, int rs, int rt, int imm) {
|
||||
if (rs == -1 || rt == -1) return -1;
|
||||
b[3] = ((op<<2)&0xfc) | ((rs>>3)&3);
|
||||
b[2] = (rs<<5) | (rt);
|
||||
b[1] = (imm>>8) &0xff;
|
||||
b[0] = imm & 0xff;
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int mips_j (ut8 *b, int op, int addr) {
|
||||
addr /= 4;
|
||||
b[3] = ((op<<2)&0xfc) | ((addr>>24)&3);
|
||||
b[2] = (addr>>16)&0xff;
|
||||
b[1] = (addr>>8) &0xff;
|
||||
b[0] = addr & 0xff;
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int getreg (const char *p) {
|
||||
int n = (int) r_num_get (NULL, p);
|
||||
if (n==0) {
|
||||
if (strcmp (p, "0")) {
|
||||
for (n=0; regs[n]; n++) {
|
||||
if (!strcmp (p, regs[n]))
|
||||
return n;
|
||||
}
|
||||
} else n = -1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int mips_assemble(const char *str, ut64 pc, ut8 *out) {
|
||||
int i, hasp;
|
||||
char *s = strdup (str);
|
||||
char w0[32], w1[32], w2[32], w3[32];
|
||||
r_str_replace_char (s, ',', ' ');
|
||||
hasp = r_str_replace_char (s, '(', ' ');
|
||||
r_str_replace_char (s, ')', ' ');
|
||||
*out = 0;
|
||||
*w0=*w1=*w2=*w3=0;
|
||||
sscanf (s, "%31s", w0);
|
||||
if (*w0)
|
||||
for (i=0; ops[i].name; i++) {
|
||||
if (!strcmp (ops[i].name, w0)) {
|
||||
switch (ops[i].args) {
|
||||
case 1: sscanf (s, "%31s %31s", w0, w1); break;
|
||||
case 2: sscanf (s, "%31s %31s %31s", w0, w1, w2); break;
|
||||
case 3: sscanf (s, "%31s %31s %31s %31s", w0, w1, w2, w3); break;
|
||||
}
|
||||
if (hasp) {
|
||||
char tmp[32];
|
||||
strcpy (tmp, w2);
|
||||
strcpy (w2, w3);
|
||||
strcpy (w3, tmp);
|
||||
}
|
||||
switch (ops[i].type) {
|
||||
case 'N': // nop
|
||||
memset (out, 0, 4);
|
||||
break;
|
||||
case 'R':
|
||||
switch (ops[i].args) {
|
||||
case 1: return mips_r (out, 0, getreg (w1), getreg (w2), getreg (w3), 0, ops[i].n);
|
||||
case 2: return mips_i (out, ops[i].n, 0, getreg (w1), getreg (w2)); break;
|
||||
case 3: return mips_i (out, ops[i].n, getreg (w1), getreg (w2), getreg (w3)); break;
|
||||
}
|
||||
break;
|
||||
case 'I':
|
||||
switch (ops[i].args) {
|
||||
case 2: return mips_i (out, ops[i].n, 0, getreg (w1), getreg (w2)); break;
|
||||
case 3: return mips_i (out, ops[i].n, getreg (w2), getreg (w1), getreg (w3)); break;
|
||||
}
|
||||
break;
|
||||
case 'J':
|
||||
switch (ops[i].args) {
|
||||
case 1: return mips_j (out, ops[i].n, getreg (w1)); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
free (s);
|
||||
return -1;
|
||||
}
|
@ -356,7 +356,7 @@ R_API char* r_str_replace(char *str, const char *key, const char *val, int g);
|
||||
R_API void r_str_cpy(char *dst, const char *src);
|
||||
R_API int r_str_bits (char *strout, const ut8 *buf, int len, const char *bitz);
|
||||
R_API int r_str_rwx(const char *str);
|
||||
R_API void r_str_replace_char (char *s, int a, int b);
|
||||
R_API int r_str_replace_char (char *s, int a, int b);
|
||||
R_API const char *r_str_rwx_i(int rwx);
|
||||
R_API void r_str_writef(int fd, const char *fmt, ...);
|
||||
R_API char **r_str_argv(const char *str, int *_argc);
|
||||
|
@ -69,12 +69,14 @@ main () {
|
||||
}
|
||||
#endif
|
||||
|
||||
R_API void r_str_replace_char (char *s, int a, int b) {
|
||||
R_API int r_str_replace_char (char *s, int a, int b) {
|
||||
int ret = 0;
|
||||
char *o = s;
|
||||
for (; *o; s++, o++) {
|
||||
if (*o==a) {
|
||||
if (b) {
|
||||
*s = b;
|
||||
ret++;
|
||||
continue;
|
||||
}
|
||||
o++;
|
||||
@ -82,6 +84,7 @@ R_API void r_str_replace_char (char *s, int a, int b) {
|
||||
*s = *o;
|
||||
}
|
||||
*s = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO: do not use toupper.. must support modes to also append lowercase chars like in r1
|
||||
|
Loading…
x
Reference in New Issue
Block a user