--- BasiliskII/src/Unix/sigsegv.cpp 2008/01/07 22:44:39 1.78 +++ BasiliskII/src/Unix/sigsegv.cpp 2008/01/19 22:25:27 1.81 @@ -49,6 +49,17 @@ using std::list; #define RETSIGTYPE void #endif +// Size of an unsigned integer large enough to hold all bits of a pointer +// NOTE: this can be different than SIGSEGV_REGISTER_TYPE. In +// particular, on ILP32 systems with a 64-bit kernel (HP-UX/ia64?) +#ifdef HAVE_WIN32_VM +// Windows is either ILP32 or LLP64 +typedef UINT_PTR sigsegv_uintptr_t; +#else +// Other systems are sane enough to follow ILP32 or LP64 models +typedef unsigned long sigsegv_uintptr_t; +#endif + // Type of the system signal handler typedef RETSIGTYPE (*signal_handler)(int); @@ -264,14 +275,14 @@ static void powerpc_decode_instruction(i #include #define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs) #define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[EIP] -#define SIGSEGV_REGISTER_FILE (unsigned long *)SIGSEGV_CONTEXT_REGS +#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS #define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction #endif #endif #if defined(__FreeBSD__) || defined(__OpenBSD__) #if (defined(i386) || defined(__i386__)) #define SIGSEGV_FAULT_INSTRUCTION (((struct sigcontext *)scp)->sc_eip) -#define SIGSEGV_REGISTER_FILE ((unsigned long *)&(((struct sigcontext *)scp)->sc_edi)) /* EDI is the first GPR (even below EIP) in sigcontext */ +#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&(((struct sigcontext *)scp)->sc_edi)) /* EDI is the first GPR (even below EIP) in sigcontext */ #define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction #endif #endif @@ -280,7 +291,7 @@ static void powerpc_decode_instruction(i #include #define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.__gregs) #define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[_REG_EIP] -#define SIGSEGV_REGISTER_FILE (unsigned long *)SIGSEGV_CONTEXT_REGS +#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS #define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction #endif #if (defined(powerpc) || defined(__powerpc__)) @@ -296,14 +307,14 @@ static void powerpc_decode_instruction(i #include #define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs) #define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[14] /* should use REG_EIP instead */ -#define SIGSEGV_REGISTER_FILE (unsigned long *)SIGSEGV_CONTEXT_REGS +#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS #define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction #endif #if (defined(x86_64) || defined(__x86_64__)) #include #define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs) #define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[16] /* should use REG_RIP instead */ -#define SIGSEGV_REGISTER_FILE (unsigned long *)SIGSEGV_CONTEXT_REGS +#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS #define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction #endif #if (defined(ia64) || defined(__ia64__)) @@ -351,7 +362,7 @@ static void powerpc_decode_instruction(i #define SIGSEGV_FAULT_HANDLER_ARGS &scs #define SIGSEGV_FAULT_ADDRESS scp->cr2 #define SIGSEGV_FAULT_INSTRUCTION scp->eip -#define SIGSEGV_REGISTER_FILE (unsigned long *)scp +#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)scp #define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction #endif #if (defined(sparc) || defined(__sparc__)) @@ -472,7 +483,7 @@ static sigsegv_address_t get_fault_addre #define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp, addr #define SIGSEGV_FAULT_ADDRESS addr #define SIGSEGV_FAULT_INSTRUCTION scp->sc_eip -#define SIGSEGV_REGISTER_FILE ((unsigned long *)&scp->sc_edi) +#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&scp->sc_edi) #define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction #endif #if (defined(alpha) || defined(__alpha__)) @@ -535,14 +546,25 @@ static sigsegv_address_t get_fault_addre #include #include +#if defined(_M_IX86) #define SIGSEGV_FAULT_HANDLER_ARGLIST EXCEPTION_POINTERS *ExceptionInfo #define SIGSEGV_FAULT_HANDLER_ARGS ExceptionInfo #define SIGSEGV_FAULT_ADDRESS ExceptionInfo->ExceptionRecord->ExceptionInformation[1] #define SIGSEGV_CONTEXT_REGS ExceptionInfo->ContextRecord #define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS->Eip -#define SIGSEGV_REGISTER_FILE ((unsigned long *)&SIGSEGV_CONTEXT_REGS->Edi) +#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIGSEGV_CONTEXT_REGS->Edi) +#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction +#endif +#if defined(_M_X64) +#define SIGSEGV_FAULT_HANDLER_ARGLIST EXCEPTION_POINTERS *ExceptionInfo +#define SIGSEGV_FAULT_HANDLER_ARGS ExceptionInfo +#define SIGSEGV_FAULT_ADDRESS ExceptionInfo->ExceptionRecord->ExceptionInformation[1] +#define SIGSEGV_CONTEXT_REGS ExceptionInfo->ContextRecord +#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS->Rip +#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIGSEGV_CONTEXT_REGS->Rax) #define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction #endif +#endif #if HAVE_MACH_EXCEPTIONS @@ -605,58 +627,74 @@ if (ret != KERN_SUCCESS) { \ } #ifdef __ppc__ +#if __DARWIN_UNIX03 && defined _STRUCT_PPC_THREAD_STATE +#define MACH_FIELD_NAME(X) __CONCAT(__,X) +#endif #define SIGSEGV_EXCEPTION_STATE_TYPE ppc_exception_state_t #define SIGSEGV_EXCEPTION_STATE_FLAVOR PPC_EXCEPTION_STATE #define SIGSEGV_EXCEPTION_STATE_COUNT PPC_EXCEPTION_STATE_COUNT -#define SIGSEGV_FAULT_ADDRESS SIP->exc_state.dar +#define SIGSEGV_FAULT_ADDRESS SIP->exc_state.MACH_FIELD_NAME(dar) #define SIGSEGV_THREAD_STATE_TYPE ppc_thread_state_t #define SIGSEGV_THREAD_STATE_FLAVOR PPC_THREAD_STATE #define SIGSEGV_THREAD_STATE_COUNT PPC_THREAD_STATE_COUNT -#define SIGSEGV_FAULT_INSTRUCTION SIP->thr_state.srr0 +#define SIGSEGV_FAULT_INSTRUCTION SIP->thr_state.MACH_FIELD_NAME(srr0) #define SIGSEGV_SKIP_INSTRUCTION powerpc_skip_instruction -#define SIGSEGV_REGISTER_FILE (unsigned long *)&SIP->thr_state.srr0, (unsigned long *)&SIP->thr_state.r0 +#define SIGSEGV_REGISTER_FILE (unsigned long *)&SIP->thr_state.MACH_FIELD_NAME(srr0), (unsigned long *)&SIP->thr_state.MACH_FIELD_NAME(r0) #endif #ifdef __ppc64__ +#if __DARWIN_UNIX03 && defined _STRUCT_PPC_THREAD_STATE64 +#define MACH_FIELD_NAME(X) __CONCAT(__,X) +#endif #define SIGSEGV_EXCEPTION_STATE_TYPE ppc_exception_state64_t #define SIGSEGV_EXCEPTION_STATE_FLAVOR PPC_EXCEPTION_STATE64 #define SIGSEGV_EXCEPTION_STATE_COUNT PPC_EXCEPTION_STATE64_COUNT -#define SIGSEGV_FAULT_ADDRESS SIP->exc_state.dar +#define SIGSEGV_FAULT_ADDRESS SIP->exc_state.MACH_FIELD_NAME(dar) #define SIGSEGV_THREAD_STATE_TYPE ppc_thread_state64_t #define SIGSEGV_THREAD_STATE_FLAVOR PPC_THREAD_STATE64 #define SIGSEGV_THREAD_STATE_COUNT PPC_THREAD_STATE64_COUNT -#define SIGSEGV_FAULT_INSTRUCTION SIP->thr_state.srr0 +#define SIGSEGV_FAULT_INSTRUCTION SIP->thr_state.MACH_FIELD_NAME(srr0) #define SIGSEGV_SKIP_INSTRUCTION powerpc_skip_instruction -#define SIGSEGV_REGISTER_FILE (unsigned long *)&SIP->thr_state.srr0, (unsigned long *)&SIP->thr_state.r0 +#define SIGSEGV_REGISTER_FILE (unsigned long *)&SIP->thr_state.MACH_FIELD_NAME(srr0), (unsigned long *)&SIP->thr_state.MACH_FIELD_NAME(r0) #endif #ifdef __i386__ -#define SIGSEGV_EXCEPTION_STATE_TYPE struct i386_exception_state +#if __DARWIN_UNIX03 && defined _STRUCT_X86_THREAD_STATE32 +#define MACH_FIELD_NAME(X) __CONCAT(__,X) +#endif +#define SIGSEGV_EXCEPTION_STATE_TYPE i386_exception_state_t #define SIGSEGV_EXCEPTION_STATE_FLAVOR i386_EXCEPTION_STATE #define SIGSEGV_EXCEPTION_STATE_COUNT i386_EXCEPTION_STATE_COUNT -#define SIGSEGV_FAULT_ADDRESS SIP->exc_state.faultvaddr -#define SIGSEGV_THREAD_STATE_TYPE struct i386_thread_state +#define SIGSEGV_FAULT_ADDRESS SIP->exc_state.MACH_FIELD_NAME(faultvaddr) +#define SIGSEGV_THREAD_STATE_TYPE i386_thread_state_t #define SIGSEGV_THREAD_STATE_FLAVOR i386_THREAD_STATE #define SIGSEGV_THREAD_STATE_COUNT i386_THREAD_STATE_COUNT -#define SIGSEGV_FAULT_INSTRUCTION SIP->thr_state.eip +#define SIGSEGV_FAULT_INSTRUCTION SIP->thr_state.MACH_FIELD_NAME(eip) #define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction -#define SIGSEGV_REGISTER_FILE ((unsigned long *)&SIP->thr_state.eax) /* EAX is the first GPR we consider */ +#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIP->thr_state.MACH_FIELD_NAME(eax)) /* EAX is the first GPR we consider */ #endif #ifdef __x86_64__ -#define SIGSEGV_EXCEPTION_STATE_TYPE struct x86_exception_state64 +#if __DARWIN_UNIX03 && defined _STRUCT_X86_THREAD_STATE64 +#define MACH_FIELD_NAME(X) __CONCAT(__,X) +#endif +#define SIGSEGV_EXCEPTION_STATE_TYPE x86_exception_state64_t #define SIGSEGV_EXCEPTION_STATE_FLAVOR x86_EXCEPTION_STATE64 #define SIGSEGV_EXCEPTION_STATE_COUNT x86_EXCEPTION_STATE64_COUNT -#define SIGSEGV_FAULT_ADDRESS SIP->exc_state.faultvaddr -#define SIGSEGV_THREAD_STATE_TYPE struct x86_thread_state64 +#define SIGSEGV_FAULT_ADDRESS SIP->exc_state.MACH_FIELD_NAME(faultvaddr) +#define SIGSEGV_THREAD_STATE_TYPE x86_thread_state64_t #define SIGSEGV_THREAD_STATE_FLAVOR x86_THREAD_STATE64 #define SIGSEGV_THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT -#define SIGSEGV_FAULT_INSTRUCTION SIP->thr_state.rip +#define SIGSEGV_FAULT_INSTRUCTION SIP->thr_state.MACH_FIELD_NAME(rip) #define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction -#define SIGSEGV_REGISTER_FILE ((unsigned long *)&SIP->thr_state.rax) /* RAX is the first GPR we consider */ +#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIP->thr_state.MACH_FIELD_NAME(rax)) /* RAX is the first GPR we consider */ #endif #define SIGSEGV_FAULT_ADDRESS_FAST code[1] #define SIGSEGV_FAULT_INSTRUCTION_FAST SIGSEGV_INVALID_ADDRESS #define SIGSEGV_FAULT_HANDLER_ARGLIST mach_port_t thread, exception_data_t code #define SIGSEGV_FAULT_HANDLER_ARGS thread, code +#ifndef MACH_FIELD_NAME +#define MACH_FIELD_NAME(X) X +#endif + // Since there can only be one exception thread running at any time // this is not a problem. #define MSG_SIZE 512 @@ -708,9 +746,13 @@ handleExceptions(void *priv) * Instruction skipping */ +#ifndef SIGSEGV_REGISTER_TYPE +#define SIGSEGV_REGISTER_TYPE sigsegv_uintptr_t +#endif + #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION // Decode and skip X86 instruction -#if (defined(i386) || defined(__i386__)) || defined(__x86_64__) +#if (defined(i386) || defined(__i386__)) || (defined(__x86_64__) || defined(_M_X64)) #if defined(__linux__) enum { #if (defined(i386) || defined(__i386__)) @@ -861,7 +903,7 @@ enum { #endif #if defined(_WIN32) enum { -#if (defined(i386) || defined(__i386__)) +#if defined(_M_IX86) X86_REG_EIP = 7, X86_REG_EAX = 5, X86_REG_ECX = 4, @@ -872,6 +914,25 @@ enum { X86_REG_ESI = 1, X86_REG_EDI = 0 #endif +#if defined(_M_X64) + X86_REG_EAX = 0, + X86_REG_ECX = 1, + X86_REG_EDX = 2, + X86_REG_EBX = 3, + X86_REG_ESP = 4, + X86_REG_EBP = 5, + X86_REG_ESI = 6, + X86_REG_EDI = 7, + X86_REG_R8 = 8, + X86_REG_R9 = 9, + X86_REG_R10 = 10, + X86_REG_R11 = 11, + X86_REG_R12 = 12, + X86_REG_R13 = 13, + X86_REG_R14 = 14, + X86_REG_R15 = 15, + X86_REG_EIP = 16 +#endif }; #endif // FIXME: this is partly redundant with the instruction decoding phase @@ -908,7 +969,7 @@ static inline int ix86_step_over_modrm(u return offset; } -static bool ix86_skip_instruction(unsigned long * regs) +static bool ix86_skip_instruction(SIGSEGV_REGISTER_TYPE * regs) { unsigned char * eip = (unsigned char *)regs[X86_REG_EIP]; @@ -944,7 +1005,7 @@ static bool ix86_skip_instruction(unsign } // REX prefix -#if defined(__x86_64__) +#if defined(__x86_64__) || defined(_M_X64) struct rex_t { unsigned char W; unsigned char R; @@ -996,7 +1057,7 @@ static bool ix86_skip_instruction(unsign goto do_transfer_load; } break; -#if defined(__x86_64__) +#if defined(__x86_64__) || defined(_M_X64) case 0x63: // MOVSXD r64, r/m32 if (has_rex && rex.W) { transfer_size = SIZE_LONG; @@ -1067,7 +1128,7 @@ static bool ix86_skip_instruction(unsign return false; } -#if defined(__x86_64__) +#if defined(__x86_64__) || defined(_M_X64) if (rex.R) reg += 8; #endif @@ -1076,7 +1137,7 @@ static bool ix86_skip_instruction(unsign static const int x86_reg_map[] = { X86_REG_EAX, X86_REG_ECX, X86_REG_EDX, X86_REG_EBX, X86_REG_ESP, X86_REG_EBP, X86_REG_ESI, X86_REG_EDI, -#if defined(__x86_64__) +#if defined(__x86_64__) || defined(_M_X64) X86_REG_R8, X86_REG_R9, X86_REG_R10, X86_REG_R11, X86_REG_R12, X86_REG_R13, X86_REG_R14, X86_REG_R15, #endif @@ -1165,9 +1226,10 @@ static bool ix86_skip_instruction(unsign // Decode and skip IA-64 instruction #if defined(__ia64__) +typedef uint64_t ia64_bundle_t[2]; #if defined(__linux__) // We can directly patch the slot number -#define IA64_CAN_PATCH_IP_SLOT 1 +#define IA64_CAN_PATCH_IP_SLOT 1 // Helper macros to access the machine context #define IA64_CONTEXT_TYPE struct sigcontext * #define IA64_CONTEXT scp @@ -1175,9 +1237,18 @@ static bool ix86_skip_instruction(unsign #define IA64_SET_IP(V) (IA64_CONTEXT->sc_ip = (V)) #define IA64_GET_PR(P) ((IA64_CONTEXT->sc_pr >> (P)) & 1) #define IA64_GET_NAT(I) ((IA64_CONTEXT->sc_nat >> (I)) & 1) -#define IA64_SET_NAT(I,V) (IA64_CONTEXT->sc_nat= (IA64_CONTEXT->sc_nat & ~(1ul << (I))) | (((unsigned long)!!(V)) << (I))) #define IA64_GET_GR(R) (IA64_CONTEXT->sc_gr[(R)]) -#define IA64_SET_GR(R,V) (IA64_CONTEXT->sc_gr[(R)] = (V)) +#define _IA64_SET_GR(R,V) (IA64_CONTEXT->sc_gr[(R)] = (V)) +#define _IA64_SET_NAT(I,V) (IA64_CONTEXT->sc_nat = (IA64_CONTEXT->sc_nat & ~(1ull << (I))) | (((uint64_t)!!(V)) << (I))) +#define IA64_SET_GR(R,V,N) (_IA64_SET_GR(R,V), _IA64_SET_NAT(R,N)) + +// Load bundle (in little-endian) +static inline void ia64_load_bundle(ia64_bundle_t bundle, uint64_t raw_ip) +{ + uint64_t *ip = (uint64_t *)(raw_ip & ~3ull); + bundle[0] = ip[0]; + bundle[1] = ip[1]; +} #endif // Instruction operations @@ -1219,112 +1290,114 @@ const int IA64_N_OPERANDS = 4; // Decoded operand type struct ia64_operand_t { - unsigned char commit; // commit result of operation to register file? - unsigned char valid; // XXX: not really used, can be removed (debug) - signed char index; // index of GPR, or -1 if immediate value - unsigned char nat; // NaT state before operation - unsigned long value; // register contents or immediate value + uint8_t commit; // commit result of operation to register file? + uint8_t valid; // XXX: not really used, can be removed (debug) + int8_t index; // index of GPR, or -1 if immediate value + uint8_t nat; // NaT state before operation + uint64_t value; // register contents or immediate value }; // Decoded instruction type struct ia64_instruction_t { - unsigned char mnemo; // operation to perform - unsigned char pred; // predicate register to check - unsigned char no_memory; // used to emulated main fault instruction - unsigned long inst; // the raw instruction bits (41-bit wide) + uint8_t mnemo; // operation to perform + uint8_t pred; // predicate register to check + uint8_t no_memory; // used to emulated main fault instruction + uint64_t inst; // the raw instruction bits (41-bit wide) ia64_operand_t operands[IA64_N_OPERANDS]; }; // Get immediate sign-bit -static inline int ia64_inst_get_sbit(unsigned long inst) +static inline int ia64_inst_get_sbit(uint64_t inst) { return (inst >> 36) & 1; } // Get 8-bit immediate value (A3, A8, I27, M30) -static inline unsigned long ia64_inst_get_imm8(unsigned long inst) +static inline uint64_t ia64_inst_get_imm8(uint64_t inst) { - unsigned long value = (inst >> 13) & 0x7ful; + uint64_t value = (inst >> 13) & 0x7full; if (ia64_inst_get_sbit(inst)) - value |= ~0x7ful; + value |= ~0x7full; return value; } // Get 9-bit immediate value (M3) -static inline unsigned long ia64_inst_get_imm9b(unsigned long inst) +static inline uint64_t ia64_inst_get_imm9b(uint64_t inst) { - unsigned long value = (((inst >> 27) & 1) << 7) | ((inst >> 13) & 0x7f); + uint64_t value = (((inst >> 27) & 1) << 7) | ((inst >> 13) & 0x7f); if (ia64_inst_get_sbit(inst)) - value |= ~0xfful; + value |= ~0xffull; return value; } // Get 9-bit immediate value (M5) -static inline unsigned long ia64_inst_get_imm9a(unsigned long inst) +static inline uint64_t ia64_inst_get_imm9a(uint64_t inst) { - unsigned long value = (((inst >> 27) & 1) << 7) | ((inst >> 6) & 0x7f); + uint64_t value = (((inst >> 27) & 1) << 7) | ((inst >> 6) & 0x7f); if (ia64_inst_get_sbit(inst)) - value |= ~0xfful; + value |= ~0xffull; return value; } // Get 14-bit immediate value (A4) -static inline unsigned long ia64_inst_get_imm14(unsigned long inst) +static inline uint64_t ia64_inst_get_imm14(uint64_t inst) { - unsigned long value = (((inst >> 27) & 0x3f) << 7) | (inst & 0x7f); + uint64_t value = (((inst >> 27) & 0x3f) << 7) | (inst & 0x7f); if (ia64_inst_get_sbit(inst)) - value |= ~0x1fful; + value |= ~0x1ffull; return value; } // Get 22-bit immediate value (A5) -static inline unsigned long ia64_inst_get_imm22(unsigned long inst) +static inline uint64_t ia64_inst_get_imm22(uint64_t inst) { - unsigned long value = ((((inst >> 22) & 0x1f) << 16) | - (((inst >> 27) & 0x1ff) << 7) | - (inst & 0x7f)); + uint64_t value = ((((inst >> 22) & 0x1f) << 16) | + (((inst >> 27) & 0x1ff) << 7) | + (inst & 0x7f)); if (ia64_inst_get_sbit(inst)) - value |= ~0x1ffffful; + value |= ~0x1fffffull; return value; } // Get 21-bit immediate value (I19) -static inline unsigned long ia64_inst_get_imm21(unsigned long inst) +static inline uint64_t ia64_inst_get_imm21(uint64_t inst) { return (((inst >> 36) & 1) << 20) | ((inst >> 6) & 0xfffff); } // Get 2-bit count value (A2) -static inline int ia64_inst_get_count2(unsigned long inst) +static inline int ia64_inst_get_count2(uint64_t inst) { return (inst >> 27) & 0x3; } // Get bundle template -static inline unsigned int ia64_get_template(unsigned long raw_ip) +static inline unsigned int ia64_get_template(uint64_t ip) { - unsigned long *ip = (unsigned long *)(raw_ip & ~3ul); - return ip[0] & 0x1f; + ia64_bundle_t bundle; + ia64_load_bundle(bundle, ip); + return bundle[0] & 0x1f; } // Get specified instruction in bundle -static unsigned long ia64_get_instruction(unsigned long raw_ip, int slot) +static uint64_t ia64_get_instruction(uint64_t ip, int slot) { - unsigned long inst; - unsigned long *ip = (unsigned long *)(raw_ip & ~3ul); + uint64_t inst; + ia64_bundle_t bundle; + ia64_load_bundle(bundle, ip); #if DEBUG - printf("Bundle: %016lx%016lx\n", ip[1], ip[0]); + printf("Bundle: %016llx%016llx\n", bundle[1], bundle[0]); #endif switch (slot) { case 0: - inst = (ip[0] >> 5) & 0x1fffffffffful; + inst = (bundle[0] >> 5) & 0x1ffffffffffull; break; case 1: - inst = ((ip[1] & 0x7ffffful) << 18) | ((ip[0] >> 46) & 0x3fffful); + inst = ((bundle[1] & 0x7fffffull) << 18) | ((bundle[0] >> 46) & 0x3ffffull); break; case 2: - inst = (ip[1] >> 23) & 0x1fffffffffful; + inst = (bundle[1] >> 23) & 0x1ffffffffffull; break; case 3: fprintf(stderr, "ERROR: ia64_get_instruction(), invalid slot number %d\n", slot); @@ -1333,7 +1406,7 @@ static unsigned long ia64_get_instructio } #if DEBUG - printf(" Instruction %d: 0x%016lx\n", slot, inst); + printf(" Instruction %d: 0x%016llx\n", slot, inst); #endif return inst; } @@ -1617,8 +1690,8 @@ static bool ia64_emulate_instruction(ia6 if (inst->pred && !IA64_GET_PR(inst->pred)) return true; - unsigned char nat, nat2; - unsigned long dst, dst2, src1, src2, src3; + uint8_t nat, nat2; + uint64_t dst, dst2, src1, src2, src3; switch (inst->mnemo) { case IA64_INST_NOP: @@ -1655,12 +1728,12 @@ static bool ia64_emulate_instruction(ia6 case IA64_INST_ZXT4: src1 = inst->operands[1].value; switch (inst->mnemo) { - case IA64_INST_SXT1: dst = (signed long)(signed char)src1; break; - case IA64_INST_SXT2: dst = (signed long)(signed short)src1; break; - case IA64_INST_SXT4: dst = (signed long)(signed int)src1; break; - case IA64_INST_ZXT1: dst = (unsigned char)src1; break; - case IA64_INST_ZXT2: dst = (unsigned short)src1; break; - case IA64_INST_ZXT4: dst = (unsigned int)src1; break; + case IA64_INST_SXT1: dst = (int64_t)(int8_t)src1; break; + case IA64_INST_SXT2: dst = (int64_t)(int16_t)src1; break; + case IA64_INST_SXT4: dst = (int64_t)(int32_t)src1; break; + case IA64_INST_ZXT1: dst = (uint8_t)src1; break; + case IA64_INST_ZXT2: dst = (uint16_t)src1; break; + case IA64_INST_ZXT4: dst = (uint32_t)src1; break; } inst->operands[0].commit = true; inst->operands[0].value = dst; @@ -1683,10 +1756,10 @@ static bool ia64_emulate_instruction(ia6 dst = 0; else { switch (inst->mnemo) { - case IA64_INST_LD1: case IA64_INST_LD1_UPDATE: dst = *((unsigned char *)src1); break; - case IA64_INST_LD2: case IA64_INST_LD2_UPDATE: dst = *((unsigned short *)src1); break; - case IA64_INST_LD4: case IA64_INST_LD4_UPDATE: dst = *((unsigned int *)src1); break; - case IA64_INST_LD8: case IA64_INST_LD8_UPDATE: dst = *((unsigned long *)src1); break; + case IA64_INST_LD1: case IA64_INST_LD1_UPDATE: dst = *((uint8_t *)src1); break; + case IA64_INST_LD2: case IA64_INST_LD2_UPDATE: dst = *((uint16_t *)src1); break; + case IA64_INST_LD4: case IA64_INST_LD4_UPDATE: dst = *((uint32_t *)src1); break; + case IA64_INST_LD8: case IA64_INST_LD8_UPDATE: dst = *((uint64_t *)src1); break; } } inst->operands[0].commit = true; @@ -1711,10 +1784,10 @@ static bool ia64_emulate_instruction(ia6 src1 = inst->operands[1].value; if (!inst->no_memory) { switch (inst->mnemo) { - case IA64_INST_ST1: case IA64_INST_ST1_UPDATE: *((unsigned char *)dst) = src1; break; - case IA64_INST_ST2: case IA64_INST_ST2_UPDATE: *((unsigned short *)dst) = src1; break; - case IA64_INST_ST4: case IA64_INST_ST4_UPDATE: *((unsigned int *)dst) = src1; break; - case IA64_INST_ST8: case IA64_INST_ST8_UPDATE: *((unsigned long *)dst) = src1; break; + case IA64_INST_ST1: case IA64_INST_ST1_UPDATE: *((uint8_t *)dst) = src1; break; + case IA64_INST_ST2: case IA64_INST_ST2_UPDATE: *((uint16_t *)dst) = src1; break; + case IA64_INST_ST4: case IA64_INST_ST4_UPDATE: *((uint32_t *)dst) = src1; break; + case IA64_INST_ST8: case IA64_INST_ST8_UPDATE: *((uint64_t *)dst) = src1; break; } } inst->operands[0].value = dst2; @@ -1730,13 +1803,12 @@ static bool ia64_emulate_instruction(ia6 continue; if (op.index == -1) return false; // XXX: internal error - IA64_SET_GR(op.index, op.value); - IA64_SET_NAT(op.index, op.nat); + IA64_SET_GR(op.index, op.value, op.nat); } return true; } -static bool ia64_emulate_instruction(unsigned long raw_inst, IA64_CONTEXT_TYPE IA64_CONTEXT) +static bool ia64_emulate_instruction(uint64_t raw_inst, IA64_CONTEXT_TYPE IA64_CONTEXT) { ia64_instruction_t inst; memset(&inst, 0, sizeof(inst)); @@ -1748,9 +1820,9 @@ static bool ia64_emulate_instruction(uns static bool ia64_skip_instruction(IA64_CONTEXT_TYPE IA64_CONTEXT) { - unsigned long ip = IA64_GET_IP(); + uint64_t ip = IA64_GET_IP(); #if DEBUG - printf("IP: 0x%016lx\n", ip); + printf("IP: 0x%016llx\n", ip); #if 0 printf(" Template 0x%02x\n", ia64_get_template(ip)); ia64_get_instruction(ip, 0); @@ -1868,12 +1940,12 @@ static bool ia64_skip_instruction(IA64_C #if IA64_CAN_PATCH_IP_SLOT if ((slot = ip & 3) < 2) - IA64_SET_IP((ip & ~3ul) + (slot + 1)); + IA64_SET_IP((ip & ~3ull) + (slot + 1)); else #endif - IA64_SET_IP((ip & ~3ul) + 16); + IA64_SET_IP((ip & ~3ull) + 16); #if DEBUG - printf("IP: 0x%016lx\n", IA64_GET_IP()); + printf("IP: 0x%016llx\n", IA64_GET_IP()); #endif return true; } @@ -2976,7 +3048,7 @@ void sigsegv_set_dump_state(sigsegv_stat const int REF_INDEX = 123; const int REF_VALUE = 45; -static int page_size; +static sigsegv_uintptr_t page_size; static volatile char * page = 0; static volatile int handler_called = 0; @@ -3014,7 +3086,7 @@ static sigsegv_return_t sigsegv_test_han (instruction_address >= (sigsegv_address_t)e_region))) exit(11); #endif - if (vm_protect((char *)((unsigned long)fault_address & -page_size), page_size, VM_PAGE_READ | VM_PAGE_WRITE) != 0) + if (vm_protect((char *)((sigsegv_uintptr_t)fault_address & -page_size), page_size, VM_PAGE_READ | VM_PAGE_WRITE) != 0) exit(12); return SIGSEGV_RETURN_SUCCESS; } @@ -3027,7 +3099,7 @@ static sigsegv_return_t sigsegv_insn_han #if DEBUG printf("sigsegv_insn_handler(%p, %p)\n", fault_address, instruction_address); #endif - if (((unsigned long)fault_address - (unsigned long)page) < page_size) { + if (((sigsegv_uintptr_t)fault_address - (sigsegv_uintptr_t)page) < page_size) { #ifdef __GNUC__ // Make sure reported fault instruction address falls into // expected code range @@ -3045,7 +3117,7 @@ static sigsegv_return_t sigsegv_insn_han // More sophisticated tests for instruction skipper static bool arch_insn_skipper_tests() { -#if (defined(i386) || defined(__i386__)) || defined(__x86_64__) +#if (defined(i386) || defined(__i386__)) || (defined(__x86_64__) || defined(_M_X64)) static const unsigned char code[] = { 0x8a, 0x00, // mov (%eax),%al 0x8a, 0x2c, 0x18, // mov (%eax,%ebx,1),%ch @@ -3059,7 +3131,7 @@ static bool arch_insn_skipper_tests() 0x8b, 0x0c, 0x18, // mov (%eax,%ebx,1),%ecx 0x89, 0x00, // mov %eax,(%eax) 0x89, 0x0c, 0x18, // mov %ecx,(%eax,%ebx,1) -#if defined(__x86_64__) +#if defined(__x86_64__) || defined(_M_X64) 0x44, 0x8a, 0x00, // mov (%rax),%r8b 0x44, 0x8a, 0x20, // mov (%rax),%r12b 0x42, 0x8a, 0x3c, 0x10, // mov (%rax,%r10,1),%dil @@ -3088,10 +3160,10 @@ static bool arch_insn_skipper_tests() 0 // end }; const int N_REGS = 20; - unsigned long regs[N_REGS]; + SIGSEGV_REGISTER_TYPE regs[N_REGS]; for (int i = 0; i < N_REGS; i++) regs[i] = i; - const unsigned long start_code = (unsigned long)&code; + const sigsegv_uintptr_t start_code = (sigsegv_uintptr_t)&code; regs[X86_REG_EIP] = start_code; while ((regs[X86_REG_EIP] - start_code) < (sizeof(code) - 1) && ix86_skip_instruction(regs))