97 |
|
char ra, rd; |
98 |
|
}; |
99 |
|
|
100 |
< |
static void powerpc_decode_instruction(instruction_t *instruction, unsigned int nip, unsigned int * gpr) |
100 |
> |
static void powerpc_decode_instruction(instruction_t *instruction, unsigned int nip, unsigned long * gpr) |
101 |
|
{ |
102 |
|
// Get opcode and divide into fields |
103 |
< |
unsigned int opcode = *((unsigned int *)nip); |
103 |
> |
unsigned int opcode = *((unsigned int *)(unsigned long)nip); |
104 |
|
unsigned int primop = opcode >> 26; |
105 |
|
unsigned int exop = (opcode >> 1) & 0x3ff; |
106 |
|
unsigned int ra = (opcode >> 16) & 0x1f; |
174 |
|
transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break; |
175 |
|
case 45: // sthu |
176 |
|
transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_U; break; |
177 |
+ |
case 58: // ld, ldu, lwa |
178 |
+ |
transfer_type = SIGSEGV_TRANSFER_LOAD; |
179 |
+ |
transfer_size = SIZE_QUAD; |
180 |
+ |
addr_mode = ((opcode & 3) == 1) ? MODE_U : MODE_NORM; |
181 |
+ |
imm &= ~3; |
182 |
+ |
break; |
183 |
+ |
case 62: // std, stdu, stq |
184 |
+ |
transfer_type = SIGSEGV_TRANSFER_STORE; |
185 |
+ |
transfer_size = SIZE_QUAD; |
186 |
+ |
addr_mode = ((opcode & 3) == 1) ? MODE_U : MODE_NORM; |
187 |
+ |
imm &= ~3; |
188 |
+ |
break; |
189 |
|
} |
190 |
|
|
191 |
|
// Calculate effective address |
286 |
|
#include <sys/ucontext.h> |
287 |
|
#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.regs) |
288 |
|
#define SIGSEGV_FAULT_INSTRUCTION (SIGSEGV_CONTEXT_REGS->nip) |
289 |
< |
#define SIGSEGV_REGISTER_FILE (unsigned int *)&SIGSEGV_CONTEXT_REGS->nip, (unsigned int *)(SIGSEGV_CONTEXT_REGS->gpr) |
289 |
> |
#define SIGSEGV_REGISTER_FILE (unsigned long *)&SIGSEGV_CONTEXT_REGS->nip, (unsigned long *)(SIGSEGV_CONTEXT_REGS->gpr) |
290 |
|
#define SIGSEGV_SKIP_INSTRUCTION powerpc_skip_instruction |
291 |
|
#endif |
292 |
|
#if (defined(hppa) || defined(__hppa__)) |
329 |
|
#define SIGSEGV_FAULT_HANDLER_ARGS sig, scp |
330 |
|
#define SIGSEGV_FAULT_ADDRESS scp->regs->dar |
331 |
|
#define SIGSEGV_FAULT_INSTRUCTION scp->regs->nip |
332 |
< |
#define SIGSEGV_REGISTER_FILE (unsigned int *)&scp->regs->nip, (unsigned int *)(scp->regs->gpr) |
332 |
> |
#define SIGSEGV_REGISTER_FILE (unsigned long *)&scp->regs->nip, (unsigned long *)(scp->regs->gpr) |
333 |
|
#define SIGSEGV_SKIP_INSTRUCTION powerpc_skip_instruction |
334 |
|
#endif |
335 |
|
#if (defined(alpha) || defined(__alpha__)) |
984 |
|
|
985 |
|
// Decode and skip PPC instruction |
986 |
|
#if (defined(powerpc) || defined(__powerpc__) || defined(__ppc__)) |
987 |
< |
static bool powerpc_skip_instruction(unsigned int * nip_p, unsigned int * regs) |
987 |
> |
static bool powerpc_skip_instruction(unsigned long * nip_p, unsigned long * regs) |
988 |
|
{ |
989 |
|
instruction_t instr; |
990 |
|
powerpc_decode_instruction(&instr, *nip_p, regs); |
996 |
|
|
997 |
|
#if DEBUG |
998 |
|
printf("%08x: %s %s access", *nip_p, |
999 |
< |
instr.transfer_size == SIZE_BYTE ? "byte" : instr.transfer_size == SIZE_WORD ? "word" : "long", |
999 |
> |
instr.transfer_size == SIZE_BYTE ? "byte" : |
1000 |
> |
instr.transfer_size == SIZE_WORD ? "word" : |
1001 |
> |
instr.transfer_size == SIZE_LONG ? "long" : "quad", |
1002 |
|
instr.transfer_type == SIGSEGV_TRANSFER_LOAD ? "read" : "write"); |
1003 |
|
|
1004 |
|
if (instr.addr_mode == MODE_U || instr.addr_mode == MODE_UX) |