This is NeXT-tdep.m in view mode; [Download] [Up]
#import "gdb.h" #import <mach/hppa/thread_status.h> extern thread_t current_thread; extern RegionManager *regionManager; int catch_alignment_traps; #define HPPA_GEN_REGNUM 37 #define HPPA_FP_REGNUM 61 #define HPPA_FRAME_REGNUM 42 #define HPPA_NUM_REGS 125 void copy_registers_integer_in(regsState) struct hp_pa_integer_thread_state *regsState; { unsigned int *r = (unsigned int *) registers; unsigned int *rs = (unsigned int *) regsState; int i; for (i = 1; i < HPPA_GEN_REGNUM; i++) r[i] = rs[i-1]; /* reg 0 is not in the regsState */ return; } void copy_registers_frame_in(regsState) struct hp_pa_frame_thread_state *regsState; { unsigned int *r = (unsigned int *) registers; unsigned int *rs = (unsigned int *) regsState; int i; for (i = HPPA_GEN_REGNUM; i < HPPA_FRAME_REGNUM; i++) { r[i] = rs[i-HPPA_GEN_REGNUM]; CLEAN_UP_REGISTER_VALUE(i,(char *)&r[i]); } return; } void copy_registers_integer_out(regsState) struct hp_pa_integer_thread_state *regsState; { unsigned int *r = (unsigned int *) registers; unsigned int *rs = (unsigned int *) regsState; int i; for (i = 1; i < HPPA_GEN_REGNUM; i++) rs[i-1] = r[i]; return; } void copy_registers_frame_out(regsState) struct hp_pa_frame_thread_state *regsState; { unsigned int *r = (unsigned int *) registers; unsigned int *rs = (unsigned int *) regsState; int i; bzero(regsState,sizeof(*regsState)); for (i = HPPA_GEN_REGNUM; i < HPPA_FRAME_REGNUM; i++) rs[i-HPPA_GEN_REGNUM] = r[i]; regsState->ts_alignment_trap_reflect = catch_alignment_traps; return; } void copy_fp_registers_in(fpState) struct hp_pa_fp_thread_state *fpState; { unsigned int *r = (unsigned int *) registers; unsigned int *rs = (unsigned int *) fpState; int i; for (i = HPPA_FP_REGNUM; i < HPPA_NUM_REGS; i++) r[i] = rs[i-HPPA_FP_REGNUM]; return; } void copy_fp_registers_out(fpState) struct hp_pa_fp_thread_state *fpState; { unsigned int *r = (unsigned int *) registers; unsigned int *rs = (unsigned int *) fpState; int i; for (i = HPPA_FP_REGNUM; i < HPPA_NUM_REGS; i++) rs[i-HPPA_FP_REGNUM] = r[i]; return; } void fetch_inferior_registers (regno) { int i; extern char registers[]; extern char register_valid[]; if (current_thread) { if (regno < HPPA_GEN_REGNUM || regno == -1) { struct hp_pa_integer_thread_state int_regsState; unsigned int_regsCount = HPPA_INTEGER_THREAD_STATE_COUNT; mach_call(thread_get_state(current_thread, HPPA_INTEGER_THREAD_STATE, (thread_state_t)&int_regsState, &int_regsCount), "thread_get_state", "fetch_inferior_registers"); copy_registers_integer_in(&int_regsState); for (i = 0; i < HPPA_GEN_REGNUM; i++) register_valid[i] = 1; for (i = HPPA_FRAME_REGNUM; i < HPPA_FP_REGNUM; i++) register_valid[i] = 1; /* since we never get them... */ } if (((regno >= HPPA_GEN_REGNUM) && (regno < HPPA_FRAME_REGNUM)) || regno == -1) { struct hp_pa_frame_thread_state frame_regsState; unsigned frame_regsCount = HPPA_FRAME_THREAD_STATE_COUNT; mach_call(thread_get_state(current_thread, HPPA_FRAME_THREAD_STATE, (thread_state_t)&frame_regsState, &frame_regsCount), "thread_get_state", "fetch_inferior_registers"); copy_registers_frame_in(&frame_regsState); for (i = HPPA_GEN_REGNUM; i < HPPA_FRAME_REGNUM; i++) register_valid[i] = 1; } /* get FP registers only if we have to */ if (regno >= FP0_REGNUM || regno == -1) { struct hp_pa_fp_thread_state fpState; unsigned fpCount = HPPA_FP_THREAD_STATE_COUNT; mach_call(thread_get_state(current_thread, HPPA_FP_THREAD_STATE, (thread_state_t)&fpState, &fpCount), "thread_get_state", "fetch_inferior_registers"); copy_fp_registers_in(&fpState); /* NOT HPPA_NUM_REGS since these end with doubles */ for (i = HPPA_FP_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 hp_pa_frame_thread_state frame_regsState; struct hp_pa_integer_thread_state int_regsState; struct hp_pa_fp_thread_state fpState; unsigned frame_regsCount = HPPA_FRAME_THREAD_STATE_COUNT; unsigned integer_regsCount = HPPA_INTEGER_THREAD_STATE_COUNT; unsigned fpCount = HPPA_FP_THREAD_STATE_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 < HPPA_GEN_REGNUM || regno == -1) { struct hp_pa_integer_thread_state int_regsState; unsigned int_regsCount = HPPA_INTEGER_THREAD_STATE_COUNT; copy_registers_integer_out(&int_regsState); mach_call(thread_set_state(current_thread, HPPA_INTEGER_THREAD_STATE, (thread_state_t)&int_regsState, int_regsCount), "thread_set_state", "store_inferior_registers"); } if (((regno >= HPPA_GEN_REGNUM) && (regno < HPPA_FRAME_REGNUM)) || regno == -1) { struct hp_pa_frame_thread_state frame_regsState; unsigned frame_regsCount = HPPA_FRAME_THREAD_STATE_COUNT; copy_registers_frame_out(&frame_regsState); mach_call(thread_set_state(current_thread, HPPA_FRAME_THREAD_STATE, (thread_state_t)&frame_regsState, frame_regsCount), "thread_set_state", "store_inferior_registers"); } /* set FP registers only if we have to */ if (regno >= FP0_REGNUM || regno == -1) { struct hp_pa_fp_thread_state fpState; unsigned fpCount = HPPA_FP_THREAD_STATE_COUNT; copy_fp_registers_out(&fpState); mach_call(thread_set_state(current_thread, HPPA_FP_THREAD_STATE, (thread_state_t)&fpState, fpCount), "thread_set_state", "store_inferior_registers"); } } } int getFirstTwoIntArgs(first, second) unsigned *first, *second; { *first = (unsigned)read_register(ARG0_REGNUM); *second = (unsigned)read_register(ARG1_REGNUM); return YES; } static unsigned long assemble_21(x) unsigned int x; { unsigned long temp; temp = ( ( x & 1 ) << 20 ) | ( ( x & 0xffe ) << 8 ) | ( ( x & 0xc000 ) >> 7 ) | ( ( x & 0x1f0000 ) >> 14 ) | ( ( x & 0x003000 ) >> 12 ); return temp & 0x1fffff; } static unsigned long assemble_17(x, y, z) unsigned int x, y, z; { unsigned long temp; temp = ( ( z & 1 ) << 16 ) | ( ( x & 0x1f ) << 11 ) | ( ( y & 1 ) << 10 ) | ( ( y & 0x7fe ) >> 1); return temp & 0x1ffff; } static unsigned long sign_ext(x, len) unsigned int x, len; { unsigned int sign; unsigned int result; unsigned int len_ones; int i; i = 0; len_ones = 0; while ( i < len ) { len_ones = (len_ones << 1) | 1; i++; } sign = (x >> (len-1)) & 1; if ( sign ) result = ( ~0 ^ len_ones ) | ( len_ones & x ); else result = len_ones & x; return result; } #define JMPTABLEOFFSET 0x54 typedef struct _JmpSlot { unsigned long opcode[2]; } JmpSlot; CORE_ADDR getBranch(pc) CORE_ADDR pc; { JmpSlot *jmpSlot; unsigned high,low; jmpSlot = WARP((JmpSlot *)pc); high = assemble_21(jmpSlot->opcode[0]&0x1fffff)<<11; low = assemble_17((jmpSlot->opcode[1] & 0x1f0000) >> 16, (jmpSlot->opcode[1] & 0x1ffc) >> 2, jmpSlot->opcode[1] & 1); low = sign_ext(low,17); low <<= 2; return high+low; } CORE_ADDR * jmpTableEnd(sectAddr, sect) CORE_ADDR sectAddr; struct section *sect; { JmpSlot *jmpSlot; void *endOfText; BOOL foundEnd = NO; for (jmpSlot = (struct _JmpSlot *)(sectAddr + JMPTABLEOFFSET), endOfText = (void *)(sectAddr + sect->size); !foundEnd && (jmpSlot < (struct _JmpSlot *)endOfText); jmpSlot++) { if (((jmpSlot->opcode[0] != 0) && (jmpSlot->opcode[1] != 0)) && ((jmpSlot->opcode[0] & 0xffe00000 != 0x20200000) && (jmpSlot->opcode[1] & 0xffe0e002 != 0xe4208002))) { foundEnd = YES; } } return (CORE_ADDR *) (sect->addr + ((void *) (jmpSlot - 1) - sectAddr)); } cpu_type_t cpuType() { return CPU_TYPE_HPPA; } /* We use this hook to turn on alignment exception trapping based on the * value of the "set alignment-traps" variable */ void set_hppa_threadstate(thread) port_t thread; { struct hp_pa_frame_thread_state frame_regsState; unsigned frame_regsCount = HPPA_FRAME_THREAD_STATE_COUNT; mach_call(thread_get_state(thread, HPPA_FRAME_THREAD_STATE, (thread_state_t)&frame_regsState, &frame_regsCount), "thread_get_state", "set_hppa_threadstate"); frame_regsState.ts_alignment_trap_reflect = catch_alignment_traps; mach_call(thread_set_state(thread, HPPA_FRAME_THREAD_STATE, (thread_state_t)&frame_regsState, frame_regsCount), "thread_set_state", "set_alignment_trapping"); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.