static int _call_operands_constant(AsmArchOperandDefinition definition, AsmArchOperand * operand) { #ifdef DEBUG fprintf(stderr, "DEBUG: %s() %u %lu\n", __func__, AO_GET_VALUE(definition), operand->value.immediate.value); #endif if(AO_GET_VALUE(definition) != operand->value.immediate.value) return -1; /* set this operand as a constant */ operand->definition &= AOM_TYPE; operand->definition |= (AOT_CONSTANT << AOD_TYPE); return 0; }
static int _call_operands_register(AsmArch * arch, AsmArchOperandDefinition opdefinition, AsmArchOperand * operand) { char const * name = operand->value._register.name; AsmArchDefinition const * definition; uint32_t size; AsmArchRegister const * ar; /* obtain the size */ if((definition = arch->definition->definition) != NULL && definition->instruction_size != 0) size = definition->instruction_size; else size = AO_GET_SIZE(opdefinition); /* check if it exists */ if((ar = arch_get_register_by_name_size(arch, name, size)) == NULL) return -1; /* for implicit instructions it must match */ if(AO_GET_FLAGS(opdefinition) & AOF_IMPLICIT && AO_GET_VALUE(opdefinition) != ar->id) return -1; return 0; }
/* 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; }