~ubuntu-branches/ubuntu/feisty/basilisk2/feisty

« back to all changes in this revision

Viewing changes to src/Unix/sigsegv.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard
  • Date: 2006-06-01 01:11:16 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060601011116-xjhegbgyfsxag5fl
Tags: 0.9.20060529-1
* New upstream CVS snapshot.
* Update local cdbs snippet copyright-check.mk:
  + Broaden scan to also look for "(c)" by default.
  + Make egrep options configurable.
  + Ignore auto-tools files.
* Bump up standards-version to 3.7.2 (no changes needed).
* Let dh_strip do the stripping (not the make install target).

Show diffs side-by-side

added added

removed removed

Lines of Context:
599
599
#define SIGSEGV_REGISTER_FILE                   (unsigned long *)&state->srr0, (unsigned long *)&state->r0
600
600
#endif
601
601
#ifdef __i386__
 
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 */
 
607
#else
 
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 */
 
612
#endif
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 */
608
615
#endif
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
613
620
 
766
773
};
767
774
#endif
768
775
#if defined(__APPLE__) && defined(__MACH__)
769
 
// expected to be the same as FreeBSD
770
776
enum {
 
777
#ifdef i386_SAVED_STATE
 
778
        // same as FreeBSD (in Open Darwin 8.0.1)
771
779
        X86_REG_EIP = 10,
772
780
        X86_REG_EAX = 7,
773
781
        X86_REG_ECX = 6,
777
785
        X86_REG_EBP = 2,
778
786
        X86_REG_ESI = 1,
779
787
        X86_REG_EDI = 0
 
788
#else
 
789
        // new layout (MacOS X 10.4.4 for x86)
 
790
        X86_REG_EIP = 10,
 
791
        X86_REG_EAX = 0,
 
792
        X86_REG_ECX = 2,
 
793
        X86_REG_EDX = 4,
 
794
        X86_REG_EBX = 1,
 
795
        X86_REG_ESP = 7,
 
796
        X86_REG_EBP = 6,
 
797
        X86_REG_ESI = 5,
 
798
        X86_REG_EDI = 4
 
799
#endif
780
800
};
781
801
#endif
782
802
#if defined(_WIN32)
923
943
                        break;
924
944
            }
925
945
          break;
 
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;
 
951
                }
 
952
                else if (transfer_size != SIZE_WORD) {
 
953
                        transfer_size = SIZE_LONG;
 
954
                        target_size = SIZE_QUAD;
 
955
                }
 
956
                switch (eip[1] & 0xc0) {
 
957
                case 0x80:
 
958
                        reg = (eip[1] >> 3) & 7;
 
959
                        transfer_type = SIGSEGV_TRANSFER_LOAD;
 
960
                        break;
 
961
                case 0x40:
 
962
                        reg = (eip[1] >> 3) & 7;
 
963
                        transfer_type = SIGSEGV_TRANSFER_LOAD;
 
964
                        break;
 
965
                case 0x00:
 
966
                        reg = (eip[1] >> 3) & 7;
 
967
                        transfer_type = SIGSEGV_TRANSFER_LOAD;
 
968
                        break;
 
969
                }
 
970
                len += 2 + ix86_step_over_modrm(eip + 1);
 
971
                break;
 
972
#endif
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)
1271
1318
  SPARC_REG_G1 = REG_G1,
1272
1319
  SPARC_REG_O0 = REG_O0,
1273
1320
  SPARC_REG_PC = REG_PC,
 
1321
  SPARC_REG_nPC = REG_nPC
1274
1322
#endif
1275
1323
};
1276
1324
static bool sparc_skip_instruction(unsigned long * regs, gwindows_t * gwins, struct rwindow * rwin)
1334
1382
        break;
1335
1383
  case 7: // Store Doubleword
1336
1384
        transfer_type = SIGSEGV_TRANSFER_STORE;
1337
 
        transfer_size = SIZE_WORD;
 
1385
        transfer_size = SIZE_LONG;
1338
1386
        register_pair = true;
1339
1387
        break;
1340
1388
  }
1344
1392
        return false;
1345
1393
  }
1346
1394
 
1347
 
  // Zero target register in case of a load operation
1348
1395
  const int reg = (opcode >> 25) & 0x1f;
 
1396
 
 
1397
#if DEBUG
 
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"
 
1403
  };
 
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",
 
1410
                 reg_names[reg]);
 
1411
#endif
 
1412
 
 
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;
1354
1419
        }
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;
1358
1423
        }
1359
 
        else if (reg >= 16 && reg <= 23) {
 
1424
        else if (reg >= 16 && reg < 24) {
1360
1425
          // local registers (in register windows)
1361
1426
          if (gwins)
1362
1427
                gwins->wbuf->rw_local[reg - 16] = 0;
1372
1437
        }
1373
1438
  }
1374
1439
 
1375
 
#if DEBUG
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"
1381
 
  };
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",
1388
 
                 reg_names[reg]);
1389
 
#endif
1390
 
 
1391
1440
  regs[SPARC_REG_PC] += 4;
 
1441
  regs[SPARC_REG_nPC] += 4;
1392
1442
  return true;
1393
1443
}
1394
1444
#endif
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;
1655
1705
 
1656
1706
        for (portIndex = 0; portIndex < oldExceptionPorts->maskCount; portIndex++) {
1669
1719
        behavior = oldExceptionPorts->behaviors[portIndex];
1670
1720
        flavor = oldExceptionPorts->flavors[portIndex];
1671
1721
 
 
1722
        if (!VALID_THREAD_STATE_FLAVOR(flavor)) {
 
1723
                fprintf(stderr, "Invalid thread_state flavor = %d. Not forwarding\n", flavor);
 
1724
                return KERN_FAILURE;
 
1725
        }
 
1726
 
1672
1727
        /*
1673
1728
         fprintf(stderr, "forwarding exception, port = 0x%x, behaviour = %d, flavor = %d\n", port, behavior, flavor);
1674
1729
         */
1675
1730
 
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);
1681
1736
        }
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);
1697
1752
          break;
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);
1706
1761
          break;
1707
1762
        default:
1708
1763
          fprintf(stderr, "forward_exception got unknown behavior\n");
 
1764
          kret = KERN_FAILURE;
1709
1765
          break;
1710
1766
        }
1711
1767
 
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);
1716
1772
        }
1717
1773
 
1718
 
        return KERN_SUCCESS;
 
1774
        return kret;
1719
1775
}
1720
1776
 
1721
1777
/*
2068
2124
static volatile char * page = 0;
2069
2125
static volatile int handler_called = 0;
2070
2126
 
 
2127
/* Barriers */
 
2128
#ifdef __GNUC__
 
2129
#define BARRIER() asm volatile ("" : : : "memory")
 
2130
#else
 
2131
#define BARRIER() /* nothing */
 
2132
#endif
 
2133
 
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
2162
2227
#endif
2163
2228
                0                              // end
2164
2229
        };
2202
2267
        if (page[REF_INDEX] != REF_VALUE)
2203
2268
          exit(20);
2204
2269
        page[REF_INDEX] = REF_VALUE;
 
2270
        BARRIER();
2205
2271
 L_e_region1:
2206
2272
 
2207
2273
        if (handler_called != 1)
2242
2308
        TEST_SKIP_INSTRUCTION(signed short);
2243
2309
        TEST_SKIP_INSTRUCTION(signed int);
2244
2310
        TEST_SKIP_INSTRUCTION(signed long);
 
2311
        BARRIER();
2245
2312
 L_e_region2:
2246
2313
 
2247
2314
        if (!arch_insn_skipper_tests())