* Fix build and linkage of r_vm

- Added dummy test program for r_vm
This commit is contained in:
pancake/fluendo 2009-07-16 12:38:49 +02:00
parent 6f0ddc5247
commit 564e11975a
11 changed files with 116 additions and 78 deletions

View File

@ -71,7 +71,7 @@ R_API const char *r_str_ansi_chrn(const char *str, int n);
R_API int r_str_ansi_len(const char *str);
R_API int r_str_word_count(const char *string);
R_API int r_str_word_set0(char *str);
R_API const char *r_str_word_get0(const char *str, int idx);
R_API char *r_str_word_get0(char *str, int idx);
R_API char *r_str_word_get_first(const char *string);
R_API char *r_str_chop(char *str);
R_API const char *r_str_chop_ro(const char *str);

View File

@ -30,8 +30,8 @@ struct r_vm_reg_t {
};
struct r_vm_op_t {
const char opcode[32];
const char code[1024];
char opcode[32];
char code[1024];
struct list_head list;
};
@ -69,57 +69,68 @@ struct r_vm_t {
ut8 *vm_stack;
struct list_head mmu_cache;
int realio;
/* io callbacks */
int (*read)(void *user, ut64 addr, ut8 *buf, int len);
int (*write)(void *user, ut64 addr, ut8 *buf, int len);
void *user;
};
ut64 vm_reg_get(const char *name);
void vm_stack_push(ut64 _val);
R_API ut64 vm_reg_get(const char *name);
R_API void vm_stack_push(ut64 _val);
#if 0
static ut64 r_vm_get_value(struct r_vm_t *vm, const char *str);
static ut64 r_vm_get_math(struct r_vm_t *vm, const char *str);
#endif
void r_vm_print(struct r_vm_t *vm, int type);
int r_vm_import(struct r_vm_t *vm, int in_vm);
void r_vm_cpu_call(struct r_vm_t *vm, ut64 addr);
int r_vm_init(struct r_vm_t *vm, int init);
int r_vm_eval_cmp(struct r_vm_t *vm, const char *str);
int r_vm_eval_eq(struct r_vm_t *vm, const char *str, const char *val);
int r_vm_eval_single(struct r_vm_t *vm, const char *str);
int r_vm_eval(struct r_vm_t *vm, const char *str);
int r_vm_eval_file(struct r_vm_t *vm, const char *str);
int r_vm_emulate(struct r_vm_t *vm, int n);
int r_vm_cmd_reg(struct r_vm_t *vm, const char *_str);
int r_vm_op_add(struct r_vm_t *vm, const char *op, const char *str);
int r_vm_op_eval(struct r_vm_t *vm, const char *str);
int r_vm_op_cmd(struct r_vm_t *vm, const char *op);
R_API void r_vm_print(struct r_vm_t *vm, int type);
R_API int r_vm_import(struct r_vm_t *vm, int in_vm);
R_API void r_vm_cpu_call(struct r_vm_t *vm, ut64 addr);
R_API int r_vm_init(struct r_vm_t *vm, int init);
R_API int r_vm_eval_cmp(struct r_vm_t *vm, const char *str);
R_API int r_vm_eval_eq(struct r_vm_t *vm, const char *str, const char *val);
R_API int r_vm_eval_single(struct r_vm_t *vm, const char *str);
R_API int r_vm_eval(struct r_vm_t *vm, const char *str);
R_API int r_vm_eval_file(struct r_vm_t *vm, const char *str);
R_API int r_vm_emulate(struct r_vm_t *vm, int n);
R_API int r_vm_cmd_reg(struct r_vm_t *vm, const char *_str);
R_API int r_vm_op_add(struct r_vm_t *vm, const char *op, const char *str);
R_API int r_vm_op_eval(struct r_vm_t *vm, const char *str);
R_API int r_vm_op_cmd(struct r_vm_t *vm, const char *op);
/* reg */
void r_vm_reg_type_list();
int r_vm_reg_add(struct r_vm_t *vm, const char *name, int type, ut64 value);
ut64 r_vm_reg_get(struct r_vm_t *vm, const char *name);
int r_vm_reg_alias_list(struct r_vm_t *vm);
const char *r_vm_reg_type(int type);
const int r_vm_reg_type_i(const char *str);
int r_vm_reg_del(struct r_vm_t *vm, const char *name);
int r_vm_reg_set(struct r_vm_t *vm, const char *name, ut64 value);
int r_vm_reg_alias(struct r_vm_t *vm, const char *name, const char *get, const char *set);
R_API void r_vm_reg_type_list();
R_API int r_vm_reg_add(struct r_vm_t *vm, const char *name, int type, ut64 value);
R_API ut64 r_vm_reg_get(struct r_vm_t *vm, const char *name);
R_API int r_vm_reg_alias_list(struct r_vm_t *vm);
R_API const char *r_vm_reg_type(int type);
R_API const int r_vm_reg_type_i(const char *str);
R_API int r_vm_reg_del(struct r_vm_t *vm, const char *name);
R_API int r_vm_reg_set(struct r_vm_t *vm, const char *name, ut64 value);
R_API int r_vm_reg_alias(struct r_vm_t *vm, const char *name, const char *get, const char *set);
/* cfg */
void r_vm_setup_flags(struct r_vm_t *vm, const char *zf);
void r_vm_setup_cpu(struct r_vm_t *vm, const char *eip, const char *esp, const char *ebp);
void r_vm_setup_fastcall(struct r_vm_t *vm, const char *eax, const char *ebx, const char *ecx, const char *edx);
void r_vm_setup_ret(struct r_vm_t *vm, const char *eax);
R_API void r_vm_setup_flags(struct r_vm_t *vm, const char *zf);
R_API void r_vm_setup_cpu(struct r_vm_t *vm, const char *eip, const char *esp, const char *ebp);
R_API void r_vm_setup_fastcall(struct r_vm_t *vm, const char *eax, const char *ebx, const char *ecx, const char *edx);
R_API void r_vm_setup_ret(struct r_vm_t *vm, const char *eax);
/* stack */
void r_vm_stack_push(struct r_vm_t *vm, ut64 _val);
void r_vm_stack_pop(struct r_vm_t *vm, const char *reg);
R_API void r_vm_stack_push(struct r_vm_t *vm, ut64 _val);
R_API void r_vm_stack_pop(struct r_vm_t *vm, const char *reg);
/* mmu */
int r_vm_mmu_cache_write(struct r_vm_t *vm, ut64 addr, ut8 *buf, int len);
int r_vm_mmu_cache_read(struct r_vm_t *vm, ut64 addr, ut8 *buf, int len);
int r_vm_mmu_read(struct r_vm_t *vm, ut64 off, ut8 *data, int len);
int r_vm_mmu_write(struct r_vm_t *vm, ut64 off, ut8 *data, int len);
int r_vm_mmu_real(struct r_vm_t *vm, int set);
R_API int r_vm_mmu_cache_write(struct r_vm_t *vm, ut64 addr, ut8 *buf, int len);
R_API int r_vm_mmu_cache_read(struct r_vm_t *vm, ut64 addr, ut8 *buf, int len);
R_API int r_vm_mmu_read(struct r_vm_t *vm, ut64 off, ut8 *data, int len);
R_API int r_vm_mmu_write(struct r_vm_t *vm, ut64 off, ut8 *data, int len);
R_API int r_vm_mmu_real(struct r_vm_t *vm, int set);
R_API void r_vm_mmu_set_io(struct r_vm_t *vm,
int (*read)(void *user, ut64 addr, ut8 *buf, int len),
int (*write)(void *user, ut64 addr, ut8 *buf, int len),
void *user);
/* extra */
int r_vm_cmd_op_help();
int r_vm_op_list(struct r_vm_t *vm);
#endif

