215 |
|
#endif |
216 |
|
#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *scp |
217 |
|
#define SIGSEGV_FAULT_ADDRESS sip->si_addr |
218 |
+ |
#if defined(__NetBSD__) || defined(__FreeBSD__) |
219 |
+ |
#if (defined(i386) || defined(__i386__)) |
220 |
+ |
#define SIGSEGV_FAULT_INSTRUCTION (((struct sigcontext *)scp)->sc_eip) |
221 |
+ |
#define SIGSEGV_REGISTER_FILE ((unsigned int *)&(((struct sigcontext *)scp)->sc_edi)) /* EDI is the first GPR (even below EIP) in sigcontext */ |
222 |
+ |
/* (gb) Disable because this would hang configure script for some reason |
223 |
+ |
* though standalone testing gets it right. Any idea why? |
224 |
+ |
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction |
225 |
+ |
*/ |
226 |
+ |
#endif |
227 |
+ |
#endif |
228 |
|
#if defined(__linux__) |
229 |
|
#if (defined(i386) || defined(__i386__)) |
230 |
|
#include <sys/ucontext.h> |
398 |
|
X86_REG_EDI = 4 |
399 |
|
}; |
400 |
|
#endif |
401 |
+ |
#if defined(__NetBSD__) || defined(__FreeBSD__) |
402 |
+ |
enum { |
403 |
+ |
X86_REG_EIP = 10, |
404 |
+ |
X86_REG_EAX = 7, |
405 |
+ |
X86_REG_ECX = 6, |
406 |
+ |
X86_REG_EDX = 5, |
407 |
+ |
X86_REG_EBX = 4, |
408 |
+ |
X86_REG_ESP = 13, |
409 |
+ |
X86_REG_EBP = 2, |
410 |
+ |
X86_REG_ESI = 1, |
411 |
+ |
X86_REG_EDI = 0 |
412 |
+ |
}; |
413 |
+ |
#endif |
414 |
|
// FIXME: this is partly redundant with the instruction decoding phase |
415 |
|
// to discover transfer type and register number |
416 |
|
static inline int ix86_step_over_modrm(unsigned char * p) |
467 |
|
|
468 |
|
// Decode instruction |
469 |
|
switch (eip[0]) { |
470 |
+ |
case 0x0f: |
471 |
+ |
switch (eip[1]) { |
472 |
+ |
case 0xb6: // MOVZX r32, r/m8 |
473 |
+ |
case 0xb7: // MOVZX r32, r/m16 |
474 |
+ |
switch (eip[2] & 0xc0) { |
475 |
+ |
case 0x80: |
476 |
+ |
reg = (eip[2] >> 3) & 7; |
477 |
+ |
transfer_type = TYPE_LOAD; |
478 |
+ |
break; |
479 |
+ |
case 0x40: |
480 |
+ |
reg = (eip[2] >> 3) & 7; |
481 |
+ |
transfer_type = TYPE_LOAD; |
482 |
+ |
break; |
483 |
+ |
case 0x00: |
484 |
+ |
reg = (eip[2] >> 3) & 7; |
485 |
+ |
transfer_type = TYPE_LOAD; |
486 |
+ |
break; |
487 |
+ |
} |
488 |
+ |
len += 3 + ix86_step_over_modrm(eip + 2); |
489 |
+ |
break; |
490 |
+ |
} |
491 |
+ |
break; |
492 |
|
case 0x8a: // MOV r8, r/m8 |
493 |
|
transfer_size = SIZE_BYTE; |
494 |
|
case 0x8b: // MOV r32, r/m32 (or 16-bit operation) |
811 |
|
if (!sigsegv_install_handler(sigsegv_insn_handler)) |
812 |
|
return 1; |
813 |
|
|
814 |
< |
if (vm_protect((char *)page, page_size, VM_PAGE_WRITE) < 0) |
814 |
> |
if (vm_protect((char *)page, page_size, VM_PAGE_READ | VM_PAGE_WRITE) < 0) |
815 |
|
return 1; |
816 |
|
|
817 |
|
for (int i = 0; i < page_size; i++) |