From: Stu Grossman Date: Sat, 22 Jan 1994 01:58:55 +0000 (+0000) Subject: * lynx-nat.c: Add Sparc support. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d575ddc0ef874292672001dc58848befa5325115;p=binutils-gdb.git * lynx-nat.c: Add Sparc support. * sparcly-nat.c: Remove. It's useless. * config/sparc/nm-sparclynx.h: Rewrite. * config/sparc/sparclynx.mh (NATDEPFILES): Replace sparcly-nat.o with lynx-nat.o * config/sparc/tm-sparclynx.h: Rewrite. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 05a8f73c687..705b3bffa11 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +Fri Jan 21 17:49:28 1994 Stu Grossman (grossman at cygnus.com) + + * lynx-nat.c: Add Sparc support. + * sparcly-nat.c: Remove. It's useless. + * config/sparc/nm-sparclynx.h: Rewrite. + * config/sparc/sparclynx.mh (NATDEPFILES): Replace sparcly-nat.o + with lynx-nat.o + * config/sparc/tm-sparclynx.h: Rewrite. + Fri Jan 21 19:08:48 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) * rs6000-pinsn.c: Use the new disassembler in the opcodes diff --git a/gdb/config/sparc/nm-sparclynx.h b/gdb/config/sparc/nm-sparclynx.h index 05a3197021d..1bb7d5f3fe7 100644 --- a/gdb/config/sparc/nm-sparclynx.h +++ b/gdb/config/sparc/nm-sparclynx.h @@ -20,45 +20,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef NM_SPARCLYNX_H #define NM_SPARCLYNX_H -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "thread.h" - -/* This is the amount to subtract from u.u_ar0 to get the offset in - the core file of the register values. */ - -#define KERNEL_U_ADDR USRSTACK - -#undef FLOAT_INFO /* No float info yet */ - -#define PTRACE_ARG3_TYPE char* - -/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */ -#define FETCH_INFERIOR_REGISTERS - -/* Thread ID of stopped thread. */ - -#define WIFTID(x) (((union wait *)&x)->w_tid) - -#define CHILD_WAIT - -extern int child_wait PARAMS ((int pid, int *status)); - -#if 0 /* need sparcly-nat.c to define this */ -/* Lynx needs a special definition of this so that we can - print out the pid and thread number seperatly. */ - -#undef target_pid_to_str -#define target_pid_to_str(PID) sparclynx_pid_to_str (PID) - -extern char *sparclynx_pid_to_str PARAMS ((int pid)); -#endif +#include "nm-lynx.h" #endif /* NM_SPARCLYNX_H */ diff --git a/gdb/config/sparc/sparclynx.mh b/gdb/config/sparc/sparclynx.mh index cc0d5bae046..51b94954857 100644 --- a/gdb/config/sparc/sparclynx.mh +++ b/gdb/config/sparc/sparclynx.mh @@ -2,7 +2,7 @@ XM_FILE= xm-sparclynx.h XDEPFILES= NAT_FILE= nm-sparclynx.h -NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o sparcly-nat.o +NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o lynx-nat.o REGEX=regex.o REGEX1=regex.o GDBSERVER_LIBS= -lbsd diff --git a/gdb/config/sparc/tm-sparclynx.h b/gdb/config/sparc/tm-sparclynx.h index d62c189f50f..525eeb4e0db 100644 --- a/gdb/config/sparc/tm-sparclynx.h +++ b/gdb/config/sparc/tm-sparclynx.h @@ -20,12 +20,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef TM_SPARCLYNX_H #define TM_SPARCLYNX_H -/* Use generic Sparc definitions. */ +#include "tm-lynx.h" +/* Use generic Sparc definitions. */ #include "sparc/tm-sparc.h" -/* Include COFF shared library support. */ - -#include "coff-solib.h" - #endif /* TM_SPARCLYNX_H */ diff --git a/gdb/lynx-nat.c b/gdb/lynx-nat.c index 48e52d2a7c2..4510972cf05 100644 --- a/gdb/lynx-nat.c +++ b/gdb/lynx-nat.c @@ -24,6 +24,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include +#include static unsigned long registers_addr PARAMS ((int pid)); @@ -95,6 +96,287 @@ 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; +{ + 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, ®isters[REGISTER_BYTE(I0_REGNUM)], + 8 * REGISTER_RAW_SIZE (I0_REGNUM), 0); + for (i = I0_REGNUM; i <= I7_REGNUM; i++) + register_valid[i] = 1; + + sp += 8 * REGISTER_RAW_SIZE (I0_REGNUM); + + target_xfer_memory (sp, ®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); + } +} + +/* 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 ("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, ®isters[REGISTER_BYTE (I0_REGNUM)], + 8 * REGISTER_RAW_SIZE (I0_REGNUM), 1); + sp += 8 * REGISTER_RAW_SIZE (I0_REGNUM); + target_xfer_memory (sp, ®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) + + 8 * REGISTER_RAW_SIZE (I0_REGNUM); + else + regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (I0_REGNUM); + 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 + +#ifndef SPARC + /* Return the offset relative to the start of the per-thread data to the saved context block. */ @@ -142,7 +424,7 @@ fetch_inferior_registers (regno) ecp = registers_addr (inferior_pid); - for (regno = reglo; regno <= reghi; regno++) + for (regno = reglo; regno <= reghi && regmap[regno] != -1; regno++) { char buf[MAX_REGISTER_RAW_SIZE]; int ptrace_fun = PTRACE_PEEKTHREAD; @@ -189,7 +471,7 @@ store_inferior_registers (regno) ecp = registers_addr (inferior_pid); - for (regno = reglo; regno <= reghi; regno++) + for (regno = reglo; regno <= reghi && regmap[regno] != -1; regno++) { int ptrace_fun = PTRACE_POKEUSER; @@ -211,6 +493,7 @@ store_inferior_registers (regno) } } } +#endif /* ifndef SPARC */ /* Wait for child to do something. Return pid of child, or -1 in case of error; store status through argument pointer OURSTATUS. */ @@ -231,7 +514,12 @@ child_wait (pid, ourstatus) if (attach_flag) set_sigint_trap(); /* Causes SIGINT to be passed on to the attached process. */ - pid = wait (status); + 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) diff --git a/gdb/sparcly-nat.c b/gdb/sparcly-nat.c index 92ab0e87cd6..e69de29bb2d 100644 --- a/gdb/sparcly-nat.c +++ b/gdb/sparcly-nat.c @@ -1,370 +0,0 @@ -/* Native-dependent code for Sparc running LynxOS. - Copyright (C) 1989, 1992, Free Software Foundation, Inc. - -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 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. */ - -#include "defs.h" -#include "inferior.h" -#include "target.h" - -#include -#include -#include -#if 0 -#include -#endif - -/* We don't store all registers immediately when requested, since they - get sent over in large chunks anyway. Instead, we accumulate most - of the changes and send them over once. "deferred_stores" keeps - track of which sets of registers we have locally-changed copies of, - so we only need send the groups that have changed. */ - -#define INT_REGS 1 -#define STACK_REGS 2 -#define FP_REGS 4 - -/* Fetch one or more registers from the inferior. REGNO == -1 to get - them all. We actually fetch more than requested, when convenient, - marking them as valid so we won't fetch them again. */ - -void -fetch_inferior_registers (regno) - int regno; -{ -#if 0 - struct regs inferior_registers; - struct fp_status inferior_fp_registers; - int i; - - /* We should never be called with deferred stores, because a prerequisite - for writing regs is to have fetched them all (PREPARE_TO_STORE), sigh. */ - if (deferred_stores) abort(); - - DO_DEFERRED_STORES; - - /* Global and Out regs are fetched directly, as well as the control - registers. If we're getting one of the in or local regs, - and the stack pointer has not yet been fetched, - we have to do that first, since they're found in memory relative - to the stack pointer. */ - if (regno < O7_REGNUM /* including -1 */ - || regno >= Y_REGNUM - || (!register_valid[SP_REGNUM] && regno < I7_REGNUM)) - { - if (0 != ptrace (PTRACE_GETREGS, inferior_pid, - (PTRACE_ARG3_TYPE) &inferior_registers, 0)) - perror("ptrace_getregs"); - - registers[REGISTER_BYTE (0)] = 0; - memcpy (®isters[REGISTER_BYTE (1)], &inferior_registers.r_g1, - 15 * REGISTER_RAW_SIZE (G0_REGNUM)); - *(int *)®isters[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; - *(int *)®isters[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc; - *(int *)®isters[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc; - *(int *)®isters[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y; - - for (i = G0_REGNUM; i <= O7_REGNUM; i++) - register_valid[i] = 1; - register_valid[Y_REGNUM] = 1; - register_valid[PS_REGNUM] = 1; - register_valid[PC_REGNUM] = 1; - register_valid[NPC_REGNUM] = 1; - /* If we don't set these valid, read_register_bytes() rereads - all the regs every time it is called! FIXME. */ - register_valid[WIM_REGNUM] = 1; /* Not true yet, FIXME */ - register_valid[TBR_REGNUM] = 1; /* Not true yet, FIXME */ - register_valid[FPS_REGNUM] = 1; /* Not true yet, FIXME */ - register_valid[CPS_REGNUM] = 1; /* Not true yet, FIXME */ - } - - /* Floating point registers */ - if (regno == -1 || (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31)) - { - if (0 != ptrace (PTRACE_GETFPREGS, inferior_pid, - (PTRACE_ARG3_TYPE) &inferior_fp_registers, - 0)) - perror("ptrace_getfpregs"); - memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers, - sizeof inferior_fp_registers.fpu_fr); - /* memcpy (®isters[REGISTER_BYTE (FPS_REGNUM)], - &inferior_fp_registers.Fpu_fsr, - sizeof (FPU_FSR_TYPE)); FIXME??? -- gnu@cyg */ - for (i = FP0_REGNUM; i <= FP0_REGNUM+31; i++) - register_valid[i] = 1; - register_valid[FPS_REGNUM] = 1; - } - - /* These regs are saved on the stack by the kernel. Only read them - all (16 ptrace calls!) if we really need them. */ - if (regno == -1) - { - target_xfer_memory (*(CORE_ADDR*)®isters[REGISTER_BYTE (SP_REGNUM)], - ®isters[REGISTER_BYTE (L0_REGNUM)], - 16*REGISTER_RAW_SIZE (L0_REGNUM), 0); - for (i = L0_REGNUM; i <= I7_REGNUM; i++) - register_valid[i] = 1; - } - else if (regno >= L0_REGNUM && regno <= I7_REGNUM) - { - CORE_ADDR sp = *(CORE_ADDR*)®isters[REGISTER_BYTE (SP_REGNUM)]; - i = REGISTER_BYTE (regno); - if (register_valid[regno]) - printf("register %d valid and read\n", regno); - target_xfer_memory (sp + i - REGISTER_BYTE (L0_REGNUM), - ®isters[i], REGISTER_RAW_SIZE (regno), 0); - register_valid[regno] = 1; - } -#endif -} - -/* 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) - int regno; -{ -#if 0 - struct regs inferior_registers; - struct fp_status inferior_fp_registers; - int wanna_store = INT_REGS + STACK_REGS + FP_REGS; - - /* First decide which pieces of machine-state we need to modify. - Default for regno == -1 case is all pieces. */ - if (regno >= 0) - if (FP0_REGNUM <= regno && regno < FP0_REGNUM + 32) - { - wanna_store = FP_REGS; - } - else - { - if (regno == SP_REGNUM) - wanna_store = INT_REGS + STACK_REGS; - else if (regno < L0_REGNUM || regno > I7_REGNUM) - wanna_store = INT_REGS; - else - wanna_store = STACK_REGS; - } - - /* See if we're forcing the stores to happen now, or deferring. */ - if (regno == -2) - { - wanna_store = deferred_stores; - deferred_stores = 0; - } - else - { - if (wanna_store == STACK_REGS) - { - /* Fall through and just store one stack reg. If we deferred - it, we'd have to store them all, or remember more info. */ - } - else - { - deferred_stores |= wanna_store; - return; - } - } - - if (wanna_store & STACK_REGS) - { - CORE_ADDR sp = *(CORE_ADDR *)®isters[REGISTER_BYTE (SP_REGNUM)]; - - if (regno < 0 || regno == SP_REGNUM) - { - if (!register_valid[L0_REGNUM+5]) abort(); - target_xfer_memory (sp, - ®isters[REGISTER_BYTE (L0_REGNUM)], - 16*REGISTER_RAW_SIZE (L0_REGNUM), 1); - } - else - { - if (!register_valid[regno]) abort(); - target_xfer_memory (sp + REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM), - ®isters[REGISTER_BYTE (regno)], - REGISTER_RAW_SIZE (regno), 1); - } - - } - - if (wanna_store & INT_REGS) - { - if (!register_valid[G1_REGNUM]) abort(); - - memcpy (&inferior_registers.r_g1, ®isters[REGISTER_BYTE (G1_REGNUM)], - 15 * REGISTER_RAW_SIZE (G1_REGNUM)); - - inferior_registers.r_ps = - *(int *)®isters[REGISTER_BYTE (PS_REGNUM)]; - inferior_registers.r_pc = - *(int *)®isters[REGISTER_BYTE (PC_REGNUM)]; - inferior_registers.r_npc = - *(int *)®isters[REGISTER_BYTE (NPC_REGNUM)]; - inferior_registers.r_y = - *(int *)®isters[REGISTER_BYTE (Y_REGNUM)]; - - if (0 != ptrace (PTRACE_SETREGS, inferior_pid, - (PTRACE_ARG3_TYPE) &inferior_registers, 0)) - perror("ptrace_setregs"); - } - - if (wanna_store & FP_REGS) - { - if (!register_valid[FP0_REGNUM+9]) abort(); - /* Initialize inferior_fp_registers members that gdb doesn't set - by reading them from the inferior. */ - if (0 != - ptrace (PTRACE_GETFPREGS, inferior_pid, - (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0)) - perror("ptrace_getfpregs"); - memcpy (&inferior_fp_registers, ®isters[REGISTER_BYTE (FP0_REGNUM)], - sizeof inferior_fp_registers.fpu_fr); - -/* memcpy (&inferior_fp_registers.Fpu_fsr, - ®isters[REGISTER_BYTE (FPS_REGNUM)], sizeof (FPU_FSR_TYPE)); -****/ - if (0 != - ptrace (PTRACE_SETFPREGS, inferior_pid, - (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0)) - perror("ptrace_setfpregs"); - } -#endif -} - - -void -fetch_core_registers (core_reg_sect, core_reg_size, which, ignore) - char *core_reg_sect; - unsigned core_reg_size; - int which; - unsigned int ignore; /* reg addr, unused in this version */ -{ -#if 0 - if (which == 0) { - - /* Integer registers */ - -#define gregs ((struct regs *)core_reg_sect) - /* G0 *always* holds 0. */ - *(int *)®isters[REGISTER_BYTE (0)] = 0; - - /* The globals and output registers. */ - memcpy (®isters[REGISTER_BYTE (G1_REGNUM)], &gregs->r_g1, - 15 * REGISTER_RAW_SIZE (G1_REGNUM)); - *(int *)®isters[REGISTER_BYTE (PS_REGNUM)] = gregs->r_ps; - *(int *)®isters[REGISTER_BYTE (PC_REGNUM)] = gregs->r_pc; - *(int *)®isters[REGISTER_BYTE (NPC_REGNUM)] = gregs->r_npc; - *(int *)®isters[REGISTER_BYTE (Y_REGNUM)] = gregs->r_y; - - /* My best guess at where to get the locals and input - registers is exactly where they usually are, right above - the stack pointer. If the core dump was caused by a bus error - from blowing away the stack pointer (as is possible) then this - won't work, but it's worth the try. */ - { - int sp; - - sp = *(int *)®isters[REGISTER_BYTE (SP_REGNUM)]; - if (0 != target_read_memory (sp, ®isters[REGISTER_BYTE (L0_REGNUM)], - 16 * REGISTER_RAW_SIZE (L0_REGNUM))) - { - /* fprintf so user can still use gdb */ - fprintf (stderr, - "Couldn't read input and local registers from core file\n"); - } - } - } else if (which == 2) { - - /* Floating point registers */ - -#define fpuregs ((struct fpu *) core_reg_sect) - if (core_reg_size >= sizeof (struct fpu)) - { - memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], fpuregs->fpu_regs, - sizeof (fpuregs->fpu_regs)); - memcpy (®isters[REGISTER_BYTE (FPS_REGNUM)], &fpuregs->fpu_fsr, - sizeof (FPU_FSR_TYPE)); - } - else - fprintf (stderr, "Couldn't read float regs from core file\n"); - } -#endif -} - -/* Wait for child to do something. Return pid of child, or -1 in case - of error; store status through argument pointer STATUS. */ - -/* FIXME: Not sparc-specific. Should be using lynx-nat.c instead; the - child_wait's are identical. */ - -int -child_wait (pid, status) - int pid; - struct target_waitstatus *ourstatus; -{ - int save_errno; - int thread; - - while (1) - { - int sig; - - if (attach_flag) - set_sigint_trap(); /* Causes SIGINT to be passed on to the - attached process. */ - pid = wait (status); - save_errno = errno; - - if (attach_flag) - 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)); - /* 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?!? */ - continue; - -/* thread = WIFTID (*status);*/ - thread = *status >> 16; - - /* Initial thread value can only be acquired via wait, so we have to - resort to this hack. */ - - if (TIDGET (inferior_pid) == 0) - { - inferior_pid = BUILDPID (inferior_pid, thread); - add_thread (inferior_pid); - } - - pid = BUILDPID (pid, thread); - - store_waitstatus (ourstatus, status); - - return pid; - } -}