#include <stdint.h>#include <stdbool.h>#include <emu/emu.h>#include <emu/emu_cpu_instruction.h>#include <emu/emu_instruction.h>#include <string.h>
Go to the source code of this file.
Classes | |
| struct | emu_cpu |
Defines | |
| #define | CPU_FLAG_SET(cpu_p, fl) (cpu_p)->eflags |= 1 << (fl) |
| #define | CPU_FLAG_UNSET(cpu_p, fl) (cpu_p)->eflags &= ~(1 << (fl)) |
| #define | CPU_FLAG_TOGGLE(cpu_p, fl) (cpu_p)->eflags ^= 1 << (fl) |
| #define | CPU_FLAG_ISSET(cpu_p, fl) ((cpu_p)->eflags & (1 << (fl))) |
| #define | CPU_DEBUG_FLAG_SET(cpu_p, fl) (cpu_p)->debugflags |= 1 << (fl) |
| #define | CPU_DEBUG_FLAG_UNSET(cpu_p, fl) (cpu_p)->debugflags &= ~(1 << (fl)) |
| #define | CPU_DEBUG_FLAG_TOGGLE(cpu_p, fl) (cpu_p)->debugflags ^= 1 << (fl) |
| #define | CPU_DEBUG_FLAG_ISSET(cpu_p, fl) ((cpu_p)->debugflags & (1 << (fl))) |
| #define | MODRM_MOD(x) (((x) >> 6) & 3) |
| #define | MODRM_REGOPC(x) (((x) >> 3) & 7) |
| #define | MODRM_RM(x) ((x) & 7) |
| #define | SIB_SCALE(x) (((x) >> 6) & 3) |
| #define | SIB_INDEX(x) (((x) >> 3) & 7) |
| #define | SIB_BASE(x) ((x) & 7) |
| #define | PREFIX_ADSIZE (1 << 0) |
| #define | PREFIX_OPSIZE (1 << 1) |
| #define | PREFIX_LOCK (1 << 2) |
| #define | PREFIX_CS_OVR (1 << 3) |
| #define | PREFIX_DS_OVR (1 << 4) |
| #define | PREFIX_ES_OVR (1 << 5) |
| #define | PREFIX_FS_OVR (1 << 6) |
| #define | PREFIX_GS_OVR (1 << 7) |
| #define | PREFIX_SS_OVR (1 << 8) |
| #define | PREFIX_F2 (1 << 9) |
| #define | PREFIX_F3 (1 << 10) |
| #define | OPSIZE_8 1 |
| #define | OPSIZE_16 2 |
| #define | OPSIZE_32 3 |
| #define | MAX_INT8 127 |
| #define | MIN_INT8 -128 |
| #define | MAX_UINT8 255 |
| #define | MIN_UINT8 0 |
| #define | MAX_INT16 32767 |
| #define | MIN_INT16 -MAX_INT16 -1 |
| #define | MAX_UINT16 65535 |
| #define | MIN_UINT16 0 |
| #define | MAX_INT32 2147483647 |
| #define | MIN_INT32 -MAX_INT32 -1 |
| #define | MAX_UINT32 4294967295U |
| #define | MIN_UINT32 0 |
| #define | INTOF(bits) int##bits##_t |
| #define | UINTOF(bits) uint##bits##_t |
| #define | INSTR_SET_FLAG_ZF(cpu) |
| #define | INSTR_SET_FLAG_PF(cpu) |
| #define | INSTR_SET_FLAG_SF(cpu) |
| #define | WORD_UPPER_TO_BYTE(to, from) memcpy(&(to),((uint8_t *)&(from))+1,1); |
| #define | WORD_LOWER_TO_BYTE(to, from) memcpy(&(to),&(from),1); |
| #define | DWORD_UPPER_TO_WORD(to, from) memcpy(&(to),((uint8_t *)&(from))+2,2); |
| #define | DWORD_LOWER_TO_WORD(to, from) memcpy(&(to),&(from),2); |
| #define | QWORD_UPPER_TO_DWORD(to, from) memcpy(&(to),((uint8_t *)&(from))+4,4); |
| #define | QWORD_LOWER_TO_DWORD(to, from) memcpy(&(to),&(from),4); |
| #define | DWORD_FROM_WORDS(to, upper, lower) |
| #define | QWORD_FROM_DWORDS(to, upper, lower) |
| #define | TRACK_INIT_REG32(instruction, reg32) (instruction).track.init.reg[reg32] = 0xffffffff; |
| #define | TRACK_NEED_REG32(instruction, reg32) (instruction).track.need.reg[reg32] = 0xffffffff; |
| #define | TRACK_INIT_REG16(instruction, reg16) (instruction).track.init.reg[reg16] |= 0xffff << 16; |
| #define | TRACK_NEED_REG16(instruction, reg16) (instruction).track.need.reg[reg16] |= 0xffff << 16; |
| #define | TRACK_INIT_REG8(instruction, reg8) (instruction).track.init.reg[reg8] |= 0xff << 24; |
| #define | TRACK_NEED_REG8(instruction, reg8) (instruction).track.need.reg[reg8] |= 0xff << 24; |
| #define | TRACK_INIT_EFLAG(instruction, fl) (instruction).track.init.eflags |= 1 << (fl) |
| #define | TRACK_NEED_EFLAG(instruction, fl) (instruction).track.need.eflags |= 1 << (fl) |
| #define | SOURCE_NORM_POS(instruction, pos) (instruction).source.norm_pos = pos; |
| #define | SOURCE_COND_POS(instruction, pos) (instruction).source.has_cond_pos = 1; (instruction).source.cond_pos = pos; |
| #define | TRACK_FPU_LAST_INSTRUCTION 0x0 |
| #define | TRACK_INIT_FPU(instruction, what) (instruction).track.init.fpu |= 1 << (what); |
| #define | TRACK_NEED_FPU(instruction, what) (instruction).track.need.fpu |= 1 << (what); |
| #define | NNY "no need yet" |
| #define | SST "16bit memory access is unsupported" |
| #define | UNIMPLEMENTED(cpu_p, reason) |
| #define | STUB(cpu_p) emu_log((cpu_p)->emu, EMU_LOG_INFO, "The following function is a stub %s %s:%i \n", __PRETTY_FUNCTION__, __FILE__, __LINE__); |
Enumerations | |
| enum | emu_cpu_flag { f_cf = 0, f_pf = 2, f_af = 4, f_zf = 6, f_sf = 7, f_tf = 8, f_if = 9, f_df = 10, f_of = 11 } |
| enum | emu_cpu_debug_flag { instruction_string = 0, instruction_size = 1 } |
Variables | |
| int64_t | max_inttype_borders [][2][2] |
| #define CPU_DEBUG_FLAG_ISSET | ( | cpu_p, | |||
| fl | ) | ((cpu_p)->debugflags & (1 << (fl))) |
Referenced by emu_cpu_parse(), and emu_source_and_track_instr_info_new().
| #define CPU_DEBUG_FLAG_SET | ( | cpu_p, | |||
| fl | ) | (cpu_p)->debugflags |= 1 << (fl) |
Referenced by emu_cpu_debugflag_set().
| #define CPU_DEBUG_FLAG_TOGGLE | ( | cpu_p, | |||
| fl | ) | (cpu_p)->debugflags ^= 1 << (fl) |
| #define CPU_DEBUG_FLAG_UNSET | ( | cpu_p, | |||
| fl | ) | (cpu_p)->debugflags &= ~(1 << (fl)) |
Referenced by emu_cpu_debugflag_unset().
| #define CPU_FLAG_ISSET | ( | cpu_p, | |||
| fl | ) | ((cpu_p)->eflags & (1 << (fl))) |
| #define CPU_FLAG_SET | ( | cpu_p, | |||
| fl | ) | (cpu_p)->eflags |= 1 << (fl) |
Referenced by instr_aaa_37(), instr_stc_f9(), and instr_std_fd().
| #define CPU_FLAG_TOGGLE | ( | cpu_p, | |||
| fl | ) | (cpu_p)->eflags ^= 1 << (fl) |
Referenced by instr_cmc_f5().
| #define CPU_FLAG_UNSET | ( | cpu_p, | |||
| fl | ) | (cpu_p)->eflags &= ~(1 << (fl)) |
Referenced by instr_aaa_37(), instr_clc_f8(), and instr_cld_fc().
| #define DWORD_FROM_WORDS | ( | to, | |||
| upper, | |||||
| lower | ) |
memcpy(&to,&lower,2); \
memcpy(((char *)&to)+2,&upper,2);
Referenced by instr_group_3_f7_div(), and instr_group_3_f7_idiv().
| #define DWORD_LOWER_TO_WORD | ( | to, | |||
| from | ) | memcpy(&(to),&(from),2); |
Referenced by instr_cwd_99(), instr_group_3_f7_imul(), and instr_group_3_f7_mul().
| #define DWORD_UPPER_TO_WORD | ( | to, | |||
| from | ) | memcpy(&(to),((uint8_t *)&(from))+2,2); |
Referenced by instr_cwd_99(), instr_group_3_f7_imul(), instr_group_3_f7_mul(), and instr_imul_0f_af().
| #define INSTR_SET_FLAG_PF | ( | cpu | ) |
{ \
int num_p_bits=0; \
int i; \
for ( i=0;i<8;i++ ) \
if (operation_result & (1 << i) ) \
num_p_bits++; \
\
if ((num_p_bits % 2) == 0) \
CPU_FLAG_SET(cpu, f_pf); \
else \
CPU_FLAG_UNSET(cpu, f_pf); \
}
| #define INSTR_SET_FLAG_SF | ( | cpu | ) |
{ \
if (operation_result & (1 << (sizeof(operation_result)*8 - 1))) \
CPU_FLAG_SET(cpu, f_sf); \
else \
CPU_FLAG_UNSET(cpu, f_sf); \
}
| #define INSTR_SET_FLAG_ZF | ( | cpu | ) |
{ \
if (operation_result == 0) \
CPU_FLAG_SET(cpu, f_zf); \
else \
CPU_FLAG_UNSET(cpu, f_zf); \
}
| #define INTOF | ( | bits | ) | int##bits##_t |
| #define MAX_INT16 32767 |
| #define MAX_INT32 2147483647 |
| #define MAX_INT8 127 |
| #define MAX_UINT16 65535 |
| #define MAX_UINT32 4294967295U |
| #define MAX_UINT8 255 |
| #define MIN_INT16 -MAX_INT16 -1 |
| #define MIN_INT32 -MAX_INT32 -1 |
| #define MIN_INT8 -128 |
| #define MIN_UINT16 0 |
| #define MIN_UINT32 0 |
| #define MIN_UINT8 0 |
| #define MODRM_MOD | ( | x | ) | (((x) >> 6) & 3) |
Referenced by emu_cpu_parse().
| #define MODRM_REGOPC | ( | x | ) | (((x) >> 3) & 7) |
Referenced by emu_cpu_parse().
| #define MODRM_RM | ( | x | ) | ((x) & 7) |
Referenced by emu_cpu_parse().
| #define NNY "no need yet" |
| #define OPSIZE_16 2 |
Referenced by emu_cpu_parse().
| #define OPSIZE_32 3 |
Referenced by emu_cpu_parse().
| #define OPSIZE_8 1 |
Referenced by emu_cpu_parse().
| #define PREFIX_ADSIZE (1 << 0) |
Referenced by init_prefix_map(), instr_cmps_a6(), instr_cmps_a7(), instr_lods_ac(), instr_lods_ad(), instr_scas_ae(), instr_scas_af(), instr_stos_aa(), and instr_stos_ab().
| #define PREFIX_CS_OVR (1 << 3) |
Referenced by init_prefix_map().
| #define PREFIX_DS_OVR (1 << 4) |
Referenced by init_prefix_map().
| #define PREFIX_ES_OVR (1 << 5) |
Referenced by init_prefix_map().
| #define PREFIX_F2 (1 << 9) |
Referenced by init_prefix_map().
| #define PREFIX_F3 (1 << 10) |
Referenced by init_prefix_map(), instr_cmps_a6(), instr_movsb(), and instr_stos_aa().
| #define PREFIX_FS_OVR (1 << 6) |
Referenced by emu_cpu_step(), and init_prefix_map().
| #define PREFIX_GS_OVR (1 << 7) |
Referenced by init_prefix_map().
| #define PREFIX_LOCK (1 << 2) |
| #define PREFIX_OPSIZE (1 << 1) |
Referenced by emu_cpu_parse(), init_prefix_map(), instr_adc_11(), instr_adc_13(), instr_adc_15(), instr_add_01(), instr_add_03(), instr_add_05(), instr_and_21(), instr_and_23(), instr_and_25(), instr_cbw_98(), instr_cmp_39(), instr_cmp_3b(), instr_cmp_3d(), instr_cmps_a7(), instr_cwd_99(), instr_dec_4x(), instr_group_10_8f_pop(), instr_group_1_81_adc(), instr_group_1_81_add(), instr_group_1_81_and(), instr_group_1_81_cmp(), instr_group_1_81_or(), instr_group_1_81_sbb(), instr_group_1_81_sub(), instr_group_1_81_xor(), instr_group_1_83_adc(), instr_group_1_83_add(), instr_group_1_83_and(), instr_group_1_83_cmp(), instr_group_1_83_or(), instr_group_1_83_sbb(), instr_group_1_83_sub(), instr_group_1_83_xor(), instr_group_2_c1_rcl(), instr_group_2_c1_rcr(), instr_group_2_c1_rol(), instr_group_2_c1_ror(), instr_group_2_c1_sal(), instr_group_2_c1_sar(), instr_group_2_c1_shr(), instr_group_2_d1_rcl(), instr_group_2_d1_rcr(), instr_group_2_d1_rol(), instr_group_2_d1_ror(), instr_group_2_d1_sal(), instr_group_2_d1_sar(), instr_group_2_d1_shr(), instr_group_2_d3_rcl(), instr_group_2_d3_rcr(), instr_group_2_d3_rol(), instr_group_2_d3_ror(), instr_group_2_d3_sal(), instr_group_2_d3_sar(), instr_group_2_d3_shr(), instr_group_3_f7_div(), instr_group_3_f7_idiv(), instr_group_3_f7_imul(), instr_group_3_f7_mul(), instr_group_3_f7_neg(), instr_group_3_f7_not(), instr_group_3_f7_test(), instr_group_5_ff_call(), instr_group_5_ff_dec(), instr_group_5_ff_inc(), instr_group_5_ff_jmp(), instr_group_5_ff_push(), instr_imul_0f_af(), instr_imul_69(), instr_imul_6b(), instr_inc_4x(), instr_jcc_e3(), instr_lea_8d(), instr_lods_ad(), instr_loop_e2(), instr_loopcc_e0(), instr_loopcc_e1(), instr_mov_89(), instr_mov_8b(), instr_mov_a1(), instr_mov_a3(), instr_mov_bx_2(), instr_mov_c7(), instr_movsb(), instr_movsx_0fbe(), instr_movzx_0fb6(), instr_or_09(), instr_or_0b(), instr_or_0d(), instr_pop_5x(), instr_popad_61(), instr_push_5x(), instr_push_68(), instr_push_6a(), instr_pushad_60(), instr_sbb_19(), instr_sbb_1b(), instr_sbb_1d(), instr_scas_af(), instr_sldt_0f00(), instr_stos_ab(), instr_sub_29(), instr_sub_2b(), instr_sub_2d(), instr_test_85(), instr_test_a9(), instr_xchg_87(), instr_xchg_9x(), instr_xor_31(), instr_xor_33(), and instr_xor_35().
| #define PREFIX_SS_OVR (1 << 8) |
Referenced by init_prefix_map().
| #define QWORD_FROM_DWORDS | ( | to, | |||
| upper, | |||||
| lower | ) |
memcpy(&to,&lower,4); \
memcpy(((char *)&to)+4,&upper,4);
Referenced by instr_group_3_f7_div(), and instr_group_3_f7_idiv().
| #define QWORD_LOWER_TO_DWORD | ( | to, | |||
| from | ) | memcpy(&(to),&(from),4); |
Referenced by instr_cwd_99(), instr_group_3_f7_imul(), and instr_group_3_f7_mul().
| #define QWORD_UPPER_TO_DWORD | ( | to, | |||
| from | ) | memcpy(&(to),((uint8_t *)&(from))+4,4); |
Referenced by instr_cwd_99(), instr_group_3_f7_imul(), instr_group_3_f7_mul(), instr_imul_69(), and instr_imul_6b().
| #define SIB_BASE | ( | x | ) | ((x) & 7) |
Referenced by emu_cpu_parse().
| #define SIB_INDEX | ( | x | ) | (((x) >> 3) & 7) |
Referenced by emu_cpu_parse().
| #define SIB_SCALE | ( | x | ) | (((x) >> 6) & 3) |
Referenced by emu_cpu_parse().
| #define SOURCE_COND_POS | ( | instruction, | |||
| pos | ) | (instruction).source.has_cond_pos = 1; (instruction).source.cond_pos = pos; |
Referenced by instr_jcc_0f80(), instr_jcc_0f81(), instr_jcc_0f82(), instr_jcc_0f83(), instr_jcc_0f84(), instr_jcc_0f85(), instr_jcc_0f86(), instr_jcc_0f87(), instr_jcc_0f88(), instr_jcc_0f89(), instr_jcc_0f8a(), instr_jcc_0f8b(), instr_jcc_0f8c(), instr_jcc_0f8d(), instr_jcc_0f8e(), instr_jcc_0f8f(), instr_jcc_70(), instr_jcc_71(), instr_jcc_72(), instr_jcc_73(), instr_jcc_74(), instr_jcc_75(), instr_jcc_76(), instr_jcc_77(), instr_jcc_78(), instr_jcc_79(), instr_jcc_7a(), instr_jcc_7b(), instr_jcc_7c(), instr_jcc_7d(), instr_jcc_7e(), instr_jcc_7f(), instr_jcc_e3(), instr_loop_e2(), instr_loopcc_e0(), and instr_loopcc_e1().
| #define SOURCE_NORM_POS | ( | instruction, | |||
| pos | ) | (instruction).source.norm_pos = pos; |
Referenced by emu_cpu_parse(), instr_call_e8(), instr_group_5_ff_call(), instr_group_5_ff_jmp(), instr_jmp_e9(), and instr_jmp_eb().
| #define SST "16bit memory access is unsupported" |
| #define STUB | ( | cpu_p | ) | emu_log((cpu_p)->emu, EMU_LOG_INFO, "The following function is a stub %s %s:%i \n", __PRETTY_FUNCTION__, __FILE__, __LINE__); |
Referenced by instr_aas_3f(), instr_daa_27(), instr_das_2f(), instr_lahf_9f(), instr_mov_8c(), instr_mov_8e(), instr_sahf_9e(), instr_sldt_0f00(), and instr_wait_9b().
| #define TRACK_FPU_LAST_INSTRUCTION 0x0 |
Referenced by emu_cpu_step().
| #define TRACK_INIT_EFLAG | ( | instruction, | |||
| fl | ) | (instruction).track.init.eflags |= 1 << (fl) |
| #define TRACK_INIT_FPU | ( | instruction, | |||
| what | ) | (instruction).track.init.fpu |= 1 << (what); |
Referenced by emu_cpu_step().
| #define TRACK_INIT_REG16 | ( | instruction, | |||
| reg16 | ) | (instruction).track.init.reg[reg16] |= 0xffff << 16; |
Referenced by instr_group_1_81_xor(), instr_group_1_83_xor(), instr_mov_8a(), instr_mov_8b(), instr_pop_5x(), instr_xor_31(), instr_xor_33(), and instr_xor_35().
| #define TRACK_INIT_REG32 | ( | instruction, | |||
| reg32 | ) | (instruction).track.init.reg[reg32] = 0xffffffff; |
| #define TRACK_INIT_REG8 | ( | instruction, | |||
| reg8 | ) | (instruction).track.init.reg[reg8] |= 0xff << 24; |
Referenced by instr_group_1_80_xor(), instr_lods_ac(), instr_setcc_0f94(), instr_setcc_0f95(), instr_xor_30(), instr_xor_32(), and instr_xor_34().
| #define TRACK_NEED_EFLAG | ( | instruction, | |||
| fl | ) | (instruction).track.need.eflags |= 1 << (fl) |
Referenced by instr_jcc_0f80(), instr_jcc_0f81(), instr_jcc_0f82(), instr_jcc_0f83(), instr_jcc_0f84(), instr_jcc_0f85(), instr_jcc_0f86(), instr_jcc_0f87(), instr_jcc_0f88(), instr_jcc_0f89(), instr_jcc_0f8a(), instr_jcc_0f8b(), instr_jcc_0f8c(), instr_jcc_0f8d(), instr_jcc_0f8e(), instr_jcc_0f8f(), instr_jcc_70(), instr_jcc_71(), instr_jcc_72(), instr_jcc_73(), instr_jcc_74(), instr_jcc_75(), instr_jcc_76(), instr_jcc_77(), instr_jcc_78(), instr_jcc_79(), instr_jcc_7a(), instr_jcc_7b(), instr_jcc_7c(), instr_jcc_7d(), instr_jcc_7e(), instr_jcc_7f(), instr_loopcc_e0(), instr_loopcc_e1(), instr_setcc_0f94(), and instr_setcc_0f95().
| #define TRACK_NEED_FPU | ( | instruction, | |||
| what | ) | (instruction).track.need.fpu |= 1 << (what); |
Referenced by emu_cpu_step().
| #define TRACK_NEED_REG16 | ( | instruction, | |||
| reg16 | ) | (instruction).track.need.reg[reg16] |= 0xffff << 16; |
| #define TRACK_NEED_REG32 | ( | instruction, | |||
| reg32 | ) | (instruction).track.need.reg[reg32] = 0xffffffff; |
| #define TRACK_NEED_REG8 | ( | instruction, | |||
| reg8 | ) | (instruction).track.need.reg[reg8] |= 0xff << 24; |
Referenced by instr_group_1_80_xor(), instr_xor_30(), instr_xor_32(), and instr_xor_34().
| #define UINTOF | ( | bits | ) | uint##bits##_t |
| #define UNIMPLEMENTED | ( | cpu_p, | |||
| reason | ) |
emu_strerror_set((cpu_p)->emu, "The following function is unimplemented %s %s:%i (%s)", __PRETTY_FUNCTION__, __FILE__, __LINE__, reason); \ return -1;
Referenced by instr_call_9a(), instr_group_5_ff_call(), instr_group_5_ff_jmp(), instr_jmp_ea(), instr_lea_8d(), instr_lods_ac(), instr_lods_ad(), instr_movsb(), instr_pop_07(), instr_pop_0fa1(), instr_pop_0fa9(), instr_pop_17(), instr_pop_1f(), instr_push_06(), instr_push_0e(), instr_push_0f08(), instr_push_0fa0(), instr_push_16(), instr_push_1e(), instr_ret_ca(), instr_ret_cb(), instr_scas_ae(), instr_scas_af(), instr_stos_aa(), and instr_stos_ab().
| #define WORD_LOWER_TO_BYTE | ( | to, | |||
| from | ) | memcpy(&(to),&(from),1); |
| #define WORD_UPPER_TO_BYTE | ( | to, | |||
| from | ) | memcpy(&(to),((uint8_t *)&(from))+1,1); |
Referenced by instr_group_3_f6_imul(), instr_group_3_f6_mul(), instr_imul_0f_af(), instr_imul_69(), and instr_imul_6b().
| enum emu_cpu_debug_flag |
| enum emu_cpu_flag |
| int64_t max_inttype_borders[][2][2] |
int type min/max for signed/unsigned int to 32bits size
access is max_inittype_border[bits/8][signed|unsigned][min|max]
where signed/min is 0 and unsigned/max is 1
1.6.1