From e2b855b6e4401c6e0fadc33f8be9149254b9e826 Mon Sep 17 00:00:00 2001 From: Nibble Date: Thu, 16 Apr 2009 18:03:51 +0200 Subject: [PATCH] * r_asm - Added full label support (fixed bug with postdefined labels) - Removed some warnings in bea - Removed r_flags dependency --- libr/asm/Makefile | 2 +- .../arch/x86/bea/Includes/Routines_ModRM.c | 2 +- libr/asm/asm.c | 100 ++++++++++++------ libr/asm/t/Makefile | 2 +- 4 files changed, 68 insertions(+), 38 deletions(-) diff --git a/libr/asm/Makefile b/libr/asm/Makefile index 42badc3f68..5b0d7ddbf6 100644 --- a/libr/asm/Makefile +++ b/libr/asm/Makefile @@ -1,5 +1,5 @@ NAME=r_asm -DEPS=r_lib r_util r_cmd r_flags +DEPS=r_lib r_util r_cmd foo: pre libr_asm.so plugins diff --git a/libr/asm/arch/x86/bea/Includes/Routines_ModRM.c b/libr/asm/arch/x86/bea/Includes/Routines_ModRM.c index fa362a06ae..19cb6cd769 100644 --- a/libr/asm/arch/x86/bea/Includes/Routines_ModRM.c +++ b/libr/asm/arch/x86/bea/Includes/Routines_ModRM.c @@ -2183,7 +2183,7 @@ int __stdcall SIB_0(ARGTYPE* pMyArgument, int i) if ((BASE_ == 5) && (MOD_ == 0)) { DECALAGE_EIP += 4; if (!Security(7)) return i; - (void) sprintf((char*) (*pMyArgument).ArgMnemonic + i, "%.8X",*((DWORD*) (EIP_ + 3))); + (void) sprintf((char*) (*pMyArgument).ArgMnemonic + i, "%.8lX",*((DWORD*) (EIP_ + 3))); (*pMyArgument).Memory.Displacement = *((DWORD*) (EIP_ + 3)); i += 4; } diff --git a/libr/asm/asm.c b/libr/asm/asm.c index 672c37a2a9..64090ed068 100644 --- a/libr/asm/asm.c +++ b/libr/asm/asm.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include "../config.h" @@ -18,8 +17,8 @@ static int r_asm_asciz(void *data, const char *input) int len = 0; struct r_asm_aop_t **aop = (struct r_asm_aop_t**)data; char *arg = strchr(input, ' '); - if (arg && (len = strlen(arg+1)+1)) { - arg += 1; + if (arg && (len = strlen(arg+1))) { + arg += 1; len += 1; r_hex_bin2str((u8*)arg, len, (*aop)->buf_hex); strncpy((char*)(*aop)->buf, arg, 1024); } @@ -204,52 +203,83 @@ R_API int r_asm_assemble(struct r_asm_t *a, struct r_asm_aop_t *aop, const char R_API int r_asm_massemble(struct r_asm_t *a, struct r_asm_aop_t *aop, char *buf) { - struct r_flag_t flags; - struct r_flag_item_t *fi; - char *lbuf = NULL, *ptr = NULL, *ptr2 = NULL, *tokens[1024], - buf_hex[1024], buf_asm[1024], *symbol = NULL; + struct { + char name[256]; + u64 offset; + } flags[1024]; + char *lbuf = NULL, buf_hex[1024], *ptr = NULL, *ptr_start = NULL, *tokens[1024], + *label_name = NULL, buf_token[1024], buf_token2[1024]; u8 buf_bin[1024]; - int ret, idx, ctr, i, j; + int labels = 0, stage, ret, idx, ctr, i, j; + u64 label_offset; if (buf == NULL) return 0; lbuf = strdup(buf); + if (strchr(lbuf, '_')) + labels = 1; + for (tokens[0] = lbuf, ctr = 0; (ptr = strchr(tokens[ctr], ';')); tokens[++ctr] = ptr+1) *ptr = '\0'; - r_flag_init(&flags); r_cmd_set_data(&a->cmd, &aop); - for (ret = idx = i = 0, *buf_hex='\0'; i <= ctr; i++, idx+=ret) { - r_asm_set_pc(a, a->pc + ret); - while ((ptr = strchr(tokens[i], '_'))) { /* Symbol */ - if ((symbol = r_str_word_get_first(ptr))) { - for (ptr2 = tokens[i];*ptr2&&isseparator(*ptr2);ptr2++); - if ((ptr == ptr2)) { /* set */ - r_flag_set(&flags, symbol, a->pc, 0, 0); - tokens[i]+=strlen(symbol)+1; - } else { /* get */ - *ptr = '\0'; - fi = r_flag_get(&flags, symbol); - sprintf(buf_asm, "%s0x%llx%s", - ptr2, fi->offset, ptr+strlen(symbol)); - tokens[i] = buf_asm; + + /* Stage 1: Parse labels*/ + /* Stage 2: Assemble */ + for (stage = 0; stage < 2; stage++) { + if (stage == 0 && !labels) + continue; + for (ret = i = j = 0, label_offset = a->pc; i <= ctr && j < 1024; i++, label_offset+=ret) { + strncpy(buf_token, tokens[i], 1024); + if (stage == 1) + r_asm_set_pc(a, a->pc + ret); + if (labels) { /* Labels */ + for (ptr_start = buf_token;*ptr_start&&isseparator(*ptr_start);ptr_start++); + while ((ptr = strchr(ptr_start, '_'))) { + if ((label_name = r_str_word_get_first(ptr))) { + if ((ptr == ptr_start)) { + if (stage == 0) { + strncpy(flags[j].name, label_name, 256); + flags[j].offset = label_offset; + j++; + } + ptr_start += strlen(label_name)+1; + } else { + *ptr = '\0'; + if (stage == 1) { + for (j = 0; j < 1024; j++) + if (!strcmp(label_name, flags[j].name)) { + label_offset = flags[j].offset; + break; + } + if (j == 1024) + return 0; + } + snprintf(buf_token2, 1024, "%s0x%llx%s", + ptr_start, label_offset, ptr+strlen(label_name)); + strncpy(buf_token, buf_token2, 1024); + ptr_start = buf_token; + } + free(label_name); + } } - free(symbol); + } else { + ptr_start = tokens[i]; + } + if ((ptr = strchr(ptr_start, '.'))) /* Pseudo */ + ret = r_cmd_call_long(&a->cmd, ptr+1); + else /* Instruction */ + ret = r_asm_assemble(a, aop, ptr_start); + if (!ret) { + return 0; + } else if (stage == 1) { + for (j = 0; j < ret && idx+j < 1024; j++) + buf_bin[idx+j] = aop->buf[j]; + strcat(buf_hex, aop->buf_hex); } - } - if ((ptr = strchr(tokens[i], '.'))) /* Pseudo */ - ret = r_cmd_call_long(&a->cmd, ptr+1); - else /* Instruction */ - ret = r_asm_assemble(a, aop, tokens[i]); - if (ret) { - for (j = 0; j < ret; j++) - buf_bin[idx+j] = aop->buf[j]; - strcat(buf_hex, aop->buf_hex); - } else { - return 0; } } diff --git a/libr/asm/t/Makefile b/libr/asm/t/Makefile index 687545c06a..a1404b4bf2 100644 --- a/libr/asm/t/Makefile +++ b/libr/asm/t/Makefile @@ -1,6 +1,6 @@ OBJ=rasm2.o BIN=rasm2 -BINDEPS=r_util r_lib r_asm r_cmd r_flags +BINDEPS=r_util r_lib r_asm r_cmd LIBS+=-ldl include ../../rules.mk