View File

@ -65,7 +65,7 @@ R_API int r_str_word_set0(char *str)
return i;
}
R_API const char *r_str_word_get0(const char *str, int idx)
R_API char *r_str_word_get0(char *str, int idx)
{
int i;
const char *ptr = str;
@ -78,11 +78,10 @@ R_API const char *r_str_word_get0(const char *str, int idx)
R_API int r_str_word_count(const char *string)
{
char *text = (char *)string;
char *tmp = (char *)string;
int word = 0;
char *text, *tmp;
int word = 0;
for(;(*text)&&(isseparator(*text));text=text+1);
for(text=tmp=string;(*text)&&(isseparator(*text));text=text+1);
for(word = 0; *text; word++) {
for(;*text && !isseparator(*text);text = text +1);

View File

@ -1,5 +1,6 @@
NAME=r_vm
DEPS=r_util
OBJ=vm.o mmu.o reg.o extra.o
OBJ=vm.o mmu.o reg.o extra.o setup.o stack.o op.o
include ../rules.mk

View File

@ -2,7 +2,7 @@
#include "r_vm.h"
int r_vm_mmu_cache_write(struct r_vm_t *vm, ut64 addr, ut8 *buf, int len)
R_API int r_vm_mmu_cache_write(struct r_vm_t *vm, ut64 addr, ut8 *buf, int len)
{
struct r_vm_change_t *ch = MALLOC_STRUCT(struct r_vm_change_t);
ch->from = addr;
@ -13,7 +13,7 @@ int r_vm_mmu_cache_write(struct r_vm_t *vm, ut64 addr, ut8 *buf, int len)
return 0;
}
int r_vm_mmu_cache_read(struct r_vm_t *vm, ut64 addr, ut8 *buf, int len)
R_API int r_vm_mmu_cache_read(struct r_vm_t *vm, ut64 addr, ut8 *buf, int len)
{
struct r_vm_change_t *c;
struct list_head *pos;
@ -29,20 +29,33 @@ int r_vm_mmu_cache_read(struct r_vm_t *vm, ut64 addr, ut8 *buf, int len)
return 0;
}
int r_vm_mmu_read(struct r_vm_t *vm, ut64 off, ut8 *data, int len)
R_API void r_vm_mmu_set_io(struct r_vm_t *vm,
int (*read)(void *user, ut64 addr, ut8 *buf, int len),
int (*write)(void *user, ut64 addr, ut8 *buf, int len),
void *user)
{
vm->read = read;
vm->write = write;
vm->user = user;
}
R_API int r_vm_mmu_read(struct r_vm_t *vm, ut64 off, ut8 *data, int len)
{
if (!vm->realio && r_vm_mmu_cache_read(vm, off, data, len))
return len;
return r_io_read_at(vm, off, data, len);
if (vm->read)
return vm->read(vm->user, off, data, len);
return -1;
}
int r_vm_mmu_write(struct r_vm_t *vm, ut64 off, ut8 *data, int len)
R_API int r_vm_mmu_write(struct r_vm_t *vm, ut64 off, ut8 *data, int len)
{
if (!vm->realio)
return r_vm_mmu_cache_write(vm, off, data, len);
fprintf(stderr, "vm_mmu_write!\n");
// XXX: callback for write-at should be userdefined
return r_io_write_at(vm, off, data, len);
if (vm->write)
return vm->write(vm->user, off, data, len);
return -1;
}
int r_vm_mmu_real(struct r_vm_t *vm, int set)

View File

@ -16,20 +16,18 @@ int r_vm_op_add(struct r_vm_t *vm, const char *op, const char *str)
int r_vm_op_eval(struct r_vm_t *vm, const char *str)
{
char *p,*s;
int j,k,len = strlen(str)+256;
struct list_head *pos;
char *p, *s, *arg0;
int j, k, len = strlen(str)+256;
int nargs = 0;
char *arg0;
// eprintf("vmopeval(%s)\n", str);
p = alloca(len);
s = alloca(len);
memcpy(p, str, len);
memcpy(s, str, len);
struct list_head *pos;
nargs = set0word(s);
arg0 = get0word(s,0);
nargs = r_str_word_set0(s);
arg0 = r_str_word_get0(s, 0);
list_for_each(pos, &vm->ops) {
struct r_vm_op_t *o = list_entry(pos, struct r_vm_op_t, list);
@ -68,7 +66,7 @@ int r_vm_op_eval(struct r_vm_t *vm, const char *str)
}
#endif
if (str[j]>='0' && str[j]<='9') {
const char *w = get0word(s,str[j]-'0');
const char *w = r_str_word_get0(s, str[j]-'0');
if (w != NULL) {
strcpy(p+k, w);
k += strlen(w)-1;
@ -79,8 +77,7 @@ int r_vm_op_eval(struct r_vm_t *vm, const char *str)
p[k]='\0';
}
}
return vm_eval(p);
return r_vm_eval(vm, p);
}
/* TODO : Allow to remove and so on */
@ -97,6 +94,6 @@ int r_vm_op_cmd(struct r_vm_t *vm, const char *op)
ptr[0]='\0';
eprintf("vm: opcode '%s' added\n", cmd);
r_vm_op_add(vm, cmd, ptr+1);
} else vm_cmd_op_help();
} else r_vm_cmd_op_help();
return 0;
}

