This is NeXT-tdep.m in view mode; [Download] [Up]
#import "gdb.h" #import <mach/m68k/thread_status.h> extern thread_t current_thread; extern RegionManager *regionManager; void fetch_inferior_registers (regno) { struct m68k_thread_state_regs regsState; unsigned regsCount = M68K_THREAD_STATE_REGS_COUNT; struct m68k_thread_state_68882 floatRegsState; unsigned floatRegsCount = M68K_THREAD_STATE_68882_COUNT; int i; extern char registers[]; extern char register_valid[]; if (current_thread) { if ((regno == -1) || (regno < FP0_REGNUM)) { mach_call(thread_get_state(current_thread, M68K_THREAD_STATE_REGS, (thread_state_t)®sState, ®sCount), "thread_get_state", "fetch_inferior_registers"); bcopy(®sState, registers, sizeof(regsState.dreg) + sizeof(regsState.areg)); *(int *)®isters[REGISTER_BYTE (PS_REGNUM)] = (int)regsState.sr; *(int *)®isters[REGISTER_BYTE (PC_REGNUM)] = regsState.pc; for (i = 0; i < FP0_REGNUM; i++) register_valid[i] = 1; } if ((regno == -1) || (regno >= FP0_REGNUM)) { mach_call(thread_get_state(current_thread, M68K_THREAD_STATE_68882, (thread_state_t)&floatRegsState, &floatRegsCount), "thread_get_state", "fetch_inferior_registers"); bcopy(&floatRegsState, ®isters[REGISTER_BYTE (FP0_REGNUM)], sizeof(floatRegsState)); for (i = FP0_REGNUM; i < NUM_REGS; i++) register_valid[i] = 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) { struct m68k_thread_state_regs regsState; unsigned regsCount = M68K_THREAD_STATE_REGS_COUNT; struct m68k_thread_state_68882 floatRegsState; unsigned floatRegsCount = M68K_THREAD_STATE_68882_COUNT; extern char registers[]; if (current_thread) { validateRegister(regno); if (!stopped_in_ptrace) mach_call(thread_abort(current_thread), "thread_abort", "store_inferior_registers"); if ((regno == -1) || (regno < FP0_REGNUM)) { bcopy(registers, ®sState, sizeof(regsState.dreg) + sizeof(regsState.areg)); (int)regsState.sr = *(int *)®isters[REGISTER_BYTE (PS_REGNUM)]; regsState.pc = *(int *)®isters[REGISTER_BYTE (PC_REGNUM)]; mach_call(thread_set_state(current_thread, M68K_THREAD_STATE_REGS, (thread_state_t)®sState, regsCount), "thread_set_state", "store_inferior_registers"); } if ((regno == -1) || (regno >= FP0_REGNUM)) { bcopy(®isters[REGISTER_BYTE (FP0_REGNUM)], &floatRegsState, sizeof(floatRegsState)); mach_call(thread_set_state(current_thread, M68K_THREAD_STATE_68882, (thread_state_t)&floatRegsState, floatRegsCount), "thread_set_state", "store_inferior_registers"); } } } CORE_ADDR skip_prologue(function) { CORE_ADDR prologue; unsigned int op; prologue = skip_prologue_by_symbol(function); if (!prologue) { prologue = function; op = read_memory_integer (prologue, 2); if (op == 0047126) prologue += 4; /* Skip link #word */ else if (op == 0044016) prologue += 6; /* Skip link #long */ /* Not sure why branches are here. */ /* From m-isi.h, m-altos.h */ else if (op == 0060000) prologue += 4; /* Skip bra #word */ else if (op == 00600377) prologue += 6; /* skip bra #long */ else if ((op & 0177400) == 0060000) prologue += 2; /* skip bra #char */ } return prologue; } typedef struct _DummyFrame { unsigned ps; unsigned regs[14]; unsigned char fpRegs[8][12]; unsigned fp; unsigned pc; } DummyFrame; void pushDummyFrame() { DummyFrame dummyFrame; int i; unsigned sp = read_register(SP_REGNUM); dummyFrame.pc = read_register(PC_REGNUM); dummyFrame.fp = read_register(FP_REGNUM); for (i = 0; i < 8; i++) read_register_bytes(REGISTER_BYTE(FP0_REGNUM + i), dummyFrame.fpRegs[i], 12); for (i = 0; i < 14; i++) dummyFrame.regs[i] = read_register(i); dummyFrame.ps = read_register(PS_REGNUM); write_register(FP_REGNUM, sp - 8); sp = push_bytes(sp, (char *) &dummyFrame, sizeof(dummyFrame)); write_register(SP_REGNUM, sp); } char breakpoint_insn[] = {0x4e, 0x4f}; typedef struct _JmpSlot { unsigned short opcode; unsigned int arg; } JmpSlot; #define JMPTABLEOFFSET 0x54 #define JMPOPCODE_68K 0x4EF9 #define TRAPOPCODE_68K 0x50FB CORE_ADDR getBranch(pc) CORE_ADDR pc; { JmpSlot *jmpSlot; jmpSlot = WARP((JmpSlot *)pc); return jmpSlot->arg; } CORE_ADDR jmpTableEnd(sectAddr, sect) CORE_ADDR sectAddr; struct section *sect; { JmpSlot *jmpSlot; void *endOfText; BOOL foundEnd = NO; for (jmpSlot = (JmpSlot *) ((char *) sectAddr + JMPTABLEOFFSET), endOfText = (char *) sectAddr + sect->size; !foundEnd && (jmpSlot < (struct _JmpSlot *) endOfText); jmpSlot++) { if ((jmpSlot->opcode != JMPOPCODE_68K) && (jmpSlot->opcode != TRAPOPCODE_68K)) foundEnd = YES; } return (CORE_ADDR) (sect->addr + ((void *) (jmpSlot - 1) - sectAddr)); } int getFirstTwoIntArgs(first, second) unsigned *first, *second; { unsigned *sp = (unsigned*) read_register(SP_REGNUM); unsigned *argsPtr = [regionManager pointerFor: sp + 1 withSize: 2 * sizeof(CORE_ADDR)]; if (argsPtr) { *first = *(argsPtr); *second = *(argsPtr + 1); return YES; } else { return NO; } } cpu_type_t cpuType() { return CPU_TYPE_MC680x0; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.