diff --git a/src/code.c b/src/code.c index 7d4366a..6169074 100644 --- a/src/code.c +++ b/src/code.c @@ -167,50 +167,6 @@ static int _decode_file_callback(void * priv, char const * section, } -#if 0 -static ArchInstruction * _decode_size(Code * code, size_t * size, - ArchInstruction * ai); - -ArchInstruction * code_decode(Code * code, char const * buffer, size_t * size) -{ - size_t i; - uint32_t opcode = 0; - ArchInstruction * ai; - - if(size == NULL || *size == 0) - return NULL; - for(i = 0; i < *size && i < sizeof(opcode); i++) - { - opcode = (opcode << 8) | (unsigned char)buffer[i]; - if((ai = arch_get_instruction_by_opcode(code->arch, i + 1, - opcode)) != NULL) - return _decode_size(code, size, ai); - } - if((ai = arch_get_instruction_by_name(code->arch, "db")) != NULL) - return _decode_size(code, size, ai); - return NULL; -} - -static ArchInstruction * _decode_size(Code * code, size_t * size, - ArchInstruction * ai) -{ - size_t s; - - if((s = code->description->instruction_size) == 0) - { - s = AO_GET_SIZE(ai->opcode); - s += AO_GET_SIZE(ai->op1); - s += AO_GET_SIZE(ai->op2); - s += AO_GET_SIZE(ai->op3); - } - if(s > *size) - return NULL; - *size = s; - return ai; -} -#endif - - /* code_function */ int code_function(Code * code, char const * function) { @@ -232,439 +188,6 @@ int code_instruction(Code * code, ArchInstructionCall * call) #endif return arch_write(code->arch, ai, call); } -#if 0 - if(code->description != NULL && code->description->instruction_size > 0) - return _instruction_fixed(code, ai, operands, operands_cnt); - return _instruction_variable(code, ai, operands, operands_cnt); -} - -static int _instruction_fixed(Code * code, ArchInstruction * ai, - AsOperand ** operands, size_t operands_cnt) -{ - uint32_t instruction; - size_t i; - uint32_t u; - ArchOperand operand; - - instruction = ai->value; - for(i = 0, u = 0; i < operands_cnt; i++, u = 0) - { - operand = (i == 0) ? ai->op1 : ((i == 1) ? ai->op2 : ai->op3); - switch(AO_GET_TYPE(operand)) - { - case AOT_DREGISTER: - case AOT_REGISTER: - if(_instruction_fixed_register(code, operand, - operands[i], &u) != 0) - return -1; - break; - case AOT_IMMEDIATE: - if(_instruction_fixed_immediate(operand, - operands[i], &u) != 0) - return -1; - break; - } - instruction |= u; - } - /* FIXME check if it is always the case */ - instruction = htonl(instruction); - if(fwrite(&instruction, sizeof(instruction), 1, code->fp) != 1) - return -error_set_code(1, "%s: %s", code->filename, - strerror(errno)); - return 0; -} - -static int _instruction_fixed_immediate(ArchOperand operand, AsOperand * aso, - uint32_t * pu) -{ - long l; - unsigned long u; - uint32_t size; - - if(aso->value == NULL) - return -1; /* XXX report error */ - if(AO_GET_FLAGS(operand) & AOF_SIGNED) - { - l = *(long*)aso->value; - u = l; - } - else - u = *(unsigned long*)aso->value; - if((size = AO_GET_SIZE(operand)) > 0) - { - size = (1 << (size + 1)) - 1; - u &= size; - } - if(AO_GET_FLAGS(operand) & AOF_SOFFSET) - u >>= AO_GET_OFFSET(operand); - else - u <<= AO_GET_OFFSET(operand); - *pu = u; - return 0; -} - -static int _instruction_fixed_register(Code * code, ArchOperand operand, - AsOperand * aso, uint32_t * pu) -{ - ArchRegister * ar; - - if((ar = arch_get_register_by_name(code->arch, aso->value)) == NULL) - return -1; - *pu = ar->id; - if(AO_GET_FLAGS(operand) & AOF_SOFFSET) - *pu >>= AO_GET_OFFSET(operand); - else - *pu <<= AO_GET_OFFSET(operand); - return 0; -} - -static int _instruction_variable(Code * code, ArchInstruction * ai, - AsOperand ** operands, size_t operands_cnt) -{ - size_t i; - ArchOperand operand; - - if(_instruction_variable_opcode(code, ai) != 0) - return -1; - for(i = 0; i < operands_cnt; i++) - { - if(i == 0) - operand = ai->op1; - else if(i == 1) - operand = ai->op2; - else if(i == 2) - operand = ai->op3; - else - return -1; /* XXX report error */ - if(_instruction_variable_operand(code, ai, operand, operands[i]) - != 0) - return -1; - } - return 0; -} - -static int _instruction_variable_dregister(Code * code, ArchInstruction * ai, - ArchOperand operand, AsOperand * aso) -{ - uint32_t value; - -#ifdef DEBUG - fprintf(stderr, "DEBUG: %s(0x%08x, \"%s\")\n", __func__, operand, name); -#endif - if(_instruction_variable_register(code, ai, operand, aso) != 0) - return -1; - /* write de-referencing value if expected */ - if(AO_GET_DSIZE(operand) > 0) - { - value = aso->dereference; - operand = AO_IMMEDIATE(0, 0, AO_GET_DSIZE(operand)); - if(_instruction_variable_immediate(code, ai, operand, &value, - 0) != 0) - return -1; - } - return 0; -} - -static int _instruction_variable_immediate(Code * code, ArchInstruction * ai, - ArchOperand operand, void * value, int swap) -{ - size_t size; - void * buf; - uint8_t u8; - uint16_t u16; - uint32_t u32; - -#ifdef DEBUG - 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"); - else if(size <= 8) - { - u8 = *(uint8_t*)value; - buf = &u8; - size = 1; - } - else if(size <= 16) - { - u16 = *(uint16_t*)value; - if(swap) - u16 = htons(u16); - buf = &u16; - size = 2; - } - else if(size <= 24) /* FIXME merge with 32? */ - { - u32 = *(uint32_t*)value; - if(swap) - u32 = htonl(u32 << 8); - else - u32 <<= 8; - buf = &u32; - size = 3; - } - else if(size <= 32) - { - u32 = *(uint32_t*)value; - if(swap) - u32 = htonl(u32); - buf = &u32; - size = 4; - } - else - return -error_set_code(1, "%u: Size not implemented", size); - if(AO_GET_FLAGS(operand) & AOF_FILTER) - _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)); - return 0; -} - -static int _instruction_variable_opcode(Code * code, ArchInstruction * ai) -{ -#ifdef DEBUG - fprintf(stderr, "DEBUG: %s() 0x%x\n", __func__, ai->value); -#endif - return _instruction_variable_immediate(code, ai, ai->opcode, &ai->value, - 1); -} - -static int _instruction_variable_operand(Code * code, ArchInstruction * ai, - ArchOperand operand, AsOperand * aso) -{ -#ifdef DEBUG - fprintf(stderr, "DEBUG: %s(\"%s\", 0x%08x) opcode=0x%x\n", __func__, - ai->name, operand, ai->value); -#endif - switch(AO_GET_TYPE(operand)) - { - case AOT_IMMEDIATE: - return _instruction_variable_immediate(code, ai, - operand, aso->value, 0); - case AOT_DREGISTER: - return _instruction_variable_dregister(code, ai, - operand, aso); - case AOT_REGISTER: - return _instruction_variable_register(code, ai, operand, - aso); - default: - /* FIXME implement */ - return -error_set_code(1, "%s", strerror(ENOSYS)); - } - return 0; -} - -static int _instruction_variable_register(Code * code, ArchInstruction * ai, - ArchOperand operand, AsOperand * aso) -{ - char const * name = aso->value; - ArchRegister * ar; - uint32_t value; - -#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) - 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; - uint32_t value; - uint32_t offset; - - /* FIXME consider merging with _instruction_variable_dregister() */ - if(AO_GET_FLAGS(operand) & AOF_IMPLICIT) - return 0; - if((ar = arch_get_register_by_name(code->arch, name)) == NULL) - return -1; - /* FIXME really implement */ - value = ar->id; - if(AO_GET_FLAGS(operand) & AOF_OFFSETSIZE) - { - offset = AO_GET_OFFSET(operand); - operand &= ~(AOM_OFFSET | AOM_SIZE); - operand |= (offset << AOD_SIZE); - } - else - value <<= AO_GET_OFFSET(operand); - return _instruction_variable_immediate(code, ai, operand, &value, 0); -} -#endif -#endif -#if 0 - switch(AO_GET_SIZE(ai->opcode)) - { - case sizeof(u8): - u8 = ai->opcode; - buf = &u8; - break; - case sizeof(u16): - u16 = htons(ai->opcode); - buf = &u16; - break; - case sizeof(u32): - default: - if(AO_GET_SIZE(ai->opcode) == 3) /* FIXME will break */ - u32 = htonl(ai->opcode << 8); - else - u32 = htonl(ai->opcode); - buf = &u32; - break; - } - if(AO_GET_SIZE(ai->opcode) != 0 && fwrite(buf, AO_GET_SIZE(ai->opcode), - 1, code->fp) != 1) - return -error_set_code(1, "%s: %s", code->filename, strerror( - errno)); - for(i = 0; i < operands_cnt; i++) - { - if(i >= 3) - return -error_set_code(1, "%s: %s", name, - "Too many arguments"); - size = AO_GET_SIZE(operands[i]->operand); - if(size == 0) - continue; - u = *(unsigned long*)operands[i]->value; - switch(AO_GET_TYPE(operands[i]->operand)) - { - case AOT_IMMEDIATE: - /* FIXME there still is an endian problem */ - switch(size) - { - case 1: - u8 = u; - buf = &u8; - break; - case 2: - u16 = u; - buf = &u16; - break; - default: /* FIXME not always so */ - case 4: - buf = &u; - break; - } - break; - case AOT_REGISTER: - default: - /* FIXME really implement */ - buf = NULL; - break; - } - if(buf != NULL && fwrite(buf, size, 1, code->fp) != 1) - return -error_set_code(1, "%s: %s", code->filename, - strerror(errno)); - } - return 0; -} - -#endif -#if 0 -static int _instruction_instruction(Code * code, ArchInstruction ** ai, - char const * instruction, AsOperand * operands[], - size_t operands_cnt) -{ - size_t i; - int cmp; - int found = 0; - - /* FIXME check */ - for(i = 0; ((*ai) = arch_get_instruction(code->arch, i)) != NULL; i++) - { - /* FIXME alphabetical order assumption disabled for 80x86 */ - if((cmp = strcmp(instruction, (*ai)->name)) != 0) - continue; - found = 1; - if(_instruction_operands(code, *ai, operands, operands_cnt) - != 0) - continue; - return 0; - } - return error_set_code(1, "%s \"%s\"", found ? "Invalid arguments to" - : "Unknown instruction", instruction); -} - -static int _instruction_operands(Code * code, ArchInstruction * ai, - AsOperand * operands[], size_t operands_cnt) -{ - unsigned long op = 0; - unsigned long o; - char const * reg; - size_t i; - ArchRegister * ar; - - for(i = 0; i < operands_cnt; i++) - { - switch(operands[i]->type) - { - case AOT_IMMEDIATE: - /* FIXME also check the operand size */ - o = _AO_IMM; -#ifdef DEBUG - fprintf(stderr, "DEBUG: op %lu: imm; ", i); -#endif - break; - case AOT_REGISTER: -#if 0 /* XXX this looked maybe better */ - reg = operands[i].value + 1; /* "%rg" => "rg" */ -#else - reg = operands[i]->value; -#endif - if((ar = _operands_register(code->arch, reg)) - == NULL) - return 1; - if(operands[i]->dereference) - o = (_AO_DREG | (ar->id << 2)); - else - o = (_AO_REG | (ar->id << 2)); -#ifdef DEBUG - fprintf(stderr, "DEBUG: op %lu: reg %s; ", i, - reg); -#endif - break; - default: - o = 0; - break; - } - op |= o << (i * 8); - } -#ifdef DEBUG - fprintf(stderr, "DEBUG: 0x%lx & 0x%x => 0x%lx\n", op, ai->operands, - op & ai->operands); -#endif - return (op == ai->operands) ? 0 : 1; -} - -static ArchRegister * _operands_register(Arch * arch, char const * name) -{ - ArchRegister * ret; - size_t i; - - for(i = 0; (ret = arch_register_get(arch, i)) != NULL; i++) - if(strcmp(ret->name, name) == 0) - break; - return ret; -} -#endif /* code_open */