* Some enhacements for rarc2.

- Add -s flag to use att syntax instead of intel one
  - Flag -A is the new -a (show selected arch)
  - Some more work on the arm code generation backend
  - Simplify some code (-58LOC)
  - Finish manpage rarc2(1)
This commit is contained in:
pancake 2010-06-29 16:50:15 +02:00
parent 6e1653881d
commit 3c7610bd9f
8 changed files with 314 additions and 369 deletions

1
TODO
View File

@ -27,7 +27,6 @@ Bugs:
TODO:
-----
* rarc2 : choose syntax in runtime
* nibble: trace counts after step..thats not correct!
* implement grep{col,row}
* nibble: mach0 new binary format is not supported by bin_mach0 :(

View File

@ -1,4 +0,0 @@
* specify syntax and arch with envvars or args
* Add support for rasm2
* Add preprocessing support to compile 32/64 bit specific code.. or OS-dependent
* Rename to r_rcc

View File

@ -1,4 +1,4 @@
/* TODO */
// TODO: The arm support is not done. only few callbacks
/* pancake // nopcode.org 2010 -- emit module for rcc */
#include "rarc2.h"
@ -12,43 +12,35 @@
#define R_GP { "r0", "r1", "r2", "r3" }
#define R_NGP 4
static char *regs[] = R_GP;
#if 0
static void emit_sc (int num) {
#if SYNTAX_ATT
rcc_printf (" sc $0x%x\n", num);
#else
rcc_printf (" sc 0x%x\n", num);
#endif
static char *emit_syscall (int num) {
if (attsyntax) return strdup (": mov $`.arg`, %"R_AX"\n: int $0x80\n");
return strdup (": mov "R_AX", `.arg`\n: int 0x80\n");
}
#endif
static void emit_frame (int sz) {
if (sz>0) rcc_printf (
#if SYNTAX_ATT
" push %%"R_BP"\n"
" mov %%"R_SP", %%"R_BP"\n"
" sub $%d, %%"R_SP"\n", sz);
#else
" push "R_BP"\n"
" mov "R_BP", "R_SP"\n"
" sub "R_SP", %d\n", sz);
#endif
if (sz>0) {
if (attsyntax)
rcc_printf (
" push {lr}\n"
" sub sp, sp, %d\n", sz);
else rcc_printf ( // XXX
" push "R_BP"\n"
" mov "R_BP", "R_SP"\n"
" sub "R_SP", %d\n", sz);
}
}
static void emit_frame_end (int sz, int ctx) {
if (sz>0) {
#if SYNTAX_ATT
rcc_printf (" add $%d, %%"R_SP"\n", sz);
rcc_printf (" pop %%"R_BP"\n");
#else
rcc_printf (" add "R_SP", %d\n", sz);
rcc_printf (" pop "R_BP"\n");
#endif
if (attsyntax)
rcc_printf (" add "R_SP", "R_SP", %d\n", sz);
else rcc_printf (" add "R_SP", "R_SP", %d\n", sz);
}
if (ctx>0)
rcc_puts (" ret\n");
rcc_puts (" pop {pc}\n");
}
static void emit_comment(const char *fmt, ...) {
@ -56,11 +48,8 @@ static void emit_comment(const char *fmt, ...) {
char buf[1024];
va_start (ap, fmt);
vsnprintf (buf, sizeof (buf), fmt, ap);
#if SYNTAX_ATT
rcc_printf (" /* %s */\n", buf);
#else
rcc_printf ("# %s\n", buf);
#endif
if (attsyntax) rcc_printf (" /* %s */\n", buf);
else rcc_printf ("# %s\n", buf);
va_end (ap);
}
@ -72,11 +61,10 @@ static void emit_syscall_args(int nargs) {
int j, k;
for (j=0; j<nargs; j++) {
k = j*R_SZ;
#if SYNTAX_ATT
rcc_printf (" mov %d(%%"R_SP"), %%%s\n", k, regs[j+1]);
#else
rcc_printf (" mov %s, dword ["R_SP"%c%d]\n", regs[j+1], k>0?'+':' ', k);
#endif
if (attsyntax)
rcc_printf (" ldr %s, ["R_SP", #%c%d]\n", regs[j+1], k>0?'+':' ', k);
else
rcc_printf (" ldr %s, ["R_SP", #%c%d]\n", regs[j+1], k>0?'+':' ', k);
}
}
@ -87,112 +75,89 @@ static void emit_set_string(const char *dstvar, const char *str, int j) {
/* XXX endian and 32/64bit issues */
int *n = (int *)(str+i);
p = mk_var (str2, dstvar, j);
#if SYNTAX_ATT
rcc_printf (" movl $0x%x, %s\n", *n, p);
#else
rcc_printf (" mov %s, 0x%x\n", p, *n);
#endif
if (attsyntax) rcc_printf (" movl $0x%x, %s\n", *n, p);
else rcc_printf (" mov %s, 0x%x\n", p, *n);
j -= 4;
}
p = mk_var (str2, dstvar, oj);
#if SYNTAX_ATT
rcc_printf (" lea %s, %%"R_AX"\n", p);
#else
rcc_printf (" lea "R_AX", %s\n", p);
#endif
if (attsyntax) rcc_printf (" lea %s, %%"R_AX"\n", p);
else rcc_printf (" lea "R_AX", %s\n", p);
p = mk_var(str2, dstvar, 0);
#if SYNTAX_ATT
rcc_printf (" mov %%"R_AX", %s\n", p);
#else
rcc_printf (" mov %s, "R_AX"\n", p);
#endif
if (attsyntax) rcc_printf (" mov %%"R_AX", %s\n", p);
else rcc_printf (" mov %s, "R_AX"\n", p);
}
static void emit_call(const char *str, int atr) {
#if SYNTAX_ATT
if (atr) rcc_printf(" call *%s\n", str);
#else
if (atr) rcc_printf(" call [%s]\n", str);
#endif
else rcc_printf(" call %s\n", str);
if (atr) {
if (attsyntax) rcc_printf(" bl *%s\n", str);
else rcc_printf(" bl [%s]\n", str);
} else rcc_printf(" bl %s\n", str);
}
static void emit_arg (int xs, int num, const char *str) {
int d = atoi (str);
#if !SYNTAX_ATT
if (*str=='$')
if (!attsyntax && (*str=='$'))
str = str +1;
#endif
switch(xs) {
switch (xs) {
case 0:
rcc_printf (" push %s\n", str);
rcc_printf (" push {%s}\n", str);
break;
case '*':
#if SYNTAX_ATT
rcc_printf (" push (%s)\n", str);
#else
rcc_printf (" push [%s]\n", str);
#endif
if (attsyntax) rcc_printf (" push (%s)\n", str);
else rcc_printf (" push [%s]\n", str);
break;
case '&':
#if SYNTAX_ATT
if (d != 0) rcc_printf (" addl $%d, %%"R_BP"\n", d);
rcc_printf (" pushl %%"R_BP"\n");
if (d != 0) rcc_printf (" subl $%d, %%"R_BP"\n", d);
#else
if (d != 0) rcc_printf (" add "R_BP", %d\n", d);
rcc_printf (" push "R_BP"\n");
if (d != 0) rcc_printf (" sub "R_BP", %d\n", d);
#endif
if (attsyntax) {
if (d != 0) rcc_printf (" addl $%d, %%"R_BP"\n", d);
rcc_printf (" pushl %%"R_BP"\n");
if (d != 0) rcc_printf (" subl $%d, %%"R_BP"\n", d);
} else {
if (d != 0) rcc_printf (" add "R_BP", %d\n", d);
rcc_printf (" push "R_BP"\n");
if (d != 0) rcc_printf (" sub "R_BP", %d\n", d);
}
break;
}
}
static void emit_get_result(const char *ocn) {
#if SYNTAX_ATT
rcc_printf (" mov %%"R_AX", %s\n", ocn);
#else
rcc_printf (" mov %s, "R_AX"\n", ocn);
#endif
if (attsyntax) rcc_printf (" mov %%"R_AX", %s\n", ocn);
else rcc_printf (" mov %s, "R_AX"\n", ocn);
}
static void emit_restore_stack (int size) {
#if SYNTAX_ATT
rcc_printf(" add $%d, %%"R_SP" /* args */\n", size);
#else
rcc_printf(" add "R_SP", %d\n", size);
#endif
if (attsyntax) rcc_printf(" add $%d, %%"R_SP" /* args */\n", size);
else rcc_printf(" add "R_SP", %d\n", size);
}
static void emit_get_while_end (char *str, const char *ctxpush, const char *label) {
#if SYNTAX_ATT
sprintf (str, " push %s\n jmp %s /* ---- */\n", ctxpush, label);
#else
sprintf (str, " push %s\n jmp %s\n", ctxpush, label);
#endif
if (attsyntax) sprintf (str, " push {%s}\n b %s /* ---- */\n", ctxpush, label);
else sprintf (str, " push {%s}\n b %s\n", ctxpush, label);
}
static void emit_while_end (const char *labelback) {
#if SYNTAX_ATT
rcc_printf (" pop %%"R_AX"\n");
rcc_printf (" cmp $0, %%"R_AX"\n"); // XXX MUST SUPPORT != 0 COMPARE HERE
rcc_printf (" bne %s\n", labelback);
#else
rcc_printf (" pop "R_AX"\n");
rcc_printf (" cmp "R_AX", $0\n"); // XXX MUST SUPPORT != 0 COMPARE HERE
rcc_printf (" bne %s\n", labelback);
#endif
if (attsyntax) {
rcc_printf (" pop %%"R_AX"\n");
rcc_printf (" cmp $0, %%"R_AX"\n"); // XXX MUST SUPPORT != 0 COMPARE HERE
rcc_printf (" beq %s\n", labelback);
} else {
rcc_printf (" pop "R_AX"\n");
rcc_printf (" test "R_AX", "R_AX"\n"); // XXX MUST SUPPORT != 0 COMPARE HERE
rcc_printf (" beq %s\n", labelback);
}
}
static void emit_get_var (int type, char *out, int idx) {
switch (type) {
#if SYNTAX_ATT
case 0: sprintf (out, "%d(%%"R_BP")", -idx); break; /* variable */
case 1: sprintf(out, "%d(%%"R_SP")", idx); break; /* argument */
#else
case 0: sprintf (out, "dword ["R_BP"%c%d]", idx>0?' ':'+', -idx); break; /* variable */
case 1: sprintf(out, "dword ["R_SP"%c%d]", idx>0?'+':' ', idx); break; /* argument */
#endif
if (attsyntax) {
switch (type) {
case 0: sprintf (out, "%d(%%"R_BP")", -idx); break; /* variable */
case 1: sprintf(out, "%d(%%"R_SP")", idx); break; /* argument */
}
} else {
switch (type) {
case 0: sprintf (out, "dword ["R_BP"%c%d]", idx>0?' ':'+', -idx); break; /* variable */
case 1: sprintf(out, "dword ["R_SP"%c%d]", idx>0?'+':' ', idx); break; /* argument */
}
}
}
@ -203,12 +168,9 @@ static void emit_trap () {
static void emit_load_ptr(const char *dst) {
int d = atoi (dst);
eprintf ("HACK HACK HACK\n");
#if SYNTAX_ATT
rcc_printf (" leal %d(%%"R_BP"), %%"R_AX"\n", d);
#else
// XXX: 32/64bit care
rcc_printf (" leal "R_AX", dword ["R_BP"+%d]\n", d);
#endif
if (attsyntax) rcc_printf (" leal %d(%%"R_BP"), %%"R_AX"\n", d);
else rcc_printf (" leal "R_AX", dword ["R_BP"+%d]\n", d);
//rcc_printf (" movl %%"R_BP", %%"R_AX"\n");
//rcc_printf (" addl $%d, %%"R_AX"\n", d);
}
@ -243,52 +205,52 @@ static void emit_branch(char *b, char *g, char *e, char *n, int sz, const char *
if (*arg=='=') arg++; /* for <=, >=, ... */
p = mk_var (str, arg, 0);
#if SYNTAX_ATT
rcc_printf (" pop %%"R_AX"\n"); /* TODO: add support for more than one arg get arg0 */
rcc_printf (" cmp%c %s, %%"R_AX"\n", sz, p);
#else
rcc_printf (" pop "R_AX"\n"); /* TODO: add support for more than one arg get arg0 */
rcc_printf (" cmp %s, "R_AX"\n", p);
#endif
if (attsyntax) {
rcc_printf (" pop %%"R_AX"\n"); /* TODO: add support for more than one arg get arg0 */
rcc_printf (" cmp%c %s, %%"R_AX"\n", sz, p);
} else {
rcc_printf (" pop "R_AX"\n"); /* TODO: add support for more than one arg get arg0 */
rcc_printf (" cmp %s, "R_AX"\n", p);
}
// if (context>0)
rcc_printf (" %s %s\n", op, dst);
}
static void emit_load(const char *dst, int sz) {
#if SYNTAX_ATT
switch (sz) {
case 'l':
rcc_printf (" movl %s, %%"R_AX"\n", dst);
rcc_printf (" movl (%%"R_AX"), %%"R_AX"\n");
case 'b':
rcc_printf (" movl %s, %%"R_AX"\n", dst);
rcc_printf (" movzb (%%"R_AX"), %%"R_AX"\n");
break;
default:
// TODO: unhandled?!?
rcc_printf (" mov%c %s, %%"R_AX"\n", sz, dst);
rcc_printf (" mov%c (%%"R_AX"), %%"R_AX"\n", sz);
if (attsyntax) {
switch (sz) {
case 'l':
rcc_printf (" movl %s, %%"R_AX"\n", dst);
rcc_printf (" movl (%%"R_AX"), %%"R_AX"\n");
case 'b':
rcc_printf (" movl %s, %%"R_AX"\n", dst);
rcc_printf (" movzb (%%"R_AX"), %%"R_AX"\n");
break;
default:
// TODO: unhandled?!?
rcc_printf (" mov%c %s, %%"R_AX"\n", sz, dst);
rcc_printf (" mov%c (%%"R_AX"), %%"R_AX"\n", sz);
}
} else {
switch (sz) {
case 'l':
rcc_printf (" mov "R_AX", %s\n", dst);
rcc_printf (" mov "R_AX", ["R_AX"]\n");
case 'b':
rcc_printf (" mov "R_AX", %s\n", dst);
rcc_printf (" movz "R_AX", ["R_AX"]\n");
break;
default:
// TODO: unhandled?!?
rcc_printf (" mov "R_AX", %s\n", dst);
rcc_printf (" mov "R_AX", ["R_AX"]\n");
}
}
#else
switch (sz) {
case 'l':
rcc_printf (" mov "R_AX", %s\n", dst);
rcc_printf (" mov "R_AX", ["R_AX"]\n");
case 'b':
rcc_printf (" mov "R_AX", %s\n", dst);
rcc_printf (" movz "R_AX", ["R_AX"]\n");
break;
default:
// TODO: unhandled?!?
rcc_printf (" mov "R_AX", %s\n", dst);
rcc_printf (" mov "R_AX", ["R_AX"]\n");
}
#endif
}
static void emit_mathop(int ch, int vs, int type, const char *eq, const char *p) {
char *op;
switch (ch) {
switch(ch) {
case '^': op = "xor"; break;
case '&': op = "and"; break;
case '|': op = "or"; break;
@ -298,21 +260,20 @@ static void emit_mathop(int ch, int vs, int type, const char *eq, const char *p)
case '/': op = "div"; break;
default: op = "mov"; break;
}
#if SYNTAX_ATT
if (eq == NULL) eq = "%"R_AX;
if (p == NULL) p = "%"R_AX;
rcc_printf (" %s%c %c%s, %s\n", op, vs, type, eq, p);
#else
if (eq == NULL) eq = R_AX;
if (p == NULL) p = R_AX;
// TODO:
eprintf ("TYPE = %c\n", type);
eprintf (" %s%c %c%s, %s\n", op, vs, type, eq, p);
eprintf (" %s %s, [%s]\n", op, p, eq);
if (type == '*') {
rcc_printf (" %s %s, [%s]\n", op, p, eq);
} else rcc_printf (" %s %s, %s\n", op, p, eq);
#endif
if (attsyntax) {
if (eq == NULL) eq = "%"R_AX;
if (p == NULL) p = "%"R_AX;
rcc_printf (" %s%c %c%s, %s\n", op, vs, type, eq, p);
} else {
if (eq == NULL) eq = R_AX;
if (p == NULL) p = R_AX;
// TODO:
eprintf ("TYPE = %c\n", type);
eprintf (" %s%c %c%s, %s\n", op, vs, type, eq, p);
eprintf (" %s %s, [%s]\n", op, p, eq);
if (type == '*') rcc_printf (" %s %s, [%s]\n", op, p, eq);
else rcc_printf (" %s %s, %s\n", op, p, eq);
}
}
static const char* emit_regs(int idx) {
@ -342,9 +303,5 @@ struct emit_t EMIT_NAME = {
.load = emit_load,
.load_ptr = emit_load_ptr,
.mathop = emit_mathop,
#if SYNTAX_ATT
.syscall_body = ": mov $`.arg`, %"R_AX"\n: int $0x80\n",
#else
.syscall_body = ": mov "R_AX", `.arg`\n: int 0x80\n",
#endif
.syscall = emit_syscall,
};

View File

@ -24,38 +24,34 @@
static char *regs[] = R_GP;
#if 0
static void emit_sc (int num) {
#if SYNTAX_ATT
rcc_printf (" int $0x%x\n", num);
#else
rcc_printf (" int 0x%x\n", num);
#endif
static char *emit_syscall (int num) {
if (attsyntax) return strdup (": mov $`.arg`, %"R_AX"\n: int $0x80\n");
return strdup (": mov "R_AX", `.arg`\n: int 0x80\n");
}
#endif
static void emit_frame (int sz) {
if (sz>0) rcc_printf (
#if SYNTAX_ATT
" push %%"R_BP"\n"
" mov %%"R_SP", %%"R_BP"\n"
" sub $%d, %%"R_SP"\n", sz);
#else
" push "R_BP"\n"
" mov "R_BP", "R_SP"\n"
" sub "R_SP", %d\n", sz);
#endif
if (sz>0) {
if (attsyntax)
rcc_printf (
" push %%"R_BP"\n"
" mov %%"R_SP", %%"R_BP"\n"
" sub $%d, %%"R_SP"\n", sz);
else rcc_printf (
" push "R_BP"\n"
" mov "R_BP", "R_SP"\n"
" sub "R_SP", %d\n", sz);
}
}
static void emit_frame_end (int sz, int ctx) {
if (sz>0) {
#if SYNTAX_ATT
rcc_printf (" add $%d, %%"R_SP"\n", sz);
rcc_printf (" pop %%"R_BP"\n");
#else
rcc_printf (" add "R_SP", %d\n", sz);
rcc_printf (" pop "R_BP"\n");
#endif
if (attsyntax) {
rcc_printf (" add $%d, %%"R_SP"\n", sz);
rcc_printf (" pop %%"R_BP"\n");
} else {
rcc_printf (" add "R_SP", %d\n", sz);
rcc_printf (" pop "R_BP"\n");
}
}
if (ctx>0)
rcc_puts (" ret\n");
@ -66,11 +62,8 @@ static void emit_comment(const char *fmt, ...) {
char buf[1024];
va_start (ap, fmt);
vsnprintf (buf, sizeof (buf), fmt, ap);
#if SYNTAX_ATT
rcc_printf (" /* %s */\n", buf);
#else
rcc_printf ("# %s\n", buf);
#endif
if (attsyntax) rcc_printf (" /* %s */\n", buf);
else rcc_printf ("# %s\n", buf);
va_end (ap);
}
@ -82,11 +75,10 @@ static void emit_syscall_args(int nargs) {
int j, k;
for (j=0; j<nargs; j++) {
k = j*R_SZ;
#if SYNTAX_ATT
if (attsyntax)
rcc_printf (" mov %d(%%"R_SP"), %%%s\n", k, regs[j+1]);
#else
else
rcc_printf (" mov %s, dword ["R_SP"%c%d]\n", regs[j+1], k>0?'+':' ', k);
#endif
}
}
@ -97,112 +89,89 @@ static void emit_set_string(const char *dstvar, const char *str, int j) {
/* XXX endian and 32/64bit issues */
int *n = (int *)(str+i);
p = mk_var (str2, dstvar, j);
#if SYNTAX_ATT
rcc_printf (" movl $0x%x, %s\n", *n, p);
#else
rcc_printf (" mov %s, 0x%x\n", p, *n);
#endif
if (attsyntax) rcc_printf (" movl $0x%x, %s\n", *n, p);
else rcc_printf (" mov %s, 0x%x\n", p, *n);
j -= 4;
}
p = mk_var (str2, dstvar, oj);
#if SYNTAX_ATT
rcc_printf (" lea %s, %%"R_AX"\n", p);
#else
rcc_printf (" lea "R_AX", %s\n", p);
#endif
if (attsyntax) rcc_printf (" lea %s, %%"R_AX"\n", p);
else rcc_printf (" lea "R_AX", %s\n", p);
p = mk_var(str2, dstvar, 0);
#if SYNTAX_ATT
rcc_printf (" mov %%"R_AX", %s\n", p);
#else
rcc_printf (" mov %s, "R_AX"\n", p);
#endif
if (attsyntax) rcc_printf (" mov %%"R_AX", %s\n", p);
else rcc_printf (" mov %s, "R_AX"\n", p);
}
static void emit_call(const char *str, int atr) {
#if SYNTAX_ATT
if (atr) rcc_printf(" call *%s\n", str);
#else
if (atr) rcc_printf(" call [%s]\n", str);
#endif
else rcc_printf(" call %s\n", str);
if (atr) {
if (attsyntax) rcc_printf(" call *%s\n", str);
else rcc_printf(" call [%s]\n", str);
} else rcc_printf(" call %s\n", str);
}
static void emit_arg (int xs, int num, const char *str) {
int d = atoi (str);
#if !SYNTAX_ATT
if (*str=='$')
if (!attsyntax && (*str=='$'))
str = str +1;
#endif
switch(xs) {
switch (xs) {
case 0:
rcc_printf (" push %s\n", str);
break;
case '*':
#if SYNTAX_ATT
rcc_printf (" push (%s)\n", str);
#else
rcc_printf (" push [%s]\n", str);
#endif
if (attsyntax) rcc_printf (" push (%s)\n", str);
else rcc_printf (" push [%s]\n", str);
break;
case '&':
#if SYNTAX_ATT
if (d != 0) rcc_printf (" addl $%d, %%"R_BP"\n", d);
rcc_printf (" pushl %%"R_BP"\n");
if (d != 0) rcc_printf (" subl $%d, %%"R_BP"\n", d);
#else
if (d != 0) rcc_printf (" add "R_BP", %d\n", d);
rcc_printf (" push "R_BP"\n");
if (d != 0) rcc_printf (" sub "R_BP", %d\n", d);
#endif
if (attsyntax) {
if (d != 0) rcc_printf (" addl $%d, %%"R_BP"\n", d);
rcc_printf (" pushl %%"R_BP"\n");
if (d != 0) rcc_printf (" subl $%d, %%"R_BP"\n", d);
} else {
if (d != 0) rcc_printf (" add "R_BP", %d\n", d);
rcc_printf (" push "R_BP"\n");
if (d != 0) rcc_printf (" sub "R_BP", %d\n", d);
}
break;
}
}
static void emit_get_result(const char *ocn) {
#if SYNTAX_ATT
rcc_printf (" mov %%"R_AX", %s\n", ocn);
#else
rcc_printf (" mov %s, "R_AX"\n", ocn);
#endif
if (attsyntax) rcc_printf (" mov %%"R_AX", %s\n", ocn);
else rcc_printf (" mov %s, "R_AX"\n", ocn);
}
static void emit_restore_stack (int size) {
#if SYNTAX_ATT
rcc_printf(" add $%d, %%"R_SP" /* args */\n", size);
#else
rcc_printf(" add "R_SP", %d\n", size);
#endif
if (attsyntax) rcc_printf(" add $%d, %%"R_SP" /* args */\n", size);
else rcc_printf(" add "R_SP", %d\n", size);
}
static void emit_get_while_end (char *str, const char *ctxpush, const char *label) {
#if SYNTAX_ATT
sprintf (str, " push %s\n jmp %s /* ---- */\n", ctxpush, label);
#else
sprintf (str, " push %s\n jmp %s\n", ctxpush, label);
#endif
if (attsyntax) sprintf (str, " push %s\n jmp %s /* ---- */\n", ctxpush, label);
else sprintf (str, " push %s\n jmp %s\n", ctxpush, label);
}
static void emit_while_end (const char *labelback) {
#if SYNTAX_ATT
rcc_printf (" pop %%"R_AX"\n");
rcc_printf (" cmp $0, %%"R_AX"\n"); // XXX MUST SUPPORT != 0 COMPARE HERE
rcc_printf (" jnz %s\n", labelback);
#else
rcc_printf (" pop "R_AX"\n");
rcc_printf (" test "R_AX", "R_AX"\n"); // XXX MUST SUPPORT != 0 COMPARE HERE
rcc_printf (" jnz %s\n", labelback);
#endif
if (attsyntax) {
rcc_printf (" pop %%"R_AX"\n");
rcc_printf (" cmp $0, %%"R_AX"\n"); // XXX MUST SUPPORT != 0 COMPARE HERE
rcc_printf (" jnz %s\n", labelback);
} else {
rcc_printf (" pop "R_AX"\n");
rcc_printf (" test "R_AX", "R_AX"\n"); // XXX MUST SUPPORT != 0 COMPARE HERE
rcc_printf (" jnz %s\n", labelback);
}
}
static void emit_get_var (int type, char *out, int idx) {
switch (type) {
#if SYNTAX_ATT
case 0: sprintf (out, "%d(%%"R_BP")", -idx); break; /* variable */
case 1: sprintf(out, "%d(%%"R_SP")", idx); break; /* argument */
#else
case 0: sprintf (out, "dword ["R_BP"%c%d]", idx>0?' ':'+', -idx); break; /* variable */
case 1: sprintf(out, "dword ["R_SP"%c%d]", idx>0?'+':' ', idx); break; /* argument */
#endif
if (attsyntax) {
switch (type) {
case 0: sprintf (out, "%d(%%"R_BP")", -idx); break; /* variable */
case 1: sprintf(out, "%d(%%"R_SP")", idx); break; /* argument */
}
} else {
switch (type) {
case 0: sprintf (out, "dword ["R_BP"%c%d]", idx>0?' ':'+', -idx); break; /* variable */
case 1: sprintf(out, "dword ["R_SP"%c%d]", idx>0?'+':' ', idx); break; /* argument */
}
}
}
@ -213,12 +182,9 @@ static void emit_trap () {
static void emit_load_ptr(const char *dst) {
int d = atoi (dst);
eprintf ("HACK HACK HACK\n");
#if SYNTAX_ATT
rcc_printf (" leal %d(%%"R_BP"), %%"R_AX"\n", d);
#else
// XXX: 32/64bit care
rcc_printf (" leal "R_AX", dword ["R_BP"+%d]\n", d);
#endif
if (attsyntax) rcc_printf (" leal %d(%%"R_BP"), %%"R_AX"\n", d);
else rcc_printf (" leal "R_AX", dword ["R_BP"+%d]\n", d);
//rcc_printf (" movl %%"R_BP", %%"R_AX"\n");
//rcc_printf (" addl $%d, %%"R_AX"\n", d);
}
@ -253,47 +219,47 @@ static void emit_branch(char *b, char *g, char *e, char *n, int sz, const char *
if (*arg=='=') arg++; /* for <=, >=, ... */
p = mk_var (str, arg, 0);
#if SYNTAX_ATT
rcc_printf (" pop %%"R_AX"\n"); /* TODO: add support for more than one arg get arg0 */
rcc_printf (" cmp%c %s, %%"R_AX"\n", sz, p);
#else
rcc_printf (" pop "R_AX"\n"); /* TODO: add support for more than one arg get arg0 */
rcc_printf (" cmp %s, "R_AX"\n", p);
#endif
if (attsyntax) {
rcc_printf (" pop %%"R_AX"\n"); /* TODO: add support for more than one arg get arg0 */
rcc_printf (" cmp%c %s, %%"R_AX"\n", sz, p);
} else {
rcc_printf (" pop "R_AX"\n"); /* TODO: add support for more than one arg get arg0 */
rcc_printf (" cmp %s, "R_AX"\n", p);
}
// if (context>0)
rcc_printf (" %s %s\n", op, dst);
}
static void emit_load(const char *dst, int sz) {
#if SYNTAX_ATT
switch (sz) {
case 'l':
rcc_printf (" movl %s, %%"R_AX"\n", dst);
rcc_printf (" movl (%%"R_AX"), %%"R_AX"\n");
case 'b':
rcc_printf (" movl %s, %%"R_AX"\n", dst);
rcc_printf (" movzb (%%"R_AX"), %%"R_AX"\n");
break;
default:
// TODO: unhandled?!?
rcc_printf (" mov%c %s, %%"R_AX"\n", sz, dst);
rcc_printf (" mov%c (%%"R_AX"), %%"R_AX"\n", sz);
if (attsyntax) {
switch (sz) {
case 'l':
rcc_printf (" movl %s, %%"R_AX"\n", dst);
rcc_printf (" movl (%%"R_AX"), %%"R_AX"\n");
case 'b':
rcc_printf (" movl %s, %%"R_AX"\n", dst);
rcc_printf (" movzb (%%"R_AX"), %%"R_AX"\n");
break;
default:
// TODO: unhandled?!?
rcc_printf (" mov%c %s, %%"R_AX"\n", sz, dst);
rcc_printf (" mov%c (%%"R_AX"), %%"R_AX"\n", sz);
}
} else {
switch (sz) {
case 'l':
rcc_printf (" mov "R_AX", %s\n", dst);
rcc_printf (" mov "R_AX", ["R_AX"]\n");
case 'b':
rcc_printf (" mov "R_AX", %s\n", dst);
rcc_printf (" movz "R_AX", ["R_AX"]\n");
break;
default:
// TODO: unhandled?!?
rcc_printf (" mov "R_AX", %s\n", dst);
rcc_printf (" mov "R_AX", ["R_AX"]\n");
}
}
#else
switch (sz) {
case 'l':
rcc_printf (" mov "R_AX", %s\n", dst);
rcc_printf (" mov "R_AX", ["R_AX"]\n");
case 'b':
rcc_printf (" mov "R_AX", %s\n", dst);
rcc_printf (" movz "R_AX", ["R_AX"]\n");
break;
default:
// TODO: unhandled?!?
rcc_printf (" mov "R_AX", %s\n", dst);
rcc_printf (" mov "R_AX", ["R_AX"]\n");
}
#endif
}
static void emit_mathop(int ch, int vs, int type, const char *eq, const char *p) {
@ -308,21 +274,20 @@ static void emit_mathop(int ch, int vs, int type, const char *eq, const char *p)
case '/': op = "div"; break;
default: op = "mov"; break;
}
#if SYNTAX_ATT
if (eq == NULL) eq = "%"R_AX;
if (p == NULL) p = "%"R_AX;
rcc_printf (" %s%c %c%s, %s\n", op, vs, type, eq, p);
#else
if (eq == NULL) eq = R_AX;
if (p == NULL) p = R_AX;
// TODO:
eprintf ("TYPE = %c\n", type);
eprintf (" %s%c %c%s, %s\n", op, vs, type, eq, p);
eprintf (" %s %s, [%s]\n", op, p, eq);
if (type == '*') {
rcc_printf (" %s %s, [%s]\n", op, p, eq);
} else rcc_printf (" %s %s, %s\n", op, p, eq);
#endif
if (attsyntax) {
if (eq == NULL) eq = "%"R_AX;
if (p == NULL) p = "%"R_AX;
rcc_printf (" %s%c %c%s, %s\n", op, vs, type, eq, p);
} else {
if (eq == NULL) eq = R_AX;
if (p == NULL) p = R_AX;
// TODO:
eprintf ("TYPE = %c\n", type);
eprintf (" %s%c %c%s, %s\n", op, vs, type, eq, p);
eprintf (" %s %s, [%s]\n", op, p, eq);
if (type == '*') rcc_printf (" %s %s, [%s]\n", op, p, eq);
else rcc_printf (" %s %s, %s\n", op, p, eq);
}
}
static const char* emit_regs(int idx) {
@ -352,9 +317,5 @@ struct emit_t EMIT_NAME = {
.load = emit_load,
.load_ptr = emit_load_ptr,
.mathop = emit_mathop,
#if SYNTAX_ATT
.syscall_body = ": mov $`.arg`, %"R_AX"\n: int $0x80\n",
#else
.syscall_body = ": mov "R_AX", `.arg`\n: int 0x80\n",
#endif
.syscall = emit_syscall,
};

View File

@ -1,14 +1,14 @@
#!/bin/sh
# pancake / nopcode.org
[ -z "${ARCH}" ] && ARCH=`rarc2 -a`
[ -z "${ARCH}" ] && ARCH=`rarc2 -A`
compile() {
spp -h 2>&1 >/dev/null
if [ $? = 0 ]; then
spp -Darch=${ARCH} $@ | rarc2 -${ARCH} > .a.S || exit $?
spp -Darch=${ARCH} $@ | rarc2 -s -${ARCH} > .a.S || exit $?
else
rarc2 -${ARCH} $@ > .a.S || exit $?
rarc2 -s -${ARCH} $@ > .a.S || exit $?
fi
}

View File

@ -35,6 +35,7 @@ static int slurpin = 0;
static int slurp = 0;
static int line = 1;
static char elem[1024];
int attsyntax = 0;
static int elem_n = 0;
static int context = 0;
static char *callname = NULL;
@ -54,12 +55,16 @@ static int mode = NORMAL;
extern struct emit_t emit_x86;
extern struct emit_t emit_x64;
struct emit_t *emits[3] = {
extern struct emit_t emit_arm;
struct emit_t *emits[4] = {
&emit_x86,
&emit_x64,
&emit_arm,
NULL
};
#if __i386__
#if __arm__
static struct emit_t *emit = &emit_arm;
#elif __i386__
static struct emit_t *emit = &emit_x86;
#else
static struct emit_t *emit = &emit_x64;
@ -689,37 +694,47 @@ static int parsechar(char c) {
static void showhelp() {
fprintf (stderr,
"Usage: r2rc [-alh] [files] > file.S\n"
" -a Show current architecture\n"
" -l List all supported architectures\n"
" -h Display this help\n"
" -x86 use x86-32\n"
" -x64 use x86-64\n");
" -A Show current architecture\n"
" -l List all supported architectures\n"
" -s use at&t syntax instead of intel\n"
" -h Display this help\n"
" -ax86 use x86-32\n"
" -ax64 use x86-64\n"
" -aarm use ARM\n");
}
static void parseflag(const char *arg) {
int i;
if (!strcmp (arg, "a")) {
printf ("%s\n", emit->arch);
} else
if (!strcmp (arg, "l")) {
for (i=0; emits[i]; i++)
printf ("%s\n", emits[i]->arch);
} else
if (!strcmp (arg, "h")) {
showhelp ();
} else {
switch (*arg) {
case 'a':
emit = NULL;
for (i=0; emits[i]; i++)
if (!strcmp (emits[i]->arch, arg)) {
if (!strcmp (emits[i]->arch, arg+1)) {
emit = emits[i];
syscallbody = strdup (emit->syscall_body);
syscallbody = emit->syscall ();
break;
}
if (emit == NULL)
eprintf ("Invalid architecture: '%s'\n", arg);
else return;
if (emit == NULL) {
eprintf ("Invalid architecture: '%s'\n", arg+1);
exit (1);
}
break;
case 's':
attsyntax = 1;
break;
case 'A':
printf ("%s\n", emit->arch);
exit (0);
case 'l':
for (i=0; emits[i]; i++)
printf ("%s\n", emits[i]->arch);
exit (0);
case 'h':
showhelp ();
exit (0);
default:
eprintf ("Unknown flag\n");
}
exit (0);
}
int main(int argc, char **argv) {

View File

@ -28,6 +28,7 @@ extern void rcc_printf(const char *fmt, ...);
extern void rcc_flush();
extern void rcc_init();
extern char *mk_var(char *out, const char *str, int delta);
extern int attsyntax;
/* emit */
typedef unsigned long long ut64;
@ -35,11 +36,12 @@ typedef unsigned long long ut64;
struct emit_t {
const char *arch;
int size; /* in bytes.. 32bit arch is 4, 64bit is 8 .. */
const char *syscall_body;
//const char *syscall_body;
const char* (*regs)(int idx);
void (*call)(const char *addr, int ptr);
//void (*sc)(int num);
void (*frame)(int sz);
char* (*syscall)();
void (*trap)();
void (*frame_end)(int sz, int ctx);
void (*comment)(const char *fmt, ...);

View File

@ -6,6 +6,10 @@
.Nd radare2 relocatable compiler
.Sh SYNOPSIS
.Nm rarc2
.Op -A
.Op -l
.Op -s
.Op -a[arch]
.Op < source
.Op > assembly
.Nm rarc2-tool
@ -18,7 +22,18 @@
This command is part of the radare project.
.Pp
This compiler parses a syntax-free language similar to C and generates assembly code for various architectures.
.Sh OPTIONS
.Pp
The benefit of using rarc2 instead of any other language is that the generated assembly code is designed to be minimal, position independent and easily injectable into processes or binaries.
.Sh OPTIONS for rarc2
.Bl -tag -width Fl
.It Fl a[arch]
Specify architecture to generate code for (x86, x64, arm)
.It Fl l
List all supported architectures
.It Fl s
Use AT&T syntax for assembly instead of the intel one
.El
.Sh OPTIONS for rarc2-tool
.Bl -tag -width Fl
.It Fl b
Dump bytes of compiled code
@ -32,14 +47,14 @@ Generate .S assembly file instead of executable
.Sh USAGE
.Pp
Using rarc2:
$ echo 'main(64){printf("hello world\n");}' | rarc2 > hello.S
$ echo 'main@global(,64){printf("hello world\\n");}' | rarc2 -s > hello.S
$ gcc hello.S
$ ./a.out
hello world
.Pp
Using rarc2-tool:
$ cat test.r
main(64){ printf("hello world\n"); }
main@global(,64){ printf("hello world\\n"); }
$ rarc2-tool -x test.r
hello world
.Sh SEE ALSO