Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/gnu Make gdb compile on sparc64. (Actually work correctly i...
details: https://anonhg.NetBSD.org/src/rev/f304caae1d90
branches: trunk
changeset: 471550:f304caae1d90
user: eeh <eeh%NetBSD.org@localhost>
date: Sun Apr 04 19:02:31 1999 +0000
description:
Make gdb compile on sparc64. (Actually work correctly is another thing....)
diffstat:
gnu/dist/gdb/config/sparc/tm-nbsd.h | 4 +
gnu/dist/gdb/sp64nbsd-nat.c | 428 ++++++++++++++++++++++++++++++++++++
gnu/usr.bin/gdb/Makefile | 7 +-
3 files changed, 437 insertions(+), 2 deletions(-)
diffs (truncated from 475 to 300 lines):
diff -r 0ae68d0fedba -r f304caae1d90 gnu/dist/gdb/config/sparc/tm-nbsd.h
--- a/gnu/dist/gdb/config/sparc/tm-nbsd.h Sun Apr 04 18:15:58 1999 +0000
+++ b/gnu/dist/gdb/config/sparc/tm-nbsd.h Sun Apr 04 19:02:31 1999 +0000
@@ -20,7 +20,11 @@
#ifndef TM_NBSD_H
#define TM_NBSD_H
+#ifdef __arch64__
+#include "sparc/tm-sp64.h"
+#else
#include "sparc/tm-sparc.h"
+#endif
#include "tm-nbsd.h"
diff -r 0ae68d0fedba -r f304caae1d90 gnu/dist/gdb/sp64nbsd-nat.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gnu/dist/gdb/sp64nbsd-nat.c Sun Apr 04 19:02:31 1999 +0000
@@ -0,0 +1,428 @@
+/* Functions specific to running gdb native on a SPARC running NetBSD
+ Copyright 1989, 1992, 1993, 1994, 1996 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+#include <machine/frame.h>
+#include <machine/pcb.h>
+#include <machine/psl.h>
+#include <string.h>
+
+#include "defs.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.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 reg inferior_registers;
+ struct fpreg inferior_fp_registers;
+ long save_g0;
+ 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 (PT_GETREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) &inferior_registers, 0))
+ perror("ptrace_getregs");
+
+ /* Copy them (in order shown in reg.h) */
+ memcpy (®isters[REGISTER_BYTE (G0_REGNUM)],
+ &inferior_registers.r_global[0],
+ sizeof(inferior_registers.r_global));
+ memcpy (®isters[REGISTER_BYTE (O0_REGNUM)],
+ &inferior_registers.r_out[0],
+ sizeof(inferior_registers.r_out));
+ *(long *)®isters[REGISTER_BYTE (TSTATE_REGNUM)] =
+ inferior_registers.r_tstate;
+ *(long *)®isters[REGISTER_BYTE (PC_REGNUM)] =
+ inferior_registers.r_pc;
+ *(long *)®isters[REGISTER_BYTE (NPC_REGNUM)] =
+ inferior_registers.r_npc;
+ *(long *)®isters[REGISTER_BYTE (Y_REGNUM)] =
+ inferior_registers.r_y;
+
+ /*
+ * Now we need to decompose good old tstate into
+ * its constituent parts.
+ */
+ *(long *)®isters[REGISTER_BYTE (CWP_REGNUM)] =
+ (inferior_registers.r_tstate&TSTATE_CWP);
+ *(long *)®isters[REGISTER_BYTE (ASI_REGNUM)] =
+ ((inferior_registers.r_tstate&TSTATE_ASI)>>TSTATE_ASI_SHIFT);
+ *(long *)®isters[REGISTER_BYTE (PSTATE_REGNUM)] =
+ ((inferior_registers.r_tstate&TSTATE_PSTATE)>>TSTATE_PSTATE_SHIFT);
+ *(long *)®isters[REGISTER_BYTE (CCR_REGNUM)] =
+ ((inferior_registers.r_tstate&TSTATE_CCR)>>TSTATE_CCR_SHIFT);
+
+ /*
+ * Note that the G0 slot actually carries the
+ * value of the %tt register, and G0 is zero.
+ */
+ *(long *)®isters[REGISTER_BYTE(TT_REGNUM)] =
+ *(long *)®isters[REGISTER_BYTE(G0_REGNUM)];
+ *(long *)®isters[REGISTER_BYTE(G0_REGNUM)] = 0;
+
+ /* Mark what is valid (not the %i regs). */
+ for (i = G0_REGNUM; i <= O7_REGNUM; i++)
+ register_valid[i] = 1;
+ register_valid[TSTATE_REGNUM] = 1;
+ register_valid[PC_REGNUM] = 1;
+ register_valid[NPC_REGNUM] = 1;
+ register_valid[Y_REGNUM] = 1;
+ register_valid[PSTATE_REGNUM] = 1;
+ register_valid[ASI_REGNUM] = 1;
+ register_valid[CCR_REGNUM] = 1;
+ register_valid[CWP_REGNUM] = 1;
+
+#if 0
+ /* If we don't set these valid, read_register_bytes() rereads
+ all the regs every time it is called! FIXME. */
+ register_valid[TBR_REGNUM] = 1; /* Not true yet, FIXME */
+ register_valid[CPS_REGNUM] = 1; /* Not true yet, FIXME */
+#endif
+ }
+
+ /* Floating point registers */
+ if (regno == -1 || regno == FSR_REGNUM ||
+ (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31))
+ {
+ if (0 != ptrace (PT_GETFPREGS, inferior_pid,
+ (PTRACE_ARG3_TYPE) &inferior_fp_registers,
+ 0))
+ perror("ptrace_getfpregs");
+ memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)],
+ &inferior_fp_registers.fr_regs[0],
+ sizeof (inferior_fp_registers.fr_regs));
+ memcpy (®isters[REGISTER_BYTE (FSR_REGNUM)],
+ &inferior_fp_registers.fr_fsr,
+ sizeof (inferior_fp_registers.fr_fsr));
+ for (i = FP0_REGNUM; i <= FP0_REGNUM+31; i++)
+ register_valid[i] = 1;
+ register_valid[FSR_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_read_memory (*(CORE_ADDR*)®isters[REGISTER_BYTE (SP_REGNUM)],
+ ®isters[REGISTER_BYTE (L0_REGNUM)],
+ 16*REGISTER_RAW_SIZE (L0_REGNUM));
+ 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_unfiltered("register %d valid and read\n", regno);
+ target_read_memory (sp + i - REGISTER_BYTE (L0_REGNUM),
+ ®isters[i], REGISTER_RAW_SIZE (regno));
+ 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 reg inferior_registers;
+ struct fpreg inferior_fp_registers;
+ int wanna_store = INT_REGS + STACK_REGS + FP_REGS;
+ long save_g0;
+
+ /* 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 if (regno == FSR_REGNUM)
+ wanna_store = FP_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_write_memory (sp,
+ ®isters[REGISTER_BYTE (L0_REGNUM)],
+ 16*REGISTER_RAW_SIZE (L0_REGNUM));
+ }
+ else
+ {
+ if (!register_valid[regno]) abort();
+ target_write_memory ((sp + REGISTER_BYTE (regno) -
+ REGISTER_BYTE (L0_REGNUM)),
+ ®isters[REGISTER_BYTE (regno)],
+ REGISTER_RAW_SIZE (regno));
+ }
+
+ }
+
+ if (wanna_store & INT_REGS)
+ {
+ if (!register_valid[G1_REGNUM]) abort();
+
+ /* The G0 slot really holds %tt (leave it alone). */
+ save_g0 = inferior_registers.r_global[0];
+ memcpy (&inferior_registers.r_global[0],
+ ®isters[REGISTER_BYTE (G0_REGNUM)],
+ sizeof(inferior_registers.r_global));
+ inferior_registers.r_global[0] = save_g0;
+ memcpy (&inferior_registers.r_out[0],
+ ®isters[REGISTER_BYTE (O0_REGNUM)],
+ sizeof(inferior_registers.r_out));
+
+ inferior_registers.r_tstate =
+ *(int *)®isters[REGISTER_BYTE (TSTATE_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 (PT_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.fr_regs[0],
+ ®isters[REGISTER_BYTE (FP0_REGNUM)],
+ sizeof(inferior_fp_registers.fr_regs));
+ memcpy (&inferior_fp_registers.fr_fsr,
Home |
Main Index |
Thread Index |
Old Index