599
599
#define SIGSEGV_REGISTER_FILE (unsigned long *)&state->srr0, (unsigned long *)&state->r0
602
#ifdef i386_SAVED_STATE
602
603
#define SIGSEGV_THREAD_STATE_TYPE struct i386_saved_state
603
604
#define SIGSEGV_THREAD_STATE_FLAVOR i386_SAVED_STATE
604
605
#define SIGSEGV_THREAD_STATE_COUNT i386_SAVED_STATE_COUNT
606
#define SIGSEGV_REGISTER_FILE ((unsigned long *)&state->edi) /* EDI is the first GPR we consider */
608
#define SIGSEGV_THREAD_STATE_TYPE struct i386_thread_state
609
#define SIGSEGV_THREAD_STATE_FLAVOR i386_THREAD_STATE
610
#define SIGSEGV_THREAD_STATE_COUNT i386_THREAD_STATE_COUNT
611
#define SIGSEGV_REGISTER_FILE ((unsigned long *)&state->eax) /* EAX is the first GPR we consider */
605
613
#define SIGSEGV_FAULT_INSTRUCTION state->eip
606
614
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction
607
#define SIGSEGV_REGISTER_FILE ((unsigned long *)&state->edi) /* EDI is the first GPR we consider */
609
616
#define SIGSEGV_FAULT_ADDRESS code[1]
610
#define SIGSEGV_FAULT_HANDLER_INVOKE(ADDR, IP) ((code[0] == KERN_PROTECTION_FAILURE) ? sigsegv_fault_handler(ADDR, IP) : SIGSEGV_RETURN_FAILURE)
617
#define SIGSEGV_FAULT_HANDLER_INVOKE(ADDR, IP) ((code[0] == KERN_PROTECTION_FAILURE || code[0] == KERN_INVALID_ADDRESS) ? sigsegv_fault_handler(ADDR, IP) : SIGSEGV_RETURN_FAILURE)
611
618
#define SIGSEGV_FAULT_HANDLER_ARGLIST mach_port_t thread, exception_data_t code, SIGSEGV_THREAD_STATE_TYPE *state
612
619
#define SIGSEGV_FAULT_HANDLER_ARGS thread, code, &state
946
#if defined(__x86_64__)
947
case 0x63: // MOVSXD r64, r/m32
948
if (has_rex && rex.W) {
949
transfer_size = SIZE_LONG;
950
target_size = SIZE_QUAD;
952
else if (transfer_size != SIZE_WORD) {
953
transfer_size = SIZE_LONG;
954
target_size = SIZE_QUAD;
956
switch (eip[1] & 0xc0) {
958
reg = (eip[1] >> 3) & 7;
959
transfer_type = SIGSEGV_TRANSFER_LOAD;
962
reg = (eip[1] >> 3) & 7;
963
transfer_type = SIGSEGV_TRANSFER_LOAD;
966
reg = (eip[1] >> 3) & 7;
967
transfer_type = SIGSEGV_TRANSFER_LOAD;
970
len += 2 + ix86_step_over_modrm(eip + 1);
926
973
case 0x8a: // MOV r8, r/m8
927
974
transfer_size = SIZE_BYTE;
928
975
case 0x8b: // MOV r32, r/m32 (or 16-bit operation)
1347
// Zero target register in case of a load operation
1348
1395
const int reg = (opcode >> 25) & 0x1f;
1398
static const char * reg_names[] = {
1399
"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
1400
"o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
1401
"l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
1402
"i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7"
1404
printf("%s %s register %s\n",
1405
transfer_size == SIZE_BYTE ? "byte" :
1406
transfer_size == SIZE_WORD ? "word" :
1407
transfer_size == SIZE_LONG ? "long" :
1408
transfer_size == SIZE_QUAD ? "quad" : "unknown",
1409
transfer_type == SIGSEGV_TRANSFER_LOAD ? "load to" : "store from",
1413
// Zero target register in case of a load operation
1349
1414
if (transfer_type == SIGSEGV_TRANSFER_LOAD && reg != 0) {
1350
1415
// FIXME: code to handle local & input registers is not tested
1351
if (reg >= 1 && reg <= 7) {
1416
if (reg >= 1 && reg < 8) {
1352
1417
// global registers
1353
1418
regs[reg - 1 + SPARC_REG_G1] = 0;
1355
else if (reg >= 8 && reg <= 15) {
1420
else if (reg >= 8 && reg < 16) {
1356
1421
// output registers
1357
1422
regs[reg - 8 + SPARC_REG_O0] = 0;
1359
else if (reg >= 16 && reg <= 23) {
1424
else if (reg >= 16 && reg < 24) {
1360
1425
// local registers (in register windows)
1362
1427
gwins->wbuf->rw_local[reg - 16] = 0;
1376
static const char * reg_names[] = {
1377
"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
1378
"o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
1379
"l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
1380
"i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7"
1382
printf("%s %s register %s\n",
1383
transfer_size == SIZE_BYTE ? "byte" :
1384
transfer_size == SIZE_WORD ? "word" :
1385
transfer_size == SIZE_LONG ? "long" :
1386
transfer_size == SIZE_QUAD ? "quad" : "unknown",
1387
transfer_type == SIGSEGV_TRANSFER_LOAD ? "load to" : "store from",
1391
1440
regs[SPARC_REG_PC] += 4;
1441
regs[SPARC_REG_nPC] += 4;
1650
1700
mach_port_t port;
1651
1701
exception_behavior_t behavior;
1652
1702
thread_state_flavor_t flavor;
1653
thread_state_t thread_state;
1703
thread_state_data_t thread_state;
1654
1704
mach_msg_type_number_t thread_state_count;
1656
1706
for (portIndex = 0; portIndex < oldExceptionPorts->maskCount; portIndex++) {
1669
1719
behavior = oldExceptionPorts->behaviors[portIndex];
1670
1720
flavor = oldExceptionPorts->flavors[portIndex];
1722
if (!VALID_THREAD_STATE_FLAVOR(flavor)) {
1723
fprintf(stderr, "Invalid thread_state flavor = %d. Not forwarding\n", flavor);
1724
return KERN_FAILURE;
1673
1728
fprintf(stderr, "forwarding exception, port = 0x%x, behaviour = %d, flavor = %d\n", port, behavior, flavor);
1676
1731
if (behavior != EXCEPTION_DEFAULT) {
1677
1732
thread_state_count = THREAD_STATE_MAX;
1678
kret = thread_get_state (thread_port, flavor, thread_state,
1733
kret = thread_get_state (thread_port, flavor, (natural_t *)&thread_state,
1679
1734
&thread_state_count);
1680
1735
MACH_CHECK_ERROR (thread_get_state, kret);
1691
1746
// fprintf(stderr, "forwarding to exception_raise_state\n");
1692
1747
kret = exception_raise_state(port, exception_type, exception_data,
1693
1748
data_count, &flavor,
1694
thread_state, thread_state_count,
1695
thread_state, &thread_state_count);
1749
(natural_t *)&thread_state, thread_state_count,
1750
(natural_t *)&thread_state, &thread_state_count);
1696
1751
MACH_CHECK_ERROR (exception_raise_state, kret);
1698
1753
case EXCEPTION_STATE_IDENTITY:
1700
1755
kret = exception_raise_state_identity(port, thread_port, task_port,
1701
1756
exception_type, exception_data,
1702
1757
data_count, &flavor,
1703
thread_state, thread_state_count,
1704
thread_state, &thread_state_count);
1758
(natural_t *)&thread_state, thread_state_count,
1759
(natural_t *)&thread_state, &thread_state_count);
1705
1760
MACH_CHECK_ERROR (exception_raise_state_identity, kret);
1708
1763
fprintf(stderr, "forward_exception got unknown behavior\n");
1764
kret = KERN_FAILURE;
1712
1768
if (behavior != EXCEPTION_DEFAULT) {
1713
kret = thread_set_state (thread_port, flavor, thread_state,
1769
kret = thread_set_state (thread_port, flavor, (natural_t *)&thread_state,
1714
1770
thread_state_count);
1715
1771
MACH_CHECK_ERROR (thread_set_state, kret);
1718
return KERN_SUCCESS;
2068
2124
static volatile char * page = 0;
2069
2125
static volatile int handler_called = 0;
2129
#define BARRIER() asm volatile ("" : : : "memory")
2131
#define BARRIER() /* nothing */
2071
2134
#ifdef __GNUC__
2072
2135
// Code range where we expect the fault to come from
2073
2136
static void *b_region, *e_region;
2159
2222
0x4c, 0x89, 0x18, // mov %r11,(%rax)
2160
2223
0x4a, 0x89, 0x0c, 0x10, // mov %rcx,(%rax,%r10,1)
2161
2224
0x4e, 0x89, 0x1c, 0x10, // mov %r11,(%rax,%r10,1)
2225
0x63, 0x47, 0x04, // movslq 4(%rdi),%eax
2226
0x48, 0x63, 0x47, 0x04, // movslq 4(%rdi),%rax