View File

@ -196,7 +196,7 @@ int r_vm_cmd_reg(struct r_vm_t *vm, const char *_str)
r_vm_print(vm, r_vm_reg_type_i(str+1));
} else {
/* show single registers */
printf("%s = 0x%08llx\n", str, vm_reg_get(str));
printf("%s = 0x%08llx\n", str, r_vm_reg_get(vm, str));
}
}
}

View File

@ -7,18 +7,18 @@ void r_vm_stack_push(struct r_vm_t *vm, ut64 _val)
{
// XXX determine size of stack here
// XXX do not write while emulating zomfg
// XXX we need a way to define the size of registers to grow/shrink the stack properly
ut32 val = _val;
vm_reg_set(vm, vm_cpu.sp, vm_reg_get(vm, vm_cpu.sp)+4);
vm_mmu_write(vm, vm_reg_get(vm, vm_cpu.sp), &val, 4);
r_vm_reg_set(vm, vm->cpu.sp, r_vm_reg_get(vm, vm->cpu.sp)+4);
r_vm_mmu_write(vm, r_vm_reg_get(vm, vm->cpu.sp), (void *)&val, 4);
}
void r_vm_stack_pop(struct r_vm_t *vm, const char *reg)
{
ut32 val = 0;
if (vm_mmu_read(vm_reg_get(vm, vm->cpu.sp), &val, 4))
if (r_vm_mmu_read(vm, r_vm_reg_get(vm, vm->cpu.sp), (void *)&val, 4))
return;
//printf("POP (%s)\n", reg);
vm_mmu_read(vm, vm_reg_get(vm, vm->cpu.sp), &val, 4);
vm_reg_set(vm, reg, val);
vm_reg_set(vm_cpu.sp, vm_reg_get(vm, vm->cpu.sp)-4);
r_vm_mmu_read(vm, r_vm_reg_get(vm, vm->cpu.sp), (void *)&val, 4);
r_vm_reg_set(vm, reg, val);
r_vm_reg_set(vm, vm->cpu.sp, r_vm_reg_get(vm, vm->cpu.sp)-4);
}

