diff options
author | Stan Shebs <shebs@codesourcery.com> | 1994-05-06 19:52:23 +0000 |
---|---|---|
committer | Stan Shebs <shebs@codesourcery.com> | 1994-05-06 19:52:23 +0000 |
commit | b292fca800177d0aef7d73a8c99951a974861050 (patch) | |
tree | 5a42454cd4e4bb9341e50f32efb714c82f8a7b49 /gdb/gdbserver/low-lynx.c | |
parent | 6149af094e48ff255fab64fb087811ee53156b8d (diff) | |
download | fsf-binutils-gdb-b292fca800177d0aef7d73a8c99951a974861050.zip fsf-binutils-gdb-b292fca800177d0aef7d73a8c99951a974861050.tar.gz fsf-binutils-gdb-b292fca800177d0aef7d73a8c99951a974861050.tar.bz2 |
Fri May 6 11:56:54 1994 Stan Shebs (shebs@andros.cygnus.com)
* gdbserver/Makefile.in: Remove irrelevant definitions and
comments inherited from the gdb Makefile.
(BFD_DIR, BFD, BFD_SRC, BFD_CFLAGS): Add from gdb Makefile.
(VERSION): Update to 4.12.3.
(gdbserver): Remove any existing executable first.
(distclean, realclean): Remove nm.h.
* gdbserver/low-lynx.c: Add Sparc Lynx support.
* gdbserver/low-sparc.c, gdbserver/low-sun3.c (sys/wait.h):
Don't use absolute pathname.
Diffstat (limited to 'gdb/gdbserver/low-lynx.c')
-rw-r--r-- | gdb/gdbserver/low-lynx.c | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/gdb/gdbserver/low-lynx.c b/gdb/gdbserver/low-lynx.c index 43c8c1e..349f702 100644 --- a/gdb/gdbserver/low-lynx.c +++ b/gdb/gdbserver/low-lynx.c @@ -29,6 +29,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <sys/signal.h> #include <sys/file.h> #include <sys/kernel.h> +#ifndef __LYNXOS +#define __LYNXOS +#endif #include <sys/itimer.h> #include <sys/time.h> #include <sys/resource.h> @@ -38,6 +41,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <sgtty.h> #include <fcntl.h> #include <sys/wait.h> +#include <sys/fpp.h> char registers[REGISTER_BYTES]; @@ -223,6 +227,294 @@ static int regmap[] = }; #endif +#ifdef SPARC +/* Mappings from tm-sparc.h */ + +#define FX(ENTRY)(offsetof(struct fcontext, ENTRY)) + +static int regmap[] = +{ + -1, /* g0 */ + X(g1), + X(g2), + X(g3), + X(g4), + -1, /* g5->g7 aren't saved by Lynx */ + -1, + -1, + + X(o[0]), + X(o[1]), + X(o[2]), + X(o[3]), + X(o[4]), + X(o[5]), + X(o[6]), /* sp */ + X(o[7]), /* ra */ + + -1,-1,-1,-1,-1,-1,-1,-1, /* l0 -> l7 */ + + -1,-1,-1,-1,-1,-1,-1,-1, /* i0 -> i7 */ + + FX(f.fregs[0]), /* f0 */ + FX(f.fregs[1]), + FX(f.fregs[2]), + FX(f.fregs[3]), + FX(f.fregs[4]), + FX(f.fregs[5]), + FX(f.fregs[6]), + FX(f.fregs[7]), + FX(f.fregs[8]), + FX(f.fregs[9]), + FX(f.fregs[10]), + FX(f.fregs[11]), + FX(f.fregs[12]), + FX(f.fregs[13]), + FX(f.fregs[14]), + FX(f.fregs[15]), + FX(f.fregs[16]), + FX(f.fregs[17]), + FX(f.fregs[18]), + FX(f.fregs[19]), + FX(f.fregs[20]), + FX(f.fregs[21]), + FX(f.fregs[22]), + FX(f.fregs[23]), + FX(f.fregs[24]), + FX(f.fregs[25]), + FX(f.fregs[26]), + FX(f.fregs[27]), + FX(f.fregs[28]), + FX(f.fregs[29]), + FX(f.fregs[30]), + FX(f.fregs[31]), + + X(y), + X(psr), + X(wim), + X(tbr), + X(pc), + X(npc), + FX(fsr), /* fpsr */ + -1, /* cpsr */ +}; +#endif + +#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 (regno) + int regno; +{ +#if 0 + 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_RAW_SIZE]; + int retval; + int i; + + errno = 0; + retval = ptrace (PTRACE_GETREGS, inferior_pid, (PTRACE_ARG3_TYPE) &ec, + 0); + if (errno) + perror_with_name ("Sparc fetch_inferior_registers(ptrace)"); + + memset (buf, 0, REGISTER_RAW_SIZE (G0_REGNUM)); + supply_register (G0_REGNUM, buf); + supply_register (TBR_REGNUM, (char *)&ec.tbr); + + memcpy (®isters[REGISTER_BYTE (G1_REGNUM)], &ec.g1, + 4 * REGISTER_RAW_SIZE (G1_REGNUM)); + for (i = G1_REGNUM; i <= G1_REGNUM + 3; i++) + 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 (NPC_REGNUM, (char *)&ec.npc); + supply_register (WIM_REGNUM, (char *)&ec.wim); + + memcpy (®isters[REGISTER_BYTE (O0_REGNUM)], ec.o, + 8 * REGISTER_RAW_SIZE (O0_REGNUM)); + for (i = O0_REGNUM; i <= O0_REGNUM + 7; i++) + register_valid[i] = 1; + } + + if (whatregs & WHATREGS_STACK) + { + CORE_ADDR sp; + int i; + + sp = read_register (SP_REGNUM); + + target_xfer_memory (sp + FRAME_SAVED_I0, + ®isters[REGISTER_BYTE(I0_REGNUM)], + 8 * REGISTER_RAW_SIZE (I0_REGNUM), 0); + for (i = I0_REGNUM; i <= I7_REGNUM; i++) + register_valid[i] = 1; + + target_xfer_memory (sp + FRAME_SAVED_L0, + ®isters[REGISTER_BYTE(L0_REGNUM)], + 8 * REGISTER_RAW_SIZE (L0_REGNUM), 0); + for (i = L0_REGNUM; i <= L0_REGNUM + 7; i++) + register_valid[i] = 1; + } + + if (whatregs & WHATREGS_FLOAT) + { + struct fcontext fc; /* fp regs */ + int retval; + int i; + + errno = 0; + retval = ptrace (PTRACE_GETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) &fc, + 0); + if (errno) + perror_with_name ("Sparc fetch_inferior_registers(ptrace)"); + + memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], fc.f.fregs, + 32 * REGISTER_RAW_SIZE (FP0_REGNUM)); + for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++) + register_valid[i] = 1; + + supply_register (FPS_REGNUM, (char *)&fc.fsr); + } +#endif +} + +/* 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 (regno) + int regno; +{ +#if 0 + 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, ®isters[REGISTER_BYTE (G1_REGNUM)], + 4 * 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 (NPC_REGNUM); + ec.wim = read_register (WIM_REGNUM); + + memcpy (ec.o, ®isters[REGISTER_BYTE (O0_REGNUM)], + 8 * REGISTER_RAW_SIZE (O0_REGNUM)); + + errno = 0; + retval = ptrace (PTRACE_SETREGS, inferior_pid, (PTRACE_ARG3_TYPE) &ec, + 0); + if (errno) + perror_with_name ("Sparc fetch_inferior_registers(ptrace)"); + } + + if (whatregs & WHATREGS_STACK) + { + int regoffset; + CORE_ADDR sp; + + sp = read_register (SP_REGNUM); + + if (regno == -1 || regno == SP_REGNUM) + { + if (!register_valid[L0_REGNUM+5]) + abort(); + target_xfer_memory (sp + FRAME_SAVED_I0, + ®isters[REGISTER_BYTE (I0_REGNUM)], + 8 * REGISTER_RAW_SIZE (I0_REGNUM), 1); + + target_xfer_memory (sp + FRAME_SAVED_L0, + ®isters[REGISTER_BYTE (L0_REGNUM)], + 8 * REGISTER_RAW_SIZE (L0_REGNUM), 1); + } + else if (regno >= L0_REGNUM && regno <= I7_REGNUM) + { + if (!register_valid[regno]) + abort(); + if (regno >= L0_REGNUM && regno <= L0_REGNUM + 7) + regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM) + + FRAME_SAVED_L0; + else + regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (I0_REGNUM) + + FRAME_SAVED_I0; + target_xfer_memory (sp + regoffset, ®isters[REGISTER_BYTE (regno)], + REGISTER_RAW_SIZE (regno), 1); + } + } + + 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, inferior_pid, (PTRACE_ARG3_TYPE) &fc, + 0); + if (errno) + perror_with_name ("Sparc fetch_inferior_registers(ptrace)"); + + memcpy (fc.f.fregs, ®isters[REGISTER_BYTE (FP0_REGNUM)], + 32 * REGISTER_RAW_SIZE (FP0_REGNUM)); + + fc.fsr = read_register (FPS_REGNUM); + + errno = 0; + retval = ptrace (PTRACE_SETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) &fc, + 0); + if (errno) + perror_with_name ("Sparc fetch_inferior_registers(ptrace)"); + } +#endif +} +#endif /* SPARC */ + +#ifndef SPARC + /* Return the offset relative to the start of the per-thread data to the saved context block. */ @@ -311,6 +603,8 @@ store_inferior_registers (ignored) } } +#endif /* ! SPARC */ + /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory in the NEW_SUN_PTRACE case. It ought to be straightforward. But it appears that writing did |