mirror of
https://github.com/radareorg/radare2.git
synced 2024-10-07 02:23:58 +00:00
* 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:
parent
6e1653881d
commit
3c7610bd9f
1
TODO
1
TODO
@ -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 :(
|
||||
|
@ -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
|
@ -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,
|
||||
};
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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, ...);
|
||||
|
21
man/rarc2.1
21
man/rarc2.1
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user