/* Native-dependent code for LynxOS.
- Copyright 1993, 1994 Free Software Foundation, Inc.
-This file is part of GDB.
+ Copyright (C) 1993, 1994, 1995, 1996, 1999, 2000, 2001, 2003, 2007
+ Free Software Foundation, Inc.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ This file is part of GDB.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#include "defs.h"
#include "frame.h"
#include "inferior.h"
#include "target.h"
+#include "gdbcore.h"
+#include "regcache.h"
#include <sys/ptrace.h>
-#include <sys/wait.h>
+#Include "gdb_wait.h"
#include <sys/fpp.h>
-static unsigned long registers_addr PARAMS ((int pid));
+static unsigned long registers_addr (int pid);
+static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
#define X(ENTRY)(offsetof(struct econtext, ENTRY))
static int regmap[] =
{
- X(eax),
- X(ecx),
- X(edx),
- X(ebx),
- X(esp), /* sp */
- X(ebp), /* fp */
- X(esi),
- X(edi),
- X(eip), /* pc */
- X(flags), /* ps */
- X(cs),
- X(ss),
- X(ds),
- X(es),
- X(ecode), /* Lynx doesn't give us either fs or gs, so */
- X(fault), /* we just substitute these two in the hopes
+ X (eax),
+ X (ecx),
+ X (edx),
+ X (ebx),
+ X (esp), /* sp */
+ X (ebp), /* fp */
+ X (esi),
+ X (edi),
+ X (eip), /* pc */
+ X (flags), /* ps */
+ X (cs),
+ X (ss),
+ X (ds),
+ X (es),
+ X (ecode), /* Lynx doesn't give us either fs or gs, so */
+ X (fault), /* we just substitute these two in the hopes
that they are useful. */
};
#endif /* I386 */
static int regmap[] =
{
- X(regs[0]), /* d0 */
- X(regs[1]), /* d1 */
- X(regs[2]), /* d2 */
- X(regs[3]), /* d3 */
- X(regs[4]), /* d4 */
- X(regs[5]), /* d5 */
- X(regs[6]), /* d6 */
- X(regs[7]), /* d7 */
- X(regs[8]), /* a0 */
- X(regs[9]), /* a1 */
- X(regs[10]), /* a2 */
- X(regs[11]), /* a3 */
- X(regs[12]), /* a4 */
- X(regs[13]), /* a5 */
- X(regs[14]), /* fp */
- offsetof (st_t, usp) - offsetof (st_t, ec), /* sp */
- X(status), /* ps */
- X(pc),
-
- X(fregs[0*3]), /* fp0 */
- X(fregs[1*3]), /* fp1 */
- X(fregs[2*3]), /* fp2 */
- X(fregs[3*3]), /* fp3 */
- X(fregs[4*3]), /* fp4 */
- X(fregs[5*3]), /* fp5 */
- X(fregs[6*3]), /* fp6 */
- X(fregs[7*3]), /* fp7 */
-
- X(fcregs[0]), /* fpcontrol */
- X(fcregs[1]), /* fpstatus */
- X(fcregs[2]), /* fpiaddr */
- X(ssw), /* fpcode */
- X(fault), /* fpflags */
+ X (regs[0]), /* d0 */
+ X (regs[1]), /* d1 */
+ X (regs[2]), /* d2 */
+ X (regs[3]), /* d3 */
+ X (regs[4]), /* d4 */
+ X (regs[5]), /* d5 */
+ X (regs[6]), /* d6 */
+ X (regs[7]), /* d7 */
+ X (regs[8]), /* a0 */
+ X (regs[9]), /* a1 */
+ X (regs[10]), /* a2 */
+ X (regs[11]), /* a3 */
+ X (regs[12]), /* a4 */
+ X (regs[13]), /* a5 */
+ X (regs[14]), /* fp */
+ offsetof (st_t, usp) - offsetof (st_t, ec), /* sp */
+ X (status), /* ps */
+ X (pc),
+
+ X (fregs[0 * 3]), /* fp0 */
+ X (fregs[1 * 3]), /* fp1 */
+ X (fregs[2 * 3]), /* fp2 */
+ X (fregs[3 * 3]), /* fp3 */
+ X (fregs[4 * 3]), /* fp4 */
+ X (fregs[5 * 3]), /* fp5 */
+ X (fregs[6 * 3]), /* fp6 */
+ X (fregs[7 * 3]), /* fp7 */
+
+ X (fcregs[0]), /* fpcontrol */
+ X (fcregs[1]), /* fpstatus */
+ X (fcregs[2]), /* fpiaddr */
+ X (ssw), /* fpcode */
+ X (fault), /* fpflags */
};
#endif /* M68K */
static int regmap[] =
{
-1, /* g0 */
- X(g1),
- X(g2),
- X(g3),
- X(g4),
+ 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 */
+ 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 /* SPARC */
static int regmap[] =
{
- X(iregs[0]), /* r0 */
- X(iregs[1]),
- X(iregs[2]),
- X(iregs[3]),
- X(iregs[4]),
- X(iregs[5]),
- X(iregs[6]),
- X(iregs[7]),
- X(iregs[8]),
- X(iregs[9]),
- X(iregs[10]),
- X(iregs[11]),
- X(iregs[12]),
- X(iregs[13]),
- X(iregs[14]),
- X(iregs[15]),
- X(iregs[16]),
- X(iregs[17]),
- X(iregs[18]),
- X(iregs[19]),
- X(iregs[20]),
- X(iregs[21]),
- X(iregs[22]),
- X(iregs[23]),
- X(iregs[24]),
- X(iregs[25]),
- X(iregs[26]),
- X(iregs[27]),
- X(iregs[28]),
- X(iregs[29]),
- X(iregs[30]),
- X(iregs[31]),
-
- X(fregs[0]), /* f0 */
- X(fregs[1]),
- X(fregs[2]),
- X(fregs[3]),
- X(fregs[4]),
- X(fregs[5]),
- X(fregs[6]),
- X(fregs[7]),
- X(fregs[8]),
- X(fregs[9]),
- X(fregs[10]),
- X(fregs[11]),
- X(fregs[12]),
- X(fregs[13]),
- X(fregs[14]),
- X(fregs[15]),
- X(fregs[16]),
- X(fregs[17]),
- X(fregs[18]),
- X(fregs[19]),
- X(fregs[20]),
- X(fregs[21]),
- X(fregs[22]),
- X(fregs[23]),
- X(fregs[24]),
- X(fregs[25]),
- X(fregs[26]),
- X(fregs[27]),
- X(fregs[28]),
- X(fregs[29]),
- X(fregs[30]),
- X(fregs[31]),
-
- X(srr0), /* IAR (PC) */
- X(srr1), /* MSR (PS) */
- X(cr), /* CR */
- X(lr), /* LR */
- X(ctr), /* CTR */
- X(xer), /* XER */
- X(mq) /* MQ */
+ X (iregs[0]), /* r0 */
+ X (iregs[1]),
+ X (iregs[2]),
+ X (iregs[3]),
+ X (iregs[4]),
+ X (iregs[5]),
+ X (iregs[6]),
+ X (iregs[7]),
+ X (iregs[8]),
+ X (iregs[9]),
+ X (iregs[10]),
+ X (iregs[11]),
+ X (iregs[12]),
+ X (iregs[13]),
+ X (iregs[14]),
+ X (iregs[15]),
+ X (iregs[16]),
+ X (iregs[17]),
+ X (iregs[18]),
+ X (iregs[19]),
+ X (iregs[20]),
+ X (iregs[21]),
+ X (iregs[22]),
+ X (iregs[23]),
+ X (iregs[24]),
+ X (iregs[25]),
+ X (iregs[26]),
+ X (iregs[27]),
+ X (iregs[28]),
+ X (iregs[29]),
+ X (iregs[30]),
+ X (iregs[31]),
+
+ X (fregs[0]), /* f0 */
+ X (fregs[1]),
+ X (fregs[2]),
+ X (fregs[3]),
+ X (fregs[4]),
+ X (fregs[5]),
+ X (fregs[6]),
+ X (fregs[7]),
+ X (fregs[8]),
+ X (fregs[9]),
+ X (fregs[10]),
+ X (fregs[11]),
+ X (fregs[12]),
+ X (fregs[13]),
+ X (fregs[14]),
+ X (fregs[15]),
+ X (fregs[16]),
+ X (fregs[17]),
+ X (fregs[18]),
+ X (fregs[19]),
+ X (fregs[20]),
+ X (fregs[21]),
+ X (fregs[22]),
+ X (fregs[23]),
+ X (fregs[24]),
+ X (fregs[25]),
+ X (fregs[26]),
+ X (fregs[27]),
+ X (fregs[28]),
+ X (fregs[29]),
+ X (fregs[30]),
+ X (fregs[31]),
+
+ X (srr0), /* IAR (PC) */
+ X (srr1), /* MSR (PS) */
+ X (cr), /* CR */
+ X (lr), /* LR */
+ X (ctr), /* CTR */
+ X (xer), /* XER */
+ X (mq) /* MQ */
};
#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 (regno)
- 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_RAW_SIZE];
- int retval;
- int i;
-
- errno = 0;
- retval = ptrace (PTRACE_GETREGS, inferior_pid, (PTRACE_ARG3_TYPE) &ec,
- 0);
- if (errno)
- perror_with_name ("ptrace(PTRACE_GETREGS)");
-
- 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 ("ptrace(PTRACE_GETFPREGS)");
-
- 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);
- }
-}
-
-/* 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;
-{
- 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 ("ptrace(PTRACE_SETREGS)");
- }
-
- 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 ("ptrace(PTRACE_GETFPREGS)");
-
- 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 ("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
saved context block. */
static unsigned long
-registers_addr(pid)
- int pid;
+registers_addr (int pid)
{
CORE_ADDR stblock;
- int ecpoff = offsetof(st_t, ecp);
+ int ecpoff = offsetof (st_t, ecp);
CORE_ADDR ecp;
errno = 0;
- stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE)0,
+ stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE) 0,
0);
if (errno)
perror_with_name ("ptrace(PTRACE_THREADUSER)");
- ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE)ecpoff,
+ ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) ecpoff,
0);
if (errno)
perror_with_name ("ptrace(PTRACE_PEEKTHREAD)");
marking them as valid so we won't fetch them again. */
void
-fetch_inferior_registers (regno)
- int regno;
+fetch_inferior_registers (int regno)
{
int reglo, reghi;
int i;
else
reglo = reghi = regno;
- ecp = registers_addr (inferior_pid);
-
- for (regno = reglo; regno <= reghi; regno++)
- {
- char buf[MAX_REGISTER_RAW_SIZE];
- int ptrace_fun = PTRACE_PEEKTHREAD;
+ ecp = registers_addr (PIDGET (inferior_ptid));
+ {
+ char buf[MAX_REGISTER_SIZE];
+ for (regno = reglo; regno <= reghi; regno++)
+ {
+ int ptrace_fun = PTRACE_PEEKTHREAD;
+
#ifdef M68K
- ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD;
+ ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD;
#endif
-
- for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
- {
- unsigned int reg;
-
- errno = 0;
- reg = ptrace (ptrace_fun, inferior_pid,
- (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), 0);
- if (errno)
- perror_with_name ("ptrace(PTRACE_PEEKUSP)");
-
- *(int *)&buf[i] = reg;
- }
- supply_register (regno, buf);
- }
+
+ for (i = 0; i < register_size (current_gdbarch, regno); i += sizeof (int))
+ {
+ unsigned int reg;
+
+ errno = 0;
+ reg = ptrace (ptrace_fun, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), 0);
+ if (errno)
+ perror_with_name ("ptrace(PTRACE_PEEKUSP)");
+
+ *(int *) &buf[i] = reg;
+ }
+ regcache_raw_supply (current_regcache, regno, buf);
+ }
+ }
}
/* 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). */
-/* Registers we shouldn't try to store. */
-#if !defined (CANNOT_STORE_REGISTER)
-#define CANNOT_STORE_REGISTER(regno) 0
-#endif
-
void
-store_inferior_registers (regno)
- int regno;
+store_inferior_registers (int regno)
{
int reglo, reghi;
int i;
else
reglo = reghi = regno;
- ecp = registers_addr (inferior_pid);
+ ecp = registers_addr (PIDGET (inferior_ptid));
for (regno = reglo; regno <= reghi; regno++)
{
ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER;
#endif
- for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
+ for (i = 0; i < register_size (current_gdbarch, regno); i += sizeof (int))
{
unsigned int reg;
- reg = *(unsigned int *)®isters[REGISTER_BYTE (regno) + i];
+ reg = *(unsigned int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno) + i];
errno = 0;
- ptrace (ptrace_fun, inferior_pid,
+ ptrace (ptrace_fun, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), reg);
if (errno)
perror_with_name ("ptrace(PTRACE_POKEUSP)");
/* Wait for child to do something. Return pid of child, or -1 in case
of error; store status through argument pointer OURSTATUS. */
-int
-child_wait (pid, ourstatus)
- int pid;
- struct target_waitstatus *ourstatus;
+ptid_t
+child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
{
int save_errno;
int thread;
- int status;
+ union wait status;
+ int pid;
while (1)
{
int sig;
- if (attach_flag)
- set_sigint_trap(); /* Causes SIGINT to be passed on to the
+ set_sigint_trap (); /* Causes SIGINT to be passed on to the
attached process. */
pid = wait (&status);
-#ifdef SPARC
-/* Swap halves of status so that the rest of GDB can understand it */
- status = (status << 16) | ((unsigned)status >> 16);
-#endif
save_errno = errno;
- if (attach_flag)
- clear_sigint_trap();
+ clear_sigint_trap ();
if (pid == -1)
{
if (save_errno == EINTR)
continue;
fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
- safe_strerror (save_errno));
+ safe_strerror (save_errno));
/* Claim it exited with unknown signal. */
ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
return -1;
}
- if (pid != PIDGET (inferior_pid)) /* Some other process?!? */
+ if (pid != PIDGET (inferior_ptid)) /* Some other process?!? */
continue;
-/* thread = WIFTID (status);*/
- thread = status >> 16;
+ thread = status.w_tid; /* Get thread id from status */
/* Initial thread value can only be acquired via wait, so we have to
- resort to this hack. */
+ resort to this hack. */
+
+ if (TIDGET (inferior_ptid) == 0 && thread != 0)
+ {
+ inferior_ptid = MERGEPID (PIDGET (inferior_ptid), thread);
+ add_thread (inferior_ptid);
+ }
+
+ ptid = BUILDPID (pid, thread);
- if (TIDGET (inferior_pid) == 0)
+ /* We've become a single threaded process again. */
+ if (thread == 0)
+ inferior_ptid = ptid;
+
+ /* Check for thread creation. */
+ if (WIFSTOPPED (status)
+ && WSTOPSIG (status) == SIGTRAP
+ && !in_thread_list (ptid))
{
- inferior_pid = BUILDPID (inferior_pid, thread);
- add_thread (inferior_pid);
+ int realsig;
+
+ realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid),
+ (PTRACE_ARG3_TYPE) 0, 0);
+
+ if (realsig == SIGNEWTHREAD)
+ {
+ /* It's a new thread notification. We don't want to much with
+ realsig -- the code in wait_for_inferior expects SIGTRAP. */
+ ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+ ourstatus->value.sig = TARGET_SIGNAL_0;
+ return ptid;
+ }
+ else
+ error ("Signal for unknown thread was not SIGNEWTHREAD");
}
- pid = BUILDPID (pid, thread);
+ /* Check for thread termination. */
+ else if (WIFSTOPPED (status)
+ && WSTOPSIG (status) == SIGTRAP
+ && in_thread_list (ptid))
+ {
+ int realsig;
+
+ realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid),
+ (PTRACE_ARG3_TYPE) 0, 0);
- store_waitstatus (ourstatus, status);
+ if (realsig == SIGTHREADEXIT)
+ {
+ ptrace (PTRACE_CONT, PIDGET (ptid), (PTRACE_ARG3_TYPE) 0, 0);
+ continue;
+ }
+ }
+
+#ifdef SPARC
+ /* SPARC Lynx uses an byte reversed wait status; we must use the
+ host macros to access it. These lines just a copy of
+ store_waitstatus. We can't use CHILD_SPECIAL_WAITSTATUS
+ because target.c can't include the Lynx <sys/wait.h>. */
+ if (WIFEXITED (status))
+ {
+ ourstatus->kind = TARGET_WAITKIND_EXITED;
+ ourstatus->value.integer = WEXITSTATUS (status);
+ }
+ else if (!WIFSTOPPED (status))
+ {
+ ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
+ ourstatus->value.sig =
+ target_signal_from_host (WTERMSIG (status));
+ }
+ else
+ {
+ ourstatus->kind = TARGET_WAITKIND_STOPPED;
+ ourstatus->value.sig =
+ target_signal_from_host (WSTOPSIG (status));
+ }
+#else
+ store_waitstatus (ourstatus, status.w_status);
+#endif
- return pid;
+ return ptid;
}
}
+/* Return nonzero if the given thread is still alive. */
+int
+child_thread_alive (ptid_t ptid)
+{
+ int pid = PIDGET (ptid);
+
+ /* Arggh. Apparently pthread_kill only works for threads within
+ the process that calls pthread_kill.
+
+ We want to avoid the lynx signal extensions as they simply don't
+ map well to the generic gdb interface we want to keep.
+
+ All we want to do is determine if a particular thread is alive;
+ it appears as if we can just make a harmless thread specific
+ ptrace call to do that. */
+ return (ptrace (PTRACE_THREADUSER, pid, 0, 0) != -1);
+}
+
/* Resume execution of the inferior process.
If STEP is nonzero, single-step it.
If SIGNAL is nonzero, give it that signal. */
void
-child_resume (pid, step, signal)
- int pid;
- int step;
- enum target_signal signal;
+child_resume (ptid_t ptid, int step, enum target_signal signal)
{
+ int func;
+ int pid = PIDGET (ptid);
+
errno = 0;
+ /* If pid == -1, then we want to step/continue all threads, else
+ we only want to step/continue a single thread. */
if (pid == -1)
- /* Resume all threads. */
- /* I think this only gets used in the non-threaded case, where "resume
- all threads" and "resume inferior_pid" are the same. */
- pid = inferior_pid;
+ {
+ pid = PIDGET (inferior_ptid);
+ func = step ? PTRACE_SINGLESTEP : PTRACE_CONT;
+ }
+ else
+ func = step ? PTRACE_SINGLESTEP_ONE : PTRACE_CONT_ONE;
+
/* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where
it was. (If GDB wanted it to start some other way, we have already
continue request (by setting breakpoints on all possible successor
instructions), so we don't have to worry about that here. */
- if (step)
- ptrace (PTRACE_SINGLESTEP_ONE, pid, (PTRACE_ARG3_TYPE) 1,
- target_signal_to_host (signal));
- else
- ptrace (PTRACE_CONT_ONE, pid, (PTRACE_ARG3_TYPE) 1,
- target_signal_to_host (signal));
+ ptrace (func, pid, (PTRACE_ARG3_TYPE) 1, target_signal_to_host (signal));
if (errno)
perror_with_name ("ptrace");
buffer. */
char *
-lynx_pid_to_str (pid)
- int pid;
+child_pid_to_str (ptid_t ptid)
{
static char buf[40];
- sprintf (buf, "process %d thread %d", PIDGET (pid), TIDGET (pid));
+ sprintf (buf, "process %d thread %d", PIDGET (ptid), TIDGET (ptid));
return buf;
}
CORE_REG_SECT points to the register values themselves, read into memory.
CORE_REG_SIZE is the size of that area.
WHICH says which set of registers we are handling (0 = int, 2 = float
- on machines where they are discontiguous).
+ on machines where they are discontiguous).
REG_ADDR is the offset from u.u_ar0 to the register values relative to
- core_reg_sect. This is used with old-fashioned core files to
- locate the registers in a large upage-plus-stack ".reg" section.
- Original upage address X is at location core_reg_sect+x+reg_addr.
+ core_reg_sect. This is used with old-fashioned core files to
+ locate the registers in a large upage-plus-stack ".reg" section.
+ Original upage address X is at location core_reg_sect+x+reg_addr.
*/
-void
-fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
- char *core_reg_sect;
- unsigned core_reg_size;
- int which;
- unsigned reg_addr;
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR reg_addr)
{
struct st_entry s;
unsigned int regno;
for (regno = 0; regno < NUM_REGS; regno++)
- supply_register (regno, core_reg_sect + offsetof (st_t, ec)
- + regmap[regno]);
+ if (regmap[regno] != -1)
+ regcache_raw_supply (current_regcache, regno,
+ core_reg_sect + offsetof (st_t, ec) + regmap[regno]);
#ifdef SPARC
/* Fetching this register causes all of the I & L regs to be read from the
fetch_inferior_registers (I0_REGNUM);
#endif
}
+\f
+
+/* Register that we are able to handle lynx core file formats.
+ FIXME: is this really bfd_target_unknown_flavour? */
+
+static struct core_fns lynx_core_fns =
+{
+ bfd_target_unknown_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_core_lynx (void)
+{
+ deprecated_add_core_fns (&lynx_core_fns);
+}