diff options
-rw-r--r-- | gdb/ChangeLog | 17 | ||||
-rw-r--r-- | gdb/Makefile.in | 2 | ||||
-rw-r--r-- | gdb/configure.in | 5 | ||||
-rw-r--r-- | gdb/infptrace.c | 15 | ||||
-rw-r--r-- | gdb/nat-sparc.c | 297 | ||||
-rw-r--r-- | gdb/nat-sun4os4.h | 27 | ||||
-rw-r--r-- | gdb/nat-trash.h | 2 | ||||
-rw-r--r-- | gdb/xm-sparc.h | 8 |
8 files changed, 355 insertions, 18 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6513826..2a73618 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,22 @@ Tue Sep 29 14:35:00 1992 K. Richard Pixley (rich@sendai.cygnus.com) + Host/target/native split for sun4. + + * Makefile.in (TSOBS): removed corelow.o. + * infptrace.c: included nat.h. + * nat-trash.h: temporary header file. This should be removed once + all hosts have the native/host/target split. + * configure.in: add a symlink from nat-trash.h to nat.h if no + other nat file exists for this configuration. + * sparc-tdep.c: no longer include sys/ptrace.h. + * sparc-xdep.c: removed. contents have been moved to nat-sparc.c. + * xm-sparc.h (ATTACH_DETACH, FETCH_INFERIOR_REGISTERS): moved to + nat-sun4os4.h. + * nat-sparc.c, nat-sun4os4.h: new files for sun4 native support. + * config/sun4os4.mh (XDEPFILES): moved infptrace.o and inftarg.o + to NATDEPFILES. removed sparc-xdep.o. + (NATDEPFILES, NAT_FILE): new macros for native support. + Break the direct connection from core_file_command to any particular type of core file support. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 03e5895..7b5bfd0 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -295,7 +295,7 @@ OBS = main.o blockframe.o breakpoint.o findvar.o stack.o source.o \ RAPP_OBS = rgdb.o rudp.o rserial.o serial.o udp.o $(XDEPFILES) -TSOBS = corelow.o inflow.o +TSOBS = inflow.o NTSOBS = standalone.o diff --git a/gdb/configure.in b/gdb/configure.in index 354ba53..4190f6f 100644 --- a/gdb/configure.in +++ b/gdb/configure.in @@ -261,6 +261,11 @@ rm -f nat.h if [ "${nativefile}" != "" ]; then files="${files} ${nativefile}" links="${links} nat.h" +# temporary scaffolding until all hosts have the host/target/native +# split in place. +else + files="${files} nat-trash.h" + links="${links} nat.h" fi # post-target: diff --git a/gdb/infptrace.c b/gdb/infptrace.c index 23cb8f4..7117bf9 100644 --- a/gdb/infptrace.c +++ b/gdb/infptrace.c @@ -22,6 +22,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "inferior.h" #include "target.h" +#include "nat.h" + #ifdef USG #include <sys/types.h> #endif @@ -89,21 +91,16 @@ call_ptrace (request, pid, addr, data) #define ptrace call_ptrace #endif -/* This is used when GDB is exiting. It gives less chance of error.*/ - void -kill_inferior_fast () +kill_inferior () { if (inferior_pid == 0) return; + /* ptrace PT_KILL only works if process is stopped!!! So stop it with + a real signal first, if we can. */ + kill (inferior_pid, SIGKILL); ptrace (PT_KILL, inferior_pid, (PTRACE_ARG3_TYPE) 0, 0); wait ((int *)0); -} - -void -kill_inferior () -{ - kill_inferior_fast (); target_mourn_inferior (); } diff --git a/gdb/nat-sparc.c b/gdb/nat-sparc.c new file mode 100644 index 0000000..fb78d2d --- /dev/null +++ b/gdb/nat-sparc.c @@ -0,0 +1,297 @@ +/* Functions specific to running gdb native on a Sun 4 running sunos4. + 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 "nat.h" + +#include <signal.h> +#include <sys/ptrace.h> +#include <sys/wait.h> +#include <machine/reg.h> + +/* 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; +{ + 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); + /* bcopy (&inferior_fp_registers.Fpu_fsr, + ®isters[REGISTER_BYTE (FPS_REGNUM)], + 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; + } +} + +/* 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; +{ + 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(); + 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"); + } +} + + +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 (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"); + } +} + diff --git a/gdb/nat-sun4os4.h b/gdb/nat-sun4os4.h new file mode 100644 index 0000000..d871289 --- /dev/null +++ b/gdb/nat-sun4os4.h @@ -0,0 +1,27 @@ +/* Macro definitions for running gdb on a Sun 4 running sunos 4. + 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. */ + +/* Do implement the attach and detach commands. */ + +#define ATTACH_DETACH + +/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */ + +#define FETCH_INFERIOR_REGISTERS + diff --git a/gdb/nat-trash.h b/gdb/nat-trash.h new file mode 100644 index 0000000..38bed5a --- /dev/null +++ b/gdb/nat-trash.h @@ -0,0 +1,2 @@ +/* this file is temporary scaffolding until all hosts have the + native/target/host split in place. FIXME. */ diff --git a/gdb/xm-sparc.h b/gdb/xm-sparc.h index 67ea6fa..9fc068f 100644 --- a/gdb/xm-sparc.h +++ b/gdb/xm-sparc.h @@ -28,14 +28,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define NEW_SUN_CORE -/* Do implement the attach and detach commands. */ - -#define ATTACH_DETACH - -/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */ - -#define FETCH_INFERIOR_REGISTERS - /* Before storing, we need to read all the registers. */ #define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES) |