Fix local var and assemble of LDR instructions in ARM eggs

This commit is contained in:
pancake 2015-09-02 00:58:39 +02:00
parent c8cb347a41
commit b321d7fd8c
4 changed files with 23 additions and 21 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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; j<nargs; j++) {
k = j*R_SZ;
r_egg_printf (egg, " ldr %s, [sp, #%c%d]\n", regs[j+1], k>0?'+':' ', 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, ..
}
}

View File

@ -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)));