ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/sigsegv.cpp
(Generate patch)

Comparing BasiliskII/src/Unix/sigsegv.cpp (file contents):
Revision 1.63 by gbeauche, 2006-05-09T06:24:05Z vs.
Revision 1.64 by gbeauche, 2006-07-19T21:31:10Z

# Line 66 | Line 66 | static bool sigsegv_do_install_handler(i
66   *  Instruction decoding aids
67   */
68  
69 + // Transfer type
70 + enum transfer_type_t {
71 +        SIGSEGV_TRANSFER_UNKNOWN        = 0,
72 +        SIGSEGV_TRANSFER_LOAD           = 1,
73 +        SIGSEGV_TRANSFER_STORE          = 2,
74 + };
75 +
76   // Transfer size
77   enum transfer_size_t {
78          SIZE_UNKNOWN,
# Line 75 | Line 82 | enum transfer_size_t {
82          SIZE_QUAD, // 8 bytes
83   };
84  
78 // Transfer type
79 typedef sigsegv_transfer_type_t transfer_type_t;
80
85   #if (defined(powerpc) || defined(__powerpc__) || defined(__ppc__))
86   // Addressing mode
87   enum addressing_mode_t {
# Line 859 | Line 863 | static bool ix86_skip_instruction(unsign
863                  return false;
864   #endif
865          
866 +        enum instruction_type_t {
867 +                i_MOV,
868 +                i_ADD
869 +        };
870 +
871          transfer_type_t transfer_type = SIGSEGV_TRANSFER_UNKNOWN;
872          transfer_size_t transfer_size = SIZE_LONG;
873 +        instruction_type_t instruction_type = i_MOV;
874          
875          int reg = -1;
876          int len = 0;
# Line 911 | Line 921 | static bool ix86_skip_instruction(unsign
921   #endif
922  
923          // Decode instruction
924 +        int op_len = 1;
925          int target_size = SIZE_UNKNOWN;
926          switch (eip[0]) {
927          case 0x0f:
# Line 925 | Line 936 | static bool ix86_skip_instruction(unsign
936                          transfer_size = SIZE_WORD;
937                          goto do_mov_extend;
938                    do_mov_extend:
939 <                        switch (eip[2] & 0xc0) {
940 <                        case 0x80:
941 <                                reg = (eip[2] >> 3) & 7;
942 <                                transfer_type = SIGSEGV_TRANSFER_LOAD;
932 <                                break;
933 <                        case 0x40:
934 <                                reg = (eip[2] >> 3) & 7;
935 <                                transfer_type = SIGSEGV_TRANSFER_LOAD;
936 <                                break;
937 <                        case 0x00:
938 <                                reg = (eip[2] >> 3) & 7;
939 <                                transfer_type = SIGSEGV_TRANSFER_LOAD;
940 <                                break;
941 <                        }
942 <                        len += 3 + ix86_step_over_modrm(eip + 2);
943 <                        break;
944 <            }
945 <          break;
939 >                        op_len = 2;
940 >                        goto do_transfer_load;
941 >                }
942 >                break;
943   #if defined(__x86_64__)
944          case 0x63: // MOVSXD r64, r/m32
945                  if (has_rex && rex.W) {
# Line 953 | Line 950 | static bool ix86_skip_instruction(unsign
950                          transfer_size = SIZE_LONG;
951                          target_size = SIZE_QUAD;
952                  }
953 <                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;
953 >                goto do_transfer_load;
954   #endif
955 +        case 0x02: // ADD r8, r/m8
956 +                transfer_size = SIZE_BYTE;
957 +        case 0x03: // ADD r32, r/m32
958 +                instruction_type = i_ADD;
959 +                goto do_transfer_load;
960          case 0x8a: // MOV r8, r/m8
961                  transfer_size = SIZE_BYTE;
962          case 0x8b: // MOV r32, r/m32 (or 16-bit operation)
963 <                switch (eip[1] & 0xc0) {
963 >          do_transfer_load:
964 >                switch (eip[op_len] & 0xc0) {
965                  case 0x80:
966 <                        reg = (eip[1] >> 3) & 7;
966 >                        reg = (eip[op_len] >> 3) & 7;
967                          transfer_type = SIGSEGV_TRANSFER_LOAD;
968                          break;
969                  case 0x40:
970 <                        reg = (eip[1] >> 3) & 7;
970 >                        reg = (eip[op_len] >> 3) & 7;
971                          transfer_type = SIGSEGV_TRANSFER_LOAD;
972                          break;
973                  case 0x00:
974 <                        reg = (eip[1] >> 3) & 7;
974 >                        reg = (eip[op_len] >> 3) & 7;
975                          transfer_type = SIGSEGV_TRANSFER_LOAD;
976                          break;
977                  }
978 <                len += 2 + ix86_step_over_modrm(eip + 1);
978 >                len += 1 + op_len + ix86_step_over_modrm(eip + op_len);
979                  break;
980 +        case 0x00: // ADD r/m8, r8
981 +                transfer_size = SIZE_BYTE;
982 +        case 0x01: // ADD r/m32, r32
983 +                instruction_type = i_ADD;
984 +                goto do_transfer_store;
985          case 0x88: // MOV r/m8, r8
986                  transfer_size = SIZE_BYTE;
987          case 0x89: // MOV r/m32, r32 (or 16-bit operation)
988 <                switch (eip[1] & 0xc0) {
988 >          do_transfer_store:
989 >                switch (eip[op_len] & 0xc0) {
990                  case 0x80:
991 <                        reg = (eip[1] >> 3) & 7;
991 >                        reg = (eip[op_len] >> 3) & 7;
992                          transfer_type = SIGSEGV_TRANSFER_STORE;
993                          break;
994                  case 0x40:
995 <                        reg = (eip[1] >> 3) & 7;
995 >                        reg = (eip[op_len] >> 3) & 7;
996                          transfer_type = SIGSEGV_TRANSFER_STORE;
997                          break;
998                  case 0x00:
999 <                        reg = (eip[1] >> 3) & 7;
999 >                        reg = (eip[op_len] >> 3) & 7;
1000                          transfer_type = SIGSEGV_TRANSFER_STORE;
1001                          break;
1002                  }
1003 <                len += 2 + ix86_step_over_modrm(eip + 1);
1003 >                len += 1 + op_len + ix86_step_over_modrm(eip + op_len);
1004                  break;
1005          }
1006          if (target_size == SIZE_UNKNOWN)
# Line 1022 | Line 1016 | static bool ix86_skip_instruction(unsign
1016                  reg += 8;
1017   #endif
1018  
1019 <        if (transfer_type == SIGSEGV_TRANSFER_LOAD && reg != -1) {
1019 >        if (instruction_type == i_MOV && transfer_type == SIGSEGV_TRANSFER_LOAD && reg != -1) {
1020                  static const int x86_reg_map[] = {
1021                          X86_REG_EAX, X86_REG_ECX, X86_REG_EDX, X86_REG_EBX,
1022                          X86_REG_ESP, X86_REG_EBP, X86_REG_ESI, X86_REG_EDI,
# Line 1058 | Line 1052 | static bool ix86_skip_instruction(unsign
1052          }
1053  
1054   #if DEBUG
1055 <        printf("%08x: %s %s access", regs[X86_REG_EIP],
1055 >        printf("%p: %s %s access", (void *)regs[X86_REG_EIP],
1056                     transfer_size == SIZE_BYTE ? "byte" :
1057                     transfer_size == SIZE_WORD ? "word" :
1058                     transfer_size == SIZE_LONG ? "long" :

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines