diff --git a/include/Asm/arch.h b/include/Asm/arch.h index c3b58d5..e337df3 100644 --- a/include/Asm/arch.h +++ b/include/Asm/arch.h @@ -40,11 +40,11 @@ typedef struct _ArchDescription /* operands */ typedef uint32_t ArchOperand; # define AOT_NONE 0x0 -# define AOT_CONSTANT 0x1 /* flags | offset | size | value */ +# define AOT_CONSTANT 0x1 /* flags | 0 | size | value */ # define AOT_IMMEDIATE 0x2 /* flags | offset | 0 | size */ -# define AOT_REGISTER 0x3 /* flags | offset | size | id */ -# define AOT_DREGISTER 0x4 /* flags | offset | dsize | id */ -# define AOT_DREGISTER2 0x5 /* flags | offset | did | id */ +# define AOT_REGISTER 0x3 /* flags | 0 | size | id */ +# define AOT_DREGISTER 0x4 /* flags | dsize | rsize | id */ +# define AOT_DREGISTER2 0x5 /* flags | did | rsize | id */ /* displacement */ # define AOD_FLAGS 24 @@ -71,21 +71,34 @@ typedef uint32_t ArchOperand; /* macros */ # define AO_GET_FLAGS(operand) ((operand & AOM_FLAGS) >> AOD_FLAGS) # define AO_GET_OFFSET(operand) ((operand & AOM_OFFSET) >> AOD_OFFSET) +# define AO_GET_DSIZE(operand) ((operand & AOM_OFFSET) >> AOD_OFFSET) +# define AO_GET_RSIZE(operand) ((operand & AOM_SIZE) >> AOD_SIZE) # define AO_GET_SIZE(operand) ((operand & AOM_SIZE) >> AOD_SIZE) # define AO_GET_TYPE(operand) ((operand & AOM_TYPE) >> AOD_TYPE) # define AO_GET_VALUE(operand) ((operand & AOM_VALUE) >> AOD_VALUE) -# define AO_IMMEDIATE(flags, offset, size) ((AOT_IMMEDIATE << AOD_TYPE) \ - | ((flags) << AOD_FLAGS) | ((offset) << AOD_OFFSET) \ - | ((size) << AOD_SIZE)) -# define AO_REGISTER(flags, offset, size, id) ((AOT_REGISTER << AOD_TYPE) \ - | ((flags) << AOD_FLAGS) | ((offset) << AOD_OFFSET) \ - | ((size) << AOD_SIZE) | ((id) << AOD_VALUE)) -# define AO_DREGISTER(flags, offset, dsize) ((AOT_DREGISTER << AOD_TYPE) \ - | (flags << AOD_FLAGS) | (offset << AOD_OFFSET) \ - | (dsize << AOD_SIZE)) -# define AO_DREGISTER2(flags, offset) ((AOT_DREGISTER2 << AOD_TYPE) \ - | (flags << AOD_FLAGS) | (offset << AOD_OFFSET)) +# define AO_IMMEDIATE(flags, offset, size) \ + ((AOT_IMMEDIATE << AOD_TYPE) \ + | ((flags) << AOD_FLAGS) \ + | ((offset) << AOD_OFFSET) \ + | ((size) << AOD_SIZE)) +# define AO_REGISTER(flags, size, id) \ + ((AOT_REGISTER << AOD_TYPE) \ + | ((flags) << AOD_FLAGS) \ + | ((size) << AOD_SIZE) \ + | ((id) << AOD_VALUE)) +# define AO_DREGISTER(flags, dsize, rsize, id) \ + ((AOT_DREGISTER << AOD_TYPE) \ + | ((flags) << AOD_FLAGS) \ + | ((dsize) << AOD_OFFSET) \ + | ((rsize) << AOD_SIZE) \ + | ((id) << AOD_VALUE)) +# define AO_DREGISTER2(flags, did, dsize, id) \ + ((AOT_DREGISTER2 << AOD_TYPE) \ + | ((flags) << AOD_FLAGS) \ + | ((did) << AOD_OFFSET) \ + | ((dsize) << AOD_SIZE) \ + | ((id) << AOD_VALUE)) typedef struct _ArchInstruction { @@ -114,7 +127,7 @@ struct _ArchPlugin ArchRegister * registers; ArchInstruction * instructions; int (*filter)(ArchPlugin * arch, ArchInstruction * instruction, - unsigned char * buf, size_t size); + ArchOperand operand, unsigned char * buf, size_t size); }; #endif /* !DEVEL_ASM_ARCH_H */ diff --git a/src/arch.c b/src/arch.c index 3b44c6a..a1417a1 100644 --- a/src/arch.c +++ b/src/arch.c @@ -165,6 +165,8 @@ ArchInstruction * arch_get_instruction_by_opcode(Arch * arch, uint8_t size, /* arch_get_instruction_by_operands */ static int _operands_operands(Arch * arch, ArchInstruction * ai, AsOperand ** operands, size_t operands_cnt); +static int _operands_operands_dregister(Arch * arch, uint32_t operand, + AsOperand * aso); static int _operands_operands_immediate(uint32_t operand, AsOperand * aso); static int _operands_operands_register(Arch * arch, uint32_t operand, AsOperand * aso); @@ -220,6 +222,10 @@ static int _operands_operands(Arch * arch, ArchInstruction * ai, return -1; break; case AOT_DREGISTER: + if(_operands_operands_dregister(arch, operand, + operands[i]) != 0) + return -1; + break; case AOT_REGISTER: if(_operands_operands_register(arch, operand, operands[i]) != 0) @@ -230,6 +236,29 @@ static int _operands_operands(Arch * arch, ArchInstruction * ai, return 0; } +static int _operands_operands_dregister(Arch * arch, uint32_t operand, + AsOperand * aso) +{ + unsigned long dereference; + unsigned long max; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() %ld\n", __func__, aso->dereference); +#endif + if(_operands_operands_register(arch, operand, aso) != 0) + return -1; + if(aso->dereference == 0) + return 0; + dereference = (aso->dereference > 0) ? aso->dereference + : -aso->dereference; + /* check if the size fits */ + max = 1; + max <<= AO_GET_DSIZE(operand); + if(dereference > max - 1) + return -1; + return 0; +} + static int _operands_operands_immediate(uint32_t operand, AsOperand * aso) { unsigned long value; @@ -248,7 +277,7 @@ static int _operands_operands_immediate(uint32_t operand, AsOperand * aso) if(AO_GET_FLAGS(operand) & AOF_SOFFSET) value >>= AO_GET_OFFSET(operand); max = 1; - max <<= AO_GET_SIZE(operand) + 1; + max <<= AO_GET_SIZE(operand); if(value > max - 1) return -1; return 0; @@ -257,24 +286,24 @@ static int _operands_operands_immediate(uint32_t operand, AsOperand * aso) static int _operands_operands_register(Arch * arch, uint32_t operand, AsOperand * aso) { - ArchRegister * ar; ArchDescription * desc; + uint32_t size; + ArchRegister * ar; + /* obtain the size */ + if((desc = arch->plugin->description) != NULL + && desc->instruction_size != 0) + size = desc->instruction_size; + else + size = AO_GET_SIZE(operand); /* check if it exists */ - ar = arch_get_register_by_name(arch, aso->value); - if(ar == NULL) - return -1; - /* check the size only for variable-length opcode encoding */ - desc = arch->plugin->description; - if((desc == NULL || desc->instruction_size == 0) - && AO_GET_SIZE(operand) != ar->size) + if((ar = arch_get_register_by_name_size(arch, aso->value, size)) + == NULL) return -1; /* for implicit instructions it must match */ - if(AO_GET_FLAGS(operand) & AOF_IMPLICIT) - { - if(AO_GET_VALUE(operand) != ar->id) - return -1; - } + if(AO_GET_FLAGS(operand) & AOF_IMPLICIT + && AO_GET_VALUE(operand) != ar->id) + return -1; return 0; } @@ -342,8 +371,8 @@ ArchRegister * arch_get_register_by_name_size(Arch * arch, char const * name, /* useful */ /* arch_filter */ -int arch_filter(Arch * arch, ArchInstruction * instruction, unsigned char * buf, - size_t size) +int arch_filter(Arch * arch, ArchInstruction * instruction, ArchOperand operand, + unsigned char * buf, size_t size) { #ifdef DEBUG fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, instruction->name); @@ -351,5 +380,6 @@ int arch_filter(Arch * arch, ArchInstruction * instruction, unsigned char * buf, if(arch->plugin->filter == NULL) return -error_set_code(1, "%s: %s", arch->plugin->name, "Instruction filter required but not defined"); - return arch->plugin->filter(arch->plugin, instruction, buf, size); + return arch->plugin->filter(arch->plugin, instruction, operand, buf, + size); } diff --git a/src/arch.h b/src/arch.h index 21658ea..3d5ebbd 100644 --- a/src/arch.h +++ b/src/arch.h @@ -53,7 +53,7 @@ ArchRegister * arch_get_register_by_name_size(Arch * arch, char const * name, uint32_t size); /* useful */ -int arch_filter(Arch * arch, ArchInstruction * ai, unsigned char * buf, - size_t size); +int arch_filter(Arch * arch, ArchInstruction * ai, ArchOperand operand, + unsigned char * buf, size_t size); #endif /* !ASM_ARCH_H */ diff --git a/src/arch/i386.c b/src/arch/i386.c index 4f64ed3..19cb348 100644 --- a/src/arch/i386.c +++ b/src/arch/i386.c @@ -63,7 +63,7 @@ static ArchInstruction _i386_instructions[] = /* prototypes */ static int _i386_filter(ArchPlugin * plugin, ArchInstruction * instruction, - unsigned char * buf, size_t size); + ArchOperand operand, unsigned char * buf, size_t size); /* public */ @@ -83,12 +83,20 @@ ArchPlugin arch_plugin = /* functions */ static int _i386_filter(ArchPlugin * plugin, ArchInstruction * instruction, - unsigned char * buf, size_t size) + ArchOperand operand, unsigned char * buf, size_t size) { #ifdef DEBUG - fprintf(stderr, "DEBUG: %s() 0x%x\n", __func__, buf[0]); + fprintf(stderr, "DEBUG: %s(\"%s\", 0x%08x) buf[0]=0x%02x\n", __func__, + instruction->name, operand, buf[0]); #endif /* the filter function is only set for mod r/m bytes at the moment */ - buf[0] |= 0xc0; + if(AO_GET_TYPE(operand) == AOT_REGISTER) + buf[0] |= 0xc0; + else if(AO_GET_TYPE(operand) == AOT_DREGISTER + && AO_GET_DSIZE(operand) == W) + buf[0] |= 0x80; + else if(AO_GET_TYPE(operand) == AOT_DREGISTER + && AO_GET_DSIZE(operand) == 8) + buf[0] |= 0x40; return 0; } diff --git a/src/arch/i386.ins b/src/arch/i386.ins index 715fa1f..b803a75 100644 --- a/src/arch/i386.ins +++ b/src/arch/i386.ins @@ -1,23 +1,29 @@ /* platform-specific */ -#if defined(ARCH_amd64) -# define W 32 -#elif defined(ARCH_i386_real) +#if defined(ARCH_i386_real) /* i386 in real mode */ # define W 16 -#else /* i386 and compatible */ +# define REG_AX_id REG_ax_id +#else /* i386 and compatible in 32-bit protected mode */ # define W 32 +# define REG_AX_id REG_eax_id #endif /* registers */ -#define OP_al AO_REGISTER(AOF_IMPLICIT, 0, REG_al_size, REG_al_id) -#define OP_AX AO_REGISTER(AOF_IMPLICIT, 0, W, REG_ax_id) +#define OP_al AO_REGISTER(AOF_IMPLICIT, REG_al_size, REG_al_id) +#define OP_AX AO_REGISTER(AOF_IMPLICIT, W, REG_AX_id) /* helpers */ #define OP1F (8 << AOD_SIZE) #define OP2F (16 << AOD_SIZE) -#define OP_RM8_D AO_DREGISTER(AOF_SOFFSET, 8, 8) -#define OP_RM8_R AO_REGISTER(AOF_SOFFSET | AOF_FILTER, 8, 8, 0) -#define OP_RMW_D AO_DREGISTER(AOF_SOFFSET, 8, W) -#define OP_RMW_R AO_REGISTER(AOF_SOFFSET | AOF_FILTER, 8, W, 0) +/* mod r/m byte */ +#define OP_RM8_D0 AO_DREGISTER(0, 0, 8, 0) +#define OP_RM8_D8 AO_DREGISTER(0, 8, 8, 0) +#define OP_RM8_DW AO_DREGISTER(0, W, 8, 0) +#define OP_RM8_RW AO_REGISTER(0, 8, 0) +#define OP_RMW_D0 AO_DREGISTER(0, 0, W, 0) +#define OP_RMW_D8 AO_DREGISTER(0, 8, W, 0) +#define OP_RMW_DW AO_DREGISTER(0, W, W, 0) +#define OP_RMW_RW AO_REGISTER(0, W, 0) +/* immediate values */ #define OP_U8 AO_IMMEDIATE(0, 0, 8) #define OP_UW AO_IMMEDIATE(0, 0, W) @@ -29,8 +35,12 @@ { "aas", 0x3f, OP1F, AOT_NONE, AOT_NONE, AOT_NONE }, { "adc", 0x14, OP1F, OP_al, OP_U8, AOT_NONE }, { "adc", 0x15, OP1F, OP_AX, OP_UW, AOT_NONE }, -{ "adc", 0x80, OP1F, OP_RM8_D, OP_U8, AOT_NONE }, -{ "adc", 0x80, OP1F, OP_RM8_R, OP_U8, AOT_NONE }, -{ "adc", 0x81, OP1F, OP_RMW_D, OP_UW, AOT_NONE }, -{ "adc", 0x81, OP1F, OP_RMW_R, OP_UW, AOT_NONE }, +{ "adc", 0x80, OP1F, OP_RM8_D0,OP_U8, AOT_NONE }, +{ "adc", 0x80, OP1F, OP_RM8_D8,OP_U8, AOT_NONE }, +{ "adc", 0x80, OP1F, OP_RM8_DW,OP_U8, AOT_NONE }, +{ "adc", 0x80, OP1F, OP_RM8_RW,OP_U8, AOT_NONE }, +{ "adc", 0x81, OP1F, OP_RMW_D0,OP_UW, AOT_NONE }, +{ "adc", 0x81, OP1F, OP_RMW_D8,OP_UW, AOT_NONE }, +{ "adc", 0x81, OP1F, OP_RMW_DW,OP_UW, AOT_NONE }, +{ "adc", 0x81, OP1F, OP_RMW_RW,OP_UW, AOT_NONE }, { "nop", 0x90, OP1F, AOT_NONE, AOT_NONE, AOT_NONE }, diff --git a/src/arch/i386.reg b/src/arch/i386.reg index 5724685..31ebbcf 100644 --- a/src/arch/i386.reg +++ b/src/arch/i386.reg @@ -3,9 +3,9 @@ REG(cl, 8, 0x01) REG(dl, 8, 0x02) REG(bl, 8, 0x03) REG(ah, 8, 0x04) -REG(bh, 8, 0x05) -REG(ch, 8, 0x06) -REG(dh, 8, 0x07) +REG(ch, 8, 0x05) +REG(dh, 8, 0x06) +REG(bh, 8, 0x07) REG(ax, 16, 0x00) REG(cx, 16, 0x01) REG(dx, 16, 0x02) diff --git a/src/arch/sparc.c b/src/arch/sparc.c index 96873e7..3e59396 100644 --- a/src/arch/sparc.c +++ b/src/arch/sparc.c @@ -39,11 +39,6 @@ static ArchInstruction _sparc_instructions[] = }; -/* prototypes */ -/* plug-in */ -static int _sparc_filter(ArchPlugin * arch, ArchInstruction * instruction); - - /* protected */ /* variables */ ArchPlugin arch_plugin = @@ -53,15 +48,5 @@ ArchPlugin arch_plugin = &_sparc_description, _sparc_registers, _sparc_instructions, - _sparc_filter + NULL }; - - -/* private */ -/* functions */ -/* sparc_filter */ -static int _sparc_filter(ArchPlugin * arch, ArchInstruction * instruction) -{ - /* FIXME implement */ - return 0; -} diff --git a/src/arch/sparc.ins b/src/arch/sparc.ins index e86e065..5acd77d 100644 --- a/src/arch/sparc.ins +++ b/src/arch/sparc.ins @@ -1,7 +1,7 @@ /* $Id$ */ /* generic */ /* registers */ -#define OP_RD AO_REGISTER(0, 25, 5, 0) +#define OP_RD AO_REGISTER(0, 32, 0) /* conditional branching */ /* opcodes */ @@ -57,8 +57,8 @@ #define OPIA1F (4 << AOD_SIZE) #define OPIA2F (4 << AOD_SIZE) /* registers */ -#define OPIA_RS1 AO_REGISTER(0, 14, 5, 0) -#define OPIA_RS2 AO_REGISTER(0, 0, 5, 0) +#define OPIA_RS1 AO_REGISTER(0, 32, 0) +#define OPIA_RS2 AO_REGISTER(0, 32, 0) /* helpers */ #define OPIA1(opcode) (0x80000000 | opcode << 19) #define OPIA2(opcode) (0x80000000 | opcode << 19 | 0x1 << 13) @@ -81,8 +81,9 @@ #define OPLS1F (4 << AOD_SIZE) #define OPLS2F (4 << AOD_SIZE) /* registers */ -#define OPLS_RS1 AO_DREGISTER(0, 14, 5) -#define OPLS_RS12 AO_DREGISTER2(AOF_FILTER, 0) +#define OPLS_RS1 AO_DREGISTER(0, 12, 32, 0) +#define OPLS_RS1D AO_DREGISTER(0, 0, 32, 0) +#define OPLS_RS12 AO_DREGISTER2(0, 32, 32, 0) /* helpers */ #define OPLS1(opcode) (0xc0000000 | (opcode << 19)) #define OPLS2(opcode) (0xc0000000 | (opcode << 19) | (0x1 << 13)) @@ -94,7 +95,7 @@ #define OPSHF (4 << AOD_SIZE) /* helpers */ #define OPSH(opcode) (opcode << 22) -#define OPSH_U21 AO_IMMEDIATE(AOF_SOFFSET, 10, 21) +#define OPSH_U21 AO_IMMEDIATE(AOF_SOFFSET, 10, 22) /* instructions */ @@ -131,7 +132,7 @@ { "ldsb", OPLS1(ldsb), OPLS1F, OPLS_RS12,OP_RD, AOT_NONE }, { "ldsh", OPLS1(ldsh), OPLS1F, OPLS_RS1, OP_RD, AOT_NONE }, { "ldsh", OPLS1(ldsh), OPLS1F, OPLS_RS12,OP_RD, AOT_NONE }, -{ "ldub", OPLS1(ldub), OPLS1F, OPLS_RS1, OP_RD, AOT_NONE }, +{ "ldub", OPLS1(ldub), OPLS1F, OPLS_RS1D, OP_RD, AOT_NONE }, { "ldub", OPLS1(ldub), OPLS1F, OPLS_RS12,OP_RD, AOT_NONE }, { "lduh", OPLS1(lduh), OPLS1F, OPLS_RS1, OP_RD, AOT_NONE }, { "lduh", OPLS1(lduh), OPLS1F, OPLS_RS12,OP_RD, AOT_NONE }, diff --git a/src/code.c b/src/code.c index b3ac2e3..0cae3ca 100644 --- a/src/code.c +++ b/src/code.c @@ -43,8 +43,8 @@ struct _Code /* prototypes */ -static int _code_filter(Code * code, ArchInstruction * ai, unsigned char * buf, - size_t size); +static int _code_filter(Code * code, ArchInstruction * ai, ArchOperand operand, + unsigned char * buf, size_t size); /* functions */ @@ -191,14 +191,14 @@ static int _instruction_fixed_register(Code * code, ArchOperand operand, static int _instruction_variable(Code * code, ArchInstruction * ai, AsOperand ** operands, size_t operands_cnt); static int _instruction_variable_dregister(Code * code, ArchInstruction * ai, - ArchOperand operand, char const * name); + ArchOperand operand, AsOperand * aso); static int _instruction_variable_immediate(Code * code, ArchInstruction * ai, ArchOperand operand, void * value, int swap); static int _instruction_variable_opcode(Code * code, ArchInstruction * ai); static int _instruction_variable_operand(Code * code, ArchInstruction * ai, ArchOperand operand, AsOperand * aso); static int _instruction_variable_register(Code * code, ArchInstruction * ai, - ArchOperand operand, char const * name); + ArchOperand operand, AsOperand * aso); int code_instruction(Code * code, char const * name, AsOperand ** operands, size_t operands_cnt) @@ -324,30 +324,25 @@ static int _instruction_variable(Code * code, ArchInstruction * ai, } static int _instruction_variable_dregister(Code * code, ArchInstruction * ai, - ArchOperand operand, char const * name) + ArchOperand operand, AsOperand * aso) { - ArchRegister * ar; uint32_t value; - uint32_t size; #ifdef DEBUG fprintf(stderr, "DEBUG: %s(0x%08x, \"%s\")\n", __func__, operand, name); #endif - if(AO_GET_FLAGS(operand) & AOF_IMPLICIT) - return 0; - if((ar = arch_get_register_by_name_size(code->arch, name, AO_GET_SIZE( - operand))) == NULL) + if(_instruction_variable_register(code, ai, operand, aso) != 0) return -1; - value = ar->id; - if(AO_GET_FLAGS(operand) & AOF_SOFFSET) + /* write de-referencing value if expected */ + if(AO_GET_DSIZE(operand) > 0) { - size = AO_GET_OFFSET(operand); - operand &= ~(AOM_OFFSET | AOM_SIZE); - operand |= (size << AOD_SIZE); + value = aso->dereference; + operand = AO_IMMEDIATE(0, 0, AO_GET_DSIZE(operand)); + if(_instruction_variable_immediate(code, ai, operand, &value, + 0) != 0) + return -1; } - else - value <<= AO_GET_OFFSET(operand); - return _instruction_variable_immediate(code, ai, operand, &value, 0); + return 0; } static int _instruction_variable_immediate(Code * code, ArchInstruction * ai, @@ -360,7 +355,8 @@ static int _instruction_variable_immediate(Code * code, ArchInstruction * ai, uint32_t u32; #ifdef DEBUG - fprintf(stderr, "DEBUG: %s(%d)\n", __func__, swap); + fprintf(stderr, "DEBUG: %s(%d) size=%u\n", __func__, swap, + AO_GET_SIZE(operand)); #endif if((size = AO_GET_SIZE(operand)) == 0) return -error_set_code(1, "%s", "Empty immediate value"); @@ -399,7 +395,7 @@ static int _instruction_variable_immediate(Code * code, ArchInstruction * ai, else return -error_set_code(1, "%u: Size not implemented", size); if(AO_GET_FLAGS(operand) & AOF_FILTER) - _code_filter(code, ai, buf, size); + _code_filter(code, ai, operand, buf, size); if(fwrite(buf, size, 1, code->fp) != 1) return -error_set_code(1, "%s: %s", code->filename, strerror( errno)); @@ -429,10 +425,10 @@ static int _instruction_variable_operand(Code * code, ArchInstruction * ai, operand, aso->value, 0); case AOT_DREGISTER: return _instruction_variable_dregister(code, ai, - operand, aso->value); + operand, aso); case AOT_REGISTER: return _instruction_variable_register(code, ai, operand, - aso->value); + aso); default: /* FIXME implement */ return -error_set_code(1, "%s", strerror(ENOSYS)); @@ -441,12 +437,35 @@ static int _instruction_variable_operand(Code * code, ArchInstruction * ai, } static int _instruction_variable_register(Code * code, ArchInstruction * ai, - ArchOperand operand, char const * name) + ArchOperand operand, AsOperand * aso) { + char const * name = aso->value; + ArchRegister * ar; + uint32_t value; + #ifdef DEBUG - fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, name); + fprintf(stderr, "DEBUG: %s(0x%08x, \"%s\")\n", __func__, operand, name); #endif - return _instruction_variable_dregister(code, ai, operand, name); + if(AO_GET_FLAGS(operand) & AOF_IMPLICIT) + return 0; + if((ar = arch_get_register_by_name_size(code->arch, name, AO_GET_SIZE( + operand))) == NULL) + return -1; + value = ar->id; +#if 0 + if(AO_GET_FLAGS(operand) & AOF_SOFFSET) + { + size = AO_GET_OFFSET(operand); + operand &= ~(AOM_OFFSET | AOM_SIZE); + operand |= (size << AOD_SIZE); + } + else + value <<= AO_GET_OFFSET(operand); +#else + operand &= ~(AOM_SIZE); + operand |= (8 << AOD_SIZE); +#endif + return _instruction_variable_immediate(code, ai, operand, &value, 0); } #if 0 ArchRegister * ar; @@ -662,8 +681,8 @@ int code_section(Code * code, char const * section) /* private */ /* functions */ /* plug-in */ -static int _code_filter(Code * code, ArchInstruction * ai, unsigned char * buf, - size_t size) +static int _code_filter(Code * code, ArchInstruction * ai, ArchOperand operand, + unsigned char * buf, size_t size) { - return arch_filter(code->arch, ai, buf, size); + return arch_filter(code->arch, ai, operand, buf, size); } diff --git a/src/parser.c b/src/parser.c index b6003bc..7bbb377 100644 --- a/src/parser.c +++ b/src/parser.c @@ -512,6 +512,7 @@ static int _operand(State * state) state->operands = p; p = &state->operands[state->operands_cnt]; (*p)->operand = 0; + (*p)->dereference = 0; (*p)->value = NULL; (*p)->value2 = NULL; switch(token_get_code(state->token)) @@ -552,10 +553,10 @@ static int _operand(State * state) case AS_CODE_REGISTER: if(code == AS_CODE_OPERATOR_LBRACKET) (*p)->operand = AO_DREGISTER(0, - 0, 0); + 0, 0, 0); else (*p)->operand = AO_REGISTER(0, - 0, 0, 0); + 0, 0); /* FIXME check errors */ (*p)->value = strdup(string); break; @@ -580,11 +581,19 @@ static int _operand(State * state) ret |= _space(state); /* FIXME register or immediate value */ p = &state->operands[state->operands_cnt - 1]; /* XXX */ + string = token_get_string(state->token); switch(token_get_code(state->token)) { + case AS_CODE_IMMEDIATE: + (*p)->operand = AO_DREGISTER(0, 0, 0, + 0); + (*p)->dereference = strtoul(string + 1, + NULL, 0); + break; case AS_CODE_REGISTER: /* FIXME check everything... */ - (*p)->operand = AO_DREGISTER2(0, 0); + (*p)->operand = AO_DREGISTER2(0, 0, 0, + 0); (*p)->value2 = strdup(string); break; } diff --git a/test/i386.S b/test/i386.S index f860918..2bc611a 100644 --- a/test/i386.S +++ b/test/i386.S @@ -7,7 +7,8 @@ aas adc %al, $0x42 adc %eax, $0x42 - adc [%eax], $0x42 + adc [%edx], $0x42 + adc [%ebx + $0x5], $0x42 adc %ecx, $0x42 adc [%edx], $0x42434445 adc %ebx, $0x42434445