예제 #1
0
static void emit_branch(REgg *egg, char *b, char *g, char *e, char *n, int sz, const char *dst) {
	char *p, str[64];
	char *arg = NULL;
	char *op = "beq";
	/* NOTE that jb/ja are inverted to fit cmp opcode */
	if (b) {
		*b = '\0';
		op = e?"bge":"bgt";
		arg = b+1;
	} else
	if (g) {
		*g = '\0';
		op = e?"ble":"blt";
		arg = g+1;
	}
	if (arg == NULL) {
		if (e) {
			arg = e+1;
			op = "bne";
		} else {
			arg = "0";
			op = n?"bne":"beq";
		}
	}

	if (*arg=='=') arg++; /* for <=, >=, ... */
	p = r_egg_mkvar (egg, str, arg, 0);
	r_egg_printf (egg, "  pop "R_AX"\n"); /* TODO: add support for more than one arg get arg0 */
	r_egg_printf (egg, "  cmp %s, "R_AX"\n", p);
	// if (context>0)
	r_egg_printf (egg, "  %s %s\n", op, dst);
}
예제 #2
0
파일: lang.c 프로젝트: bigos/radare2
static void rcc_pusharg(REgg *egg, char *str) {
	REggEmit *e = egg->emit;
	char buf[64], *p = r_egg_mkvar (egg, buf, str, 0);
	if (!p) return;
	// TODO: free (ctxpush[context]);
	ctxpush[context] = strdup (p); // INDEX IT WITH NARGS OR CONTEXT?!?
	nargs++;
	if (pushargs)
		e->push_arg (egg, varxs, nargs, p);
	//ctxpush[context+nbrackets] = strdup(str); // use nargs??? (in callname)
}
예제 #3
0
파일: emit_x86.c 프로젝트: AmesianX/radare2
static void emit_branch(REgg *egg, char *b, char *g, char *e, char *n, int sz, const char *dst) {
	char *p, str[64];
	char *arg = NULL;
	char *op = "jz";
	int signed_value = 1; // XXX: add support for signed/unsigned variables
	/* NOTE that jb/ja are inverted to fit cmp opcode */
	if (b) {
		*b = '\0';
		if (signed_value) {
			if (e) op = "jge";
			else op = "jg";
		} else {
			if (e) op = "jae";
			else op = "ja";
		}
		arg = b+1;
	} else
	if (g) {
		*g = '\0';
		if (signed_value) {
			if (e) op = "jle";
			else op = "jl";
		} else {
			if (e) op = "jbe";
			else op = "jb";
		}
		arg = g+1;
	}
	if (arg == NULL) {
		if (e) {
			arg = e+1;
			op = "jne";
		} else {
			arg = attsyntax? "$0": "0";
			if (n) op = "jnz";
			else op ="jz";
		}
	}

	if (*arg=='=') arg++; /* for <=, >=, ... */
	p = r_egg_mkvar (egg, str, arg, 0);
	if (attsyntax) {
		r_egg_printf (egg, "  pop %%"R_AX"\n"); /* TODO: add support for more than one arg get arg0 */
		r_egg_printf (egg, "  cmp%c %s, %%"R_AX"\n", sz, p);
	} else {
		r_egg_printf (egg, "  pop "R_AX"\n"); /* TODO: add support for more than one arg get arg0 */
		r_egg_printf (egg, "  cmp "R_AX", %s\n", p);
	}
	// if (context>0)
	free (p);
	r_egg_printf (egg, "  %s %s\n", op, dst);
}
예제 #4
0
파일: emit_x86.c 프로젝트: 0xroot/radare2
static void emit_string(REgg *egg, const char *dstvar, const char *str, int j) {
	char *p, *s, str2[64];
	int i, len, oj = j;

	len = strlen (str);
	s = malloc (len+4);
	memcpy (s, str, len);
	memset (s+len, 0, 4);

	for (i=4; i<=oj; i+=4) {
		/* XXX endian and 32/64bit issues */
		int *n = (int *)(s+i-4);
		p = r_egg_mkvar (egg, str2, dstvar, i);
		if (attsyntax) r_egg_printf (egg, "  movl $0x%x, %s\n", *n, p);
		else r_egg_printf (egg, "  mov %s, 0x%x\n", p, *n);
		j -= 4;
	}
	/* zero */
	p = r_egg_mkvar (egg, str2, dstvar, i);
	if (attsyntax) r_egg_printf (egg, "  movl $0, %s\n", p);
	else r_egg_printf (egg, "  mov %s, 0\n", p);

	/* store pointer */
	p = r_egg_mkvar (egg, str2, dstvar, j+4);
	if (attsyntax) r_egg_printf (egg, "  lea %s, %%"R_AX"\n", p);
	else r_egg_printf (egg, "  lea "R_AX", %s\n", p);
	p = r_egg_mkvar (egg, str2, dstvar, 0);
	if (attsyntax) r_egg_printf (egg, "  mov %%"R_AX", %s\n", p);
	else r_egg_printf (egg, "  mov %s, "R_AX"\n", p);
#if 0
	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 = r_egg_mkvar (egg, str2, dstvar, j);
		if (attsyntax) r_egg_printf (egg, "  movl $0x%x, %s\n", *n, p);
		else r_egg_printf (egg, "  mov %s, 0x%x\n", p, *n);
		j -= 4;
	}
	p = r_egg_mkvar (egg, str2, dstvar, oj);
	if (attsyntax) r_egg_printf (egg, "  lea %s, %%"R_AX"\n", p);
	else r_egg_printf (egg, "  lea "R_AX", %s\n", p);
	p = r_egg_mkvar (egg, str2, dstvar, 0);
	if (attsyntax) r_egg_printf (egg, "  mov %%"R_AX", %s\n", p);
	else r_egg_printf (egg, "  mov %s, "R_AX"\n", p);
