|
|
|
@ -256,214 +256,6 @@ static int regmap[] = |
|
|
|
|
|
|
|
#endif /* rs6000 */ |
|
|
|
|
|
|
|
#ifdef SPARC |
|
|
|
|
|
|
|
/* This routine handles some oddball cases for Sparc registers and LynxOS.
|
|
|
|
In partucular, it causes refs to G0, g5->7, and all fp regs to return zero. |
|
|
|
It also handles knows where to find the I & L regs on the stack. */ |
|
|
|
|
|
|
|
void |
|
|
|
fetch_inferior_registers (int regno) |
|
|
|
{ |
|
|
|
int whatregs = 0; |
|
|
|
|
|
|
|
#define WHATREGS_FLOAT 1 |
|
|
|
#define WHATREGS_GEN 2 |
|
|
|
#define WHATREGS_STACK 4 |
|
|
|
|
|
|
|
if (regno == -1) |
|
|
|
whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK; |
|
|
|
else if (regno >= L0_REGNUM && regno <= I7_REGNUM) |
|
|
|
whatregs = WHATREGS_STACK; |
|
|
|
else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32) |
|
|
|
whatregs = WHATREGS_FLOAT; |
|
|
|
else |
|
|
|
whatregs = WHATREGS_GEN; |
|
|
|
|
|
|
|
if (whatregs & WHATREGS_GEN) |
|
|
|
{ |
|
|
|
struct econtext ec; /* general regs */ |
|
|
|
char buf[MAX_REGISTER_SIZE]; |
|
|
|
int retval; |
|
|
|
int i; |
|
|
|
|
|
|
|
errno = 0; |
|
|
|
retval = ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid), |
|
|
|
(PTRACE_ARG3_TYPE) & ec, 0); |
|
|
|
if (errno) |
|
|
|
perror_with_name ("ptrace(PTRACE_GETREGS)"); |
|
|
|
|
|
|
|
memset (buf, 0, DEPRECATED_REGISTER_RAW_SIZE (G0_REGNUM)); |
|
|
|
supply_register (G0_REGNUM, buf); |
|
|
|
supply_register (TBR_REGNUM, (char *) &ec.tbr); |
|
|
|
|
|
|
|
memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (G1_REGNUM)], &ec.g1, |
|
|
|
4 * DEPRECATED_REGISTER_RAW_SIZE (G1_REGNUM)); |
|
|
|
for (i = G1_REGNUM; i <= G1_REGNUM + 3; i++) |
|
|
|
deprecated_register_valid[i] = 1; |
|
|
|
|
|
|
|
supply_register (PS_REGNUM, (char *) &ec.psr); |
|
|
|
supply_register (Y_REGNUM, (char *) &ec.y); |
|
|
|
supply_register (PC_REGNUM, (char *) &ec.pc); |
|
|
|
supply_register (DEPRECATED_NPC_REGNUM, (char *) &ec.npc); |
|
|
|
supply_register (WIM_REGNUM, (char *) &ec.wim); |
|
|
|
|
|
|
|
memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (O0_REGNUM)], ec.o, |
|
|
|
8 * DEPRECATED_REGISTER_RAW_SIZE (O0_REGNUM)); |
|
|
|
for (i = O0_REGNUM; i <= O0_REGNUM + 7; i++) |
|
|
|
deprecated_register_valid[i] = 1; |
|
|
|
} |
|
|
|
|
|
|
|
if (whatregs & WHATREGS_STACK) |
|
|
|
{ |
|
|
|
CORE_ADDR sp; |
|
|
|
int i; |
|
|
|
|
|
|
|
sp = read_register (SP_REGNUM); |
|
|
|
|
|
|
|
target_read_memory (sp + FRAME_SAVED_I0, |
|
|
|
&deprecated_registers[DEPRECATED_REGISTER_BYTE (I0_REGNUM)], |
|
|
|
8 * DEPRECATED_REGISTER_RAW_SIZE (I0_REGNUM)); |
|
|
|
for (i = I0_REGNUM; i <= I7_REGNUM; i++) |
|
|
|
deprecated_register_valid[i] = 1; |
|
|
|
|
|
|
|
target_read_memory (sp + FRAME_SAVED_L0, |
|
|
|
&deprecated_registers[DEPRECATED_REGISTER_BYTE (L0_REGNUM)], |
|
|
|
8 * DEPRECATED_REGISTER_RAW_SIZE (L0_REGNUM)); |
|
|
|
for (i = L0_REGNUM; i <= L0_REGNUM + 7; i++) |
|
|
|
deprecated_register_valid[i] = 1; |
|
|
|
} |
|
|
|
|
|
|
|
if (whatregs & WHATREGS_FLOAT) |
|
|
|
{ |
|
|
|
struct fcontext fc; /* fp regs */ |
|
|
|
int retval; |
|
|
|
int i; |
|
|
|
|
|
|
|
errno = 0; |
|
|
|
retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid), |
|
|
|
(PTRACE_ARG3_TYPE) & fc, 0); |
|
|
|
if (errno) |
|
|
|
perror_with_name ("ptrace(PTRACE_GETFPREGS)"); |
|
|
|
|
|
|
|
memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], fc.f.fregs, |
|
|
|
32 * DEPRECATED_REGISTER_RAW_SIZE (FP0_REGNUM)); |
|
|
|
for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++) |
|
|
|
deprecated_register_valid[i] = 1; |
|
|
|
|
|
|
|
supply_register (FPS_REGNUM, (char *) &fc.fsr); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* This routine handles storing of the I & L regs for the Sparc. The trick
|
|
|
|
here is that they actually live on the stack. The really tricky part is |
|
|
|
that when changing the stack pointer, the I & L regs must be written to |
|
|
|
where the new SP points, otherwise the regs will be incorrect when the |
|
|
|
process is started up again. We assume that the I & L regs are valid at |
|
|
|
this point. */ |
|
|
|
|
|
|
|
void |
|
|
|
store_inferior_registers (int regno) |
|
|
|
{ |
|
|
|
int whatregs = 0; |
|
|
|
|
|
|
|
if (regno == -1) |
|
|
|
whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK; |
|
|
|
else if (regno >= L0_REGNUM && regno <= I7_REGNUM) |
|
|
|
whatregs = WHATREGS_STACK; |
|
|
|
else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32) |
|
|
|
whatregs = WHATREGS_FLOAT; |
|
|
|
else if (regno == SP_REGNUM) |
|
|
|
whatregs = WHATREGS_STACK | WHATREGS_GEN; |
|
|
|
else |
|
|
|
whatregs = WHATREGS_GEN; |
|
|
|
|
|
|
|
if (whatregs & WHATREGS_GEN) |
|
|
|
{ |
|
|
|
struct econtext ec; /* general regs */ |
|
|
|
int retval; |
|
|
|
|
|
|
|
ec.tbr = read_register (TBR_REGNUM); |
|
|
|
memcpy (&ec.g1, &deprecated_registers[DEPRECATED_REGISTER_BYTE (G1_REGNUM)], |
|
|
|
4 * DEPRECATED_REGISTER_RAW_SIZE (G1_REGNUM)); |
|
|
|
|
|
|
|
ec.psr = read_register (PS_REGNUM); |
|
|
|
ec.y = read_register (Y_REGNUM); |
|
|
|
ec.pc = read_register (PC_REGNUM); |
|
|
|
ec.npc = read_register (DEPRECATED_NPC_REGNUM); |
|
|
|
ec.wim = read_register (WIM_REGNUM); |
|
|
|
|
|
|
|
memcpy (ec.o, &deprecated_registers[DEPRECATED_REGISTER_BYTE (O0_REGNUM)], |
|
|
|
8 * DEPRECATED_REGISTER_RAW_SIZE (O0_REGNUM)); |
|
|
|
|
|
|
|
errno = 0; |
|
|
|
retval = ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid), |
|
|
|
(PTRACE_ARG3_TYPE) & ec, 0); |
|
|
|
if (errno) |
|
|
|
perror_with_name ("ptrace(PTRACE_SETREGS)"); |
|
|
|
} |
|
|
|
|
|
|
|
if (whatregs & WHATREGS_STACK) |
|
|
|
{ |
|
|
|
int regoffset; |
|
|
|
CORE_ADDR sp; |
|
|
|
|
|
|
|
sp = read_register (SP_REGNUM); |
|
|
|
|
|
|
|
if (regno == -1 || regno == SP_REGNUM) |
|
|
|
{ |
|
|
|
if (!deprecated_register_valid[L0_REGNUM + 5]) |
|
|
|
internal_error (__FILE__, __LINE__, "failed internal consistency check"); |
|
|
|
target_write_memory (sp + FRAME_SAVED_I0, |
|
|
|
&deprecated_registers[DEPRECATED_REGISTER_BYTE (I0_REGNUM)], |
|
|
|
8 * DEPRECATED_REGISTER_RAW_SIZE (I0_REGNUM)); |
|
|
|
|
|
|
|
target_write_memory (sp + FRAME_SAVED_L0, |
|
|
|
&deprecated_registers[DEPRECATED_REGISTER_BYTE (L0_REGNUM)], |
|
|
|
8 * DEPRECATED_REGISTER_RAW_SIZE (L0_REGNUM)); |
|
|
|
} |
|
|
|
else if (regno >= L0_REGNUM && regno <= I7_REGNUM) |
|
|
|
{ |
|
|
|
if (!deprecated_register_valid[regno]) |
|
|
|
internal_error (__FILE__, __LINE__, "failed internal consistency check"); |
|
|
|
if (regno >= L0_REGNUM && regno <= L0_REGNUM + 7) |
|
|
|
regoffset = DEPRECATED_REGISTER_BYTE (regno) - DEPRECATED_REGISTER_BYTE (L0_REGNUM) |
|
|
|
+ FRAME_SAVED_L0; |
|
|
|
else |
|
|
|
regoffset = DEPRECATED_REGISTER_BYTE (regno) - DEPRECATED_REGISTER_BYTE (I0_REGNUM) |
|
|
|
+ FRAME_SAVED_I0; |
|
|
|
target_write_memory (sp + regoffset, |
|
|
|
&deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)], |
|
|
|
DEPRECATED_REGISTER_RAW_SIZE (regno)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (whatregs & WHATREGS_FLOAT) |
|
|
|
{ |
|
|
|
struct fcontext fc; /* fp regs */ |
|
|
|
int retval; |
|
|
|
|
|
|
|
/* We read fcontext first so that we can get good values for fq_t... */ |
|
|
|
errno = 0; |
|
|
|
retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid), |
|
|
|
(PTRACE_ARG3_TYPE) & fc, 0); |
|
|
|
if (errno) |
|
|
|
perror_with_name ("ptrace(PTRACE_GETFPREGS)"); |
|
|
|
|
|
|
|
memcpy (fc.f.fregs, &deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], |
|
|
|
32 * DEPRECATED_REGISTER_RAW_SIZE (FP0_REGNUM)); |
|
|
|
|
|
|
|
fc.fsr = read_register (FPS_REGNUM); |
|
|
|
|
|
|
|
errno = 0; |
|
|
|
retval = ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid), |
|
|
|
(PTRACE_ARG3_TYPE) & fc, 0); |
|
|
|
if (errno) |
|
|
|
perror_with_name ("ptrace(PTRACE_SETFPREGS)"); |
|
|
|
} |
|
|
|
} |
|
|
|
#endif /* SPARC */ |
|
|
|
|
|
|
|
#if defined (I386) || defined (M68K) || defined (rs6000) |
|
|
|
|
|
|
|
/* Return the offset relative to the start of the per-thread data to the
|
|
|
|
|