mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-22 05:37:06 +00:00
* Many fixes in ARM assembler and rarc2 support for ARM
- Still not yet usable, but * Add .byte and .hex in r_asm as directives * Add test case for r_word api - Fix r_word_count() * Also handle .globl (and .global) to keep GAS compatibility - TODO: add .word .fill .align and others
This commit is contained in:
parent
45daf51358
commit
a9f8d52e59
@ -6,41 +6,31 @@
|
||||
#define EMIT_NAME emit_arm
|
||||
#define R_ARCH "arm"
|
||||
#define R_SZ 8
|
||||
#define R_SP "r14"
|
||||
#define R_BP "rbp" // XXX
|
||||
#define R_SP "sp"
|
||||
#define R_BP "fp"
|
||||
#define R_AX "r0"
|
||||
#define R_GP { "r0", "r1", "r2", "r3" }
|
||||
#define R_NGP 4
|
||||
|
||||
#define R_GP { "r0", "r1", "r2", "r3", "r4" }
|
||||
#define R_TMP "r9"
|
||||
#define R_NGP 5
|
||||
|
||||
// no attsyntax for arm
|
||||
static char *regs[] = R_GP;
|
||||
|
||||
static char *emit_syscall (int num) {
|
||||
if (attsyntax) return strdup (": mov $`.arg`, %"R_AX"\n: int $0x80\n");
|
||||
return strdup (": mov "R_AX", `.arg`\n: int 0x80\n");
|
||||
return strdup (": mov "R_AX", `.arg`\n: svc 0x8000\n");
|
||||
}
|
||||
|
||||
static void emit_frame (int sz) {
|
||||
if (sz>0) {
|
||||
if (attsyntax)
|
||||
rcc_printf (
|
||||
" push {lr}\n"
|
||||
" sub sp, sp, %d\n", sz);
|
||||
else rcc_printf ( // XXX
|
||||
" push "R_BP"\n"
|
||||
" mov "R_BP", "R_SP"\n"
|
||||
" sub "R_SP", %d\n", sz);
|
||||
}
|
||||
if (sz>0) rcc_printf (
|
||||
" push {fp,lr}\n"
|
||||
//" mov "R_BP", "R_SP"\n"
|
||||
" add fp, sp, 4\n" // huh?
|
||||
" sub sp, %d\n", sz); // 8, 16, ..
|
||||
}
|
||||
|
||||
static void emit_frame_end (int sz, int ctx) {
|
||||
if (sz>0) {
|
||||
if (attsyntax)
|
||||
rcc_printf (" add "R_SP", "R_SP", %d\n", sz);
|
||||
else rcc_printf (" add "R_SP", "R_SP", %d\n", sz);
|
||||
}
|
||||
if (ctx>0)
|
||||
rcc_puts (" pop {pc}\n");
|
||||
if (sz>0) rcc_printf (" add "R_SP", %d\n", sz);
|
||||
if (ctx>0) rcc_puts (" pop {fp,pc}\n");
|
||||
}
|
||||
|
||||
static void emit_comment(const char *fmt, ...) {
|
||||
@ -48,8 +38,7 @@ static void emit_comment(const char *fmt, ...) {
|
||||
char buf[1024];
|
||||
va_start (ap, fmt);
|
||||
vsnprintf (buf, sizeof (buf), fmt, ap);
|
||||
if (attsyntax) rcc_printf (" /* %s */\n", buf);
|
||||
else rcc_printf ("# %s\n", buf);
|
||||
rcc_printf ("# %s\n", buf);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
@ -61,116 +50,82 @@ static void emit_syscall_args(int nargs) {
|
||||
int j, k;
|
||||
for (j=0; j<nargs; j++) {
|
||||
k = j*R_SZ;
|
||||
if (attsyntax)
|
||||
rcc_printf (" ldr %s, ["R_SP", #%c%d]\n", regs[j+1], k>0?'+':' ', k);
|
||||
else
|
||||
rcc_printf (" ldr %s, ["R_SP", #%c%d]\n", regs[j+1], k>0?'+':' ', k);
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_set_string(const char *dstvar, const char *str, int j) {
|
||||
char *p, str2[64];
|
||||
int i, oj = j;
|
||||
for (i=0; i<oj; i+=4) {
|
||||
/* XXX endian and 32/64bit issues */
|
||||
int *n = (int *)(str+i);
|
||||
p = mk_var (str2, dstvar, j);
|
||||
if (attsyntax) rcc_printf (" movl $0x%x, %s\n", *n, p);
|
||||
else rcc_printf (" mov %s, 0x%x\n", p, *n);
|
||||
j -= 4;
|
||||
}
|
||||
p = mk_var (str2, dstvar, oj);
|
||||
if (attsyntax) rcc_printf (" lea %s, %%"R_AX"\n", p);
|
||||
else rcc_printf (" lea "R_AX", %s\n", p);
|
||||
p = mk_var(str2, dstvar, 0);
|
||||
if (attsyntax) rcc_printf (" mov %%"R_AX", %s\n", p);
|
||||
else rcc_printf (" mov %s, "R_AX"\n", p);
|
||||
int off = 0;
|
||||
// TODO: branch string+off
|
||||
off = strlen (str);
|
||||
off += (off%4);
|
||||
rcc_printf (" add pc, %d\n", off);
|
||||
// XXX: does not handle \n and so on.. must use r_util
|
||||
rcc_printf (".string \"%s\"\n", str);
|
||||
if (off%4) rcc_printf (".fill %d, 1, 0\n", (off%4));
|
||||
rcc_printf (" sub r0, pc, %d\n", off);
|
||||
}
|
||||
|
||||
static void emit_call(const char *str, int atr) {
|
||||
if (atr) {
|
||||
if (attsyntax) rcc_printf(" bl *%s\n", str);
|
||||
else rcc_printf(" bl [%s]\n", str);
|
||||
rcc_printf(" ldr r0, %s", str);
|
||||
rcc_printf(" blx r0\n");
|
||||
} else rcc_printf(" bl %s\n", str);
|
||||
}
|
||||
|
||||
static void emit_arg (int xs, int num, const char *str) {
|
||||
int d = atoi (str);
|
||||
if (!attsyntax && (*str=='$'))
|
||||
str = str +1;
|
||||
str++;
|
||||
switch (xs) {
|
||||
case 0:
|
||||
rcc_printf (" push {%s}\n", str);
|
||||
break;
|
||||
case '*':
|
||||
if (attsyntax) rcc_printf (" push (%s)\n", str);
|
||||
else rcc_printf (" push [%s]\n", str);
|
||||
rcc_printf (" push {%s}\n", str);
|
||||
break;
|
||||
case '&':
|
||||
if (attsyntax) {
|
||||
if (d != 0) rcc_printf (" addl $%d, %%"R_BP"\n", d);
|
||||
rcc_printf (" pushl %%"R_BP"\n");
|
||||
if (d != 0) rcc_printf (" subl $%d, %%"R_BP"\n", d);
|
||||
} else {
|
||||
if (d != 0) rcc_printf (" add "R_BP", %d\n", d);
|
||||
rcc_printf (" push "R_BP"\n");
|
||||
if (d != 0) rcc_printf (" sub "R_BP", %d\n", d);
|
||||
}
|
||||
if (d) rcc_printf (" add "R_BP", %d\n", d);
|
||||
rcc_printf (" push {"R_BP"}\n");
|
||||
if (d) rcc_printf (" sub "R_BP", %d\n", d);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_get_result(const char *ocn) {
|
||||
if (attsyntax) rcc_printf (" mov %%"R_AX", %s\n", ocn);
|
||||
else rcc_printf (" mov %s, "R_AX"\n", ocn);
|
||||
rcc_printf (" mov %s, r0\n", ocn);
|
||||
}
|
||||
|
||||
static void emit_restore_stack (int size) {
|
||||
if (attsyntax) rcc_printf(" add $%d, %%"R_SP" /* args */\n", size);
|
||||
else rcc_printf(" add "R_SP", %d\n", size);
|
||||
rcc_printf(" add sp, %d\n", size);
|
||||
}
|
||||
|
||||
static void emit_get_while_end (char *str, const char *ctxpush, const char *label) {
|
||||
if (attsyntax) sprintf (str, " push {%s}\n b %s /* ---- */\n", ctxpush, label);
|
||||
else sprintf (str, " push {%s}\n b %s\n", ctxpush, label);
|
||||
sprintf (str, " push {%s}\n b %s\n", ctxpush, label);
|
||||
}
|
||||
|
||||
static void emit_while_end (const char *labelback) {
|
||||
if (attsyntax) {
|
||||
rcc_printf (" pop %%"R_AX"\n");
|
||||
rcc_printf (" cmp $0, %%"R_AX"\n"); // XXX MUST SUPPORT != 0 COMPARE HERE
|
||||
rcc_printf (" beq %s\n", labelback);
|
||||
} else {
|
||||
rcc_printf (" pop "R_AX"\n");
|
||||
rcc_printf (" test "R_AX", "R_AX"\n"); // XXX MUST SUPPORT != 0 COMPARE HERE
|
||||
rcc_printf (" beq %s\n", labelback);
|
||||
}
|
||||
rcc_printf (" pop "R_AX"\n");
|
||||
rcc_printf (" cmp "R_AX", "R_AX"\n"); // XXX MUST SUPPORT != 0 COMPARE HERE
|
||||
rcc_printf (" beq %s\n", labelback);
|
||||
}
|
||||
|
||||
static void emit_get_var (int type, char *out, int idx) {
|
||||
if (attsyntax) {
|
||||
switch (type) {
|
||||
case 0: sprintf (out, "%d(%%"R_BP")", -idx); break; /* variable */
|
||||
case 1: sprintf(out, "%d(%%"R_SP")", idx); break; /* argument */
|
||||
}
|
||||
} else {
|
||||
switch (type) {
|
||||
case 0: sprintf (out, "dword ["R_BP"%c%d]", idx>0?' ':'+', -idx); break; /* variable */
|
||||
case 1: sprintf(out, "dword ["R_SP"%c%d]", idx>0?'+':' ', idx); break; /* argument */
|
||||
}
|
||||
switch (type) {
|
||||
case 0: sprintf (out, "fp,%c%d", idx>0?' ':'+', -idx); break; /* variable */
|
||||
case 1: sprintf (out, "sp,%c%d", idx>0?'+':' ', idx); break; /* argument */
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_trap () {
|
||||
rcc_printf (" int3\n");
|
||||
rcc_printf (" svc 3\n");
|
||||
}
|
||||
|
||||
static void emit_load_ptr(const char *dst) {
|
||||
int d = atoi (dst);
|
||||
eprintf ("HACK HACK HACK\n");
|
||||
// XXX: 32/64bit care
|
||||
if (attsyntax) rcc_printf (" leal %d(%%"R_BP"), %%"R_AX"\n", d);
|
||||
else rcc_printf (" leal "R_AX", dword ["R_BP"+%d]\n", d);
|
||||
rcc_printf (" ldr "R_AX", ["R_BP", %d]\n", d);
|
||||
//rcc_printf (" movl %%"R_BP", %%"R_AX"\n");
|
||||
//rcc_printf (" addl $%d, %%"R_AX"\n", d);
|
||||
}
|
||||
@ -178,28 +133,25 @@ static void emit_load_ptr(const char *dst) {
|
||||
static void emit_branch(char *b, char *g, char *e, char *n, int sz, const char *dst) {
|
||||
char *p, str[64];
|
||||
char *arg = NULL;
|
||||
char *op = "jz";
|
||||
char *op = "beq";
|
||||
/* NOTE that jb/ja are inverted to fit cmp opcode */
|
||||
if (b) {
|
||||
*b = '\0';
|
||||
if (e) op = "jae";
|
||||
else op = "ja";
|
||||
op = e?"bge":"bgt";
|
||||
arg = b+1;
|
||||
} else
|
||||
if (g) {
|
||||
*g = '\0';
|
||||
if (e) op = "jbe";
|
||||
else op = "jb";
|
||||
op = e?"ble":"blt";
|
||||
arg = g+1;
|
||||
}
|
||||
if (arg == NULL) {
|
||||
if (e) {
|
||||
arg = e+1;
|
||||
op = "jne";
|
||||
op = "bne";
|
||||
} else {
|
||||
arg = "$0";
|
||||
if (n) op = "jnz";
|
||||
else op ="jz";
|
||||
arg = "0";
|
||||
op = n?"bne":"beq";
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,40 +169,24 @@ static void emit_branch(char *b, char *g, char *e, char *n, int sz, const char *
|
||||
}
|
||||
|
||||
static void emit_load(const char *dst, int sz) {
|
||||
if (attsyntax) {
|
||||
switch (sz) {
|
||||
case 'l':
|
||||
rcc_printf (" movl %s, %%"R_AX"\n", dst);
|
||||
rcc_printf (" movl (%%"R_AX"), %%"R_AX"\n");
|
||||
case 'b':
|
||||
rcc_printf (" movl %s, %%"R_AX"\n", dst);
|
||||
rcc_printf (" movzb (%%"R_AX"), %%"R_AX"\n");
|
||||
break;
|
||||
default:
|
||||
// TODO: unhandled?!?
|
||||
rcc_printf (" mov%c %s, %%"R_AX"\n", sz, dst);
|
||||
rcc_printf (" mov%c (%%"R_AX"), %%"R_AX"\n", sz);
|
||||
}
|
||||
} else {
|
||||
switch (sz) {
|
||||
case 'l':
|
||||
rcc_printf (" mov "R_AX", %s\n", dst);
|
||||
rcc_printf (" mov "R_AX", ["R_AX"]\n");
|
||||
case 'b':
|
||||
rcc_printf (" mov "R_AX", %s\n", dst);
|
||||
rcc_printf (" movz "R_AX", ["R_AX"]\n");
|
||||
break;
|
||||
default:
|
||||
// TODO: unhandled?!?
|
||||
rcc_printf (" mov "R_AX", %s\n", dst);
|
||||
rcc_printf (" mov "R_AX", ["R_AX"]\n");
|
||||
}
|
||||
switch (sz) {
|
||||
case 'l':
|
||||
rcc_printf (" mov "R_AX", %s\n", dst);
|
||||
rcc_printf (" mov "R_AX", ["R_AX"]\n");
|
||||
case 'b':
|
||||
rcc_printf (" mov "R_AX", %s\n", dst);
|
||||
rcc_printf (" movz "R_AX", ["R_AX"]\n");
|
||||
break;
|
||||
default:
|
||||
// TODO: unhandled?!?
|
||||
rcc_printf (" mov "R_AX", %s\n", dst);
|
||||
rcc_printf (" mov "R_AX", ["R_AX"]\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_mathop(int ch, int vs, int type, const char *eq, const char *p) {
|
||||
char *op;
|
||||
switch(ch) {
|
||||
switch (ch) {
|
||||
case '^': op = "xor"; break;
|
||||
case '&': op = "and"; break;
|
||||
case '|': op = "or"; break;
|
||||
@ -260,20 +196,16 @@ static void emit_mathop(int ch, int vs, int type, const char *eq, const char *p)
|
||||
case '/': op = "div"; break;
|
||||
default: op = "mov"; break;
|
||||
}
|
||||
if (attsyntax) {
|
||||
if (eq == NULL) eq = "%"R_AX;
|
||||
if (p == NULL) p = "%"R_AX;
|
||||
rcc_printf (" %s%c %c%s, %s\n", op, vs, type, eq, p);
|
||||
} else {
|
||||
if (eq == NULL) eq = R_AX;
|
||||
if (p == NULL) p = R_AX;
|
||||
if (eq == NULL) eq = R_AX;
|
||||
if (p == NULL) p = R_AX;
|
||||
#if 0
|
||||
// TODO:
|
||||
eprintf ("TYPE = %c\n", type);
|
||||
eprintf (" %s%c %c%s, %s\n", op, vs, type, eq, p);
|
||||
eprintf (" %s %s, [%s]\n", op, p, eq);
|
||||
if (type == '*') rcc_printf (" %s %s, [%s]\n", op, p, eq);
|
||||
else rcc_printf (" %s %s, %s\n", op, p, eq);
|
||||
}
|
||||
eprintf ("TYPE = %c\n", type);
|
||||
eprintf (" %s%c %c%s, %s\n", op, vs, type, eq, p);
|
||||
eprintf (" %s %s, [%s]\n", op, p, eq);
|
||||
#endif
|
||||
if (type == '*') rcc_printf (" %s %s, [%s]\n", op, p, eq);
|
||||
else rcc_printf (" %s %s, %s\n", op, p, eq);
|
||||
}
|
||||
|
||||
static const char* emit_regs(int idx) {
|
||||
|
@ -760,7 +760,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
if (!once) {
|
||||
once++;
|
||||
if (!attsyntax)
|
||||
if (!attsyntax && (emit==&emit_x86 || emit==&emit_x64))
|
||||
rcc_printf (".intel_syntax noprefix\n");
|
||||
if (showmain) {
|
||||
emit->call ("main", 0);
|
||||
|
@ -24,11 +24,14 @@ enum {
|
||||
TYPE_TST = 2,
|
||||
TYPE_SWI = 3,
|
||||
TYPE_BRA = 4,
|
||||
TYPE_ARI = 5,
|
||||
TYPE_IMM = 6,
|
||||
TYPE_MEM = 7,
|
||||
TYPE_BRR = 5,
|
||||
TYPE_ARI = 6,
|
||||
TYPE_IMM = 7,
|
||||
TYPE_MEM = 8,
|
||||
};
|
||||
|
||||
// static const char *const arm_shift[] = {"lsl", "lsr", "asr", "ror"};
|
||||
|
||||
static ArmOp ops[] = {
|
||||
{ "adc", 0xa000, TYPE_ARI },
|
||||
{ "adcs", 0xb000, TYPE_ARI },
|
||||
@ -52,13 +55,18 @@ static ArmOp ops[] = {
|
||||
{ "ldr", 0x9000, TYPE_MEM },
|
||||
{ "str", 0x8000, TYPE_MEM },
|
||||
|
||||
{ "blx", 0x30ff2fe1, TYPE_BRA },
|
||||
{ "blx", 0x30ff2fe1, TYPE_BRR },
|
||||
{ "bx", 0x10ff2fe1, TYPE_BRR },
|
||||
|
||||
{ "bl", 0xb, TYPE_BRA },
|
||||
{ "bx", 0x10ff2fe1, TYPE_BRA },
|
||||
// bx/blx - to register, b, bne,.. justjust offset
|
||||
// 2220: e12fff1e bx lr
|
||||
// 2224: e12fff12 bx r2
|
||||
// 2228: e12fff13 bx r3
|
||||
|
||||
//{ "bx", 0xb, TYPE_BRA },
|
||||
{ "b", 0xa, TYPE_BRA },
|
||||
|
||||
|
||||
//{ "mov", 0x3, TYPE_MOV },
|
||||
//{ "mov", 0x0a3, TYPE_MOV },
|
||||
{ "mov", 0xa001, TYPE_MOV },
|
||||
@ -80,11 +88,13 @@ static ArmOp ops[] = {
|
||||
};
|
||||
|
||||
static int getnum(const char *str) {
|
||||
while (str&&(*str=='$'||*str=='#'))
|
||||
if (!str)
|
||||
return 0;
|
||||
while (*str=='$'||*str=='#')
|
||||
str++;
|
||||
if (*str=='0'&&str[1]=='x') {
|
||||
int x;
|
||||
if(sscanf(str+2, "%x", &x))
|
||||
if (sscanf (str+2, "%x", &x))
|
||||
return x;
|
||||
}
|
||||
return atoi(str);
|
||||
@ -98,7 +108,7 @@ static char *getrange(char *s) {
|
||||
*p=0;
|
||||
}
|
||||
if (*s=='[' || *s==']')
|
||||
strcpy(s, s+1);
|
||||
strcpy (s, s+1);
|
||||
if (*s=='}')
|
||||
*s=0;
|
||||
s++;
|
||||
@ -108,28 +118,21 @@ static char *getrange(char *s) {
|
||||
}
|
||||
|
||||
static int getreg(const char *str) {
|
||||
int i;
|
||||
const char *aliases[] = { "sl", "fp", "ip", "sp", "lr", "pc", NULL };
|
||||
if (!str)
|
||||
return -1;
|
||||
if (*str=='r')
|
||||
return atoi (str+1);
|
||||
if (!strcmp(str, "pc"))
|
||||
return 15;
|
||||
if (!strcmp(str, "lr"))
|
||||
return 14;
|
||||
if (!strcmp(str, "sp"))
|
||||
return 13;
|
||||
if (!strcmp(str, "ip"))
|
||||
return 12;
|
||||
if (!strcmp(str, "fp"))
|
||||
return 11;
|
||||
if (!strcmp(str, "sl"))
|
||||
return 10;
|
||||
return -1; // XXX
|
||||
for(i=0;aliases[i];i++)
|
||||
if (!strcmp (str, aliases[i]))
|
||||
return 10+i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int getshift(const char *str) {
|
||||
if(!str) return 0;
|
||||
while (str&&*str&&!atoi(str))
|
||||
while (str&&*str&&!atoi (str))
|
||||
str++;
|
||||
return atoi(str)/2;
|
||||
}
|
||||
@ -162,8 +165,8 @@ static void arm_opcode_cond(ArmOpcode *ao, int delta) {
|
||||
};
|
||||
int i, cond = 14; // 'always' is default
|
||||
char *c = ao->op+delta;
|
||||
for(i=0;conds[i];i++) {
|
||||
if (!strcmp(c, conds[i])) {
|
||||
for (i=0;conds[i];i++) {
|
||||
if (!strcmp (c, conds[i])) {
|
||||
cond = i;
|
||||
break;
|
||||
}
|
||||
@ -191,7 +194,7 @@ static int arm_opcode_name(ArmOpcode *ao, const char *str) {
|
||||
ao->o |= (ret&0x0f)<<24;//(getreg(ao->a2)&0x0f);
|
||||
} else {
|
||||
ao->o |= (strstr(str,"],"))?4:5;
|
||||
ao->o |= (getnum(ao->a2)&0x7f)<<24; // delta
|
||||
ao->o |= (getnum (ao->a2)&0x7f)<<24; // delta
|
||||
}
|
||||
break;
|
||||
case TYPE_IMM:
|
||||
@ -207,40 +210,50 @@ static int arm_opcode_name(ArmOpcode *ao, const char *str) {
|
||||
} else ao->o |= getnum(ao->a0)<<24; // ???
|
||||
break;
|
||||
case TYPE_BRA:
|
||||
if ((ret = getreg(ao->a0)) != -1) {
|
||||
// XXX: Needs to calc (eip-off-8)>>2
|
||||
arm_opcode_cond(ao, strlen(ops[i].name));
|
||||
ao->o = (ao->o&0x70) | 0xb | (getnum(ao->a0)<<24);
|
||||
} else {
|
||||
if ((ret = getreg(ao->a0)) == -1) {
|
||||
// TODO: control if branch out of range
|
||||
ret = (getnum(ao->a0)-ao->off-8)/4;
|
||||
ao->o |= ((ret>>8)&0xff)<<16;
|
||||
ao->o |= ((ret)&0xff)<<24;
|
||||
} else {
|
||||
printf("This branch does not accept reg as arg\n");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case TYPE_BRR:
|
||||
if ((ret = getreg(ao->a0)) != -1) {
|
||||
ao->o |= (getreg (ao->a0)<<24);
|
||||
} else {
|
||||
printf("This branch does not accept off as arg\n");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case TYPE_SWI:
|
||||
ao->o |= getnum(ao->a0)<<24;
|
||||
ao->o |= (getnum (ao->a0)&0xff)<<24;
|
||||
ao->o |= ((getnum (ao->a0)>>8)&0xff)<<16;
|
||||
ao->o |= ((getnum (ao->a0)>>16)&0xff)<<8;
|
||||
break;
|
||||
case TYPE_ARI:
|
||||
if (!ao->a2) {
|
||||
ao->a2 = ao->a1;
|
||||
ao->a1 = ao->a0;
|
||||
}
|
||||
ao->o |= getreg(ao->a0)<<20;
|
||||
ao->o |= getreg(ao->a1)<<8;
|
||||
ret = getreg(ao->a2);
|
||||
ao->o |= getreg (ao->a0)<<20;
|
||||
ao->o |= getreg (ao->a1)<<8;
|
||||
ret = getreg (ao->a2);
|
||||
ao->o |= (ret!=-1)? ret<<24 : 2 | getnum(ao->a2)<<24;
|
||||
break;
|
||||
case TYPE_MOV:
|
||||
ao->o |= getreg(ao->a0)<<20;
|
||||
ret = getreg(ao->a1);
|
||||
ao->o |= getreg (ao->a0)<<20;
|
||||
ret = getreg (ao->a1);
|
||||
if (ret!=-1) ao->o |= ret<<24;
|
||||
else ao->o |= 0xa003 | getnum(ao->a1)<<24;
|
||||
else ao->o |= 0xa003 | getnum (ao->a1)<<24;
|
||||
break;
|
||||
case TYPE_TST:
|
||||
//ao->o |= getreg(ao->a0)<<20; // ???
|
||||
ao->o |= getreg(ao->a0)<<8;
|
||||
ao->o |= getreg(ao->a1)<<24;
|
||||
ao->o |= getshift(ao->a2)<<16; // shift
|
||||
ao->o |= getreg (ao->a0)<<8;
|
||||
ao->o |= getreg (ao->a1)<<24;
|
||||
ao->o |= getshift (ao->a2)<<16; // shift
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
@ -249,7 +262,6 @@ static int arm_opcode_name(ArmOpcode *ao, const char *str) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// XXX: check endian stuff
|
||||
int armass_assemble(const char *str, unsigned long off) {
|
||||
ArmOpcode aop = {0};
|
||||
aop.off = off;
|
||||
@ -265,10 +277,10 @@ int armass_assemble(const char *str, unsigned long off) {
|
||||
#ifdef MAIN
|
||||
void display(const char *str) {
|
||||
char cmd[32];
|
||||
int op = armass_assemble(str, 0x1000);
|
||||
printf("%08x %s\n", op, str);
|
||||
snprintf(cmd, sizeof(cmd), "rasm2 -d -a arm %08x", op);
|
||||
system(cmd);
|
||||
int op = armass_assemble (str, 0x1000);
|
||||
printf ("%08x %s\n", op, str);
|
||||
snprintf (cmd, sizeof(cmd), "rasm2 -d -a arm %08x", op);
|
||||
system (cmd);
|
||||
}
|
||||
|
||||
main() {
|
||||
@ -288,6 +300,7 @@ main() {
|
||||
display("bx pc");
|
||||
display("blx fp");
|
||||
display("pop {pc}");
|
||||
display("add lr, pc, lr");
|
||||
display("adds r3, #8");
|
||||
display("adds r3, r2, #8");
|
||||
display("subs r2, #1");
|
||||
@ -306,11 +319,20 @@ main() {
|
||||
display("str r1, [pc], 2");
|
||||
display("str r1, [pc, 3]");
|
||||
display("str r1, [pc, r4]");
|
||||
#endif
|
||||
display("b r3");
|
||||
display("bx r3");
|
||||
display("bcc 33");
|
||||
display("bne r3");
|
||||
display("blx r3");
|
||||
display("bne 0x1200");
|
||||
display("str r0, [r1]");
|
||||
#endif
|
||||
|
||||
//10ab4: 00047e30 andeq r7, r4, r0, lsr lr
|
||||
//10ab8: 00036e70 andeq r6, r3, r0, ror lr
|
||||
|
||||
display("andeq r7, r4, r0, lsr lr");
|
||||
display("andeq r6, r3, r0, ror lr");
|
||||
display("push {fp,lr}");
|
||||
display("pop {fp,lr}");
|
||||
|
||||
|
||||
#if 0
|
||||
@ -325,12 +347,3 @@ main() {
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
[pancake@dazo ~]$ rasm2 -o 0 -a arm -d 000080e5
|
||||
str r0, [r0]
|
||||
|
||||
[pancake@dazo ~]$ rasm2 -o 0 -a arm -d 000081e5
|
||||
str r0, [r1]
|
||||
|
||||
[pancake@dazo ~]$ rasm2 -o 0 -a arm -d 000081e5
|
||||
#endif
|
||||
|
@ -11,6 +11,11 @@
|
||||
static RAsmPlugin *asm_static_plugins[] =
|
||||
{ R_ASM_STATIC_PLUGINS };
|
||||
|
||||
static int r_asm_pseudo_align(struct r_asm_aop_t *aop, char *input) {
|
||||
eprintf ("TODO: .align\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int r_asm_pseudo_string(struct r_asm_aop_t *aop, char *input) {
|
||||
int len = strlen (input)+1;
|
||||
r_hex_bin2str ((ut8*)input, len, aop->buf_hex);
|
||||
@ -38,12 +43,34 @@ static inline int r_asm_pseudo_org(RAsm *a, char *input) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int r_asm_pseudo_byte(struct r_asm_aop_t *aop, char *input) {
|
||||
static inline int r_asm_pseudo_hex(struct r_asm_aop_t *aop, char *input) {
|
||||
int len = r_hex_str2bin (input, aop->buf);
|
||||
strncpy (aop->buf_hex, r_str_trim(input), R_ASM_BUFSIZE);
|
||||
strncpy (aop->buf_hex, r_str_trim (input), R_ASM_BUFSIZE);
|
||||
return len;
|
||||
}
|
||||
|
||||
// TODO: add .short, .word, .dword, ...
|
||||
static inline int r_asm_pseudo_byte(struct r_asm_aop_t *aop, char *input) {
|
||||
int i, len = 0;
|
||||
r_str_subchr (input, ',', ' ');
|
||||
len = r_str_word_count (input);
|
||||
r_str_word_set0 (input);
|
||||
for(i=0;i<len;i++) {
|
||||
char *word = r_str_word_get0 (input, i);
|
||||
int num = (int)r_num_math (NULL, word);
|
||||
aop->buf[i] = num;
|
||||
}
|
||||
r_hex_bin2str (aop->buf, len, aop->buf_hex);
|
||||
return len;
|
||||
}
|
||||
|
||||
static inline int r_asm_pseudo_fill(struct r_asm_aop_t *aop, char *input) {
|
||||
// repeat, size, value
|
||||
// TODO
|
||||
eprintf ("TODO: .fill\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
R_API RAsm *r_asm_new() {
|
||||
int i;
|
||||
RAsmPlugin *static_plugin;
|
||||
@ -53,8 +80,8 @@ R_API RAsm *r_asm_new() {
|
||||
a->cur = NULL;
|
||||
a->bits = 32;
|
||||
a->big_endian = 0;
|
||||
a->syntax = R_ASM_SYNTAX_INTEL;
|
||||
a->pc = 0;
|
||||
a->syntax = R_ASM_SYNTAX_INTEL;
|
||||
a->plugins = r_list_new ();
|
||||
for (i=0; asm_static_plugins[i]; i++) {
|
||||
static_plugin = R_NEW (RAsmPlugin);
|
||||
@ -67,7 +94,7 @@ R_API RAsm *r_asm_new() {
|
||||
|
||||
R_API void r_asm_free(RAsm *a) {
|
||||
// TODO: free plugins and so on
|
||||
free(a);
|
||||
free (a);
|
||||
}
|
||||
|
||||
/* return fastcall register argument 'idx' for a syscall with 'num' args */
|
||||
@ -220,18 +247,13 @@ R_API RAsmCode* r_asm_mdisassemble(RAsm *a, ut8 *buf, ut64 len) {
|
||||
eprintf ("error disassemble at offset %"PFMT64d"\n", idx);
|
||||
return r_asm_code_free (acode);
|
||||
}
|
||||
//eprintf ("++ %d %d\n", ret, aop.inst_len);
|
||||
//ret = aop.inst_len; // are always equal??
|
||||
slen += strlen (aop.buf_asm) + 2;
|
||||
if(!(acode->buf_asm = realloc (acode->buf_asm, slen)))
|
||||
return r_asm_code_free (acode);
|
||||
strcat (acode->buf_asm, aop.buf_asm);
|
||||
strcat (acode->buf_asm, "\n");
|
||||
//if (idx + ret < len)
|
||||
}
|
||||
|
||||
acode->len = idx;
|
||||
|
||||
return acode;
|
||||
}
|
||||
|
||||
@ -322,13 +344,19 @@ R_API RAsmCode* r_asm_massemble(RAsm *a, const char *buf) {
|
||||
a->syntax = R_ASM_SYNTAX_ATT;
|
||||
else if (!memcmp (ptr, ".string ", 8))
|
||||
ret = r_asm_pseudo_string (&aop, ptr+8);
|
||||
else if (!memcmp (ptr, ".align", 7))
|
||||
ret = r_asm_pseudo_align (&aop, ptr+7);
|
||||
else if (!memcmp (ptr, ".arch ", 6))
|
||||
ret = r_asm_pseudo_arch (a, ptr+6);
|
||||
else if (!memcmp (ptr, ".bits ", 6))
|
||||
ret = r_asm_pseudo_bits (a, ptr+6);
|
||||
else if (!memcmp (ptr, ".fill ", 6))
|
||||
ret = r_asm_pseudo_fill (&aop, ptr+6);
|
||||
else if (!memcmp (ptr, ".hex ", 5))
|
||||
ret = r_asm_pseudo_hex (&aop, ptr+5);
|
||||
else if (!memcmp (ptr, ".byte ", 6))
|
||||
ret = r_asm_pseudo_byte (&aop, ptr+6);
|
||||
else if (!memcmp (ptr, ".global ", 8)) {
|
||||
else if (!memcmp (ptr, ".glob", 5)) { // .global .globl
|
||||
// eprintf (".global directive not yet implemented\n");
|
||||
ret = 0;
|
||||
continue;
|
||||
|
@ -85,7 +85,7 @@ static int assemble(RAsm *a, RAsmAop *aop, const char *buf) {
|
||||
int op = armass_assemble(buf, a->pc);
|
||||
if (op==-1)
|
||||
return -1;
|
||||
r_mem_copyendian (aop->buf, &op, 4, a->big_endian);
|
||||
r_mem_copyendian (aop->buf, (void *)&op, 4, a->big_endian);
|
||||
return (a->bits/8);
|
||||
}
|
||||
|
||||
|
@ -152,9 +152,8 @@ R_API int r_str_word_count(const char *string) {
|
||||
for (word = 0; *text; word++) {
|
||||
for (;*text && !isseparator (*text); text++);
|
||||
for (tmp = text; *text && isseparator (*text); text++);
|
||||
if (tmp == text) word--;
|
||||
}
|
||||
return word-1;
|
||||
return word;
|
||||
}
|
||||
|
||||
R_API char *r_str_ichr(char *str, char chr) {
|
||||
|
@ -10,6 +10,7 @@ EFLAGS=../libr_util.a
|
||||
endif
|
||||
|
||||
BINS=test${EXT_EXE}
|
||||
BINS=set0${EXT_EXE}
|
||||
BINS+=rax2${EXT_EXE}
|
||||
BINS+=ralloc${EXT_EXE}
|
||||
BINS+=array${EXT_EXE}
|
||||
@ -28,6 +29,9 @@ ralloc${EXT_EXE}:
|
||||
test${EXT_EXE}:
|
||||
${CC} ${FLAGS} test.c ${EFLAGS} -o test${EXT_EXE}
|
||||
|
||||
set0${EXT_EXE}:
|
||||
${CC} ${FLAGS} set0.c ${EFLAGS} -o set0${EXT_EXE}
|
||||
|
||||
argv${EXT_EXE}:
|
||||
${CC} ${FLAGS} argv.c ${EFLAGS} -o argv${EXT_EXE}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* radare - LGPL - Copyright 2009 pancake<nopcode.org> */
|
||||
/* radare - LGPL - Copyright 2009-2010 pancake<nopcode.org> */
|
||||
#include "r_util.h"
|
||||
|
||||
int main() {
|
||||
|
17
libr/util/t/set0.c
Normal file
17
libr/util/t/set0.c
Normal file
@ -0,0 +1,17 @@
|
||||
#include <r_util.h>
|
||||
|
||||
void test(const char *s) {
|
||||
int n;
|
||||
printf("STR: %s\n", s);
|
||||
n = r_str_word_count(s);
|
||||
printf("NUM: %d\n", n);
|
||||
}
|
||||
|
||||
void main() {
|
||||
test("1");
|
||||
test("");
|
||||
test("1 2 3");
|
||||
test("1,2,3");
|
||||
test("1, 2, 3");
|
||||
test(" 1, 2, 3 ");
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user