| #include <stdio.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <time.h> |
| #include <errno.h> |
| |
| #include <nwtypes.h> |
| #include <nwdfs.h> |
| #include <nwconio.h> |
| #include <nwadv.h> |
| #include <nwdbgapi.h> |
| #include <nwthread.h> |
| #include "ppc.h" |
| |
| extern char *mem2hex (void *mem, char *buf, int count, int may_fault); |
| extern char *hex2mem (char *buf, void *mem, int count, int may_fault); |
| extern int computeSignal (int exceptionVector); |
| |
| void |
| flush_i_cache (void) |
| { |
| } |
| |
| /* Get the registers out of the frame information. */ |
| |
| void |
| frame_to_registers (frame, regs) |
| struct StackFrame *frame; |
| char *regs; |
| { |
| mem2hex (&frame->ExceptionState.CsavedRegs, ®s[GP0_REGNUM * 4 * 2], 4 * 32, 0); |
| |
| mem2hex (&frame->ExceptionState.CSavedFPRegs, ®s[FP0_REGNUM * 4 * 2], 4 * 32, 0); |
| |
| mem2hex (&frame->ExceptionPC, ®s[PC_REGNUM * 4 * 2], 4 * 1, 0); |
| |
| mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR1, ®s[CR_REGNUM * 4 * 2], 4 * 1, 0); |
| mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR, ®s[LR_REGNUM * 4 * 2], 4 * 1, 0); |
| mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR, ®s[CTR_REGNUM * 4 * 2], 4 * 1, 0); |
| mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedXER, ®s[XER_REGNUM * 4 * 2], 4 * 1, 0); |
| mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedMQ, ®s[MQ_REGNUM * 4 * 2], 4 * 1, 0); |
| } |
| |
| /* Put the registers back into the frame information. */ |
| |
| void |
| registers_to_frame (regs, frame) |
| char *regs; |
| struct StackFrame *frame; |
| { |
| hex2mem (®s[GP0_REGNUM * 4 * 2], &frame->ExceptionState.CsavedRegs, 4 * 32, 0); |
| |
| hex2mem (®s[FP0_REGNUM * 4 * 2], &frame->ExceptionState.CSavedFPRegs, 4 * 32, 0); |
| |
| hex2mem (®s[PC_REGNUM * 4 * 2], &frame->ExceptionPC, 4 * 1, 0); |
| |
| hex2mem (®s[CR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR1, 4 * 1, 0); |
| hex2mem (®s[LR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR, 4 * 1, 0); |
| hex2mem (®s[CTR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR, 4 * 1, 0); |
| hex2mem (®s[XER_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedXER, 4 * 1, 0); |
| hex2mem (®s[MQ_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedMQ, 4 * 1, 0); |
| } |
| |
| |
| extern volatile int mem_err; |
| |
| #ifdef ALTERNATE_MEM_FUNCS |
| extern int ReadByteAltDebugger (char* addr, char *theByte); |
| extern int WriteByteAltDebugger (char* addr, char theByte); |
| int |
| get_char (addr) |
| char *addr; |
| { |
| char c; |
| |
| if (!ReadByteAltDebugger (addr, &c)) |
| mem_err = 1; |
| |
| return c; |
| } |
| |
| void |
| set_char (addr, val) |
| char *addr; |
| int val; |
| { |
| if (!WriteByteAltDebugger (addr, val)) |
| mem_err = 1; |
| } |
| #endif |
| |
| int |
| mem_write (dst, src, len) |
| char *dst, *src; |
| int len; |
| { |
| while (len-- && !mem_err) |
| set_char (dst++, *src++); |
| |
| return mem_err; |
| } |
| |
| union inst |
| { |
| LONG l; |
| |
| struct |
| { |
| union |
| { |
| struct /* Unconditional branch */ |
| { |
| unsigned opcode : 6; /* 18 */ |
| signed li : 24; |
| unsigned aa : 1; |
| unsigned lk : 1; |
| } b; |
| struct /* Conditional branch */ |
| { |
| unsigned opcode : 6; /* 16 */ |
| unsigned bo : 5; |
| unsigned bi : 5; |
| signed bd : 14; |
| unsigned aa : 1; |
| unsigned lk : 1; |
| } bc; |
| struct /* Conditional branch to ctr or lr reg */ |
| { |
| unsigned opcode : 6; /* 19 */ |
| unsigned bo : 5; |
| unsigned bi : 5; |
| unsigned type : 15; /* 528 = ctr, 16 = lr */ |
| unsigned lk : 1; |
| } bclr; |
| } variant; |
| } inst; |
| }; |
| |
| static LONG saved_inst; |
| static LONG *saved_inst_pc = 0; |
| static LONG saved_target_inst; |
| static LONG *saved_target_inst_pc = 0; |
| |
| void |
| set_step_traps (frame) |
| struct StackFrame *frame; |
| { |
| union inst inst; |
| LONG *target; |
| int opcode; |
| int ra, rb; |
| LONG *pc = (LONG *)frame->ExceptionPC; |
| |
| inst.l = *pc++; |
| |
| opcode = inst.inst.variant.b.opcode; |
| |
| target = pc; |
| |
| switch (opcode) |
| { |
| case 18: /* Unconditional branch */ |
| |
| if (inst.inst.variant.b.aa) /* Absolute? */ |
| target = 0; |
| target += inst.inst.variant.b.li; |
| |
| break; |
| case 16: /* Conditional branch */ |
| |
| if (!inst.inst.variant.bc.aa) /* Absolute? */ |
| target = 0; |
| target += inst.inst.variant.bc.bd; |
| |
| break; |
| case 19: /* Cond. branch via ctr or lr reg */ |
| switch (inst.inst.variant.bclr.type) |
| { |
| case 528: /* ctr */ |
| target = (LONG *)frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR; |
| break; |
| case 16: /* lr */ |
| target = (LONG *)frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR; |
| break; |
| } |
| break; |
| } |
| |
| saved_inst = *pc; |
| mem_write (pc, breakpoint_insn, BREAKPOINT_SIZE); |
| saved_inst_pc = pc; |
| |
| if (target != pc) |
| { |
| saved_target_inst = *target; |
| mem_write (target, breakpoint_insn, BREAKPOINT_SIZE); |
| saved_target_inst_pc = target; |
| } |
| } |
| |
| /* Remove step breakpoints. Returns non-zero if pc was at a step breakpoint, |
| zero otherwise. This routine works even if there were no step breakpoints |
| set. */ |
| |
| int |
| clear_step_traps (frame) |
| struct StackFrame *frame; |
| { |
| int retcode; |
| LONG *pc = (LONG *)frame->ExceptionPC; |
| |
| if (saved_inst_pc == pc || saved_target_inst_pc == pc) |
| retcode = 1; |
| else |
| retcode = 0; |
| |
| if (saved_inst_pc) |
| { |
| mem_write (saved_inst_pc, saved_inst, BREAKPOINT_SIZE); |
| saved_inst_pc = 0; |
| } |
| |
| if (saved_target_inst_pc) |
| { |
| mem_write (saved_target_inst_pc, saved_target_inst, BREAKPOINT_SIZE); |
| saved_target_inst_pc = 0; |
| } |
| |
| return retcode; |
| } |
| |
| void |
| do_status (ptr, frame) |
| char *ptr; |
| struct StackFrame *frame; |
| { |
| int sigval; |
| |
| sigval = computeSignal (frame->ExceptionNumber); |
| |
| sprintf (ptr, "T%02x", sigval); |
| ptr += 3; |
| |
| sprintf (ptr, "%02x:", PC_REGNUM); |
| ptr = mem2hex (&frame->ExceptionPC, ptr + 3, 4, 0); |
| *ptr++ = ';'; |
| |
| sprintf (ptr, "%02x:", SP_REGNUM); |
| ptr = mem2hex (&frame->ExceptionState.CsavedRegs[SP_REGNUM], ptr + 3, 4, 0); |
| *ptr++ = ';'; |
| |
| sprintf (ptr, "%02x:", LR_REGNUM); |
| ptr = mem2hex (&frame->ExceptionState.CsavedRegs[LR_REGNUM], ptr + 3, 4, 0); |
| *ptr++ = ';'; |
| |
| *ptr = '\000'; |
| } |