static void rcc_element(REgg *egg, char *str) { REggEmit *e = egg->remit; char *p = strrchr (str, ','); int num, num2; if (CTX) { nargs = 0; if (mode == GOTO) mode = NORMAL; // XXX while (p) { *p = '\0'; p = (char *)skipspaces (p+1); rcc_pusharg (egg, p); p = strrchr (str, ','); } if (callname) rcc_pusharg (egg, str); else if (mode == NORMAL) { if (!atoi (str)) { if (dstvar == NULL) /* return string */ dstvar = strdup (".fix0"); rcc_pushstr (egg, str, 1); } } } else { switch (mode) { case ALIAS: e->equ (egg, dstvar, str); R_FREE (dstvar); mode = NORMAL; break; case SYSCALL: syscalls[nsyscalls].name = strdup (dstvar); syscalls[nsyscalls].arg = strdup (str); nsyscalls++; R_FREE (dstvar); break; case GOTO: elem[elem_n] = 0; e->jmp (egg, elem, 0); break; default: p = strchr (str, ','); if (p) { *p='\0'; num2 = atoi (p+1); } else num2 = 0; num = atoi (str) + num2; stackframe = num; stackfixed = num2; if (mode != NAKED) e->frame (egg, stackframe+stackfixed); } elem[0] = 0; elem_n = 0; } }
R_API char *r_egg_mkvar(REgg *egg, char *out, const char *_str, int delta) { int i, idx, len, qi; char *oldstr = NULL, *str = NULL, foo[32], *q, *ret = NULL; delta += stackfixed; // XXX can be problematic if (!_str) return NULL; /* fix segfault, but not badparsing */ /* XXX memory leak */ ret = str = oldstr = strdup (skipspaces (_str)); //if (num || str[0]=='0') { sprintf(out, "$%d", num); ret = out; } if ( (q = strchr (str, ':')) ) { *q = '\0'; qi = atoi (q+1); varsize = (qi==1)? 'b': 'l'; } else varsize='l'; if (*str == '*' || *str == '&') { varxs = *str; str++; } else varxs = 0; if (str[0] == '.') { REggEmit *e = egg->remit; idx = atoi (str+4) + delta + e->size; if (!strncmp (str+1, "ret", 3)) { strcpy (out, e->retvar); } else 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 (!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 (!strncmp (str+1, "arg", 3)) { if (str[4]) { if (stackframe == 0) { e->get_var (egg, 1, out, 4); //idx-4); } else { e->get_var (egg, 2, out, idx+4); } } else { /* TODO: return size of syscall */ if (callname) { for (i=0; i<nsyscalls; i++) if (!strcmp (syscalls[i].name, callname)) { free (oldstr); return strdup(syscalls[i].arg); } eprintf ("Unknown arg for syscall '%s'\n", callname); } else eprintf ("NO CALLNAME '%s'\n", callname); } } else 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))); else snprintf (out, 32, "%s", e->regs (egg, atoi (str+4))); } else { out = str; /* TODO: show error, invalid var name? */ eprintf ("Something is really wrong\n"); } ret = strdup(out); free (oldstr); } else if (*str=='"' || *str=='\'') { int mustfilter = *str=='"'; /* TODO: check for room in stackfixed area */ str++; len = strlen (str)-1; if (!stackfixed || stackfixed <len) eprintf ("WARNING: No room in the static stackframe! (%d must be %d)\n", stackfixed, len); str[len]='\0'; snprintf (foo, sizeof (foo)-1, ".fix%d", nargs*16); /* XXX FIX DELTA !!!1 */ free(dstvar); dstvar = strdup (skipspaces (foo)); rcc_pushstr (egg, str, mustfilter); ret = r_egg_mkvar (egg, out, foo, 0); free (oldstr); } return ret; }