/* immediate */ static int _immediate(State * state) /* [ sign ] "$" NUMBER */ { int ret = 0; AsmArchOperand * p; char const * string; uint64_t value = 0; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif /* [ sign ] */ if(_parser_in_set(state, TS_SIGN)) ret |= _sign(state); else state->negative = 0; /* "$" NUMBER */ p = &state->call.operands[state->call.operands_cnt]; if((string = token_get_string(state->token)) != NULL || strlen(string) == 0) value = strtoul(string + 1, NULL, 0); else ret = _parser_error(state, "%s", "Empty values are not" " allowed"); if(state->address > 0) p->value.dregister.offset = value; else { p->value.immediate.value = strtoul(string + 1, NULL, 0); p->definition = AO_IMMEDIATE(0, 0, 0); p->value.immediate.negative = state->negative; } return ret | _parser_scan(state); }
/* asm_arch_amd64_function_begin */ static int _asm_arch_amd64_function_begin(char const * name) { AsmArchOperand arg1; AsmArchOperand arg2; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif if(asm_set_function(_asm_as, name, -1, -1) != 0) return -1; /* FIXME give real arguments */ memset(&arg1, 0, sizeof(arg1)); arg1.definition = AO_IMMEDIATE(0, 0, 32); arg1.value.immediate.value = 0; memset(&arg2, 0, sizeof(arg2)); arg2.definition = AO_IMMEDIATE(0, 0, 32); arg2.value.immediate.value = 0; return asm_instruction(_asm_as, "enter", 2, &arg1, &arg2); }
/* asm_arch_amd64_function_call */ static int _asm_arch_amd64_function_call(char const * name) { AsmArchOperand arg; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif /* FIXME give a real argument */ memset(&arg, 0, sizeof(arg)); arg.definition = AO_IMMEDIATE(0, 0, 32); arg.value.immediate.value = 0; return asm_instruction(_asm_as, "call", 1, &arg); }
/* java_decode */ static int _java_decode(AsmArchPlugin * plugin, AsmArchInstructionCall * call) { AsmArchPluginHelper * helper = plugin->helper; uint8_t u8; AsmArchInstruction const * ai; size_t i; AsmArchOperand * ao; uint16_t u16; uint32_t u32; AsmString * as; uint32_t begin; uint32_t end; if(helper->read(helper->arch, &u8, sizeof(u8)) != sizeof(u8)) return -1; if((ai = helper->get_instruction_by_opcode(helper->arch, 8, u8)) == NULL) { call->name = "db"; call->operands[0].definition = AO_IMMEDIATE(0, 8, 0); call->operands[0].value.immediate.name = NULL; call->operands[0].value.immediate.value = u8; call->operands[0].value.immediate.negative = 0; call->operands_cnt = 1; return 0; } call->name = ai->name; /* tableswitch may be followed by padding */ if(ai->opcode == 0xaa && (i = call->offset % 4) > 0 && helper->read(helper->arch, &u32, i) != i) return -1; call->operands[0].definition = ai->op1; call->operands[1].definition = ai->op2; call->operands[2].definition = ai->op3; for(i = 0; i < 3 && AO_GET_TYPE(call->operands[i].definition) != AOT_NONE; i++) { ao = &call->operands[i]; if(AO_GET_TYPE(ao->definition) != AOT_IMMEDIATE) /* XXX should there be more types? */ return -error_set_code(1, "%s", "Not implemented"); if(AO_GET_SIZE(ao->definition) == 8) { if(helper->read(helper->arch, &u8, 1) != 1) return -1; ao->value.immediate.value = u8; } else if(AO_GET_SIZE(ao->definition) == 16) { if(helper->read(helper->arch, &u16, 2) != 2) return -1; u16 = _htob16(u16); ao->value.immediate.value = u16; } else if(AO_GET_SIZE(ao->definition) == 32) { if(helper->read(helper->arch, &u32, 4) != 4) return -1; u32 = _htob32(u32); ao->value.immediate.value = u32; } else return -error_set_code(1, "%s", "Size not implemented"); ao->value.immediate.name = NULL; ao->value.immediate.negative = 0; switch(AO_GET_VALUE(ao->definition)) { case AOI_REFERS_FUNCTION: case AOI_REFERS_STRING: as = helper->get_string_by_id(helper->arch, ao->value.immediate.value); if(as != NULL) ao->value.immediate.name = as->name; ao->value.immediate.negative = 0; break; } } call->operands_cnt = i; /* tableswitch may be followed by offsets */ if(ai->opcode == 0xaa) { for(begin = call->operands[1].value.immediate.value, end = call->operands[2].value.immediate.value; begin <= end; begin++) if(helper->read(helper->arch, &u32, sizeof(u32)) != (ssize_t)sizeof(u32)) return -1; } return 0; }