/* Native-dependent code for LynxOS.
- Copyright 1993, 1994 Free Software Foundation, Inc.
+ Copyright 1993, 1994, 1995, 1996, 1999, 2000, 2001
+ Free Software Foundation, Inc.
-This file is part of GDB.
+ This file is part of GDB.
-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 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 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 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, 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 <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 */
It also handles knows where to find the I & L regs on the stack. */
void
-fetch_inferior_registers (regno)
- int regno;
+fetch_inferior_registers (int regno)
{
int whatregs = 0;
if (whatregs & WHATREGS_GEN)
{
- struct econtext ec; /* general regs */
+ 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);
+ retval = ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
+ (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);
+ 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);
+ 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));
sp = read_register (SP_REGNUM);
- target_xfer_memory (sp + FRAME_SAVED_I0,
- ®isters[REGISTER_BYTE(I0_REGNUM)],
- 8 * REGISTER_RAW_SIZE (I0_REGNUM), 0);
+ target_read_memory (sp + FRAME_SAVED_I0,
+ ®isters[REGISTER_BYTE (I0_REGNUM)],
+ 8 * REGISTER_RAW_SIZE (I0_REGNUM));
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);
+ target_read_memory (sp + FRAME_SAVED_L0,
+ ®isters[REGISTER_BYTE (L0_REGNUM)],
+ 8 * REGISTER_RAW_SIZE (L0_REGNUM));
for (i = L0_REGNUM; i <= L0_REGNUM + 7; i++)
register_valid[i] = 1;
}
if (whatregs & WHATREGS_FLOAT)
{
- struct fcontext fc; /* fp regs */
+ struct fcontext fc; /* fp regs */
int retval;
int i;
errno = 0;
- retval = ptrace (PTRACE_GETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) &fc,
- 0);
+ retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
+ (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);
+ supply_register (FPS_REGNUM, (char *) &fc.fsr);
}
}
this point. */
void
-store_inferior_registers (regno)
- int regno;
+store_inferior_registers (int regno)
{
int whatregs = 0;
if (whatregs & WHATREGS_GEN)
{
- struct econtext ec; /* general regs */
+ struct econtext ec; /* general regs */
int retval;
ec.tbr = read_register (TBR_REGNUM);
8 * REGISTER_RAW_SIZE (O0_REGNUM));
errno = 0;
- retval = ptrace (PTRACE_SETREGS, inferior_pid, (PTRACE_ARG3_TYPE) &ec,
- 0);
+ retval = ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & ec, 0);
if (errno)
perror_with_name ("ptrace(PTRACE_SETREGS)");
}
if (regno == -1 || regno == SP_REGNUM)
{
- if (!register_valid[L0_REGNUM+5])
- abort();
- target_xfer_memory (sp + FRAME_SAVED_I0,
+ if (!register_valid[L0_REGNUM + 5])
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ target_write_memory (sp + FRAME_SAVED_I0,
®isters[REGISTER_BYTE (I0_REGNUM)],
- 8 * REGISTER_RAW_SIZE (I0_REGNUM), 1);
+ 8 * REGISTER_RAW_SIZE (I0_REGNUM));
- target_xfer_memory (sp + FRAME_SAVED_L0,
+ target_write_memory (sp + FRAME_SAVED_L0,
®isters[REGISTER_BYTE (L0_REGNUM)],
- 8 * REGISTER_RAW_SIZE (L0_REGNUM), 1);
+ 8 * REGISTER_RAW_SIZE (L0_REGNUM));
}
else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
{
if (!register_valid[regno])
- abort();
+ internal_error (__FILE__, __LINE__, "failed internal consistency check");
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);
+ target_write_memory (sp + regoffset,
+ ®isters[REGISTER_BYTE (regno)],
+ REGISTER_RAW_SIZE (regno));
}
}
if (whatregs & WHATREGS_FLOAT)
{
- struct fcontext fc; /* fp regs */
+ 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);
+ retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
+ (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);
+ retval = ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) & fc, 0);
if (errno)
perror_with_name ("ptrace(PTRACE_SETFPREGS)");
- }
+ }
}
#endif /* SPARC */
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);
+ ecp = registers_addr (PIDGET (inferior_ptid));
for (regno = reglo; regno <= reghi; regno++)
{
unsigned int reg;
errno = 0;
- reg = ptrace (ptrace_fun, inferior_pid,
+ 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;
+
+ *(int *) &buf[i] = reg;
}
supply_register (regno, buf);
}
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++)
{
{
unsigned int reg;
- reg = *(unsigned int *)®isters[REGISTER_BYTE (regno) + i];
+ reg = *(unsigned int *) ®isters[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);
+ }
- if (TIDGET (inferior_pid) == 0)
+ ptid = BUILDPID (pid, thread);
+
+ /* 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;
- store_waitstatus (ourstatus, status);
+ realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid),
+ (PTRACE_ARG3_TYPE) 0, 0);
- return pid;
+ 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 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)
+ supply_register (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)
+{
+ add_core_fns (&lynx_core_fns);
+}