#endif
	free (s);
}
예제 #5
0
static void emit_set_string(REgg *egg, const char *dstvar, const char *str, int j) {
	int rest, off = 0;
	off = strlen (str)+1;
	rest = (off%4);
	if (rest) rest = 4-rest;
	off += rest-8;
	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);
	{
		char str[32], *p = r_egg_mkvar (egg, str, dstvar, 0);
		//r_egg_printf (egg, "DSTVAR=%s --> %s\n", dstvar, p);
		r_egg_printf (egg, "  str r0, [%s]\n", p);
		free (p);
	}
}
예제 #6
0
R_API int r_egg_lang_parsechar(REgg *egg, char c) {
	REggEmit *e = egg->remit;
	char *ptr, str[64], *tmp_ptr = NULL;
	if (c=='\n') {
		line++;
		elem_n = 0;
	}
//eprintf ("CH  %c\n", c);
	/* comments */
	if (skipline) {
		if (c != '\n') {
			oc = c;
			return 0;
		}
		skipline = 0;
	}
	if (mode == DATA)
		return parsedatachar (egg, c);
	if (mode == INLINE)
		return parseinlinechar (egg, c);
	/* quotes */
	if (quoteline) {
		if (c != quoteline) {
			if (quotelinevar == 1) {
				if (c == '`') {
					elem[elem_n] = 0;
					elem_n = 0;
					tmp_ptr = r_egg_mkvar (egg, str, elem, 0);
					r_egg_printf (egg, "%s", tmp_ptr);
					free (tmp_ptr);
					quotelinevar = 0;
				} else elem[elem_n++] = c;
			} else {
				if (c == '`') {
					elem_n = 0;
					quotelinevar = 1;
				} else r_egg_printf (egg, "%c", c);
			}
			oc = c;
			return 0;
		} else {
			r_egg_printf (egg, "\n");
			quoteline = 0;
		}
	}

	if (commentmode) {
		if (c=='/' && oc == '*')
			commentmode = 0;
		oc = c;
		return 0;
	} else if (c=='*' && oc == '/')
		commentmode = 1;
	if (slurp) {
		if (slurp != '"' && c == slurpin)
			exit (eprintf (
				"%s:%d Nesting of expressions not yet supported\n",
				file, line));
		if (c == slurp && oc != '\\') {
			slurp = 0;
			elem[elem_n] = '\0';
			if (elem_n > 0)
				rcc_element (egg, elem);
			else e->frame (egg, 0);
			elem_n = 0;
		} else elem[elem_n++] = c;
		elem[elem_n] = '\0';
	} else {
		switch (c) {
		case ';':
			rcc_next (egg);
			break;
		case '"':
			slurp = '"';
			break;
		case '(':
			slurpin = '(';
			slurp = ')';
			break;
		case '{':
			if (CTX>0) {
			//	r_egg_printf (egg, " %s:\n", get_frame_label (0));
				r_egg_printf (egg, " __begin_%d_%d_%d:\n",
					nfunctions, CTX, nestedi[CTX]); //%s:\n", get_frame_label (0));
			}
			rcc_context (egg, 1);
			break;
		case '}':
			endframe = nested[CTX-1];
			if (endframe) {
				// XXX: use endframe[context]
				r_egg_printf (egg, "%s\n", endframe);
			//	R_FREE (endframe);
			}
			if (CTX>0) {
				if (nestede[CTX]) {
					r_egg_printf (egg, "%s:\n", nestede[CTX]);
					//nestede[CTX] = NULL;
				} else {
					r_egg_printf (egg, "  __end_%d_%d_%d:\n",
						nfunctions, CTX, nestedi[CTX-1]);
					//get_end_frame_label (egg));
				}
				nbrackets++;
			}
			rcc_context (egg, -1);
			if (CTX== 0) {
				nbrackets = 0;
				nfunctions++;
			}
			break;
		case ':':
			if (oc == '\n' || oc == '}')
				quoteline = '\n';
			else elem[elem_n++] = c;
			break;
		case '#':
			if (oc == '\n')
				skipline = 1;
			break;
		case '/':
			if (oc == '/')
				skipline = 1;
			else elem[elem_n++] = c;
			break;
		default:
			elem[elem_n++] = c;
		}
		if (slurp) {
			if (elem_n) {
				ptr = elem;
				elem[elem_n] = '\0';
				while (is_space (*ptr)) ptr++;
				rcc_fun (egg, ptr);
			}
			elem_n = 0;
		}
	}
	if (c!='\t' && c!=' ')
		oc = c;
	return 0;
}
예제 #7
0
/* TODO: split this function into several ones..quite long fun */
static void rcc_next(REgg *egg) {
	const char *ocn;
	REggEmit *e = egg->remit;
	char *str = NULL, *p, *ptr, buf[64];
	int i;

	if (setenviron) {
		elem[elem_n - 1] = 0;
		r_sys_setenv (setenviron, elem);
		R_FREE (setenviron);
		return;
	}
	if (includefile) {
		char *p, *q, *path;
		// TODO: add support for directories
		elem[elem_n-1] = 0;
		path = find_include (elem, includefile);
		if (!path) {
			eprintf ("Cannot find include file '%s'\n", elem);
			return;
		}
		free (includefile);
		includefile = NULL;
		rcc_reset_callname ();
		p = q = r_file_slurp (path, NULL);
		if (p) {
			int oline = ++line;
			elem[0] = 0; // TODO: this must be a separate function
			elem_n = 0;
			line = 0;
			for (; *p; p++)
				r_egg_lang_parsechar (egg, *p);
			free (q);
			line = oline;
		} else {
			eprintf ("Cannot find '%s'\n", path);
		}
		free (path);
		return;
	}
	docall = 1;
	if (callname) {
		if (!strcmp (callname, "goto")) {
			if (nargs != 1) {
				eprintf ("Invalid number of arguments for goto()\n");
				return;
			}
			e->jmp (egg, ctxpush[CTX], 0);
			rcc_reset_callname ();
			return;
		}
		if (!strcmp (callname, "break")) {
			e->trap (egg);
			rcc_reset_callname ();
			return;
		}
		ptr = strchr (callname, '=');
		if (ptr) {
			*ptr = '\0';
			//ocn = ptr+1; // what is the point of this?
		}
		ocn = skipspaces (callname);
		if (!ocn) return;
		str = r_egg_mkvar (egg, buf, ocn, 0);
		if (!str) {
			eprintf ("Cannot mkvar\n");
			return;
		}
		if (*ocn=='.')
			e->call (egg, str, 1);
		if (!strcmp (str, "while")) {
			char var[128];
			if (lastctxdelta >= 0)
				exit (eprintf ("ERROR: Unsupported while syntax\n"));
			sprintf (var, "__begin_%d_%d_%d\n", nfunctions, CTX, nestedi[CTX-1]);
			e->while_end (egg, var); //get_frame_label (1));
#if 0
			eprintf ("------------------------------------------ lastctx: %d\n", lastctxdelta);
			// TODO: the pushvar is required for the if(){}while(); constructions
			//char *pushvar = ctxpush[context+nbrackets-1];
			/* TODO: support to compare more than one expression (LOGICAL OR) */
			rcc_printf ("  pop %%eax\n");
			rcc_printf ("  cmp $0, %%eax\n"); // XXX MUST SUPPORT != 0 COMPARE HERE
			/* TODO : Simplify!! */
			//if (pushvar)
			//	printf("  push %s /* wihle push */\n", pushvar);
			if (lastctxdelta<0)
				rcc_printf ("  jnz %s\n", get_frame_label (1));
			else rcc_printf ("  jnz %s\n", get_frame_label (0));
			//if (pushvar)
			//	printf("  pop %%"R_AX" /* while pop */\n");
#endif
			nargs = 0;
		} else {
			for (i = 0; i < nsyscalls; i++) {
				if (!strcmp (str, syscalls[i].name)) {
					p = syscallbody;
					e->comment (egg, "set syscall args");
					e->syscall_args (egg, nargs);
					docall = 0;
					e->comment (egg, "syscall");
					r_egg_lang_parsechar (egg, '\n'); /* FIX parsing issue */
					if (p) {
						for (; *p; p++)
							r_egg_lang_parsechar (egg, *p);
					} else {
						char *q, *s = e->syscall (egg, nargs);
						if (s) {
							for (q=s; *q; q++)
								r_egg_lang_parsechar (egg, *q);
							free (s);
						} else eprintf ("Cannot get @syscall payload\n");
					}
					docall = 0;
					break;
				}
			}
			if (docall)
			for (i = 0; i < ninlines; i++) {
				if (!strcmp (str, inlines[i].name)) {
					p = inlines[i].body;
					docall = 0;
					e->comment (egg, "inline");
					r_egg_lang_parsechar (egg, '\n'); /* FIX parsing issue */
					for (; *p; p++)
						r_egg_lang_parsechar (egg, *p);
					docall = 0;
					break;
				}
			}
			if (docall) {
				e->comment (egg, "call in mode %d", mode);
				e->call (egg, str, 0);
			}
		}
		if (nargs > 0)
			e->restore_stack (egg, nargs*e->size);
		if (ocn) { // Used to call .var0()
			/* XXX: Probably buggy and wrong */
			*buf = 0;
			free (str);
			str = r_egg_mkvar (egg, buf, ocn, 0);
			if (*buf)
				e->get_result (egg, buf);
			//else { eprintf("external symbol %s\n", ocn); }
		}
		/* store result of call */
		if (dstvar) {
			if (mode != NAKED) {
				*buf = 0;
				free (str);
				str = r_egg_mkvar (egg, buf, dstvar, 0);
				if (*buf == 0)
					eprintf ("Cannot resolve variable '%s'\n", dstvar);
				else e->get_result (egg, buf);
			}
			R_FREE (dstvar);
		}
		rcc_reset_callname ();
	} else {
		int vs = 'l';
		char type, *eq, *ptr = elem;
		elem[elem_n] = '\0';
		ptr = (char*)skipspaces (ptr);
		if (*ptr) {
			eq = strchr (ptr, '=');
			if (eq) {
				char str2[64], *p, ch = *(eq-1);
				*eq = '\0';
				eq = (char*) skipspaces (eq+1);
				p = r_egg_mkvar (egg, str2, ptr, 0);
				vs = varsize;
				if (is_var (eq)) {
					eq = r_egg_mkvar (egg, buf, eq, 0);
					if (varxs=='*')
						e->load (egg, eq, varsize);
					else
					/* XXX this is a hack .. must be integrated with pusharg */
					if (varxs=='&')
						e->load_ptr (egg, eq);
					if (eq) {
						free (eq);
						eq = NULL;
					}
					type = ' ';
				} else type = '$';
				vs = 'l'; // XXX: add support for != 'l' size
				e->mathop (egg, ch, vs, type, eq, p);
				free(p);
			} else {
				if (!strcmp (ptr, "break")) { // handle 'break;'
					e->trap (egg);
					rcc_reset_callname ();
				} else {
					e->mathop (egg, '=', vs, '$', ptr, NULL);
				}
			}
		}
	}
	free (str);
}
예제 #8
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;
}
예제 #9
0
파일: emit_x86.c 프로젝트: AmesianX/radare2
static void emit_string(REgg *egg, const char *dstvar, const char *str, int j) {
	char *p, *s, str2[64];
	int i, len, oj = j;

	len = strlen (str);
	s = malloc (len+4);
	if (!s) return;
	memcpy (s, str, len);
	memset (s+len, 0, 4);

	/* XXX: Hack: Adjust offset in R_BP correctly for 64b addresses */
#define BPOFF R_SZ-4
#define M32(x) (unsigned int)((x) & 0xffffffff)
	/* XXX: Assumes sizeof(ut32) == 4 */
	for (i=4; i<=oj; i+=4) {
		/* XXX endian issues (non-portable asm) */
		ut32 *n = (ut32 *)(s+i-4);
		p = r_egg_mkvar (egg, str2, dstvar, i+BPOFF);
		if (attsyntax) r_egg_printf (egg, "  movl $0x%x, %s\n", M32(*n), p);
		else r_egg_printf (egg, "  mov %s, 0x%x\n", p, M32(*n));
		free (p);
		j -= 4;
	}
#undef M32

	/* zero */
	p = r_egg_mkvar (egg, str2, dstvar, i+BPOFF);
	if (attsyntax) r_egg_printf (egg, "  movl $0, %s\n", p);
	else r_egg_printf (egg, "  mov %s, 0\n", p);
	free (p);

	/* store pointer */
	p = r_egg_mkvar (egg, str2, dstvar, j+4+BPOFF);
	if (attsyntax) r_egg_printf (egg, "  lea %s, %%"R_AX"\n", p);
	else r_egg_printf (egg, "  lea "R_AX", %s\n", p);
	free (p);

	p = r_egg_mkvar (egg, str2, dstvar, 0);
	if (attsyntax) r_egg_printf (egg, "  mov %%"R_AX", %s\n", p);
	else r_egg_printf (egg, "  mov %s, "R_AX"\n", p);
	free (p);

#undef BPOFF
#if 0
	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 = r_egg_mkvar (egg, str2, dstvar, j);
		if (attsyntax) r_egg_printf (egg, "  movl $0x%x, %s\n", *n, p);
		else r_egg_printf (egg, "  mov %s, 0x%x\n", p, *n);
		j -= 4;
	}
	p = r_egg_mkvar (egg, str2, dstvar, oj);
	if (attsyntax) r_egg_printf (egg, "  lea %s, %%"R_AX"\n", p);
	else r_egg_printf (egg, "  lea "R_AX", %s\n", p);
	p = r_egg_mkvar (egg, str2, dstvar, 0);
	if (attsyntax) r_egg_printf (egg, "  mov %%"R_AX", %s\n", p);
	else r_egg_printf (egg, "  mov %s, "R_AX"\n", p);
#endif
	free (s);
}