From b321d7fd8c49d5e44619ae7c67dc54b65117c667 Mon Sep 17 00:00:00 2001 From: pancake Date: Wed, 2 Sep 2015 00:58:39 +0200 Subject: [PATCH] Fix local var and assemble of LDR instructions in ARM eggs --- libr/anal/p/anal_arm_cs.c | 2 +- libr/asm/arch/arm/armass.c | 2 +- libr/egg/emit_arm.c | 26 ++++++++++++++------------ libr/egg/lang.c | 14 +++++++------- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/libr/anal/p/anal_arm_cs.c b/libr/anal/p/anal_arm_cs.c index 5ce0cee109..daa05df555 100644 --- a/libr/anal/p/anal_arm_cs.c +++ b/libr/anal/p/anal_arm_cs.c @@ -623,7 +623,7 @@ jmp $$ + 4 + ( [delta] * 2 ) break; case ARM_INS_ADD: op->type = R_ANAL_OP_TYPE_ADD; - if (REGID(1)==ARM_REG_PC) { + if (REGID(1) == ARM_REG_PC) { op->ptr = addr + 8 + IMM(2); op->refptr = 0; } diff --git a/libr/asm/arch/arm/armass.c b/libr/asm/arch/arm/armass.c index e07019161b..1550949a31 100644 --- a/libr/asm/arch/arm/armass.c +++ b/libr/asm/arch/arm/armass.c @@ -698,7 +698,7 @@ static int arm_assemble(ArmOpcode *ao, const char *str) { getrange (ao->a[1]); getrange (ao->a[2]); ao->o |= getreg (ao->a[0])<<20; - ao->o |= getreg (ao->a[1])<<5; // delta + ao->o |= getreg (ao->a[1])<<8; // delta ret = getreg (ao->a[2]); if (ret != -1) { ao->o |= (strstr (str,"],"))?6:7; diff --git a/libr/egg/emit_arm.c b/libr/egg/emit_arm.c index 2f4de5a7ba..c907800919 100644 --- a/libr/egg/emit_arm.c +++ b/libr/egg/emit_arm.c @@ -31,11 +31,11 @@ static void emit_frame (REgg *egg, int sz) { if (sz>0) r_egg_printf (egg, //" mov "R_BP", "R_SP"\n" " add fp, sp, $4\n" // size of arguments - " sub sp, $%d\n", sz); // size of stackframe 8, 16, .. + " sub sp, %d\n", sz); // size of stackframe 8, 16, .. } static void emit_frame_end (REgg *egg, int sz, int ctx) { - if (sz>0) r_egg_printf (egg, " add sp, fp, $%d\n", sz); + if (sz>0) r_egg_printf (egg, " add sp, fp, %d\n", sz); if (ctx>0) r_egg_printf (egg, " pop {fp,pc}\n"); } @@ -49,14 +49,15 @@ static void emit_comment(REgg *egg, const char *fmt, ...) { } static void emit_equ (REgg *egg, const char *key, const char *value) { - r_egg_printf (egg, ".equ %s,%s\n", key, value); + r_egg_printf (egg, ".equ %s, %s\n", key, value); } static void emit_syscall_args(REgg *egg, int nargs) { int j, k; - for (j=0; j0?'+':' ', k); + for (j = 0; j < nargs; j++) { + k = j * R_SZ; + r_egg_printf (egg, " ldr %s, [sp, %d]\n", + regs[j+1], k?k+4:k+8); } } @@ -66,11 +67,11 @@ static void emit_set_string(REgg *egg, const char *dstvar, const char *str, int rest = (off%4); if (rest) rest = 4 - rest; off += rest - 4; - r_egg_printf (egg, " add pc, $%d\n", (off)); + r_egg_printf (egg, " add pc, %d\n", (off)); // XXX: does not handle \n and so on.. must use r_util r_egg_printf (egg, ".string \"%s\"\n", str); if (rest) r_egg_printf (egg, ".fill %d, 1, 0\n", (rest)); - r_egg_printf (egg, " sub r0, pc, $%d\n", off+16); + r_egg_printf (egg, " sub r0, pc, %d\n", off+16); { char str[32], *p = r_egg_mkvar (egg, str, dstvar, 0); //r_egg_printf (egg, "DSTVAR=%s --> %s\n", dstvar, p); @@ -112,8 +113,8 @@ static void emit_arg (REgg *egg, int xs, int num, const char *str) { strncpy (lastargs[num-1], str, sizeof(lastargs[0])-1); } else { if (!atoi (str)) eprintf ("WARNING: probably a bug?\n"); - r_egg_printf (egg, " mov r0, $%s\n", str); - snprintf (lastargs[num-1], sizeof (lastargs[0]), "fp, $-%d", 8+(num*4)); + r_egg_printf (egg, " mov r0, %s\n", str); + snprintf (lastargs[num-1], sizeof (lastargs[0]), "sp, %d", 8+(num*4)); r_egg_printf (egg, " str r0, [%s]\n", lastargs[num-1]); } break; @@ -150,8 +151,9 @@ static void emit_while_end (REgg *egg, const char *labelback) { static void emit_get_var (REgg *egg, int type, char *out, int idx) { switch (type) { - case 0: sprintf (out, "fp,$%d", -idx); break; /* variable */ - case 1: sprintf (out, "sp,$%d", idx); break; /* argument */ // XXX: MUST BE r0, r1, r2, .. + case 0: sprintf (out, "sp, %d", idx-1); break; /* variable */ + case 1: sprintf (out, "r%d", idx); break; /* registers */ +//sp,$%d", idx); break; /* argument */ // XXX: MUST BE r0, r1, r2, .. } } diff --git a/libr/egg/lang.c b/libr/egg/lang.c index 0fbd6fca36..2a585e2307 100644 --- a/libr/egg/lang.c +++ b/libr/egg/lang.c @@ -326,25 +326,25 @@ R_API char *r_egg_mkvar(REgg *egg, char *out, const char *_str, int delta) { qi = atoi (q+1); varsize = (qi==1)? 'b': 'l'; } else varsize='l'; - if (*str=='*'||*str=='&') { + if (*str == '*' || *str == '&') { varxs = *str; str++; } else varxs = 0; - if (str[0]=='.') { + if (str[0] == '.') { REggEmit *e = egg->remit; idx = atoi (str+4) + delta + e->size; - if (!memcmp (str+1, "ret", 3)) { + if (!strncmp (str+1, "ret", 3)) { strcpy (out, e->retvar); } else - if (!memcmp (str+1, "fix", 3)) { + if (!strncmp (str+1, "fix", 3)) { e->get_var (egg, 0, out, idx-stackfixed); //sprintf(out, "%d(%%"R_BP")", -(atoi(str+4)+delta+R_SZ-stackfixed)); } else - if (!memcmp (str+1, "var", 3)) { + if (!strncmp (str+1, "var", 3)) { e->get_var (egg, 0, out, idx); //sprintf(out, "%d(%%"R_BP")", -(atoi(str+4)+delta+R_SZ)); } else - if (!memcmp (str+1, "arg", 3)) { + if (!strncmp (str+1, "arg", 3)) { if (str[4]) { if (stackframe == 0) { e->get_var (egg, 1, out, 4); //idx-4); @@ -363,7 +363,7 @@ R_API char *r_egg_mkvar(REgg *egg, char *out, const char *_str, int delta) { } else eprintf ("NO CALLNAME '%s'\n", callname); } } else - if (!memcmp (str+1, "reg", 3)) { + if (!strncmp (str+1, "reg", 3)) { // XXX: can overflow if out is small if (attsyntax) snprintf (out, 32, "%%%s", e->regs (egg, atoi (str+4)));