This is NeXT-tdep.m in view mode; [Download] [Up]
#import "gdb.h" #import <mach/sparc/thread_status.h> extern thread_t current_thread; extern RegionManager *regionManager; #define sizeofA(a) (sizeof(a)/sizeof(a[0])) static int thread_reg_offsets[] = { PS_REGNUM, PC_REGNUM, NPC_REGNUM, Y_REGNUM, G0_REGNUM + 1, G0_REGNUM + 2, G0_REGNUM + 3, G0_REGNUM + 4, G0_REGNUM + 5, G0_REGNUM + 6, G0_REGNUM + 7, O0_REGNUM, O0_REGNUM + 1, O0_REGNUM + 2, O0_REGNUM + 3, O0_REGNUM + 4, O0_REGNUM + 5, O0_REGNUM + 6, O0_REGNUM + 7 }; void copy_registers_in(regsState) struct sparc_thread_state_regs *regsState; { int i; unsigned int *r = (unsigned int *) registers; unsigned int *rs = (unsigned int *) regsState; r[G0_REGNUM] = 0; register_valid[G0_REGNUM] = 1; for (i = 0; i < sizeofA(thread_reg_offsets); i++) { r[thread_reg_offsets[i]] = rs[i]; register_valid[thread_reg_offsets[i]] = 1; } } void copy_registers_out(regsState) struct sparc_thread_state_regs *regsState; { int i; unsigned int *r = (unsigned int *) registers; unsigned int *rs = (unsigned int *) regsState; for (i = 0; i < sizeofA(thread_reg_offsets); i++) rs[i] = r[thread_reg_offsets[i]]; } void copy_fp_registers_in(fpState) struct sparc_thread_state_fpu *fpState; { int i; unsigned int *r = (unsigned int *) registers; r[FPS_REGNUM] = fpState->fpu.Fpu_fsr; register_valid[FPS_REGNUM] = 1; r[FQ0_REGNUM] = (unsigned int) fpState->fpu.Fpu_q[0].FQu.fpq.addr; register_valid[FQ0_REGNUM] = 1; r[FQ1_REGNUM] = fpState->fpu.Fpu_q[0].FQu.fpq.instr; register_valid[FQ1_REGNUM] = 1; memmove(r + FP0_REGNUM, &fpState->fpu.fpu_fr.Fpu_regs, REGISTER_RAW_SIZE(FP0_REGNUM) * 32); for (i = 0; i < 32; i++) register_valid[FP0_REGNUM + i] = 1; } void copy_fp_registers_out(fpState) struct sparc_thread_state_fpu *fpState; { unsigned int *r = (unsigned int *) registers; memmove(&fpState->fpu.fpu_fr.Fpu_regs, r + FP0_REGNUM, REGISTER_RAW_SIZE(FP0_REGNUM) * 32); fpState->fpu.Fpu_fsr = registers[FPS_REGNUM]; } void fetch_inferior_registers (regno) { int i; if (! current_thread) return; /* Global and Out regs are fetched directly, as well as the * control registers. If we're getting one of the in or * local regs, and the stack pointer has not yet been fetched, * we have to do that first, since they're found in memory * relative to the stack pointer. * Note that we ignore the WIM,TBR, & CSR since they're not * in any regs state. */ if (regno < O7_REGNUM /* including -1 */ || regno == Y_REGNUM || regno == PS_REGNUM || regno == PC_REGNUM || regno == NPC_REGNUM || (!register_valid[SP_REGNUM] && regno <= I7_REGNUM)) { struct sparc_thread_state_regs int_regsState; unsigned int_regsCount = SPARC_THREAD_STATE_REGS_COUNT; mach_call(thread_get_state(current_thread, SPARC_THREAD_STATE_REGS, (thread_state_t)&int_regsState, &int_regsCount), "thread_get_state", "fetch_inferior_registers"); copy_registers_in(&int_regsState); } /* Get the fp registers if needed. */ if ((regno == -1) || ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))) { struct sparc_thread_state_fpu fpu_State; unsigned fpu_regsCount = SPARC_THREAD_STATE_FPU_COUNT; mach_call(thread_get_state(current_thread, SPARC_THREAD_STATE_FPU, (thread_state_t)&fpu_State, &fpu_regsCount), "thread_get_state", "fetch_inferior_registers"); copy_fp_registers_in(&fpu_State); } /* These regs are saved on the stack by the kernel. Only read * them all if we really need them. */ if (regno == -1) { target_xfer_memory (*(CORE_ADDR*)®isters[REGISTER_BYTE (SP_REGNUM)], ®isters[REGISTER_BYTE (L0_REGNUM)], 16*REGISTER_RAW_SIZE (L0_REGNUM), 0); for (i = L0_REGNUM; i <= I7_REGNUM; i++) register_valid[i] = 1; } else if (regno >= L0_REGNUM && regno <= I7_REGNUM) { CORE_ADDR sp = *(CORE_ADDR*)®isters[REGISTER_BYTE (SP_REGNUM)]; i = REGISTER_BYTE (regno); if (register_valid[regno]) fprintf(stderr, "register %d valid and read\n", regno); target_xfer_memory (sp + i - REGISTER_BYTE (L0_REGNUM), ®isters[i], REGISTER_RAW_SIZE (regno), 0); register_valid[regno] = 1; } } /* Store our register values back into the inferior. If REGNO is -1, do this for all registers. Otherwise, REGNO specifies which register (so we can save time). */ void store_inferior_registers(regno) { if (current_thread) { validateRegister(regno); if (!stopped_in_ptrace) mach_call(thread_abort(current_thread), "thread_abort", "store_inferior_registers"); if ((regno < FP0_REGNUM) || ((regno >= Y_REGNUM) && (regno <=NPC_REGNUM)) || (regno == -1)) { struct sparc_thread_state_regs intState; unsigned intCount = SPARC_THREAD_STATE_REGS_COUNT; copy_registers_out(&intState); mach_call(thread_set_state(current_thread, SPARC_THREAD_STATE_REGS, (thread_state_t)&intState, intCount), "thread_set_state", "store_inferior_registers"); } /* set FP registers only if we have to */ if (((regno >= FP0_REGNUM) && (regno < Y_REGNUM)) || regno == -1) { struct sparc_thread_state_fpu fpState; unsigned fpCount = SPARC_THREAD_STATE_FPU_COUNT; copy_fp_registers_out(&fpState); mach_call(thread_set_state(current_thread, SPARC_THREAD_STATE_FPU, (thread_state_t)&fpState, fpCount), "thread_set_state", "store_inferior_registers"); } /* The following regs (%l0 - %l7 & %i0 - %i7) are on the stack. * We have to write them to the inferior's stack in order to * change them. * Also, if the stack pointer was changed, make sure that * these registers are re-written to new location on stack. */ if (regno == -1 || regno == SP_REGNUM) { target_xfer_memory (*(CORE_ADDR*)®isters[REGISTER_BYTE (SP_REGNUM)], ®isters[REGISTER_BYTE (L0_REGNUM)], 16*REGISTER_RAW_SIZE (L0_REGNUM),1); } else if (regno >= L0_REGNUM && regno <= I7_REGNUM) { CORE_ADDR sp = *(CORE_ADDR*)®isters[REGISTER_BYTE (SP_REGNUM)]; int i = REGISTER_BYTE (regno); target_xfer_memory (sp + i - REGISTER_BYTE (L0_REGNUM), ®isters[i], REGISTER_RAW_SIZE (regno),1); } } } int getFirstTwoIntArgs(first, second) unsigned *first, *second; { *first = (unsigned)read_register(O0_REGNUM); *second = (unsigned)read_register(O0_REGNUM+1); return YES; } typedef unsigned long JmpSlot; #define JMPTABLEOFFSET 0x54 #define TRAPOPCODE_SPARC 0x91d02000 #define JMPOPCODE_SPARC 0x30800000 #define OPCODE_MASK_SPARC 0xffc00000 CORE_ADDR getBranch(pc) CORE_ADDR pc; { JmpSlot *jmpSlot; long offset; jmpSlot = WARP((JmpSlot *)pc); offset = (*jmpSlot & 0x3fffff); if (offset & 0x200000) offset |= 0xffe00000; return pc + 4*offset; } CORE_ADDR * jmpTableEnd(sectAddr, sect) CORE_ADDR sectAddr; struct section *sect; { JmpSlot *jmpSlot; void *endOfText; BOOL foundEnd = NO; for (jmpSlot = (JmpSlot *)(sectAddr + JMPTABLEOFFSET), endOfText = (void *)(sectAddr + sect->size); !foundEnd && (jmpSlot < (JmpSlot *)endOfText); jmpSlot++) { if ((*jmpSlot != TRAPOPCODE_SPARC) && ((*jmpSlot & OPCODE_MASK_SPARC) != JMPOPCODE_SPARC)) { foundEnd = YES; } } return (CORE_ADDR *)(sect->addr + ((void *)(jmpSlot - 1)- sectAddr)); } cpu_type_t cpuType() { return CPU_TYPE_SPARC; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.