Browse Source
sparcnbsd-nat.c, and sparcnbsd-tdep.c. (sparc64nbsd-nat.o) (sparcnbsd-nat.o) (sparcnbsd-tdep.o): New dependency lists. * NEWS: Note new UltraSPARC NetBSD native configuration. * configure.host (sparc64-*-netbsd*): New host. * configure.tgt (sparc-*-netbsdelf*) (sparc-*-netbsd*): Set gdb_target to nbsd. (sparc64-*-netbsd*): New target. * sparc64nbsd-nat.c: New file. * sparcnbsd-nat.c: New file. * sparcnbsd-tdep.c: New file. * sparcnbsd-tdep.h: New file. * config/sparc/nbsd.mt: New file. * config/sparc/nbsd64.mh: New file. * config/sparc/nbsd64.mt: New file. * config/sparc/nbsdaout.mh (NATDEPFILES): Remove corelow.o, sparc-nat.o, and solib.o. Add sparcnbsd-nat.o. (HOST_IPC): Remove. * config/sparc/nbsdaout.mt: Remove. * config/sparc/nbsdelf.mh (NATDEPFILES): Remove corelow.o, sparc-nat.o, and solib.o. Add sparcnbsd-nat.o. (HOST_IPC): Remove. * config/sparc/nbsdelf.mt: Remove. * config/sparc/nm-nbsd.h: Update copyright years. Remove all sparc-nat.c compatiblity defines. * config/sparc/tm-nbsd.h: Update copyright years. Include solib.h. (GDB_MULTI_ARCH): Set to GDB_MULTI_ARCH_PARTIAL. * config/sparc/tm-nbsd64.h: New file. * config/sparc/tm-nbsdaout.h: Remove. * config/sparc/xm-nbsd.h: Remove.binutils-2_13-branch
19 changed files with 982 additions and 55 deletions
@ -0,0 +1,4 @@ |
|||
# Target: SPARC running NetBSD |
|||
TDEPFILES= sparc-tdep.o sparcnbsd-tdep.o nbsd-tdep.o corelow.o solib.o \ |
|||
solib-svr4.o |
|||
TM_FILE= tm-nbsd.h |
|||
@ -0,0 +1,3 @@ |
|||
# Host: UltraSPARC running NetBSD |
|||
NATDEPFILES= fork-child.o infptrace.o inftarg.o sparc64nbsd-nat.o |
|||
NAT_FILE= nm-nbsd.h |
|||
@ -0,0 +1,4 @@ |
|||
# Target: UltraSPARC running NetBSD |
|||
TDEPFILES= sparc-tdep.o sparcnbsd-tdep.o nbsd-tdep.o corelow.o solib.o \ |
|||
solib-svr4.o |
|||
TM_FILE= tm-nbsd64.h |
|||
@ -1,3 +0,0 @@ |
|||
# Target: Sun 4 or Sparcstation, running NetBSD |
|||
TDEPFILES= sparc-tdep.o |
|||
TM_FILE= tm-nbsdaout.h |
|||
@ -1,3 +0,0 @@ |
|||
# Target: Sun 4 or Sparcstation, running NetBSD |
|||
TDEPFILES= sparc-tdep.o |
|||
TM_FILE= tm-nbsd.h |
|||
@ -0,0 +1,207 @@ |
|||
/* Native-dependent code for UltraSPARC systems running NetBSD.
|
|||
Copyright 2002 Free Software Foundation, Inc. |
|||
Contributed by Wasabi Systems, 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 "defs.h" |
|||
#include "inferior.h" |
|||
#include "regcache.h" |
|||
|
|||
#include "sparcnbsd-tdep.h" |
|||
|
|||
#include <sys/types.h> |
|||
#include <sys/ptrace.h> |
|||
#include <machine/reg.h> |
|||
|
|||
/* NOTE: We don't bother with any of the deferred_store nonsense; it
|
|||
makes things a lot more complicated than they need to be. */ |
|||
|
|||
/* Determine if PT_GETREGS fetches this register. */ |
|||
static int |
|||
getregs_supplies (int regno) |
|||
{ |
|||
/* FIXME: PS_REGNUM for 32-bit code. */ |
|||
return (regno == TSTATE_REGNUM |
|||
|| regno == PC_REGNUM |
|||
|| regno == NPC_REGNUM |
|||
|| regno == Y_REGNUM |
|||
|| (regno >= G0_REGNUM && regno <= G7_REGNUM) |
|||
|| (regno >= O0_REGNUM && regno <= O7_REGNUM) |
|||
/* stack regs (handled by sparcnbsd_supply_reg) */ |
|||
|| (regno >= L0_REGNUM && regno <= I7_REGNUM)); |
|||
} |
|||
|
|||
/* Determine if PT_GETFPREGS fetches this register. */ |
|||
static int |
|||
getfpregs_supplies (int regno) |
|||
{ |
|||
return ((regno >= FP0_REGNUM && regno <= (FP0_REGNUM + 47)) |
|||
|| regno == FPS_REGNUM); |
|||
} |
|||
|
|||
void |
|||
fetch_inferior_registers (int regno) |
|||
{ |
|||
/* We don't use deferred stores. */ |
|||
if (deferred_stores) |
|||
internal_error (__FILE__, __LINE__, |
|||
"fetch_inferior_registers: deferred stores pending"); |
|||
|
|||
if (regno == -1 || getregs_supplies (regno)) |
|||
{ |
|||
union { |
|||
struct reg32 regs32; |
|||
struct reg64 regs64; |
|||
} regs; |
|||
|
|||
if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), |
|||
(PTRACE_ARG3_TYPE) ®s, 0) == -1) |
|||
perror_with_name ("Couldn't get registers"); |
|||
|
|||
if (gdbarch_ptr_bit (current_gdbarch) == 32) |
|||
sparcnbsd_supply_reg32 ((char *) ®s.regs32, regno); |
|||
else |
|||
sparcnbsd_supply_reg64 ((char *) ®s.regs64, regno); |
|||
if (regno != -1) |
|||
return; |
|||
} |
|||
|
|||
if (regno == -1 || getfpregs_supplies (regno)) |
|||
{ |
|||
union { |
|||
struct fpreg32 fpregs32; |
|||
struct fpreg64 fpregs64; |
|||
} fpregs; |
|||
|
|||
if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), |
|||
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1) |
|||
perror_with_name ("Couldn't get floating point registers"); |
|||
|
|||
if (gdbarch_ptr_bit (current_gdbarch) == 32) |
|||
sparcnbsd_supply_fpreg32 ((char *) &fpregs.fpregs32, regno); |
|||
else |
|||
sparcnbsd_supply_fpreg64 ((char *) &fpregs.fpregs64, regno); |
|||
if (regno != -1) |
|||
return; |
|||
} |
|||
} |
|||
|
|||
void |
|||
store_inferior_registers (int regno) |
|||
{ |
|||
/* We don't use deferred stores. */ |
|||
if (deferred_stores) |
|||
internal_error (__FILE__, __LINE__, |
|||
"store_inferior_registers: deferred stores pending"); |
|||
|
|||
if (regno == -1 || getregs_supplies (regno)) |
|||
{ |
|||
union { |
|||
struct reg32 regs32; |
|||
struct reg64 regs64; |
|||
} regs; |
|||
|
|||
if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), |
|||
(PTRACE_ARG3_TYPE) ®s, 0) == -1) |
|||
perror_with_name ("Couldn't get registers"); |
|||
|
|||
if (gdbarch_ptr_bit (current_gdbarch) == 32) |
|||
sparcnbsd_fill_reg32 ((char *) ®s.regs32, regno); |
|||
else |
|||
sparcnbsd_fill_reg64 ((char *) ®s.regs64, regno); |
|||
|
|||
if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), |
|||
(PTRACE_ARG3_TYPE) ®s, 0) == -1) |
|||
perror_with_name ("Couldn't write registers"); |
|||
|
|||
/* Deal with the stack regs. */ |
|||
if (regno == -1 || regno == SP_REGNUM |
|||
|| (regno >= L0_REGNUM && regno <= I7_REGNUM)) |
|||
{ |
|||
CORE_ADDR sp = read_register (SP_REGNUM); |
|||
int i; |
|||
char buf[8]; |
|||
|
|||
if (sp & 1) |
|||
{ |
|||
/* Registers are 64-bit. */ |
|||
sp += 2047; |
|||
|
|||
for (i = L0_REGNUM; i <= I7_REGNUM; i++) |
|||
{ |
|||
if (regno == -1 || regno == SP_REGNUM || regno == i) |
|||
{ |
|||
regcache_collect (i, buf); |
|||
target_write_memory (sp + ((i - L0_REGNUM) * 8), |
|||
buf, sizeof (buf)); |
|||
} |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
/* Registers are 32-bit. Toss any sign-extension of the stack
|
|||
pointer. |
|||
|
|||
FIXME: We don't currently handle 32-bit code in a binary |
|||
that indicated LP64. Do we have to care about that? */ |
|||
if (gdbarch_ptr_bit (current_gdbarch) != 32) |
|||
internal_error |
|||
(__FILE__, __LINE__, |
|||
"store_inferior_registers: 32-bit code in 64-bit inferior"); |
|||
|
|||
sp &= 0xffffffffUL; |
|||
for (i = L0_REGNUM; i <= I7_REGNUM; i++) |
|||
{ |
|||
if (regno == -1 || regno == SP_REGNUM || regno == i) |
|||
{ |
|||
regcache_collect (i, buf); |
|||
target_write_memory (sp + ((i - L0_REGNUM) * 4), buf, 4); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (regno != -1) |
|||
return; |
|||
} |
|||
|
|||
if (regno == -1 || getfpregs_supplies (regno)) |
|||
{ |
|||
union { |
|||
struct fpreg32 fpregs32; |
|||
struct fpreg64 fpregs64; |
|||
} fpregs; |
|||
|
|||
if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), |
|||
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1) |
|||
perror_with_name ("Couldn't get floating point registers"); |
|||
|
|||
if (gdbarch_ptr_bit (current_gdbarch) == 32) |
|||
sparcnbsd_fill_fpreg32 ((char *) &fpregs.fpregs32, regno); |
|||
else |
|||
sparcnbsd_fill_fpreg64 ((char *) &fpregs.fpregs64, regno); |
|||
|
|||
if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), |
|||
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1) |
|||
perror_with_name ("Couldn't write floating point registers"); |
|||
|
|||
if (regno != -1) |
|||
return; |
|||
} |
|||
} |
|||
@ -0,0 +1,154 @@ |
|||
/* Native-dependent code for SPARC systems running NetBSD.
|
|||
Copyright 2002 Free Software Foundation, Inc. |
|||
Contributed by Wasabi Systems, 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 "defs.h" |
|||
#include "inferior.h" |
|||
#include "regcache.h" |
|||
|
|||
#include "sparcnbsd-tdep.h" |
|||
|
|||
#include <sys/types.h> |
|||
#include <sys/ptrace.h> |
|||
#include <machine/reg.h> |
|||
|
|||
/* NOTE: We don't bother with any of the deferred_store nonsense; it
|
|||
makes things a lot more complicated than they need to be. */ |
|||
|
|||
/* Determine if PT_GETREGS fetches this register. */ |
|||
static int |
|||
getregs_supplies (int regno) |
|||
{ |
|||
return (regno == PS_REGNUM |
|||
|| regno == PC_REGNUM |
|||
|| regno == NPC_REGNUM |
|||
|| regno == Y_REGNUM |
|||
|| (regno >= G0_REGNUM && regno <= G7_REGNUM) |
|||
|| (regno >= O0_REGNUM && regno <= O7_REGNUM) |
|||
/* stack regs (handled by sparcnbsd_supply_reg) */ |
|||
|| (regno >= L0_REGNUM && regno <= I7_REGNUM)); |
|||
} |
|||
|
|||
/* Determine if PT_GETFPREGS fetches this register. */ |
|||
static int |
|||
getfpregs_supplies (int regno) |
|||
{ |
|||
return ((regno >= FP0_REGNUM && regno <= (FP0_REGNUM + 31)) |
|||
|| regno == FPS_REGNUM); |
|||
} |
|||
|
|||
void |
|||
fetch_inferior_registers (int regno) |
|||
{ |
|||
/* We don't use deferred stores. */ |
|||
if (deferred_stores) |
|||
internal_error (__FILE__, __LINE__, |
|||
"fetch_inferior_registers: deferred stores pending"); |
|||
|
|||
if (regno == -1 || getregs_supplies (regno)) |
|||
{ |
|||
struct reg regs; |
|||
|
|||
if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), |
|||
(PTRACE_ARG3_TYPE) ®s, 0) == -1) |
|||
perror_with_name ("Couldn't get registers"); |
|||
|
|||
sparcnbsd_supply_reg32 ((char *) ®s, regno); |
|||
if (regno != -1) |
|||
return; |
|||
} |
|||
|
|||
if (regno == -1 || getfpregs_supplies (regno)) |
|||
{ |
|||
struct fpreg fpregs; |
|||
|
|||
if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), |
|||
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1) |
|||
perror_with_name ("Couldn't get floating point registers"); |
|||
|
|||
sparcnbsd_supply_fpreg32 ((char *) &fpregs, regno); |
|||
if (regno != -1) |
|||
return; |
|||
} |
|||
} |
|||
|
|||
void |
|||
store_inferior_registers (int regno) |
|||
{ |
|||
/* We don't use deferred stores. */ |
|||
if (deferred_stores) |
|||
internal_error (__FILE__, __LINE__, |
|||
"store_inferior_registers: deferred stores pending"); |
|||
|
|||
if (regno == -1 || getregs_supplies (regno)) |
|||
{ |
|||
struct reg regs; |
|||
|
|||
if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), |
|||
(PTRACE_ARG3_TYPE) ®s, 0) == -1) |
|||
perror_with_name ("Couldn't get registers"); |
|||
|
|||
sparcnbsd_fill_reg32 ((char *) ®s, regno); |
|||
|
|||
if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), |
|||
(PTRACE_ARG3_TYPE) ®s, 0) == -1) |
|||
perror_with_name ("Couldn't write registers"); |
|||
|
|||
/* Deal with the stack regs. */ |
|||
if (regno == -1 || regno == SP_REGNUM |
|||
|| (regno >= L0_REGNUM && regno <= I7_REGNUM)) |
|||
{ |
|||
CORE_ADDR sp = read_register (SP_REGNUM); |
|||
int i; |
|||
char buf[4]; |
|||
|
|||
for (i = L0_REGNUM; i <= I7_REGNUM; i++) |
|||
{ |
|||
if (regno == -1 || regno == SP_REGNUM || regno == i) |
|||
{ |
|||
regcache_collect (i, buf); |
|||
target_write_memory (sp + ((i - L0_REGNUM) * 4), |
|||
buf, sizeof (buf)); |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (regno != -1) |
|||
return; |
|||
} |
|||
|
|||
if (regno == -1 || getfpregs_supplies (regno)) |
|||
{ |
|||
struct fpreg fpregs; |
|||
|
|||
if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), |
|||
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1) |
|||
perror_with_name ("Couldn't get floating point registers"); |
|||
|
|||
sparcnbsd_fill_fpreg32 ((char *) &fpregs, regno); |
|||
|
|||
if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), |
|||
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1) |
|||
perror_with_name ("Couldn't write floating point registers"); |
|||
|
|||
if (regno != -1) |
|||
return; |
|||
} |
|||
} |
|||
@ -0,0 +1,531 @@ |
|||
/* Target-dependent code for SPARC systems running NetBSD.
|
|||
Copyright 2002 Free Software Foundation, Inc. |
|||
Contributed by Wasabi Systems, 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 "defs.h" |
|||
#include "gdbcore.h" |
|||
#include "regcache.h" |
|||
#include "target.h" |
|||
#include "value.h" |
|||
#include "osabi.h" |
|||
|
|||
#include "sparcnbsd-tdep.h" |
|||
#include "nbsd-tdep.h" |
|||
|
|||
#include "solib-svr4.h" |
|||
|
|||
#define REG32_OFFSET_PSR (0 * 4) |
|||
#define REG32_OFFSET_PC (1 * 4) |
|||
#define REG32_OFFSET_NPC (2 * 4) |
|||
#define REG32_OFFSET_Y (3 * 4) |
|||
#define REG32_OFFSET_GLOBAL (4 * 4) |
|||
#define REG32_OFFSET_OUT (12 * 4) |
|||
|
|||
#define REG64_OFFSET_TSTATE (0 * 8) |
|||
#define REG64_OFFSET_PC (1 * 8) |
|||
#define REG64_OFFSET_NPC (2 * 8) |
|||
#define REG64_OFFSET_Y (3 * 8) |
|||
#define REG64_OFFSET_GLOBAL (4 * 8) |
|||
#define REG64_OFFSET_OUT (12 * 8) |
|||
|
|||
void |
|||
sparcnbsd_supply_reg32 (char *regs, int regno) |
|||
{ |
|||
int i; |
|||
|
|||
if (regno == PS_REGNUM || regno == -1) |
|||
supply_register (PS_REGNUM, regs + REG32_OFFSET_PSR); |
|||
|
|||
if (regno == PC_REGNUM || regno == -1) |
|||
supply_register (PC_REGNUM, regs + REG32_OFFSET_PC); |
|||
|
|||
if (regno == NPC_REGNUM || regno == -1) |
|||
supply_register (NPC_REGNUM, regs + REG32_OFFSET_NPC); |
|||
|
|||
if (regno == Y_REGNUM || regno == -1) |
|||
supply_register (Y_REGNUM, regs + REG32_OFFSET_Y); |
|||
|
|||
if ((regno >= G0_REGNUM && regno <= G7_REGNUM) || regno == -1) |
|||
{ |
|||
if (regno == G0_REGNUM || regno == -1) |
|||
supply_register (G0_REGNUM, NULL); /* %g0 is always zero */ |
|||
for (i = G1_REGNUM; i <= G7_REGNUM; i++) |
|||
{ |
|||
if (regno == i || regno == -1) |
|||
supply_register (i, regs + REG32_OFFSET_GLOBAL + |
|||
((i - G0_REGNUM) * 4)); |
|||
} |
|||
} |
|||
|
|||
if ((regno >= O0_REGNUM && regno <= O7_REGNUM) || regno == -1) |
|||
{ |
|||
for (i = O0_REGNUM; i <= O7_REGNUM; i++) |
|||
{ |
|||
if (regno == i || regno == -1) |
|||
supply_register (i, regs + REG32_OFFSET_OUT + |
|||
((i - O0_REGNUM) * 4)); |
|||
} |
|||
} |
|||
|
|||
/* Inputs and Locals are stored onto the stack by by the kernel. */ |
|||
if ((regno >= L0_REGNUM && regno <= I7_REGNUM) || regno == -1) |
|||
{ |
|||
CORE_ADDR sp = read_register (SP_REGNUM); |
|||
char buf[4]; |
|||
|
|||
for (i = L0_REGNUM; i <= I7_REGNUM; i++) |
|||
{ |
|||
if (regno == i || regno == -1) |
|||
{ |
|||
target_read_memory (sp + ((i - L0_REGNUM) * 4), |
|||
buf, sizeof (buf)); |
|||
supply_register (i, buf); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/* FIXME: If we don't set these valid, read_register_bytes() rereads
|
|||
all the regs every time it is called! */ |
|||
if (regno == WIM_REGNUM || regno == -1) |
|||
supply_register (WIM_REGNUM, NULL); |
|||
if (regno == TBR_REGNUM || regno == -1) |
|||
supply_register (TBR_REGNUM, NULL); |
|||
if (regno == CPS_REGNUM || regno == -1) |
|||
supply_register (CPS_REGNUM, NULL); |
|||
} |
|||
|
|||
void |
|||
sparcnbsd_supply_reg64 (char *regs, int regno) |
|||
{ |
|||
int i; |
|||
char buf[8]; |
|||
|
|||
if (regno == TSTATE_REGNUM || regno == -1) |
|||
supply_register (PS_REGNUM, regs + REG64_OFFSET_TSTATE); |
|||
|
|||
if (regno == PC_REGNUM || regno == -1) |
|||
supply_register (PC_REGNUM, regs + REG64_OFFSET_PC); |
|||
|
|||
if (regno == NPC_REGNUM || regno == -1) |
|||
supply_register (NPC_REGNUM, regs + REG64_OFFSET_NPC); |
|||
|
|||
if (regno == Y_REGNUM || regno == -1) |
|||
{ |
|||
memset (buf, 0, sizeof (buf)); |
|||
memcpy (&buf[4], regs + REG64_OFFSET_Y, 4); |
|||
supply_register (Y_REGNUM, buf); |
|||
} |
|||
|
|||
if ((regno >= G0_REGNUM && regno <= G7_REGNUM) || regno == -1) |
|||
{ |
|||
if (regno == G0_REGNUM || regno == -1) |
|||
supply_register (G0_REGNUM, NULL); /* %g0 is always zero */ |
|||
for (i = G1_REGNUM; i <= G7_REGNUM; i++) |
|||
{ |
|||
if (regno == i || regno == -1) |
|||
supply_register (i, regs + REG64_OFFSET_GLOBAL + |
|||
((i - G0_REGNUM) * 8)); |
|||
} |
|||
} |
|||
|
|||
if ((regno >= O0_REGNUM && regno <= O7_REGNUM) || regno == -1) |
|||
{ |
|||
for (i = O0_REGNUM; i <= O7_REGNUM; i++) |
|||
{ |
|||
if (regno == i || regno == -1) |
|||
supply_register (i, regs + REG64_OFFSET_OUT + |
|||
((i - O0_REGNUM) * 8)); |
|||
} |
|||
} |
|||
|
|||
/* Inputs and Locals are stored onto the stack by by the kernel. */ |
|||
if ((regno >= L0_REGNUM && regno <= I7_REGNUM) || regno == -1) |
|||
{ |
|||
CORE_ADDR sp = read_register (SP_REGNUM); |
|||
char buf[8]; |
|||
|
|||
if (sp & 1) |
|||
{ |
|||
/* Registers are 64-bit. */ |
|||
sp += 2047; |
|||
|
|||
for (i = L0_REGNUM; i <= I7_REGNUM; i++) |
|||
{ |
|||
if (regno == i || regno == -1) |
|||
{ |
|||
target_read_memory (sp + ((i - L0_REGNUM) * 8), |
|||
buf, sizeof (buf)); |
|||
supply_register (i, buf); |
|||
} |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
/* Registers are 32-bit. Toss any sign-extension of the stack
|
|||
pointer, clear out the top half of the temporary buffer, and |
|||
put the register value in the bottom half. */ |
|||
|
|||
sp &= 0xffffffffUL; |
|||
memset (buf, 0, sizeof (buf)); |
|||
for (i = L0_REGNUM; i <= I7_REGNUM; i++) |
|||
{ |
|||
if (regno == i || regno == -1) |
|||
{ |
|||
target_read_memory (sp + ((i - L0_REGNUM) * 4), |
|||
&buf[4], sizeof (buf)); |
|||
supply_register (i, buf); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
/* FIXME: If we don't set these valid, read_register_bytes() rereads
|
|||
all the regs every time it is called! */ |
|||
if (regno == WIM_REGNUM || regno == -1) |
|||
supply_register (WIM_REGNUM, NULL); |
|||
if (regno == TBR_REGNUM || regno == -1) |
|||
supply_register (TBR_REGNUM, NULL); |
|||
if (regno == CPS_REGNUM || regno == -1) |
|||
supply_register (CPS_REGNUM, NULL); |
|||
} |
|||
|
|||
void |
|||
sparcnbsd_fill_reg32 (char *regs, int regno) |
|||
{ |
|||
int i; |
|||
|
|||
if (regno == PS_REGNUM || regno == -1) |
|||
regcache_collect (PS_REGNUM, regs + REG32_OFFSET_PSR); |
|||
|
|||
if (regno == PC_REGNUM || regno == -1) |
|||
regcache_collect (PC_REGNUM, regs + REG32_OFFSET_PC); |
|||
|
|||
if (regno == NPC_REGNUM || regno == -1) |
|||
regcache_collect (NPC_REGNUM, regs + REG32_OFFSET_NPC); |
|||
|
|||
if (regno == Y_REGNUM || regno == -1) |
|||
regcache_collect (Y_REGNUM, regs + REG32_OFFSET_Y); |
|||
|
|||
if ((regno >= G0_REGNUM && regno <= G7_REGNUM) || regno == -1) |
|||
{ |
|||
/* %g0 is always zero */ |
|||
for (i = G1_REGNUM; i <= G7_REGNUM; i++) |
|||
{ |
|||
if (regno == i || regno == -1) |
|||
regcache_collect (i, regs + REG32_OFFSET_GLOBAL + |
|||
((i - G0_REGNUM) * 4)); |
|||
} |
|||
} |
|||
|
|||
if ((regno >= O0_REGNUM && regno <= O7_REGNUM) || regno == -1) |
|||
{ |
|||
for (i = O0_REGNUM; i <= O7_REGNUM; i++) |
|||
{ |
|||
if (regno == i || regno == -1) |
|||
regcache_collect (i, regs + REG32_OFFSET_OUT + |
|||
((i - O0_REGNUM) * 4)); |
|||
} |
|||
} |
|||
|
|||
/* Responsibility for the stack regs is pushed off onto the caller. */ |
|||
} |
|||
|
|||
void |
|||
sparcnbsd_fill_reg64 (char *regs, int regno) |
|||
{ |
|||
int i; |
|||
|
|||
if (regno == TSTATE_REGNUM || regno == -1) |
|||
regcache_collect (TSTATE_REGNUM, regs + REG64_OFFSET_TSTATE); |
|||
|
|||
if (regno == PC_REGNUM || regno == -1) |
|||
regcache_collect (PC_REGNUM, regs + REG64_OFFSET_PC); |
|||
|
|||
if (regno == NPC_REGNUM || regno == -1) |
|||
regcache_collect (NPC_REGNUM, regs + REG64_OFFSET_NPC); |
|||
|
|||
if (regno == Y_REGNUM || regno == -1) |
|||
regcache_collect (Y_REGNUM, regs + REG64_OFFSET_Y); |
|||
|
|||
if ((regno >= G0_REGNUM && regno <= G7_REGNUM) || regno == -1) |
|||
{ |
|||
/* %g0 is always zero */ |
|||
for (i = G1_REGNUM; i <= G7_REGNUM; i++) |
|||
{ |
|||
if (regno == i || regno == -1) |
|||
regcache_collect (i, regs + REG64_OFFSET_GLOBAL + |
|||
((i - G0_REGNUM) * 4)); |
|||
} |
|||
} |
|||
|
|||
if ((regno >= O0_REGNUM && regno <= O7_REGNUM) || regno == -1) |
|||
{ |
|||
for (i = O0_REGNUM; i <= O7_REGNUM; i++) |
|||
{ |
|||
if (regno == i || regno == -1) |
|||
regcache_collect (i, regs + REG64_OFFSET_OUT + |
|||
((i - O0_REGNUM) * 4)); |
|||
} |
|||
} |
|||
|
|||
/* Responsibility for the stack regs is pushed off onto the caller. */ |
|||
} |
|||
|
|||
void |
|||
sparcnbsd_supply_fpreg32 (char *fpregs, int regno) |
|||
{ |
|||
int i; |
|||
|
|||
for (i = 0; i <= 31; i++) |
|||
{ |
|||
if (regno == (FP0_REGNUM + i) || regno == -1) |
|||
supply_register (FP0_REGNUM + i, fpregs + (i * 4)); |
|||
} |
|||
|
|||
if (regno == FPS_REGNUM || regno == -1) |
|||
supply_register (FPS_REGNUM, fpregs + (32 * 4)); |
|||
} |
|||
|
|||
void |
|||
sparcnbsd_supply_fpreg64 (char *fpregs, int regno) |
|||
{ |
|||
int i; |
|||
|
|||
for (i = 0; i <= 31; i++) |
|||
{ |
|||
if (regno == (FP0_REGNUM + i) || regno == -1) |
|||
supply_register (FP0_REGNUM + i, fpregs + (i * 4)); |
|||
} |
|||
|
|||
for (; i <= 47; i++) |
|||
{ |
|||
if (regno == (FP0_REGNUM + i) || regno == -1) |
|||
supply_register (FP0_REGNUM + i, fpregs + (32 * 4) + (i * 8)); |
|||
} |
|||
|
|||
if (regno == FPS_REGNUM || regno == -1) |
|||
supply_register (FPS_REGNUM, fpregs + (32 * 4) + (16 * 8)); |
|||
|
|||
/* XXX %gsr */ |
|||
} |
|||
|
|||
void |
|||
sparcnbsd_fill_fpreg32 (char *fpregs, int regno) |
|||
{ |
|||
int i; |
|||
|
|||
for (i = 0; i <= 31; i++) |
|||
{ |
|||
if (regno == (FP0_REGNUM + i) || regno == -1) |
|||
regcache_collect (FP0_REGNUM + i, fpregs + (i * 4)); |
|||
} |
|||
|
|||
if (regno == FPS_REGNUM || regno == -1) |
|||
regcache_collect (FPS_REGNUM, fpregs + (32 * 4)); |
|||
} |
|||
|
|||
void |
|||
sparcnbsd_fill_fpreg64 (char *fpregs, int regno) |
|||
{ |
|||
int i; |
|||
|
|||
for (i = 0; i <= 31; i++) |
|||
{ |
|||
if (regno == (FP0_REGNUM + i) || regno == -1) |
|||
regcache_collect (FP0_REGNUM + i, fpregs + (i * 4)); |
|||
} |
|||
|
|||
for (; i <= 47; i++) |
|||
{ |
|||
if (regno == (FP0_REGNUM + i) || regno == -1) |
|||
regcache_collect (FP0_REGNUM + i, fpregs + (32 * 4) + (i * 8)); |
|||
} |
|||
|
|||
if (regno == FPS_REGNUM || regno == -1) |
|||
regcache_collect (FPS_REGNUM, fpregs + (32 * 4) + (16 * 8)); |
|||
|
|||
/* XXX %gsr */ |
|||
} |
|||
|
|||
/* Unlike other NetBSD implementations, the SPARC port historically used
|
|||
.reg and .reg2 (see bfd/netbsd-core.c), and as such, we can share one |
|||
routine for a.out and ELF core files. */ |
|||
static void |
|||
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, |
|||
CORE_ADDR ignore) |
|||
{ |
|||
int reg_size, fpreg_size; |
|||
|
|||
if (gdbarch_ptr_bit (current_gdbarch) == 32) |
|||
{ |
|||
reg_size = (20 * 4); |
|||
fpreg_size = (33 * 4); |
|||
} |
|||
else |
|||
{ |
|||
reg_size = (20 * 8); |
|||
fpreg_size = (64 * 4) |
|||
+ 8 /* fsr */ |
|||
+ 4 /* gsr */ |
|||
+ 4; /* pad */ |
|||
} |
|||
|
|||
switch (which) |
|||
{ |
|||
case 0: /* Integer registers */ |
|||
if (core_reg_size != reg_size) |
|||
warning ("Wrong size register set in core file."); |
|||
else if (gdbarch_ptr_bit (current_gdbarch) == 32) |
|||
sparcnbsd_supply_reg32 (core_reg_sect, -1); |
|||
else |
|||
sparcnbsd_supply_reg64 (core_reg_sect, -1); |
|||
break; |
|||
|
|||
case 2: /* Floating pointer registers */ |
|||
if (core_reg_size != fpreg_size) |
|||
warning ("Wrong size FP register set in core file."); |
|||
else if (gdbarch_ptr_bit (current_gdbarch) == 32) |
|||
sparcnbsd_supply_fpreg32 (core_reg_sect, -1); |
|||
else |
|||
sparcnbsd_supply_fpreg64 (core_reg_sect, -1); |
|||
break; |
|||
|
|||
default: |
|||
/* Don't know what kind of register request this is; just ignore it. */ |
|||
break; |
|||
} |
|||
} |
|||
|
|||
static struct core_fns sparcnbsd_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 |
|||
}; |
|||
|
|||
static struct core_fns sparcnbsd_elfcore_fns = |
|||
{ |
|||
bfd_target_elf_flavour, /* core_flavour */ |
|||
default_check_format, /* check_format */ |
|||
default_core_sniffer, /* core_sniffer */ |
|||
fetch_core_registers, /* core_read_registers */ |
|||
NULL |
|||
}; |
|||
|
|||
/* FIXME: Need PC_IN_SIGTRAMP() support, but NetBSD/sparc signal trampolines
|
|||
aren't easily identified. */ |
|||
|
|||
static int |
|||
sparcnbsd_get_longjmp_target_32 (CORE_ADDR *pc) |
|||
{ |
|||
CORE_ADDR jb_addr; |
|||
char buf[4]; |
|||
|
|||
jb_addr = read_register (O0_REGNUM); |
|||
|
|||
if (target_read_memory (jb_addr + 12, buf, sizeof (buf))) |
|||
return 0; |
|||
|
|||
*pc = extract_address (buf, sizeof (buf)); |
|||
|
|||
return 1; |
|||
} |
|||
|
|||
static int |
|||
sparcnbsd_get_longjmp_target_64 (CORE_ADDR *pc) |
|||
{ |
|||
CORE_ADDR jb_addr; |
|||
char buf[8]; |
|||
|
|||
jb_addr = read_register (O0_REGNUM); |
|||
|
|||
if (target_read_memory (jb_addr + 16, buf, sizeof (buf))) |
|||
return 0; |
|||
|
|||
*pc = extract_address (buf, sizeof (buf)); |
|||
|
|||
return 1; |
|||
} |
|||
|
|||
static int |
|||
sparcnbsd_aout_in_solib_call_trampoline (CORE_ADDR pc, char *name) |
|||
{ |
|||
if (strcmp (name, "_DYNAMIC") == 0) |
|||
return 1; |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
static void |
|||
sparcnbsd_init_abi_common (struct gdbarch_info info, |
|||
struct gdbarch *gdbarch) |
|||
{ |
|||
set_gdbarch_get_longjmp_target (gdbarch, gdbarch_ptr_bit (gdbarch) == 32 ? |
|||
sparcnbsd_get_longjmp_target_32 : |
|||
sparcnbsd_get_longjmp_target_64); |
|||
} |
|||
|
|||
static void |
|||
sparcnbsd_init_abi_aout (struct gdbarch_info info, |
|||
struct gdbarch *gdbarch) |
|||
{ |
|||
sparcnbsd_init_abi_common (info, gdbarch); |
|||
|
|||
set_gdbarch_in_solib_call_trampoline (gdbarch, |
|||
sparcnbsd_aout_in_solib_call_trampoline); |
|||
} |
|||
|
|||
static void |
|||
sparcnbsd_init_abi_elf (struct gdbarch_info info, |
|||
struct gdbarch *gdbarch) |
|||
{ |
|||
sparcnbsd_init_abi_common (info, gdbarch); |
|||
|
|||
set_solib_svr4_fetch_link_map_offsets (gdbarch, |
|||
gdbarch_ptr_bit (gdbarch) == 32 ? |
|||
nbsd_ilp32_solib_svr4_fetch_link_map_offsets : |
|||
nbsd_lp64_solib_svr4_fetch_link_map_offsets); |
|||
} |
|||
|
|||
static enum gdb_osabi |
|||
sparcnbsd_aout_osabi_sniffer (bfd *abfd) |
|||
{ |
|||
if (strcmp (bfd_get_target (abfd), "a.out-sparc-netbsd") == 0) |
|||
return GDB_OSABI_NETBSD_AOUT; |
|||
|
|||
return GDB_OSABI_UNKNOWN; |
|||
} |
|||
|
|||
void |
|||
_initialize_sparnbsd_tdep (void) |
|||
{ |
|||
gdbarch_register_osabi_sniffer (bfd_arch_sparc, bfd_target_aout_flavour, |
|||
sparcnbsd_aout_osabi_sniffer); |
|||
|
|||
gdbarch_register_osabi (bfd_arch_sparc, GDB_OSABI_NETBSD_AOUT, |
|||
sparcnbsd_init_abi_aout); |
|||
gdbarch_register_osabi (bfd_arch_sparc, GDB_OSABI_NETBSD_ELF, |
|||
sparcnbsd_init_abi_elf); |
|||
|
|||
add_core_fns (&sparcnbsd_core_fns); |
|||
add_core_fns (&sparcnbsd_elfcore_fns); |
|||
} |
|||
Loading…
Reference in new issue