5
libr/vm/t/Makefile Normal file
View File

@ -0,0 +1,5 @@
OBJ=test.o
BIN=test
BINDEPS=r_vm
include ../../rules.mk

9
libr/vm/t/test.c Normal file
View File

@ -0,0 +1,9 @@
#include <r_vm.h>
int main()
{
struct r_vm_t vm;
r_vm_init(&vm, 1);
/* ... TODO ... */
return 0;
}

View File

@ -175,7 +175,7 @@ R_API int r_vm_import(struct r_vm_t *vm, int in_vm)
R_API void r_vm_cpu_call(struct r_vm_t *vm, ut64 addr)
{
/* x86 style */
r_vm_stack_push(vm, vm_reg_get(vm->cpu.pc));
r_vm_stack_push(vm, r_vm_reg_get(vm, vm->cpu.pc));
r_vm_reg_set(vm, vm->cpu.pc, addr);
// XXX this should be the next instruction after pc (we need insn length here)
}
@ -192,6 +192,7 @@ R_API int r_vm_init(struct r_vm_t *vm, int init)
INIT_LIST_HEAD(&vm->regs);
INIT_LIST_HEAD(&vm->ops);
memset(&vm->cpu, '\0', sizeof(struct r_vm_cpu_t));
vm->user = vm->read = vm->write = NULL;
}
//vm_mmu_real(vm, config_get_i("vm.realio"));
@ -247,8 +248,10 @@ R_API int r_vm_init(struct r_vm_t *vm, int init)
//vm_setup_copy("esi", "edi");
r_vm_setup_ret(vm, "eax");
// TODO: do the same for fpregs and mmregs
#if 0
if (init) // XXX
r_vm_arch_x86_init(vm);
#endif
break;
#if 0
case ARCH_MIPS:
@ -326,7 +329,7 @@ R_API int r_vm_eval_eq(struct r_vm_t *vm, const char *str, const char *val)
} else {
r_vm_mmu_read(vm, off, (ut8*)&_int32, 4);
//off = r_vm_get_math(val);
r_vm_mmu_write(vm, off, (const ut8*)&_int32, 4);
r_vm_mmu_write(vm, off, (void*)&_int32, 4);
}
} else {
// [0x804800] = eax
@ -454,20 +457,20 @@ R_API int r_vm_eval_single(struct r_vm_t *vm, const char *str)
if((!memcmp(ptr, "call ", 4))
|| (!memcmp(ptr, "jmp ", 4))){
if (ptr[0]=='c')
r_vm_stack_push(vm, vm->cpu.pc);
r_vm_stack_push(vm, r_vm_get_value(vm, vm->cpu.pc));
printf("CALL(%s)\n", ptr+4);
r_vm_reg_set(vm, vm->cpu.pc, r_vm_get_value(vm, ptr+4));
} else
if (!memcmp(ptr, "jz ", 3)){
if (vm_reg_get(ptr+3)==0)
if (r_vm_reg_get(vm, ptr+3)==0)
r_vm_reg_set(vm, vm->cpu.pc, r_vm_get_value(vm, ptr+3));
} else
if (!memcmp(ptr, "jnz ", 4)){
if (vm_reg_get(ptr+4)==0)
if (r_vm_reg_get(vm, ptr+4)==0)
r_vm_reg_set(vm, vm->cpu.pc, r_vm_get_value(vm, ptr+4));
} else
if (!memcmp(ptr, "push ", 5)) {
r_vm_stack_push(vm, str+5);
r_vm_stack_push(vm, r_vm_get_value(vm, str+5));
} else
if (!memcmp(str, "pop ", 4)) {
r_vm_stack_pop(vm, str+5);