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.39 by gbeauche, 2003-12-20T21:50:08Z vs.
Revision 1.42 by gbeauche, 2004-01-19T16:59:13Z

# Line 10 | Line 10
10   *    tjw@omnigroup.com Sun, 4 Jun 2000
11   *    www.omnigroup.com/mailman/archive/macosx-dev/2000-June/002030.html
12   *
13 < *  Basilisk II (C) 1997-2002 Christian Bauer
13 > *  Basilisk II (C) 1997-2004 Christian Bauer
14   *
15   *  This program is free software; you can redistribute it and/or modify
16   *  it under the terms of the GNU General Public License as published by
# Line 234 | Line 234 | static void powerpc_decode_instruction(i
234   #endif
235   #if defined(__sun__)
236   #if (defined(sparc) || defined(__sparc__))
237 + #include <sys/stack.h>
238 + #include <sys/regset.h>
239   #include <sys/ucontext.h>
240   #define SIGSEGV_CONTEXT_REGS                    (((ucontext_t *)scp)->uc_mcontext.gregs)
241   #define SIGSEGV_FAULT_INSTRUCTION               SIGSEGV_CONTEXT_REGS[REG_PC]
242 + #define SIGSEGV_SPARC_GWINDOWS                  (((ucontext_t *)scp)->uc_mcontext.gwins)
243 + #define SIGSEGV_SPARC_RWINDOW                   (struct rwindow *)((char *)SIGSEGV_CONTEXT_REGS[REG_SP] + STACK_BIAS)
244 + #define SIGSEGV_REGISTER_FILE                   ((unsigned long *)SIGSEGV_CONTEXT_REGS), SIGSEGV_SPARC_GWINDOWS, SIGSEGV_SPARC_RWINDOW
245 + #define SIGSEGV_SKIP_INSTRUCTION                sparc_skip_instruction
246   #endif
247   #endif
248   #if defined(__FreeBSD__)
# Line 275 | Line 281 | static void powerpc_decode_instruction(i
281   #undef  SIGSEGV_FAULT_ADDRESS
282   #define SIGSEGV_FAULT_ADDRESS                   sip->si_ptr
283   #endif
284 + #if (defined(arm) || defined(__arm__))
285 + #include <asm/ucontext.h> /* use kernel structure, glibc may not be in sync */
286 + #define SIGSEGV_CONTEXT_REGS                    (((struct ucontext *)scp)->uc_mcontext)
287 + #define SIGSEGV_FAULT_INSTRUCTION               (SIGSEGV_CONTEXT_REGS.arm_pc)
288 + #endif
289   #endif
290   #endif
291  
# Line 314 | Line 325 | static void powerpc_decode_instruction(i
325   #define SIGSEGV_FAULT_ADDRESS                   get_fault_address(scp)
326   #define SIGSEGV_FAULT_INSTRUCTION               scp->sc_pc
327   #endif
328 + #if (defined(arm) || defined(__arm__))
329 + #define SIGSEGV_FAULT_HANDLER_ARGLIST   int sig, int r1, int r2, int r3, struct sigcontext sc
330 + #define SIGSEGV_FAULT_HANDLER_ARGLIST_1 struct sigcontext *scp
331 + #define SIGSEGV_FAULT_HANDLER_ARGS              &sc
332 + #define SIGSEGV_FAULT_ADDRESS                   scp->fault_address
333 + #define SIGSEGV_FAULT_INSTRUCTION               scp->arm_pc
334 + #endif
335   #endif
336  
337   // Irix 5 or 6 on MIPS
# Line 1103 | Line 1121 | static bool mips_skip_instruction(greg_t
1121    return true;
1122   }
1123   #endif
1124 +
1125 + // Decode and skip SPARC instruction
1126 + #if (defined(sparc) || defined(__sparc__))
1127 + enum {
1128 + #if (defined(__sun__))
1129 +  SPARC_REG_G1 = REG_G1,
1130 +  SPARC_REG_O0 = REG_O0,
1131 +  SPARC_REG_PC = REG_PC,
1132 + #endif
1133 + };
1134 + static bool sparc_skip_instruction(unsigned long * regs, gwindows_t * gwins, struct rwindow * rwin)
1135 + {
1136 +  unsigned int * pc = (unsigned int *)regs[SPARC_REG_PC];
1137 +
1138 +  if (pc == 0)
1139 +        return false;
1140 +
1141 + #if DEBUG
1142 +  printf("IP: %p [%08x]\n", pc, pc[0]);
1143 + #endif
1144 +
1145 +  transfer_type_t transfer_type = SIGSEGV_TRANSFER_UNKNOWN;
1146 +  transfer_size_t transfer_size = SIZE_LONG;
1147 +  bool register_pair = false;
1148 +
1149 +  const unsigned int opcode = pc[0];
1150 +  if ((opcode >> 30) != 3)
1151 +        return false;
1152 +  switch ((opcode >> 19) & 0x3f) {
1153 +  case 9: // Load Signed Byte
1154 +  case 1: // Load Unsigned Byte
1155 +        transfer_type = SIGSEGV_TRANSFER_LOAD;
1156 +        transfer_size = SIZE_BYTE;
1157 +        break;
1158 +  case 10:// Load Signed Halfword
1159 +  case 2: // Load Unsigned Word
1160 +        transfer_type = SIGSEGV_TRANSFER_LOAD;
1161 +        transfer_size = SIZE_WORD;
1162 +        break;
1163 +  case 8: // Load Word
1164 +  case 0: // Load Unsigned Word
1165 +        transfer_type = SIGSEGV_TRANSFER_LOAD;
1166 +        transfer_size = SIZE_LONG;
1167 +        break;
1168 +  case 11:// Load Extended Word
1169 +        transfer_type = SIGSEGV_TRANSFER_LOAD;
1170 +        transfer_size = SIZE_QUAD;
1171 +        break;
1172 +  case 3: // Load Doubleword
1173 +        transfer_type = SIGSEGV_TRANSFER_LOAD;
1174 +        transfer_size = SIZE_LONG;
1175 +        register_pair = true;
1176 +        break;
1177 +  case 5: // Store Byte
1178 +        transfer_type = SIGSEGV_TRANSFER_STORE;
1179 +        transfer_size = SIZE_BYTE;
1180 +        break;
1181 +  case 6: // Store Halfword
1182 +        transfer_type = SIGSEGV_TRANSFER_STORE;
1183 +        transfer_size = SIZE_WORD;
1184 +        break;
1185 +  case 4: // Store Word
1186 +        transfer_type = SIGSEGV_TRANSFER_STORE;
1187 +        transfer_size = SIZE_LONG;
1188 +        break;
1189 +  case 14:// Store Extended Word
1190 +        transfer_type = SIGSEGV_TRANSFER_STORE;
1191 +        transfer_size = SIZE_QUAD;
1192 +        break;
1193 +  case 7: // Store Doubleword
1194 +        transfer_type = SIGSEGV_TRANSFER_STORE;
1195 +        transfer_size = SIZE_WORD;
1196 +        register_pair = true;
1197 +        break;
1198 +  }
1199 +
1200 +  if (transfer_type == SIGSEGV_TRANSFER_UNKNOWN) {
1201 +        // Unknown machine code, let it crash. Then patch the decoder
1202 +        return false;
1203 +  }
1204 +
1205 +  // Zero target register in case of a load operation
1206 +  const int reg = (opcode >> 25) & 0x1f;
1207 +  if (transfer_type == SIGSEGV_TRANSFER_LOAD && reg != 0) {
1208 +        // FIXME: code to handle local & input registers is not tested
1209 +        if (reg >= 1 && reg <= 7) {
1210 +          // global registers
1211 +          regs[reg - 1 + SPARC_REG_G1] = 0;
1212 +        }
1213 +        else if (reg >= 8 && reg <= 15) {
1214 +          // output registers
1215 +          regs[reg - 8 + SPARC_REG_O0] = 0;
1216 +        }
1217 +        else if (reg >= 16 && reg <= 23) {
1218 +          // local registers (in register windows)
1219 +          if (gwins)
1220 +                gwins->wbuf->rw_local[reg - 16] = 0;
1221 +          else
1222 +                rwin->rw_local[reg - 16] = 0;
1223 +        }
1224 +        else {
1225 +          // input registers (in register windows)
1226 +          if (gwins)
1227 +                gwins->wbuf->rw_in[reg - 24] = 0;
1228 +          else
1229 +                rwin->rw_in[reg - 24] = 0;
1230 +        }
1231 +  }
1232 +
1233 + #if DEBUG
1234 +  static const char * reg_names[] = {
1235 +        "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
1236 +        "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
1237 +        "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
1238 +        "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7"
1239 +  };
1240 +  printf("%s %s register %s\n",
1241 +                 transfer_size == SIZE_BYTE ? "byte" :
1242 +                 transfer_size == SIZE_WORD ? "word" :
1243 +                 transfer_size == SIZE_LONG ? "long" :
1244 +                 transfer_size == SIZE_QUAD ? "quad" : "unknown",
1245 +                 transfer_type == SIGSEGV_TRANSFER_LOAD ? "load to" : "store from",
1246 +                 reg_names[reg]);
1247 + #endif
1248 +
1249 +  regs[SPARC_REG_PC] += 4;
1250 +  return true;
1251 + }
1252 + #endif
1253   #endif
1254  
1255   // Fallbacks

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines