예제 #1
0
파일: lang.c 프로젝트: tkzv/radare2
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;
	}
}
예제 #2
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;
}