* Many fixes in ARM assembler and rarc2 support for ARM

- Still not yet usable, but
* Add .byte and .hex in r_asm as directives
* Add test case for r_word api
  - Fix r_word_count()
* Also handle .globl (and .global) to keep GAS compatibility
  - TODO: add .word .fill .align and others
This commit is contained in:
pancake 2010-09-14 01:29:09 +02:00
parent 45daf51358
commit a9f8d52e59
9 changed files with 204 additions and 211 deletions

View File

@ -6,41 +6,31 @@
#define EMIT_NAME emit_arm
#define R_ARCH "arm"
#define R_SZ 8
#define R_SP "r14"
#define R_BP "rbp" // XXX
#define R_SP "sp"
#define R_BP "fp"
#define R_AX "r0"
#define R_GP { "r0", "r1", "r2", "r3" }
#define R_NGP 4
#define R_GP { "r0", "r1", "r2", "r3", "r4" }
#define R_TMP "r9"
#define R_NGP 5
// no attsyntax for arm
static char *regs[] = R_GP;
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");
return strdup (": mov "R_AX", `.arg`\n: svc 0x8000\n");
}
static void emit_frame (int sz) {
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);
}
if (sz>0) rcc_printf (
" push {fp,lr}\n"
//" mov "R_BP", "R_SP"\n"
" add fp, sp, 4\n" // huh?
" sub sp, %d\n", sz); // 8, 16, ..
}
static void emit_frame_end (int sz, int ctx) {
if (sz>0) {
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 (" pop {pc}\n");
if (sz>0) rcc_printf (" add "R_SP", %d\n", sz);
if (ctx>0) rcc_puts (" pop {fp,pc}\n");
}
static void emit_comment(const char *fmt, ...) {
@ -48,8 +38,7 @@ static void emit_comment(const char *fmt, ...) {
char buf[1024];
va_start (ap, fmt);
vsnprintf (buf, sizeof (buf), fmt, ap);
if (attsyntax) rcc_printf (" /* %s */\n", buf);
else rcc_printf ("# %s\n", buf);
rcc_printf ("# %s\n", buf);
va_end (ap);
}
@ -61,116 +50,82 @@ static void emit_syscall_args(int nargs) {
int j, k;
for (j=0; j<nargs; j++) {
k = j*R_SZ;
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);
}
}
static void emit_set_string(const char *dstvar, const char *str, int j) {
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 = mk_var (str2, dstvar, j);
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 (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 (attsyntax) rcc_printf (" mov %%"R_AX", %s\n", p);
else rcc_printf (" mov %s, "R_AX"\n", p);
int off = 0;
// TODO: branch string+off
off = strlen (str);
off += (off%4);
rcc_printf (" add pc, %d\n", off);
// XXX: does not handle \n and so on.. must use r_util
rcc_printf (".string \"%s\"\n", str);
if (off%4) rcc_printf (".fill %d, 1, 0\n", (off%4));
rcc_printf (" sub r0, pc, %d\n", off);
}
static void emit_call(const char *str, int atr) {
if (atr) {
if (attsyntax) rcc_printf(" bl *%s\n", str);
else rcc_printf(" bl [%s]\n", str);
rcc_printf(" ldr r0, %s", str);
rcc_printf(" blx r0\n");
} else rcc_printf(" bl %s\n", str);
}
static void emit_arg (int xs, int num, const char *str) {
int d = atoi (str);
if (!attsyntax && (*str=='$'))
str = str +1;
str++;
switch (xs) {
case 0:
rcc_printf (" push {%s}\n", str);
break;
case '*':
if (attsyntax) rcc_printf (" push (%s)\n", str);
else rcc_printf (" push [%s]\n", str);
rcc_printf (" push {%s}\n", str);
break;
case '&':
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);
}
if (d) rcc_printf (" add "R_BP", %d\n", d);
rcc_printf (" push {"R_BP"}\n");
if (d) rcc_printf (" sub "R_BP", %d\n", d);
break;
}
}
static void emit_get_result(const char *ocn) {
if (attsyntax) rcc_printf (" mov %%"R_AX", %s\n", ocn);
else rcc_printf (" mov %s, "R_AX"\n", ocn);
rcc_printf (" mov %s, r0\n", ocn);
}
static void emit_restore_stack (int size) {
if (attsyntax) rcc_printf(" add $%d, %%"R_SP" /* args */\n", size);
else rcc_printf(" add "R_SP", %d\n", size);
rcc_printf(" add sp, %d\n", size);
}
static void emit_get_while_end (char *str, const char *ctxpush, const char *label) {
if (attsyntax) sprintf (str, " push {%s}\n b %s /* ---- */\n", ctxpush, label);
else sprintf (str, " push {%s}\n b %s\n", ctxpush, label);
sprintf (str, " push {%s}\n b %s\n", ctxpush, label);
}
static void emit_while_end (const char *labelback) {
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);
}
rcc_printf (" pop "R_AX"\n");
rcc_printf (" cmp "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) {
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 */
}
switch (type) {
case 0: sprintf (out, "fp,%c%d", idx>0?' ':'+', -idx); break; /* variable */
case 1: sprintf (out, "sp,%c%d", idx>0?'+':' ', idx); break; /* argument */
}
}
static void emit_trap () {
rcc_printf (" int3\n");
rcc_printf (" svc 3\n");
}
static void emit_load_ptr(const char *dst) {
int d = atoi (dst);
eprintf ("HACK HACK HACK\n");
// XXX: 32/64bit care
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 (" ldr "R_AX", ["R_BP", %d]\n", d);
//rcc_printf (" movl %%"R_BP", %%"R_AX"\n");
//rcc_printf (" addl $%d, %%"R_AX"\n", d);
}
@ -178,28 +133,25 @@ static void emit_load_ptr(const char *dst) {
static void emit_branch(char *b, char *g, char *e, char *n, int sz, const char *dst) {
char *p, str[64];
char *arg = NULL;
char *op = "jz";
char *op = "beq";
/* NOTE that jb/ja are inverted to fit cmp opcode */
if (b) {
*b = '\0';
if (e) op = "jae";
else op = "ja";
op = e?"bge":"bgt";
arg = b+1;
} else
if (g) {
*g = '\0';
if (e) op = "jbe";
else op = "jb";
op = e?"ble":"blt";
arg = g+1;
}
if (arg == NULL) {
if (e) {
arg = e+1;
op = "jne";
op = "bne";
} else {
arg = "$0";
if (n) op = "jnz";
else op ="jz";
arg = "0";
op = n?"bne":"beq";
}
}
@ -217,40 +169,24 @@ static void emit_branch(char *b, char *g, char *e, char *n, int sz, const char *
}
static void emit_load(const char *dst, int 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");
}
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");
}
}
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;
@ -260,20 +196,16 @@ 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 (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;
if (eq == NULL) eq = R_AX;
if (p == NULL) p = R_AX;
#if 0
// 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);
}
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);
#endif
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) {

View File

@ -760,7 +760,7 @@ int main(int argc, char **argv) {
}
if (!once) {
once++;
if (!attsyntax)
if (!attsyntax && (emit==&emit_x86 || emit==&emit_x64))
rcc_printf (".intel_syntax noprefix\n");
if (showmain) {
emit->call ("main", 0);

View File

@ -24,11 +24,14 @@ enum {
TYPE_TST = 2,
TYPE_SWI = 3,
TYPE_BRA = 4,
TYPE_ARI = 5,
TYPE_IMM = 6,
TYPE_MEM = 7,
TYPE_BRR = 5,
TYPE_ARI = 6,
TYPE_IMM = 7,
TYPE_MEM = 8,
};
// static const char *const arm_shift[] = {"lsl", "lsr", "asr", "ror"};
static ArmOp ops[] = {
{ "adc", 0xa000, TYPE_ARI },
{ "adcs", 0xb000, TYPE_ARI },
@ -52,13 +55,18 @@ static ArmOp ops[] = {
{ "ldr", 0x9000, TYPE_MEM },
{ "str", 0x8000, TYPE_MEM },
{ "blx", 0x30ff2fe1, TYPE_BRA },
{ "blx", 0x30ff2fe1, TYPE_BRR },
{ "bx", 0x10ff2fe1, TYPE_BRR },
{ "bl", 0xb, TYPE_BRA },
{ "bx", 0x10ff2fe1, TYPE_BRA },
// bx/blx - to register, b, bne,.. justjust offset
// 2220: e12fff1e bx lr
// 2224: e12fff12 bx r2
// 2228: e12fff13 bx r3
//{ "bx", 0xb, TYPE_BRA },
{ "b", 0xa, TYPE_BRA },
//{ "mov", 0x3, TYPE_MOV },
//{ "mov", 0x0a3, TYPE_MOV },
{ "mov", 0xa001, TYPE_MOV },
@ -80,11 +88,13 @@ static ArmOp ops[] = {
};
static int getnum(const char *str) {
while (str&&(*str=='$'||*str=='#'))
if (!str)
return 0;
while (*str=='$'||*str=='#')
str++;
if (*str=='0'&&str[1]=='x') {
int x;
if(sscanf(str+2, "%x", &x))
if (sscanf (str+2, "%x", &x))
return x;
}
return atoi(str);
@ -98,7 +108,7 @@ static char *getrange(char *s) {
*p=0;
}
if (*s=='[' || *s==']')
strcpy(s, s+1);
strcpy (s, s+1);
if (*s=='}')
*s=0;
s++;
@ -108,28 +118,21 @@ static char *getrange(char *s) {
}
static int getreg(const char *str) {
int i;
const char *aliases[] = { "sl", "fp", "ip", "sp", "lr", "pc", NULL };
if (!str)
return -1;
if (*str=='r')
return atoi (str+1);
if (!strcmp(str, "pc"))
return 15;
if (!strcmp(str, "lr"))
return 14;
if (!strcmp(str, "sp"))
return 13;
if (!strcmp(str, "ip"))
return 12;
if (!strcmp(str, "fp"))
return 11;
if (!strcmp(str, "sl"))
return 10;
return -1; // XXX
for(i=0;aliases[i];i++)
if (!strcmp (str, aliases[i]))
return 10+i;
return -1;
}
static int getshift(const char *str) {
if(!str) return 0;
while (str&&*str&&!atoi(str))
while (str&&*str&&!atoi (str))
str++;
return atoi(str)/2;
}
@ -162,8 +165,8 @@ static void arm_opcode_cond(ArmOpcode *ao, int delta) {
};
int i, cond = 14; // 'always' is default
char *c = ao->op+delta;
for(i=0;conds[i];i++) {
if (!strcmp(c, conds[i])) {
for (i=0;conds[i];i++) {
if (!strcmp (c, conds[i])) {
cond = i;
break;
}
@ -191,7 +194,7 @@ static int arm_opcode_name(ArmOpcode *ao, const char *str) {
ao->o |= (ret&0x0f)<<24;//(getreg(ao->a2)&0x0f);
} else {
ao->o |= (strstr(str,"],"))?4:5;
ao->o |= (getnum(ao->a2)&0x7f)<<24; // delta
ao->o |= (getnum (ao->a2)&0x7f)<<24; // delta
}
break;
case TYPE_IMM:
@ -207,40 +210,50 @@ static int arm_opcode_name(ArmOpcode *ao, const char *str) {
} else ao->o |= getnum(ao->a0)<<24; // ???
break;
case TYPE_BRA:
if ((ret = getreg(ao->a0)) != -1) {
// XXX: Needs to calc (eip-off-8)>>2
arm_opcode_cond(ao, strlen(ops[i].name));
ao->o = (ao->o&0x70) | 0xb | (getnum(ao->a0)<<24);
} else {
if ((ret = getreg(ao->a0)) == -1) {
// TODO: control if branch out of range
ret = (getnum(ao->a0)-ao->off-8)/4;
ao->o |= ((ret>>8)&0xff)<<16;
ao->o |= ((ret)&0xff)<<24;
} else {
printf("This branch does not accept reg as arg\n");
return 0;
}
break;
case TYPE_BRR:
if ((ret = getreg(ao->a0)) != -1) {
ao->o |= (getreg (ao->a0)<<24);
} else {
printf("This branch does not accept off as arg\n");
return 0;
}
break;
case TYPE_SWI:
ao->o |= getnum(ao->a0)<<24;
ao->o |= (getnum (ao->a0)&0xff)<<24;
ao->o |= ((getnum (ao->a0)>>8)&0xff)<<16;
ao->o |= ((getnum (ao->a0)>>16)&0xff)<<8;
break;
case TYPE_ARI:
if (!ao->a2) {
ao->a2 = ao->a1;
ao->a1 = ao->a0;
}
ao->o |= getreg(ao->a0)<<20;
ao->o |= getreg(ao->a1)<<8;
ret = getreg(ao->a2);
ao->o |= getreg (ao->a0)<<20;
ao->o |= getreg (ao->a1)<<8;
ret = getreg (ao->a2);
ao->o |= (ret!=-1)? ret<<24 : 2 | getnum(ao->a2)<<24;
break;
case TYPE_MOV:
ao->o |= getreg(ao->a0)<<20;
ret = getreg(ao->a1);
ao->o |= getreg (ao->a0)<<20;
ret = getreg (ao->a1);
if (ret!=-1) ao->o |= ret<<24;
else ao->o |= 0xa003 | getnum(ao->a1)<<24;
else ao->o |= 0xa003 | getnum (ao->a1)<<24;
break;
case TYPE_TST:
//ao->o |= getreg(ao->a0)<<20; // ???
ao->o |= getreg(ao->a0)<<8;
ao->o |= getreg(ao->a1)<<24;
ao->o |= getshift(ao->a2)<<16; // shift
ao->o |= getreg (ao->a0)<<8;
ao->o |= getreg (ao->a1)<<24;
ao->o |= getshift (ao->a2)<<16; // shift
break;
}
return 1;
@ -249,7 +262,6 @@ static int arm_opcode_name(ArmOpcode *ao, const char *str) {
return 0;
}
// XXX: check endian stuff
int armass_assemble(const char *str, unsigned long off) {
ArmOpcode aop = {0};
aop.off = off;
@ -265,10 +277,10 @@ int armass_assemble(const char *str, unsigned long off) {
#ifdef MAIN
void display(const char *str) {
char cmd[32];
int op = armass_assemble(str, 0x1000);
printf("%08x %s\n", op, str);
snprintf(cmd, sizeof(cmd), "rasm2 -d -a arm %08x", op);
system(cmd);
int op = armass_assemble (str, 0x1000);
printf ("%08x %s\n", op, str);
snprintf (cmd, sizeof(cmd), "rasm2 -d -a arm %08x", op);
system (cmd);
}
main() {
@ -288,6 +300,7 @@ main() {
display("bx pc");
display("blx fp");
display("pop {pc}");
display("add lr, pc, lr");
display("adds r3, #8");
display("adds r3, r2, #8");
display("subs r2, #1");
@ -306,11 +319,20 @@ main() {
display("str r1, [pc], 2");
display("str r1, [pc, 3]");
display("str r1, [pc, r4]");
#endif
display("b r3");
display("bx r3");
display("bcc 33");
display("bne r3");
display("blx r3");
display("bne 0x1200");
display("str r0, [r1]");
#endif
//10ab4: 00047e30 andeq r7, r4, r0, lsr lr
//10ab8: 00036e70 andeq r6, r3, r0, ror lr
display("andeq r7, r4, r0, lsr lr");
display("andeq r6, r3, r0, ror lr");
display("push {fp,lr}");
display("pop {fp,lr}");
#if 0
@ -325,12 +347,3 @@ main() {
#endif
}
#endif
#if 0
[pancake@dazo ~]$ rasm2 -o 0 -a arm -d 000080e5
str r0, [r0]
[pancake@dazo ~]$ rasm2 -o 0 -a arm -d 000081e5
str r0, [r1]
[pancake@dazo ~]$ rasm2 -o 0 -a arm -d 000081e5
#endif

View File

@ -11,6 +11,11 @@
static RAsmPlugin *asm_static_plugins[] =
{ R_ASM_STATIC_PLUGINS };
static int r_asm_pseudo_align(struct r_asm_aop_t *aop, char *input) {
eprintf ("TODO: .align\n");
return 0;
}
static int r_asm_pseudo_string(struct r_asm_aop_t *aop, char *input) {
int len = strlen (input)+1;
r_hex_bin2str ((ut8*)input, len, aop->buf_hex);
@ -38,12 +43,34 @@ static inline int r_asm_pseudo_org(RAsm *a, char *input) {
return 0;
}
static inline int r_asm_pseudo_byte(struct r_asm_aop_t *aop, char *input) {
static inline int r_asm_pseudo_hex(struct r_asm_aop_t *aop, char *input) {
int len = r_hex_str2bin (input, aop->buf);
strncpy (aop->buf_hex, r_str_trim(input), R_ASM_BUFSIZE);
strncpy (aop->buf_hex, r_str_trim (input), R_ASM_BUFSIZE);
return len;
}
// TODO: add .short, .word, .dword, ...
static inline int r_asm_pseudo_byte(struct r_asm_aop_t *aop, char *input) {
int i, len = 0;
r_str_subchr (input, ',', ' ');
len = r_str_word_count (input);
r_str_word_set0 (input);
for(i=0;i<len;i++) {
char *word = r_str_word_get0 (input, i);
int num = (int)r_num_math (NULL, word);
aop->buf[i] = num;
}
r_hex_bin2str (aop->buf, len, aop->buf_hex);
return len;
}
static inline int r_asm_pseudo_fill(struct r_asm_aop_t *aop, char *input) {
// repeat, size, value
// TODO
eprintf ("TODO: .fill\n");
return 0;
}
R_API RAsm *r_asm_new() {
int i;
RAsmPlugin *static_plugin;
@ -53,8 +80,8 @@ R_API RAsm *r_asm_new() {
a->cur = NULL;
a->bits = 32;
a->big_endian = 0;
a->syntax = R_ASM_SYNTAX_INTEL;
a->pc = 0;
a->syntax = R_ASM_SYNTAX_INTEL;
a->plugins = r_list_new ();
for (i=0; asm_static_plugins[i]; i++) {
static_plugin = R_NEW (RAsmPlugin);
@ -67,7 +94,7 @@ R_API RAsm *r_asm_new() {
R_API void r_asm_free(RAsm *a) {
// TODO: free plugins and so on
free(a);
free (a);
}
/* return fastcall register argument 'idx' for a syscall with 'num' args */
@ -220,18 +247,13 @@ R_API RAsmCode* r_asm_mdisassemble(RAsm *a, ut8 *buf, ut64 len) {
eprintf ("error disassemble at offset %"PFMT64d"\n", idx);
return r_asm_code_free (acode);
}
//eprintf ("++ %d %d\n", ret, aop.inst_len);
//ret = aop.inst_len; // are always equal??
slen += strlen (aop.buf_asm) + 2;
if(!(acode->buf_asm = realloc (acode->buf_asm, slen)))
return r_asm_code_free (acode);
strcat (acode->buf_asm, aop.buf_asm);
strcat (acode->buf_asm, "\n");
//if (idx + ret < len)
}
acode->len = idx;
return acode;
}
@ -322,13 +344,19 @@ R_API RAsmCode* r_asm_massemble(RAsm *a, const char *buf) {
a->syntax = R_ASM_SYNTAX_ATT;
else if (!memcmp (ptr, ".string ", 8))
ret = r_asm_pseudo_string (&aop, ptr+8);
else if (!memcmp (ptr, ".align", 7))
ret = r_asm_pseudo_align (&aop, ptr+7);
else if (!memcmp (ptr, ".arch ", 6))
ret = r_asm_pseudo_arch (a, ptr+6);
else if (!memcmp (ptr, ".bits ", 6))
ret = r_asm_pseudo_bits (a, ptr+6);
else if (!memcmp (ptr, ".fill ", 6))
ret = r_asm_pseudo_fill (&aop, ptr+6);
else if (!memcmp (ptr, ".hex ", 5))
ret = r_asm_pseudo_hex (&aop, ptr+5);
else if (!memcmp (ptr, ".byte ", 6))
ret = r_asm_pseudo_byte (&aop, ptr+6);
else if (!memcmp (ptr, ".global ", 8)) {
else if (!memcmp (ptr, ".glob", 5)) { // .global .globl
// eprintf (".global directive not yet implemented\n");
ret = 0;
continue;

View File

@ -85,7 +85,7 @@ static int assemble(RAsm *a, RAsmAop *aop, const char *buf) {
int op = armass_assemble(buf, a->pc);
if (op==-1)
return -1;
r_mem_copyendian (aop->buf, &op, 4, a->big_endian);
r_mem_copyendian (aop->buf, (void *)&op, 4, a->big_endian);
return (a->bits/8);
}

View File

@ -152,9 +152,8 @@ R_API int r_str_word_count(const char *string) {
for (word = 0; *text; word++) {
for (;*text && !isseparator (*text); text++);
for (tmp = text; *text && isseparator (*text); text++);
if (tmp == text) word--;
}
return word-1;
return word;
}
R_API char *r_str_ichr(char *str, char chr) {

View File

@ -10,6 +10,7 @@ EFLAGS=../libr_util.a
endif
BINS=test${EXT_EXE}
BINS=set0${EXT_EXE}
BINS+=rax2${EXT_EXE}
BINS+=ralloc${EXT_EXE}
BINS+=array${EXT_EXE}
@ -28,6 +29,9 @@ ralloc${EXT_EXE}:
test${EXT_EXE}:
${CC} ${FLAGS} test.c ${EFLAGS} -o test${EXT_EXE}
set0${EXT_EXE}:
${CC} ${FLAGS} set0.c ${EFLAGS} -o set0${EXT_EXE}
argv${EXT_EXE}:
${CC} ${FLAGS} argv.c ${EFLAGS} -o argv${EXT_EXE}

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009 pancake<nopcode.org> */
/* radare - LGPL - Copyright 2009-2010 pancake<nopcode.org> */
#include "r_util.h"
int main() {

17
libr/util/t/set0.c Normal file
View File

@ -0,0 +1,17 @@
#include <r_util.h>
void test(const char *s) {
int n;
printf("STR: %s\n", s);
n = r_str_word_count(s);
printf("NUM: %d\n", n);
}
void main() {
test("1");
test("");
test("1 2 3");
test("1,2,3");
test("1, 2, 3");
test(" 1, 2, 3 ");
}