diff options
author | Mark Kettenis <kettenis@gnu.org> | 2004-11-20 17:23:57 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@gnu.org> | 2004-11-20 17:23:57 +0000 |
commit | eeb8076cc0223e448166731544417efbfaf6fed0 (patch) | |
tree | c198e62a6bf6dd3a2b0e45b6922fd9dec9f08e8a /gdb/hppa-hpux-nat.c | |
parent | f6ffd89b00eb37a4d9a8725c0b0219379dced517 (diff) | |
download | gdb-eeb8076cc0223e448166731544417efbfaf6fed0.zip gdb-eeb8076cc0223e448166731544417efbfaf6fed0.tar.gz gdb-eeb8076cc0223e448166731544417efbfaf6fed0.tar.bz2 |
* hppa-hpux-nat.c: New file.
* config/pa/hpux.mh (NATDEPFILES): New file.
* Makefile.in (ALLDEPFILES): Add hppa-hpux-nat.c.
(hppa-hpux-nat.o): New dependency.
* configure.host: Remove hppa*-*-hpux10.20.
(hppa*-*-hpux*, hppa*-*-hiux*): Set gdb_host to hpux.mh.
Diffstat (limited to 'gdb/hppa-hpux-nat.c')
-rw-r--r-- | gdb/hppa-hpux-nat.c | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/gdb/hppa-hpux-nat.c b/gdb/hppa-hpux-nat.c new file mode 100644 index 0000000..9f77b4d --- /dev/null +++ b/gdb/hppa-hpux-nat.c @@ -0,0 +1,290 @@ +/* Native-dependent code for PA-RISC HP-UX. + + Copyright 2004 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 "defs.h" +#include "inferior.h" +#include "regcache.h" +#include "target.h" + +#include "gdb_assert.h" +#include <sys/ptrace.h> +#include <machine/save_state.h> + +#include "hppa-tdep.h" +#include "inf-ptrace.h" + +static int hppa_hpux_save_state_offset[] = +{ + ssoff(ss_flags), + ssoff(ss_narrow.ss_gr1), + ssoff(ss_narrow.ss_rp), + ssoff(ss_narrow.ss_gr3), + ssoff(ss_narrow.ss_gr4), + ssoff(ss_narrow.ss_gr5), + ssoff(ss_narrow.ss_gr6), + ssoff(ss_narrow.ss_gr7), + ssoff(ss_narrow.ss_gr8), + ssoff(ss_narrow.ss_gr9), + ssoff(ss_narrow.ss_gr10), + ssoff(ss_narrow.ss_gr11), + ssoff(ss_narrow.ss_gr12), + ssoff(ss_narrow.ss_gr13), + ssoff(ss_narrow.ss_gr14), + ssoff(ss_narrow.ss_gr15), + ssoff(ss_narrow.ss_gr16), + ssoff(ss_narrow.ss_gr17), + ssoff(ss_narrow.ss_gr18), + ssoff(ss_narrow.ss_gr19), + ssoff(ss_narrow.ss_gr20), + ssoff(ss_narrow.ss_gr21), + ssoff(ss_narrow.ss_gr22), + ssoff(ss_narrow.ss_arg3), + ssoff(ss_narrow.ss_arg2), + ssoff(ss_narrow.ss_arg1), + ssoff(ss_narrow.ss_arg0), + ssoff(ss_narrow.ss_dp), + ssoff(ss_narrow.ss_ret0), + ssoff(ss_narrow.ss_ret1), + ssoff(ss_narrow.ss_sp), + ssoff(ss_narrow.ss_gr31), + ssoff(ss_narrow.ss_cr11), + ssoff(ss_narrow.ss_pcoq_head), + ssoff(ss_narrow.ss_pcsq_head), + ssoff(ss_narrow.ss_pcoq_tail), + ssoff(ss_narrow.ss_pcsq_tail), + ssoff(ss_narrow.ss_cr15), + ssoff(ss_narrow.ss_cr19), + ssoff(ss_narrow.ss_cr20), + ssoff(ss_narrow.ss_cr21), + ssoff(ss_narrow.ss_cr22), + ssoff(ss_narrow.ss_cpustate), + ssoff(ss_narrow.ss_sr4), + ssoff(ss_narrow.ss_sr0), + ssoff(ss_narrow.ss_sr1), + ssoff(ss_narrow.ss_sr2), + ssoff(ss_narrow.ss_sr3), + ssoff(ss_narrow.ss_sr5), + ssoff(ss_narrow.ss_sr6), + ssoff(ss_narrow.ss_sr7), + ssoff(ss_narrow.ss_cr0), + ssoff(ss_narrow.ss_cr8), + ssoff(ss_narrow.ss_cr9), + ssoff(ss_narrow.ss_cr10), + ssoff(ss_narrow.ss_cr12), + ssoff(ss_narrow.ss_cr13), + ssoff(ss_narrow.ss_cr24), + ssoff(ss_narrow.ss_cr25), + ssoff(ss_narrow.ss_cr26), + ssoff(ss_narrow.ss_mpsfu_high), + ssoff(ss_narrow.ss_mpsfu_low), + ssoff(ss_narrow.ss_mpsfu_ovflo), + ssoff(ss_pad), + ssoff(ss_frstat), + ssoff(ss_frexcp1), + ssoff(ss_frexcp2), + ssoff(ss_frexcp3), + ssoff(ss_frexcp4), + ssoff(ss_frexcp5), + ssoff(ss_frexcp6), + ssoff(ss_frexcp7), + ssoff(ss_fr4_hi), + ssoff(ss_fr4_lo), + ssoff(ss_fr5_hi), + ssoff(ss_fr5_lo), + ssoff(ss_fr6_hi), + ssoff(ss_fr6_lo), + ssoff(ss_fr7_hi), + ssoff(ss_fr7_lo), + ssoff(ss_fr8_hi), + ssoff(ss_fr8_lo), + ssoff(ss_fr9_hi), + ssoff(ss_fr9_lo), + ssoff(ss_fr10_hi), + ssoff(ss_fr10_lo), + ssoff(ss_fr11_hi), + ssoff(ss_fr11_lo), + ssoff(ss_fr12_hi), + ssoff(ss_fr12_lo), + ssoff(ss_fr13_hi), + ssoff(ss_fr13_lo), + ssoff(ss_fr14_hi), + ssoff(ss_fr14_lo), + ssoff(ss_fr15_hi), + ssoff(ss_fr15_lo), + ssoff(ss_fr16_hi), + ssoff(ss_fr16_lo), + ssoff(ss_fr17_hi), + ssoff(ss_fr17_lo), + ssoff(ss_fr18_hi), + ssoff(ss_fr18_lo), + ssoff(ss_fr19_hi), + ssoff(ss_fr19_lo), + ssoff(ss_fr20_hi), + ssoff(ss_fr20_lo), + ssoff(ss_fr21_hi), + ssoff(ss_fr21_lo), + ssoff(ss_fr22_hi), + ssoff(ss_fr22_lo), + ssoff(ss_fr23_hi), + ssoff(ss_fr23_lo), + ssoff(ss_fr24_hi), + ssoff(ss_fr24_lo), + ssoff(ss_fr25_hi), + ssoff(ss_fr25_lo), + ssoff(ss_fr26_hi), + ssoff(ss_fr26_lo), + ssoff(ss_fr27_hi), + ssoff(ss_fr27_lo), + ssoff(ss_fr28_hi), + ssoff(ss_fr28_lo), + ssoff(ss_fr29_hi), + ssoff(ss_fr29_lo), + ssoff(ss_fr30_hi), + ssoff(ss_fr30_lo), + ssoff(ss_fr31_hi), + ssoff(ss_fr31_lo) +}; + +static int +hppa_hpux_cannot_fetch_register (int regnum) +{ + gdb_assert (regnum >= 0 && regnum < NUM_REGS); + return (regnum >= ARRAY_SIZE(hppa_hpux_save_state_offset)); +} + +static int +hppa_hpux_cannot_store_register (int regnum) +{ + return hppa_hpux_cannot_fetch_register (regnum); +} + +static void +hppa_hpux_fetch_register (int regnum) +{ + CORE_ADDR addr; + size_t size; + PTRACE_TYPE_RET *buf; + pid_t pid; + int i; + + if (hppa_hpux_cannot_fetch_register (regnum)) + { + regcache_raw_supply (current_regcache, regnum, NULL); + return; + } + + pid = PIDGET (inferior_ptid); + + /* This isn't really an address. But ptrace thinks of it as one. */ + addr = hppa_hpux_save_state_offset[regnum]; + size = register_size (current_gdbarch, regnum); + + gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0); + buf = alloca (size); + + /* Read the register contents from the inferior a chuck at the time. */ + for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++) + { + errno = 0; + buf[i] = ptrace (PT_RUREGS, pid, (PTRACE_TYPE_ARG3) addr, 0, 0); + if (errno != 0) + error ("Couldn't read register %s (#%d): %s.", REGISTER_NAME (regnum), + regnum, safe_strerror (errno)); + + addr += sizeof (PTRACE_TYPE_RET); + } + regcache_raw_supply (current_regcache, regnum, buf); +} + +static void +hppa_hpux_fetch_inferior_registers (int regnum) +{ + if (regnum == -1) + for (regnum = 0; regnum < NUM_REGS; regnum++) + hppa_hpux_fetch_register (regnum); + else + hppa_hpux_fetch_register (regnum); +} + +/* Store register REGNUM into the inferior. */ + +static void +hppa_hpux_store_register (int regnum) +{ + CORE_ADDR addr; + size_t size; + PTRACE_TYPE_RET *buf; + pid_t pid; + int i; + + if (hppa_hpux_cannot_store_register (regnum)) + return; + + pid = PIDGET (inferior_ptid); + + /* This isn't really an address. But ptrace thinks of it as one. */ + addr = hppa_hpux_save_state_offset[regnum]; + size = register_size (current_gdbarch, regnum); + + gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0); + buf = alloca (size); + + /* Write the register contents into the inferior a chunk at the time. */ + regcache_raw_collect (current_regcache, regnum, buf); + for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++) + { + errno = 0; + ptrace (PT_WUREGS, pid, (PTRACE_TYPE_ARG3) addr, buf[i], 0); + if (errno != 0) + error ("Couldn't write register %s (#%d): %s.", REGISTER_NAME (regnum), + regnum, safe_strerror (errno)); + + addr += sizeof (PTRACE_TYPE_RET); + } +} + +/* Store register REGNUM back into the inferior. If REGNUM is -1, do + this for all registers (including the floating point registers). */ + +static void +hppa_hpux_store_inferior_registers (int regnum) +{ + if (regnum == -1) + for (regnum = 0; regnum < NUM_REGS; regnum++) + hppa_hpux_store_register (regnum); + else + hppa_hpux_store_register (regnum); +} + + +/* Prevent warning from -Wmissing-prototypes. */ +void _initialize_hppa_hpux_nat (void); + +void +_initialize_hppa_hpux_nat (void) +{ + struct target_ops *t; + + t = inf_ptrace_target (); + t->to_fetch_registers = hppa_hpux_fetch_inferior_registers; + t->to_store_registers = hppa_hpux_store_inferior_registers; + add_target (t); +} |