+2020-10-13 Kamil Rytarowski <n54@gmx.com>
+
+ * Makefile.in (ALL_64_TARGET_OBS, ALL_TARGET_OBS)
+ HFILES_NO_SRCDIR, ALLDEPFILES): Rename files.
+ * alpha-bsd-nat.c: Adjust include.
+ * alpha-bsd-tdep.h: Adjust comment.
+ * alpha-nbsd-tdep.c: Rename to ...
+ * alpha-netbsd-tdep.c: ... this, adjust include.
+ * amd64-nbsd-nat.c: Rename to ...
+ * amd64-netbsd-nat.c: ... this, adjust include.
+ * amd64-nbsd-tdep.c: Rename to ...
+ * amd64-netbsd-tdep.c: ... this, adjust include.
+ * amd64-tdep.h: Adjust include.
+ * arm-nbsd-nat.c: Rename to ...
+ * arm-netbsd-nat.c: ... this, adjust include.
+ * arm-nbsd-tdep.c: Rename to ...
+ * arm-netbsd-tdep.c: ... this, adjust include.
+ * arm-nbsd-tdep.h: Rename to ...
+ * arm-netbsd-tdep.h: ... this, adjust include.
+ * configure.nat: Adjust file lists.
+ * configure.tgt: Likewise.
+ * hppa-nbsd-nat.c: Rename to ...
+ * hppa-netbsd-nat.c: ... this, adjust include.
+ * hppa-nbsd-tdep.c: Rename to ...
+ * hppa-netbsd-tdep.c: ... this, adjust include.
+ * i386-nbsd-nat.c: Rename to ...
+ * i386-netbsd-nat.c: ... this, adjust include.
+ * i386-nbsd-tdep.c: Rename to ...
+ * i386-netbsd-tdep.c: ... this, adjust include.
+ * m68k-bsd-nat.c: Adjust include.
+ * mips-nbsd-nat.c: Rename to ...
+ * mips-netbsd-nat.c: ... this, adjust include.
+ * mips-nbsd-tdep.c: Rename to ...
+ * mips-netbsd-tdep.c: ... this, adjust include.
+ * mips-nbsd-tdep.h: Rename to ...
+ * mips-netbsd-tdep.h: ... this.
+ * nbsd-nat.c: Rename to ...
+ * netbsd-nat.c: ... this, adjust include.
+ * nbsd-nat.h: Rename to ...
+ * netbsd-nat.h: ... this, adjust include.
+ * nbsd-tdep.c: Rename to ...
+ * netbsd-tdep.c: ... this, adjust include.
+ * nbsd-tdep.h: Rename to ...
+ * netbsd-tdep.h: ... this.
+ * ppc-nbsd-nat.c: Rename to ...
+ * ppc-netbsd-nat.c: ... this, adjust include.
+ * ppc-nbsd-tdep.c: Rename to ...
+ * ppc-netbsd-tdep.c: ... this, adjust include and comment.
+ * ppc-nbsd-tdep.h: Rename to ...
+ * ppc-netbsd-tdep.h: ... this.
+ * sh-nbsd-nat.c: Rename to ...
+ * sh-netbsd-nat.c: ... this, adjust include.
+ * sh-nbsd-tdep.c: Rename to ...
+ * sh-netbsd-tdep.c: ... this, adjust include.
+ * sparc-nbsd-nat.c: Rename to ...
+ * sparc-netbsd-nat.c: ... this.
+ * sparc-nbsd-tdep.c: Rename to ...
+ * sparc-netbsd-tdep.c: ... this, adjust include.
+ * sparc64-nbsd-nat.c: Rename to ...
+ * sparc64-netbsd-nat.c: ... this.
+ * sparc64-nbsd-tdep.c: Rename to ...
+ * sparc64-netbsd-tdep.c: ... this, adjust include.
+ * sparc64-tdep.h: Adjust comment.
+ * vax-bsd-nat.c: Adjust include.
+ * vax-nbsd-tdep.c: Rename to ...
+ * vax-netbsd-tdep.c: ... this, adjust include.
+
2020-10-12 Tom Tromey <tom@tromey.com>
* target.h (struct target_ops) <get_section_table>: Update.
alpha-bsd-tdep.o \
alpha-linux-tdep.o \
alpha-mdebug-tdep.o \
- alpha-nbsd-tdep.o \
+ alpha-netbsd-tdep.o \
alpha-obsd-tdep.o \
alpha-tdep.o \
amd64-darwin-tdep.o \
amd64-dicos-tdep.o \
amd64-fbsd-tdep.o \
amd64-linux-tdep.o \
- amd64-nbsd-tdep.o \
+ amd64-netbsd-tdep.o \
amd64-obsd-tdep.o \
amd64-sol2-tdep.o \
amd64-tdep.o \
mips64-obsd-tdep.o \
sparc64-fbsd-tdep.o \
sparc64-linux-tdep.o \
- sparc64-nbsd-tdep.o \
+ sparc64-netbsd-tdep.o \
sparc64-obsd-tdep.o \
sparc64-sol2-tdep.o \
sparc64-tdep.o
arm-bsd-tdep.o \
arm-fbsd-tdep.o \
arm-linux-tdep.o \
- arm-nbsd-tdep.o \
+ arm-netbsd-tdep.o \
arm-obsd-tdep.o \
arm-pikeos-tdep.o \
arm-symbian-tdep.o \
h8300-tdep.o \
hppa-bsd-tdep.o \
hppa-linux-tdep.o \
- hppa-nbsd-tdep.o \
+ hppa-netbsd-tdep.o \
hppa-obsd-tdep.o \
hppa-tdep.o \
i386-bsd-tdep.o \
i386-gnu-tdep.o \
i386-go32-tdep.o \
i386-linux-tdep.o \
- i386-nbsd-tdep.o \
+ i386-netbsd-tdep.o \
i386-nto-tdep.o \
i386-obsd-tdep.o \
i386-sol2-tdep.o \
microblaze-tdep.o \
mips-fbsd-tdep.o \
mips-linux-tdep.o \
- mips-nbsd-tdep.o \
+ mips-netbsd-tdep.o \
mips-sde-tdep.o \
mips-tdep.o \
mn10300-linux-tdep.o \
mn10300-tdep.o \
moxie-tdep.o \
msp430-tdep.o \
- nbsd-tdep.o \
+ netbsd-tdep.o \
nds32-tdep.o \
nios2-linux-tdep.o \
nios2-tdep.o \
or1k-tdep.o \
ppc-fbsd-tdep.o \
ppc-linux-tdep.o \
- ppc-nbsd-tdep.o \
+ ppc-netbsd-tdep.o \
ppc-obsd-tdep.o \
ppc-ravenscar-thread.o \
ppc-sysv-tdep.o \
s390-tdep.o \
score-tdep.o \
sh-linux-tdep.o \
- sh-nbsd-tdep.o \
+ sh-netbsd-tdep.o \
sh-tdep.o \
sol2-tdep.o \
solib-aix.o \
solib-frv.o \
solib-svr4.o \
sparc-linux-tdep.o \
- sparc-nbsd-tdep.o \
+ sparc-netbsd-tdep.o \
sparc-obsd-tdep.o \
sparc-ravenscar-thread.o \
sparc-sol2-tdep.o \
tilegx-linux-tdep.o \
tilegx-tdep.o \
v850-tdep.o \
- vax-nbsd-tdep.o \
+ vax-netbsd-tdep.o \
vax-tdep.o \
windows-tdep.o \
x86-tdep.o \
arc-tdep.h \
arch-utils.h \
arm-linux-tdep.h \
- arm-nbsd-tdep.h \
+ arm-netbsd-tdep.h \
arm-tdep.h \
async-event.h \
auto-load.h \
memrange.h \
microblaze-tdep.h \
mips-linux-tdep.h \
- mips-nbsd-tdep.h \
+ mips-netbsd-tdep.h \
mips-tdep.h \
mn10300-tdep.h \
moxie-tdep.h \
- nbsd-nat.h \
- nbsd-tdep.h \
+ netbsd-nat.h \
+ netbsd-tdep.h \
nds32-tdep.h \
nios2-tdep.h \
nto-tdep.h \
parser-defs.h \
ppc-fbsd-tdep.h \
ppc-linux-tdep.h \
- ppc-nbsd-tdep.h \
+ ppc-netbsd-tdep.h \
ppc-obsd-tdep.h \
ppc-ravenscar-thread.h \
ppc-tdep.h \
alpha-linux-nat.c \
alpha-linux-tdep.c \
alpha-mdebug-tdep.c \
- alpha-nbsd-tdep.c \
+ alpha-netbsd-tdep.c \
alpha-obsd-tdep.c \
alpha-tdep.c \
amd64-bsd-nat.c \
amd64-linux-nat.c \
amd64-linux-tdep.c \
amd64-nat.c \
- amd64-nbsd-nat.c \
- amd64-nbsd-tdep.c \
+ amd64-netbsd-nat.c \
+ amd64-netbsd-tdep.c \
amd64-obsd-nat.c \
amd64-obsd-tdep.c \
amd64-sol2-tdep.c \
arm-linux.c \
arm-linux-nat.c \
arm-linux-tdep.c \
- arm-nbsd-nat.c \
- arm-nbsd-tdep.c \
+ arm-netbsd-nat.c \
+ arm-netbsd-tdep.c \
arm-obsd-tdep.c \
arm-symbian-tdep.c \
arm-tdep.c \
hppa-bsd-tdep.c \
hppa-linux-nat.c \
hppa-linux-tdep.c \
- hppa-nbsd-nat.c \
- hppa-nbsd-tdep.c \
+ hppa-netbsd-nat.c \
+ hppa-netbsd-tdep.c \
hppa-obsd-nat.c \
hppa-obsd-tdep.c \
hppa-tdep.c \
i386-gnu-tdep.c \
i386-linux-nat.c \
i386-linux-tdep.c \
- i386-nbsd-nat.c \
- i386-nbsd-tdep.c \
+ i386-netbsd-nat.c \
+ i386-netbsd-tdep.c \
i386-obsd-nat.c \
i386-obsd-tdep.c \
i386-sol2-nat.c \
mips-fbsd-tdep.c \
mips-linux-nat.c \
mips-linux-tdep.c \
- mips-nbsd-nat.c \
- mips-nbsd-tdep.c \
+ mips-netbsd-nat.c \
+ mips-netbsd-tdep.c \
mips-sde-tdep.c \
mips-tdep.c \
mips64-obsd-nat.c \
mips64-obsd-tdep.c \
msp430-tdep.c \
- nbsd-nat.c \
- nbsd-tdep.c \
+ netbsd-nat.c \
+ netbsd-tdep.c \
nds32-tdep.c \
nios2-linux-tdep.c \
nios2-tdep.c \
ppc-fbsd-tdep.c \
ppc-linux-nat.c \
ppc-linux-tdep.c \
- ppc-nbsd-nat.c \
- ppc-nbsd-tdep.c \
+ ppc-netbsd-nat.c \
+ ppc-netbsd-tdep.c \
ppc-obsd-nat.c \
ppc-obsd-tdep.c \
ppc-ravenscar-thread.c \
ser-pipe.c \
ser-tcp.c \
ser-uds.c \
- sh-nbsd-nat.c \
- sh-nbsd-tdep.c \
+ sh-netbsd-nat.c \
+ sh-netbsd-tdep.c \
sh-tdep.c \
sol2-tdep.c \
solib-aix.c \
sparc-linux-nat.c \
sparc-linux-tdep.c \
sparc-nat.c \
- sparc-nbsd-nat.c \
- sparc-nbsd-tdep.c \
+ sparc-netbsd-nat.c \
+ sparc-netbsd-tdep.c \
sparc-obsd-tdep.c \
sparc-ravenscar-thread.c \
sparc-sol2-nat.c \
sparc64-linux-nat.c \
sparc64-linux-tdep.c \
sparc64-nat.c \
- sparc64-nbsd-nat.c \
- sparc64-nbsd-tdep.c \
+ sparc64-netbsd-nat.c \
+ sparc64-netbsd-tdep.c \
sparc64-obsd-nat.c \
sparc64-obsd-tdep.c \
sparc64-sol2-tdep.c \
tilegx-tdep.c \
v850-tdep.c \
vax-bsd-nat.c \
- vax-nbsd-tdep.c \
+ vax-netbsd-tdep.c \
vax-tdep.c \
windows-nat.c \
windows-tdep.c \
#include "alpha-tdep.h"
#include "alpha-bsd-tdep.h"
#include "inf-ptrace.h"
-#include "nbsd-nat.h"
+#include "netbsd-nat.h"
#include <sys/types.h>
#include <sys/ptrace.h>
void alphabsd_fill_fpreg (const struct regcache *, char *, int);
\f
-/* Functions exported from alpha-nbsd-tdep.c. */
+/* Functions exported from alpha-netbsd-tdep.c. */
/* Iterate over supported core file register note sections. */
void alphanbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+++ /dev/null
-/* Target-dependent code for NetBSD/alpha.
-
- Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "frame.h"
-#include "gdbcore.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-#include "value.h"
-
-#include "alpha-tdep.h"
-#include "alpha-bsd-tdep.h"
-#include "nbsd-tdep.h"
-#include "solib-svr4.h"
-#include "target.h"
-
-/* Core file support. */
-
-/* Sizeof `struct reg' in <machine/reg.h>. */
-#define ALPHANBSD_SIZEOF_GREGS (32 * 8)
-
-/* Sizeof `struct fpreg' in <machine/reg.h. */
-#define ALPHANBSD_SIZEOF_FPREGS ((32 * 8) + 8)
-
-/* Supply register REGNUM from the buffer specified by FPREGS and LEN
- in the floating-point register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-alphanbsd_supply_fpregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *fpregs, size_t len)
-{
- const gdb_byte *regs = (const gdb_byte *) fpregs;
- int i;
-
- gdb_assert (len >= ALPHANBSD_SIZEOF_FPREGS);
-
- for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; i++)
- {
- if (regnum == i || regnum == -1)
- regcache->raw_supply (i, regs + (i - ALPHA_FP0_REGNUM) * 8);
- }
-
- if (regnum == ALPHA_FPCR_REGNUM || regnum == -1)
- regcache->raw_supply (ALPHA_FPCR_REGNUM, regs + 32 * 8);
-}
-
-/* Supply register REGNUM from the buffer specified by GREGS and LEN
- in the general-purpose register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-alphanbsd_aout_supply_gregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
-{
- const gdb_byte *regs = (const gdb_byte *) gregs;
- int i;
-
- /* Table to map a GDB register number to a trapframe register index. */
- static const int regmap[] =
- {
- 0, 1, 2, 3,
- 4, 5, 6, 7,
- 8, 9, 10, 11,
- 12, 13, 14, 15,
- 30, 31, 32, 16,
- 17, 18, 19, 20,
- 21, 22, 23, 24,
- 25, 29, 26
- };
-
- gdb_assert (len >= ALPHANBSD_SIZEOF_GREGS);
-
- for (i = 0; i < ARRAY_SIZE(regmap); i++)
- {
- if (regnum == i || regnum == -1)
- regcache->raw_supply (i, regs + regmap[i] * 8);
- }
-
- if (regnum == ALPHA_PC_REGNUM || regnum == -1)
- regcache->raw_supply (ALPHA_PC_REGNUM, regs + 31 * 8);
-
- if (len >= ALPHANBSD_SIZEOF_GREGS + ALPHANBSD_SIZEOF_FPREGS)
- {
- regs += ALPHANBSD_SIZEOF_GREGS;
- len -= ALPHANBSD_SIZEOF_GREGS;
- alphanbsd_supply_fpregset (regset, regcache, regnum, regs, len);
- }
-}
-
-/* Supply register REGNUM from the buffer specified by GREGS and LEN
- in the general-purpose register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-alphanbsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
-{
- const gdb_byte *regs = (const gdb_byte *) gregs;
- int i;
-
- if (len >= ALPHANBSD_SIZEOF_GREGS + ALPHANBSD_SIZEOF_FPREGS)
- {
- alphanbsd_aout_supply_gregset (regset, regcache, regnum, gregs, len);
- return;
- }
-
- for (i = 0; i < ALPHA_ZERO_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- regcache->raw_supply (i, regs + i * 8);
- }
-
- if (regnum == ALPHA_PC_REGNUM || regnum == -1)
- regcache->raw_supply (ALPHA_PC_REGNUM, regs + 31 * 8);
-}
-
-/* NetBSD/alpha register sets. */
-
-static const struct regset alphanbsd_gregset =
-{
- NULL,
- alphanbsd_supply_gregset,
- NULL,
- REGSET_VARIABLE_SIZE
-};
-
-static const struct regset alphanbsd_fpregset =
-{
- NULL,
- alphanbsd_supply_fpregset
-};
-
-/* Iterate over supported core file register note sections. */
-
-void
-alphanbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- cb (".reg", ALPHANBSD_SIZEOF_GREGS, ALPHANBSD_SIZEOF_GREGS,
- &alphanbsd_gregset, NULL, cb_data);
- cb (".reg2", ALPHANBSD_SIZEOF_FPREGS, ALPHANBSD_SIZEOF_FPREGS,
- &alphanbsd_fpregset, NULL, cb_data);
-}
-\f
-
-/* Signal trampolines. */
-
-/* Under NetBSD/alpha, signal handler invocations can be identified by the
- designated code sequence that is used to return from a signal handler.
- In particular, the return address of a signal handler points to the
- following code sequence:
-
- ldq a0, 0(sp)
- lda sp, 16(sp)
- lda v0, 295(zero) # __sigreturn14
- call_pal callsys
-
- Each instruction has a unique encoding, so we simply attempt to match
- the instruction the PC is pointing to with any of the above instructions.
- If there is a hit, we know the offset to the start of the designated
- sequence and can then check whether we really are executing in the
- signal trampoline. If not, -1 is returned, otherwise the offset from the
- start of the return sequence is returned. */
-static const gdb_byte sigtramp_retcode[] =
-{
- 0x00, 0x00, 0x1e, 0xa6, /* ldq a0, 0(sp) */
- 0x10, 0x00, 0xde, 0x23, /* lda sp, 16(sp) */
- 0x27, 0x01, 0x1f, 0x20, /* lda v0, 295(zero) */
- 0x83, 0x00, 0x00, 0x00, /* call_pal callsys */
-};
-#define RETCODE_NWORDS 4
-#define RETCODE_SIZE (RETCODE_NWORDS * 4)
-
-static LONGEST
-alphanbsd_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc)
-{
- gdb_byte ret[RETCODE_SIZE], w[4];
- LONGEST off;
- int i;
-
- if (target_read_memory (pc, w, 4) != 0)
- return -1;
-
- for (i = 0; i < RETCODE_NWORDS; i++)
- {
- if (memcmp (w, sigtramp_retcode + (i * 4), 4) == 0)
- break;
- }
- if (i == RETCODE_NWORDS)
- return (-1);
-
- off = i * 4;
- pc -= off;
-
- if (target_read_memory (pc, ret, sizeof (ret)) != 0)
- return -1;
-
- if (memcmp (ret, sigtramp_retcode, RETCODE_SIZE) == 0)
- return off;
-
- return -1;
-}
-
-static int
-alphanbsd_pc_in_sigtramp (struct gdbarch *gdbarch,
- CORE_ADDR pc, const char *func_name)
-{
- return (nbsd_pc_in_sigtramp (pc, func_name)
- || alphanbsd_sigtramp_offset (gdbarch, pc) >= 0);
-}
-
-static CORE_ADDR
-alphanbsd_sigcontext_addr (struct frame_info *frame)
-{
- /* FIXME: This is not correct for all versions of NetBSD/alpha.
- We will probably need to disassemble the trampoline to figure
- out which trampoline frame type we have. */
- if (!get_next_frame (frame))
- return 0;
- return get_frame_base (get_next_frame (frame));
-}
-\f
-
-static void
-alphanbsd_init_abi (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* Hook into the DWARF CFI frame unwinder. */
- alpha_dwarf2_init_abi (info, gdbarch);
-
- /* Hook into the MDEBUG frame unwinder. */
- alpha_mdebug_init_abi (info, gdbarch);
-
- nbsd_init_abi (info, gdbarch);
-
- /* NetBSD/alpha does not provide single step support via ptrace(2); we
- must use software single-stepping. */
- set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
-
- /* NetBSD/alpha has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
-
- tdep->dynamic_sigtramp_offset = alphanbsd_sigtramp_offset;
- tdep->pc_in_sigtramp = alphanbsd_pc_in_sigtramp;
- tdep->sigcontext_addr = alphanbsd_sigcontext_addr;
-
- tdep->jb_pc = 2;
- tdep->jb_elt_size = 8;
-
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, alphanbsd_iterate_over_regset_sections);
-}
-\f
-
-void _initialize_alphanbsd_tdep ();
-void
-_initialize_alphanbsd_tdep ()
-{
- /* Even though NetBSD/alpha used ELF since day one, it used the
- traditional a.out-style core dump format before NetBSD 1.6, but
- we don't support those. */
- gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_NETBSD,
- alphanbsd_init_abi);
-}
--- /dev/null
+/* Target-dependent code for NetBSD/alpha.
+
+ Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "frame.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "value.h"
+
+#include "alpha-tdep.h"
+#include "alpha-bsd-tdep.h"
+#include "netbsd-tdep.h"
+#include "solib-svr4.h"
+#include "target.h"
+
+/* Core file support. */
+
+/* Sizeof `struct reg' in <machine/reg.h>. */
+#define ALPHANBSD_SIZEOF_GREGS (32 * 8)
+
+/* Sizeof `struct fpreg' in <machine/reg.h. */
+#define ALPHANBSD_SIZEOF_FPREGS ((32 * 8) + 8)
+
+/* Supply register REGNUM from the buffer specified by FPREGS and LEN
+ in the floating-point register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+alphanbsd_supply_fpregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *fpregs, size_t len)
+{
+ const gdb_byte *regs = (const gdb_byte *) fpregs;
+ int i;
+
+ gdb_assert (len >= ALPHANBSD_SIZEOF_FPREGS);
+
+ for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache->raw_supply (i, regs + (i - ALPHA_FP0_REGNUM) * 8);
+ }
+
+ if (regnum == ALPHA_FPCR_REGNUM || regnum == -1)
+ regcache->raw_supply (ALPHA_FPCR_REGNUM, regs + 32 * 8);
+}
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+ in the general-purpose register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+alphanbsd_aout_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ const gdb_byte *regs = (const gdb_byte *) gregs;
+ int i;
+
+ /* Table to map a GDB register number to a trapframe register index. */
+ static const int regmap[] =
+ {
+ 0, 1, 2, 3,
+ 4, 5, 6, 7,
+ 8, 9, 10, 11,
+ 12, 13, 14, 15,
+ 30, 31, 32, 16,
+ 17, 18, 19, 20,
+ 21, 22, 23, 24,
+ 25, 29, 26
+ };
+
+ gdb_assert (len >= ALPHANBSD_SIZEOF_GREGS);
+
+ for (i = 0; i < ARRAY_SIZE(regmap); i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache->raw_supply (i, regs + regmap[i] * 8);
+ }
+
+ if (regnum == ALPHA_PC_REGNUM || regnum == -1)
+ regcache->raw_supply (ALPHA_PC_REGNUM, regs + 31 * 8);
+
+ if (len >= ALPHANBSD_SIZEOF_GREGS + ALPHANBSD_SIZEOF_FPREGS)
+ {
+ regs += ALPHANBSD_SIZEOF_GREGS;
+ len -= ALPHANBSD_SIZEOF_GREGS;
+ alphanbsd_supply_fpregset (regset, regcache, regnum, regs, len);
+ }
+}
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+ in the general-purpose register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+alphanbsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ const gdb_byte *regs = (const gdb_byte *) gregs;
+ int i;
+
+ if (len >= ALPHANBSD_SIZEOF_GREGS + ALPHANBSD_SIZEOF_FPREGS)
+ {
+ alphanbsd_aout_supply_gregset (regset, regcache, regnum, gregs, len);
+ return;
+ }
+
+ for (i = 0; i < ALPHA_ZERO_REGNUM; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache->raw_supply (i, regs + i * 8);
+ }
+
+ if (regnum == ALPHA_PC_REGNUM || regnum == -1)
+ regcache->raw_supply (ALPHA_PC_REGNUM, regs + 31 * 8);
+}
+
+/* NetBSD/alpha register sets. */
+
+static const struct regset alphanbsd_gregset =
+{
+ NULL,
+ alphanbsd_supply_gregset,
+ NULL,
+ REGSET_VARIABLE_SIZE
+};
+
+static const struct regset alphanbsd_fpregset =
+{
+ NULL,
+ alphanbsd_supply_fpregset
+};
+
+/* Iterate over supported core file register note sections. */
+
+void
+alphanbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ cb (".reg", ALPHANBSD_SIZEOF_GREGS, ALPHANBSD_SIZEOF_GREGS,
+ &alphanbsd_gregset, NULL, cb_data);
+ cb (".reg2", ALPHANBSD_SIZEOF_FPREGS, ALPHANBSD_SIZEOF_FPREGS,
+ &alphanbsd_fpregset, NULL, cb_data);
+}
+\f
+
+/* Signal trampolines. */
+
+/* Under NetBSD/alpha, signal handler invocations can be identified by the
+ designated code sequence that is used to return from a signal handler.
+ In particular, the return address of a signal handler points to the
+ following code sequence:
+
+ ldq a0, 0(sp)
+ lda sp, 16(sp)
+ lda v0, 295(zero) # __sigreturn14
+ call_pal callsys
+
+ Each instruction has a unique encoding, so we simply attempt to match
+ the instruction the PC is pointing to with any of the above instructions.
+ If there is a hit, we know the offset to the start of the designated
+ sequence and can then check whether we really are executing in the
+ signal trampoline. If not, -1 is returned, otherwise the offset from the
+ start of the return sequence is returned. */
+static const gdb_byte sigtramp_retcode[] =
+{
+ 0x00, 0x00, 0x1e, 0xa6, /* ldq a0, 0(sp) */
+ 0x10, 0x00, 0xde, 0x23, /* lda sp, 16(sp) */
+ 0x27, 0x01, 0x1f, 0x20, /* lda v0, 295(zero) */
+ 0x83, 0x00, 0x00, 0x00, /* call_pal callsys */
+};
+#define RETCODE_NWORDS 4
+#define RETCODE_SIZE (RETCODE_NWORDS * 4)
+
+static LONGEST
+alphanbsd_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+ gdb_byte ret[RETCODE_SIZE], w[4];
+ LONGEST off;
+ int i;
+
+ if (target_read_memory (pc, w, 4) != 0)
+ return -1;
+
+ for (i = 0; i < RETCODE_NWORDS; i++)
+ {
+ if (memcmp (w, sigtramp_retcode + (i * 4), 4) == 0)
+ break;
+ }
+ if (i == RETCODE_NWORDS)
+ return (-1);
+
+ off = i * 4;
+ pc -= off;
+
+ if (target_read_memory (pc, ret, sizeof (ret)) != 0)
+ return -1;
+
+ if (memcmp (ret, sigtramp_retcode, RETCODE_SIZE) == 0)
+ return off;
+
+ return -1;
+}
+
+static int
+alphanbsd_pc_in_sigtramp (struct gdbarch *gdbarch,
+ CORE_ADDR pc, const char *func_name)
+{
+ return (nbsd_pc_in_sigtramp (pc, func_name)
+ || alphanbsd_sigtramp_offset (gdbarch, pc) >= 0);
+}
+
+static CORE_ADDR
+alphanbsd_sigcontext_addr (struct frame_info *frame)
+{
+ /* FIXME: This is not correct for all versions of NetBSD/alpha.
+ We will probably need to disassemble the trampoline to figure
+ out which trampoline frame type we have. */
+ if (!get_next_frame (frame))
+ return 0;
+ return get_frame_base (get_next_frame (frame));
+}
+\f
+
+static void
+alphanbsd_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* Hook into the DWARF CFI frame unwinder. */
+ alpha_dwarf2_init_abi (info, gdbarch);
+
+ /* Hook into the MDEBUG frame unwinder. */
+ alpha_mdebug_init_abi (info, gdbarch);
+
+ nbsd_init_abi (info, gdbarch);
+
+ /* NetBSD/alpha does not provide single step support via ptrace(2); we
+ must use software single-stepping. */
+ set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
+
+ /* NetBSD/alpha has SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_lp64_fetch_link_map_offsets);
+
+ tdep->dynamic_sigtramp_offset = alphanbsd_sigtramp_offset;
+ tdep->pc_in_sigtramp = alphanbsd_pc_in_sigtramp;
+ tdep->sigcontext_addr = alphanbsd_sigcontext_addr;
+
+ tdep->jb_pc = 2;
+ tdep->jb_elt_size = 8;
+
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, alphanbsd_iterate_over_regset_sections);
+}
+\f
+
+void _initialize_alphanbsd_tdep ();
+void
+_initialize_alphanbsd_tdep ()
+{
+ /* Even though NetBSD/alpha used ELF since day one, it used the
+ traditional a.out-style core dump format before NetBSD 1.6, but
+ we don't support those. */
+ gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_NETBSD,
+ alphanbsd_init_abi);
+}
+++ /dev/null
-/* Native-dependent code for NetBSD/amd64.
-
- Copyright (C) 2003-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "target.h"
-
-#include "nbsd-nat.h"
-#include "amd64-tdep.h"
-#include "amd64-bsd-nat.h"
-#include "amd64-nat.h"
-
-/* Mapping between the general-purpose registers in NetBSD/amd64
- `struct reg' format and GDB's register cache layout for
- NetBSD/i386.
-
- Note that most (if not all) NetBSD/amd64 registers are 64-bit,
- while the NetBSD/i386 registers are all 32-bit, but since we're
- little-endian we get away with that. */
-
-/* From <machine/reg.h>. */
-static int amd64nbsd32_r_reg_offset[] =
-{
- 14 * 8, /* %eax */
- 3 * 8, /* %ecx */
- 2 * 8, /* %edx */
- 13 * 8, /* %ebx */
- 24 * 8, /* %esp */
- 12 * 8, /* %ebp */
- 1 * 8, /* %esi */
- 0 * 8, /* %edi */
- 21 * 8, /* %eip */
- 23 * 8, /* %eflags */
- 22 * 8, /* %cs */
- 25 * 8, /* %ss */
- 18 * 8, /* %ds */
- 17 * 8, /* %es */
- 16 * 8, /* %fs */
- 15 * 8 /* %gs */
-};
-
-static amd64_bsd_nat_target<nbsd_nat_target> the_amd64_nbsd_nat_target;
-
-void _initialize_amd64nbsd_nat ();
-void
-_initialize_amd64nbsd_nat ()
-{
- amd64_native_gregset32_reg_offset = amd64nbsd32_r_reg_offset;
- amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64nbsd32_r_reg_offset);
- amd64_native_gregset64_reg_offset = amd64nbsd_r_reg_offset;
-
- add_inf_child_target (&the_amd64_nbsd_nat_target);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/amd64.
-
- Copyright (C) 2003-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "arch-utils.h"
-#include "frame.h"
-#include "gdbcore.h"
-#include "osabi.h"
-#include "symtab.h"
-
-#include "amd64-tdep.h"
-#include "gdbsupport/x86-xstate.h"
-#include "nbsd-tdep.h"
-#include "solib-svr4.h"
-
-/* Support for signal handlers. */
-
-/* Return whether THIS_FRAME corresponds to a NetBSD sigtramp
- routine. */
-
-static int
-amd64nbsd_sigtramp_p (struct frame_info *this_frame)
-{
- CORE_ADDR pc = get_frame_pc (this_frame);
- const char *name;
-
- find_pc_partial_function (pc, &name, NULL, NULL);
- return nbsd_pc_in_sigtramp (pc, name);
-}
-
-/* Assuming THIS_FRAME corresponds to a NetBSD sigtramp routine,
- return the address of the associated mcontext structure. */
-
-static CORE_ADDR
-amd64nbsd_mcontext_addr (struct frame_info *this_frame)
-{
- CORE_ADDR addr;
-
- /* The register %r15 points at `struct ucontext' upon entry of a
- signal trampoline. */
- addr = get_frame_register_unsigned (this_frame, AMD64_R15_REGNUM);
-
- /* The mcontext structure lives as offset 56 in `struct ucontext'. */
- return addr + 56;
-}
-\f
-/* NetBSD 2.0 or later. */
-
-/* Mapping between the general-purpose registers in `struct reg'
- format and GDB's register cache layout. */
-
-/* From <machine/reg.h>. */
-int amd64nbsd_r_reg_offset[] =
-{
- 14 * 8, /* %rax */
- 13 * 8, /* %rbx */
- 3 * 8, /* %rcx */
- 2 * 8, /* %rdx */
- 1 * 8, /* %rsi */
- 0 * 8, /* %rdi */
- 12 * 8, /* %rbp */
- 24 * 8, /* %rsp */
- 4 * 8, /* %r8 .. */
- 5 * 8,
- 6 * 8,
- 7 * 8,
- 8 * 8,
- 9 * 8,
- 10 * 8,
- 11 * 8, /* ... %r15 */
- 21 * 8, /* %rip */
- 23 * 8, /* %eflags */
- 22 * 8, /* %cs */
- 25 * 8, /* %ss */
- 18 * 8, /* %ds */
- 17 * 8, /* %es */
- 16 * 8, /* %fs */
- 15 * 8 /* %gs */
-};
-
-static void
-amd64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* Initialize general-purpose register set details first. */
- tdep->gregset_reg_offset = amd64nbsd_r_reg_offset;
- tdep->gregset_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset);
- tdep->sizeof_gregset = 26 * 8;
-
- amd64_init_abi (info, gdbarch,
- amd64_target_description (X86_XSTATE_SSE_MASK, true));
- nbsd_init_abi (info, gdbarch);
-
- tdep->jb_pc_offset = 7 * 8;
-
- /* NetBSD has its own convention for signal trampolines. */
- tdep->sigtramp_p = amd64nbsd_sigtramp_p;
- tdep->sigcontext_addr = amd64nbsd_mcontext_addr;
- tdep->sc_reg_offset = amd64nbsd_r_reg_offset;
- tdep->sc_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset);
-
- /* NetBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
-}
-
-void _initialize_amd64nbsd_tdep ();
-void
-_initialize_amd64nbsd_tdep ()
-{
- /* The NetBSD/amd64 native dependent code makes this assumption. */
- gdb_assert (ARRAY_SIZE (amd64nbsd_r_reg_offset) == AMD64_NUM_GREGS);
-
- gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
- GDB_OSABI_NETBSD, amd64nbsd_init_abi);
-}
--- /dev/null
+/* Native-dependent code for NetBSD/amd64.
+
+ Copyright (C) 2003-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "target.h"
+
+#include "netbsd-nat.h"
+#include "amd64-tdep.h"
+#include "amd64-bsd-nat.h"
+#include "amd64-nat.h"
+
+/* Mapping between the general-purpose registers in NetBSD/amd64
+ `struct reg' format and GDB's register cache layout for
+ NetBSD/i386.
+
+ Note that most (if not all) NetBSD/amd64 registers are 64-bit,
+ while the NetBSD/i386 registers are all 32-bit, but since we're
+ little-endian we get away with that. */
+
+/* From <machine/reg.h>. */
+static int amd64nbsd32_r_reg_offset[] =
+{
+ 14 * 8, /* %eax */
+ 3 * 8, /* %ecx */
+ 2 * 8, /* %edx */
+ 13 * 8, /* %ebx */
+ 24 * 8, /* %esp */
+ 12 * 8, /* %ebp */
+ 1 * 8, /* %esi */
+ 0 * 8, /* %edi */
+ 21 * 8, /* %eip */
+ 23 * 8, /* %eflags */
+ 22 * 8, /* %cs */
+ 25 * 8, /* %ss */
+ 18 * 8, /* %ds */
+ 17 * 8, /* %es */
+ 16 * 8, /* %fs */
+ 15 * 8 /* %gs */
+};
+
+static amd64_bsd_nat_target<nbsd_nat_target> the_amd64_nbsd_nat_target;
+
+void _initialize_amd64nbsd_nat ();
+void
+_initialize_amd64nbsd_nat ()
+{
+ amd64_native_gregset32_reg_offset = amd64nbsd32_r_reg_offset;
+ amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64nbsd32_r_reg_offset);
+ amd64_native_gregset64_reg_offset = amd64nbsd_r_reg_offset;
+
+ add_inf_child_target (&the_amd64_nbsd_nat_target);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/amd64.
+
+ Copyright (C) 2003-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "frame.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "symtab.h"
+
+#include "amd64-tdep.h"
+#include "gdbsupport/x86-xstate.h"
+#include "netbsd-tdep.h"
+#include "solib-svr4.h"
+
+/* Support for signal handlers. */
+
+/* Return whether THIS_FRAME corresponds to a NetBSD sigtramp
+ routine. */
+
+static int
+amd64nbsd_sigtramp_p (struct frame_info *this_frame)
+{
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ const char *name;
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ return nbsd_pc_in_sigtramp (pc, name);
+}
+
+/* Assuming THIS_FRAME corresponds to a NetBSD sigtramp routine,
+ return the address of the associated mcontext structure. */
+
+static CORE_ADDR
+amd64nbsd_mcontext_addr (struct frame_info *this_frame)
+{
+ CORE_ADDR addr;
+
+ /* The register %r15 points at `struct ucontext' upon entry of a
+ signal trampoline. */
+ addr = get_frame_register_unsigned (this_frame, AMD64_R15_REGNUM);
+
+ /* The mcontext structure lives as offset 56 in `struct ucontext'. */
+ return addr + 56;
+}
+\f
+/* NetBSD 2.0 or later. */
+
+/* Mapping between the general-purpose registers in `struct reg'
+ format and GDB's register cache layout. */
+
+/* From <machine/reg.h>. */
+int amd64nbsd_r_reg_offset[] =
+{
+ 14 * 8, /* %rax */
+ 13 * 8, /* %rbx */
+ 3 * 8, /* %rcx */
+ 2 * 8, /* %rdx */
+ 1 * 8, /* %rsi */
+ 0 * 8, /* %rdi */
+ 12 * 8, /* %rbp */
+ 24 * 8, /* %rsp */
+ 4 * 8, /* %r8 .. */
+ 5 * 8,
+ 6 * 8,
+ 7 * 8,
+ 8 * 8,
+ 9 * 8,
+ 10 * 8,
+ 11 * 8, /* ... %r15 */
+ 21 * 8, /* %rip */
+ 23 * 8, /* %eflags */
+ 22 * 8, /* %cs */
+ 25 * 8, /* %ss */
+ 18 * 8, /* %ds */
+ 17 * 8, /* %es */
+ 16 * 8, /* %fs */
+ 15 * 8 /* %gs */
+};
+
+static void
+amd64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* Initialize general-purpose register set details first. */
+ tdep->gregset_reg_offset = amd64nbsd_r_reg_offset;
+ tdep->gregset_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset);
+ tdep->sizeof_gregset = 26 * 8;
+
+ amd64_init_abi (info, gdbarch,
+ amd64_target_description (X86_XSTATE_SSE_MASK, true));
+ nbsd_init_abi (info, gdbarch);
+
+ tdep->jb_pc_offset = 7 * 8;
+
+ /* NetBSD has its own convention for signal trampolines. */
+ tdep->sigtramp_p = amd64nbsd_sigtramp_p;
+ tdep->sigcontext_addr = amd64nbsd_mcontext_addr;
+ tdep->sc_reg_offset = amd64nbsd_r_reg_offset;
+ tdep->sc_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset);
+
+ /* NetBSD uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_lp64_fetch_link_map_offsets);
+}
+
+void _initialize_amd64nbsd_tdep ();
+void
+_initialize_amd64nbsd_tdep ()
+{
+ /* The NetBSD/amd64 native dependent code makes this assumption. */
+ gdb_assert (ARRAY_SIZE (amd64nbsd_r_reg_offset) == AMD64_NUM_GREGS);
+
+ gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
+ GDB_OSABI_NETBSD, amd64nbsd_init_abi);
+}
/* Variables exported from amd64-linux-tdep.c. */
extern int amd64_linux_gregset_reg_offset[];
-/* Variables exported from amd64-nbsd-tdep.c. */
+/* Variables exported from amd64-netbsd-tdep.c. */
extern int amd64nbsd_r_reg_offset[];
/* Variables exported from amd64-obsd-tdep.c. */
+++ /dev/null
-/* Native-dependent code for BSD Unix running on ARM's, for GDB.
-
- Copyright (C) 1988-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-/* We define this to get types like register_t. */
-#define _KERNTYPES
-#include "defs.h"
-#include "gdbcore.h"
-#include "inferior.h"
-#include "regcache.h"
-#include "target.h"
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <sys/sysctl.h>
-#include <machine/reg.h>
-#include <machine/frame.h>
-
-#include "arm-tdep.h"
-#include "arm-nbsd-tdep.h"
-#include "aarch32-tdep.h"
-#include "inf-ptrace.h"
-#include "nbsd-nat.h"
-
-class arm_netbsd_nat_target final : public nbsd_nat_target
-{
-public:
- /* Add our register access methods. */
- void fetch_registers (struct regcache *, int) override;
- void store_registers (struct regcache *, int) override;
- const struct target_desc *read_description () override;
-};
-
-static arm_netbsd_nat_target the_arm_netbsd_nat_target;
-
-static void
-arm_supply_vfpregset (struct regcache *regcache, struct fpreg *fpregset)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
- if (tdep->vfp_register_count == 0)
- return;
-
- struct vfpreg &vfp = fpregset->fpr_vfp;
- for (int regno = 0; regno <= tdep->vfp_register_count; regno++)
- regcache->raw_supply (regno + ARM_D0_REGNUM, (char *) &vfp.vfp_regs[regno]);
-
- regcache->raw_supply (ARM_FPSCR_REGNUM, (char *) &vfp.vfp_fpscr);
-}
-
-static void
-fetch_register (struct regcache *regcache, int regno)
-{
- struct reg inferior_registers;
- int ret;
- int lwp = regcache->ptid ().lwp ();
-
- ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
- (PTRACE_TYPE_ARG3) &inferior_registers, lwp);
-
- if (ret < 0)
- {
- warning (_("unable to fetch general register"));
- return;
- }
- arm_nbsd_supply_gregset (nullptr, regcache, regno, &inferior_registers,
- sizeof (inferior_registers));
-}
-
-static void
-fetch_fp_register (struct regcache *regcache, int regno)
-{
- struct fpreg inferior_fp_registers;
- int lwp = regcache->ptid ().lwp ();
-
- int ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
- (PTRACE_TYPE_ARG3) &inferior_fp_registers, lwp);
-
- struct vfpreg &vfp = inferior_fp_registers.fpr_vfp;
-
- if (ret < 0)
- {
- warning (_("unable to fetch floating-point register"));
- return;
- }
-
- struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
- if (regno == ARM_FPSCR_REGNUM && tdep->vfp_register_count != 0)
- regcache->raw_supply (ARM_FPSCR_REGNUM, (char *) &vfp.vfp_fpscr);
- else if (regno >= ARM_D0_REGNUM
- && regno <= ARM_D0_REGNUM + tdep->vfp_register_count)
- {
- regcache->raw_supply (regno,
- (char *) &vfp.vfp_regs[regno - ARM_D0_REGNUM]);
- }
- else
- warning (_("Invalid register number."));
-}
-
-static void
-fetch_fp_regs (struct regcache *regcache)
-{
- struct fpreg inferior_fp_registers;
- int lwp = regcache->ptid ().lwp ();
- int ret;
- int regno;
-
- ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
- (PTRACE_TYPE_ARG3) &inferior_fp_registers, lwp);
-
- if (ret < 0)
- {
- warning (_("unable to fetch general registers"));
- return;
- }
-
- arm_supply_vfpregset (regcache, &inferior_fp_registers);
-}
-
-void
-arm_netbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
-{
- if (regno >= 0)
- {
- if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
- fetch_register (regcache, regno);
- else
- fetch_fp_register (regcache, regno);
- }
- else
- {
- fetch_register (regcache, -1);
- fetch_fp_regs (regcache);
- }
-}
-
-
-static void
-store_register (const struct regcache *regcache, int regno)
-{
- struct gdbarch *gdbarch = regcache->arch ();
- struct reg inferior_registers;
- int lwp = regcache->ptid ().lwp ();
- int ret;
-
- ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
- (PTRACE_TYPE_ARG3) &inferior_registers, lwp);
-
- if (ret < 0)
- {
- warning (_("unable to fetch general registers"));
- return;
- }
-
- switch (regno)
- {
- case ARM_SP_REGNUM:
- regcache->raw_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
- break;
-
- case ARM_LR_REGNUM:
- regcache->raw_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
- break;
-
- case ARM_PC_REGNUM:
- if (arm_apcs_32)
- regcache->raw_collect (ARM_PC_REGNUM,
- (char *) &inferior_registers.r_pc);
- else
- {
- unsigned pc_val;
-
- regcache->raw_collect (ARM_PC_REGNUM, (char *) &pc_val);
-
- pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
- inferior_registers.r_pc ^= gdbarch_addr_bits_remove
- (gdbarch, inferior_registers.r_pc);
- inferior_registers.r_pc |= pc_val;
- }
- break;
-
- case ARM_PS_REGNUM:
- if (arm_apcs_32)
- regcache->raw_collect (ARM_PS_REGNUM,
- (char *) &inferior_registers.r_cpsr);
- else
- {
- unsigned psr_val;
-
- regcache->raw_collect (ARM_PS_REGNUM, (char *) &psr_val);
-
- psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
- inferior_registers.r_pc = gdbarch_addr_bits_remove
- (gdbarch, inferior_registers.r_pc);
- inferior_registers.r_pc |= psr_val;
- }
- break;
-
- default:
- regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]);
- break;
- }
-
- ret = ptrace (PT_SETREGS, regcache->ptid ().pid (),
- (PTRACE_TYPE_ARG3) &inferior_registers, lwp);
-
- if (ret < 0)
- warning (_("unable to write register %d to inferior"), regno);
-}
-
-static void
-store_regs (const struct regcache *regcache)
-{
- struct gdbarch *gdbarch = regcache->arch ();
- struct reg inferior_registers;
- int lwp = regcache->ptid ().lwp ();
- int ret;
- int regno;
-
-
- for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
- regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]);
-
- regcache->raw_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
- regcache->raw_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
-
- if (arm_apcs_32)
- {
- regcache->raw_collect (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
- regcache->raw_collect (ARM_PS_REGNUM,
- (char *) &inferior_registers.r_cpsr);
- }
- else
- {
- unsigned pc_val;
- unsigned psr_val;
-
- regcache->raw_collect (ARM_PC_REGNUM, (char *) &pc_val);
- regcache->raw_collect (ARM_PS_REGNUM, (char *) &psr_val);
-
- pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
- psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
-
- inferior_registers.r_pc = pc_val | psr_val;
- }
-
- ret = ptrace (PT_SETREGS, regcache->ptid ().pid (),
- (PTRACE_TYPE_ARG3) &inferior_registers, lwp);
-
- if (ret < 0)
- warning (_("unable to store general registers"));
-}
-
-static void
-store_fp_register (const struct regcache *regcache, int regno)
-{
- struct fpreg inferior_fp_registers;
- int lwp = regcache->ptid ().lwp ();
- int ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
- (PTRACE_TYPE_ARG3) &inferior_fp_registers, lwp);
- struct vfpreg &vfp = inferior_fp_registers.fpr_vfp;
-
- if (ret < 0)
- {
- warning (_("unable to fetch floating-point registers"));
- return;
- }
-
- struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
- if (regno == ARM_FPSCR_REGNUM && tdep->vfp_register_count != 0)
- regcache->raw_collect (ARM_FPSCR_REGNUM, (char *) &vfp.vfp_fpscr);
- else if (regno >= ARM_D0_REGNUM
- && regno <= ARM_D0_REGNUM + tdep->vfp_register_count)
- {
- regcache->raw_collect (regno,
- (char *) &vfp.vfp_regs[regno - ARM_D0_REGNUM]);
- }
- else
- warning (_("Invalid register number."));
-
- ret = ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
- (PTRACE_TYPE_ARG3) &inferior_fp_registers, lwp);
-
- if (ret < 0)
- warning (_("unable to write register %d to inferior"), regno);
-}
-
-static void
-store_fp_regs (const struct regcache *regcache)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
- int lwp = regcache->ptid ().lwp ();
- if (tdep->vfp_register_count == 0)
- return;
-
- struct fpreg fpregs;
- for (int regno = 0; regno <= tdep->vfp_register_count; regno++)
- regcache->raw_collect
- (regno + ARM_D0_REGNUM, (char *) &fpregs.fpr_vfp.vfp_regs[regno]);
-
- regcache->raw_collect (ARM_FPSCR_REGNUM,
- (char *) &fpregs.fpr_vfp.vfp_fpscr);
-
- int ret = ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
- (PTRACE_TYPE_ARG3) &fpregs, lwp);
-
- if (ret < 0)
- warning (_("unable to store floating-point registers"));
-}
-
-void
-arm_netbsd_nat_target::store_registers (struct regcache *regcache, int regno)
-{
- if (regno >= 0)
- {
- if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
- store_register (regcache, regno);
- else
- store_fp_register (regcache, regno);
- }
- else
- {
- store_regs (regcache);
- store_fp_regs (regcache);
- }
-}
-
-const struct target_desc *
-arm_netbsd_nat_target::read_description ()
-{
- int flag;
- size_t len = sizeof (flag);
-
- if (sysctlbyname("machdep.fpu_present", &flag, &len, NULL, 0) != 0
- || !flag)
- return arm_read_description (ARM_FP_TYPE_NONE);
-
- len = sizeof(flag);
- if (sysctlbyname("machdep.neon_present", &flag, &len, NULL, 0) == 0 && flag)
- return aarch32_read_description ();
-
- return arm_read_description (ARM_FP_TYPE_VFPV3);
-}
-
-void _initialize_arm_netbsd_nat ();
-void
-_initialize_arm_netbsd_nat ()
-{
- add_inf_child_target (&the_arm_netbsd_nat_target);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/arm.
-
- Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "osabi.h"
-
-#include "arch/arm.h"
-#include "arm-nbsd-tdep.h"
-#include "nbsd-tdep.h"
-#include "arm-tdep.h"
-#include "regset.h"
-#include "solib-svr4.h"
-
-/* Description of the longjmp buffer. */
-#define ARM_NBSD_JB_PC 24
-#define ARM_NBSD_JB_ELEMENT_SIZE ARM_INT_REGISTER_SIZE
-
-/* For compatibility with previous implementations of GDB on arm/NetBSD,
- override the default little-endian breakpoint. */
-static const gdb_byte arm_nbsd_arm_le_breakpoint[] = {0x11, 0x00, 0x00, 0xe6};
-static const gdb_byte arm_nbsd_arm_be_breakpoint[] = {0xe6, 0x00, 0x00, 0x11};
-static const gdb_byte arm_nbsd_thumb_le_breakpoint[] = {0xfe, 0xde};
-static const gdb_byte arm_nbsd_thumb_be_breakpoint[] = {0xde, 0xfe};
-
-/* This matches struct reg from NetBSD's sys/arch/arm/include/reg.h:
- https://github.com/NetBSD/src/blob/7c13e6e6773bb171f4ed3ed53013e9d24b3c1eac/sys/arch/arm/include/reg.h#L39
- */
-struct arm_nbsd_reg
-{
- uint32_t reg[13];
- uint32_t sp;
- uint32_t lr;
- uint32_t pc;
- uint32_t cpsr;
-};
-
-void
-arm_nbsd_supply_gregset (const struct regset *regset, struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
-{
- const arm_nbsd_reg *gregset = static_cast<const arm_nbsd_reg *>(gregs);
- gdb_assert (len >= sizeof (arm_nbsd_reg));
-
- /* Integer registers. */
- for (int i = ARM_A1_REGNUM; i < ARM_SP_REGNUM; i++)
- if (regnum == -1 || regnum == i)
- regcache->raw_supply (i, (char *) &gregset->reg[i]);
-
- if (regnum == -1 || regnum == ARM_SP_REGNUM)
- regcache->raw_supply (ARM_SP_REGNUM, (char *) &gregset->sp);
-
- if (regnum == -1 || regnum == ARM_LR_REGNUM)
- regcache->raw_supply (ARM_LR_REGNUM, (char *) &gregset->lr);
-
- if (regnum == -1 || regnum == ARM_PC_REGNUM)
- {
- CORE_ADDR r_pc = gdbarch_addr_bits_remove (regcache->arch (), gregset->pc);
- regcache->raw_supply (ARM_PC_REGNUM, (char *) &r_pc);
- }
-
- if (regnum == -1 || regnum == ARM_PS_REGNUM)
- {
- if (arm_apcs_32)
- regcache->raw_supply (ARM_PS_REGNUM, (char *) &gregset->cpsr);
- else
- regcache->raw_supply (ARM_PS_REGNUM, (char *) &gregset->pc);
- }
-}
-
-static const struct regset arm_nbsd_regset = {
- nullptr,
- arm_nbsd_supply_gregset,
- /* We don't need a collect function because we only use this reading registers
- (via iterate_over_regset_sections and fetch_regs/fetch_register). */
- nullptr,
- 0
-};
-
-static void
-arm_nbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- cb (".reg", sizeof (arm_nbsd_reg), sizeof (arm_nbsd_reg), &arm_nbsd_regset,
- NULL, cb_data);
- /* cbiesinger/2020-02-12 -- as far as I can tell, ARM/NetBSD does
- not write any floating point registers into the core file (tested
- with NetBSD 9.1_RC1). When it does, this function will need to read them,
- and the arm-netbsd gdbarch will need a core_read_description function
- to return the right description for them. */
-}
-
-static void
-arm_netbsd_init_abi_common (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- tdep->lowest_pc = 0x8000;
- switch (info.byte_order)
- {
- case BFD_ENDIAN_LITTLE:
- tdep->arm_breakpoint = arm_nbsd_arm_le_breakpoint;
- tdep->thumb_breakpoint = arm_nbsd_thumb_le_breakpoint;
- tdep->arm_breakpoint_size = sizeof (arm_nbsd_arm_le_breakpoint);
- tdep->thumb_breakpoint_size = sizeof (arm_nbsd_thumb_le_breakpoint);
- break;
-
- case BFD_ENDIAN_BIG:
- tdep->arm_breakpoint = arm_nbsd_arm_be_breakpoint;
- tdep->thumb_breakpoint = arm_nbsd_thumb_be_breakpoint;
- tdep->arm_breakpoint_size = sizeof (arm_nbsd_arm_be_breakpoint);
- tdep->thumb_breakpoint_size = sizeof (arm_nbsd_thumb_be_breakpoint);
- break;
-
- default:
- internal_error (__FILE__, __LINE__,
- _("arm_gdbarch_init: bad byte order for float format"));
- }
-
- tdep->jb_pc = ARM_NBSD_JB_PC;
- tdep->jb_elt_size = ARM_NBSD_JB_ELEMENT_SIZE;
-
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, arm_nbsd_iterate_over_regset_sections);
- /* Single stepping. */
- set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
-}
-
-static void
-arm_netbsd_elf_init_abi (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- arm_netbsd_init_abi_common (info, gdbarch);
-
- nbsd_init_abi (info, gdbarch);
-
- if (tdep->fp_model == ARM_FLOAT_AUTO)
- tdep->fp_model = ARM_FLOAT_SOFT_VFP;
-
- /* NetBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-}
-
-void _initialize_arm_netbsd_tdep ();
-void
-_initialize_arm_netbsd_tdep ()
-{
- gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_NETBSD,
- arm_netbsd_elf_init_abi);
-}
+++ /dev/null
-/* NetBSD/ARM support.
-
- Copyright (C) 2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#ifndef ARM_NBSD_TDEP_H
-#define ARM_NBSD_TDEP_H
-
-void arm_nbsd_supply_gregset
- (const struct regset *regset, struct regcache *regcache,
- int regnum, const void *gregs, size_t len);
-
-#endif
--- /dev/null
+/* Native-dependent code for BSD Unix running on ARM's, for GDB.
+
+ Copyright (C) 1988-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+/* We define this to get types like register_t. */
+#define _KERNTYPES
+#include "defs.h"
+#include "gdbcore.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "target.h"
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/sysctl.h>
+#include <machine/reg.h>
+#include <machine/frame.h>
+
+#include "arm-tdep.h"
+#include "arm-netbsd-tdep.h"
+#include "aarch32-tdep.h"
+#include "inf-ptrace.h"
+#include "netbsd-nat.h"
+
+class arm_netbsd_nat_target final : public nbsd_nat_target
+{
+public:
+ /* Add our register access methods. */
+ void fetch_registers (struct regcache *, int) override;
+ void store_registers (struct regcache *, int) override;
+ const struct target_desc *read_description () override;
+};
+
+static arm_netbsd_nat_target the_arm_netbsd_nat_target;
+
+static void
+arm_supply_vfpregset (struct regcache *regcache, struct fpreg *fpregset)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
+ if (tdep->vfp_register_count == 0)
+ return;
+
+ struct vfpreg &vfp = fpregset->fpr_vfp;
+ for (int regno = 0; regno <= tdep->vfp_register_count; regno++)
+ regcache->raw_supply (regno + ARM_D0_REGNUM, (char *) &vfp.vfp_regs[regno]);
+
+ regcache->raw_supply (ARM_FPSCR_REGNUM, (char *) &vfp.vfp_fpscr);
+}
+
+static void
+fetch_register (struct regcache *regcache, int regno)
+{
+ struct reg inferior_registers;
+ int ret;
+ int lwp = regcache->ptid ().lwp ();
+
+ ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
+ (PTRACE_TYPE_ARG3) &inferior_registers, lwp);
+
+ if (ret < 0)
+ {
+ warning (_("unable to fetch general register"));
+ return;
+ }
+ arm_nbsd_supply_gregset (nullptr, regcache, regno, &inferior_registers,
+ sizeof (inferior_registers));
+}
+
+static void
+fetch_fp_register (struct regcache *regcache, int regno)
+{
+ struct fpreg inferior_fp_registers;
+ int lwp = regcache->ptid ().lwp ();
+
+ int ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
+ (PTRACE_TYPE_ARG3) &inferior_fp_registers, lwp);
+
+ struct vfpreg &vfp = inferior_fp_registers.fpr_vfp;
+
+ if (ret < 0)
+ {
+ warning (_("unable to fetch floating-point register"));
+ return;
+ }
+
+ struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
+ if (regno == ARM_FPSCR_REGNUM && tdep->vfp_register_count != 0)
+ regcache->raw_supply (ARM_FPSCR_REGNUM, (char *) &vfp.vfp_fpscr);
+ else if (regno >= ARM_D0_REGNUM
+ && regno <= ARM_D0_REGNUM + tdep->vfp_register_count)
+ {
+ regcache->raw_supply (regno,
+ (char *) &vfp.vfp_regs[regno - ARM_D0_REGNUM]);
+ }
+ else
+ warning (_("Invalid register number."));
+}
+
+static void
+fetch_fp_regs (struct regcache *regcache)
+{
+ struct fpreg inferior_fp_registers;
+ int lwp = regcache->ptid ().lwp ();
+ int ret;
+ int regno;
+
+ ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
+ (PTRACE_TYPE_ARG3) &inferior_fp_registers, lwp);
+
+ if (ret < 0)
+ {
+ warning (_("unable to fetch general registers"));
+ return;
+ }
+
+ arm_supply_vfpregset (regcache, &inferior_fp_registers);
+}
+
+void
+arm_netbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
+{
+ if (regno >= 0)
+ {
+ if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
+ fetch_register (regcache, regno);
+ else
+ fetch_fp_register (regcache, regno);
+ }
+ else
+ {
+ fetch_register (regcache, -1);
+ fetch_fp_regs (regcache);
+ }
+}
+
+
+static void
+store_register (const struct regcache *regcache, int regno)
+{
+ struct gdbarch *gdbarch = regcache->arch ();
+ struct reg inferior_registers;
+ int lwp = regcache->ptid ().lwp ();
+ int ret;
+
+ ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
+ (PTRACE_TYPE_ARG3) &inferior_registers, lwp);
+
+ if (ret < 0)
+ {
+ warning (_("unable to fetch general registers"));
+ return;
+ }
+
+ switch (regno)
+ {
+ case ARM_SP_REGNUM:
+ regcache->raw_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
+ break;
+
+ case ARM_LR_REGNUM:
+ regcache->raw_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
+ break;
+
+ case ARM_PC_REGNUM:
+ if (arm_apcs_32)
+ regcache->raw_collect (ARM_PC_REGNUM,
+ (char *) &inferior_registers.r_pc);
+ else
+ {
+ unsigned pc_val;
+
+ regcache->raw_collect (ARM_PC_REGNUM, (char *) &pc_val);
+
+ pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
+ inferior_registers.r_pc ^= gdbarch_addr_bits_remove
+ (gdbarch, inferior_registers.r_pc);
+ inferior_registers.r_pc |= pc_val;
+ }
+ break;
+
+ case ARM_PS_REGNUM:
+ if (arm_apcs_32)
+ regcache->raw_collect (ARM_PS_REGNUM,
+ (char *) &inferior_registers.r_cpsr);
+ else
+ {
+ unsigned psr_val;
+
+ regcache->raw_collect (ARM_PS_REGNUM, (char *) &psr_val);
+
+ psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
+ inferior_registers.r_pc = gdbarch_addr_bits_remove
+ (gdbarch, inferior_registers.r_pc);
+ inferior_registers.r_pc |= psr_val;
+ }
+ break;
+
+ default:
+ regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]);
+ break;
+ }
+
+ ret = ptrace (PT_SETREGS, regcache->ptid ().pid (),
+ (PTRACE_TYPE_ARG3) &inferior_registers, lwp);
+
+ if (ret < 0)
+ warning (_("unable to write register %d to inferior"), regno);
+}
+
+static void
+store_regs (const struct regcache *regcache)
+{
+ struct gdbarch *gdbarch = regcache->arch ();
+ struct reg inferior_registers;
+ int lwp = regcache->ptid ().lwp ();
+ int ret;
+ int regno;
+
+
+ for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
+ regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]);
+
+ regcache->raw_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
+ regcache->raw_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
+
+ if (arm_apcs_32)
+ {
+ regcache->raw_collect (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
+ regcache->raw_collect (ARM_PS_REGNUM,
+ (char *) &inferior_registers.r_cpsr);
+ }
+ else
+ {
+ unsigned pc_val;
+ unsigned psr_val;
+
+ regcache->raw_collect (ARM_PC_REGNUM, (char *) &pc_val);
+ regcache->raw_collect (ARM_PS_REGNUM, (char *) &psr_val);
+
+ pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
+ psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
+
+ inferior_registers.r_pc = pc_val | psr_val;
+ }
+
+ ret = ptrace (PT_SETREGS, regcache->ptid ().pid (),
+ (PTRACE_TYPE_ARG3) &inferior_registers, lwp);
+
+ if (ret < 0)
+ warning (_("unable to store general registers"));
+}
+
+static void
+store_fp_register (const struct regcache *regcache, int regno)
+{
+ struct fpreg inferior_fp_registers;
+ int lwp = regcache->ptid ().lwp ();
+ int ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
+ (PTRACE_TYPE_ARG3) &inferior_fp_registers, lwp);
+ struct vfpreg &vfp = inferior_fp_registers.fpr_vfp;
+
+ if (ret < 0)
+ {
+ warning (_("unable to fetch floating-point registers"));
+ return;
+ }
+
+ struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
+ if (regno == ARM_FPSCR_REGNUM && tdep->vfp_register_count != 0)
+ regcache->raw_collect (ARM_FPSCR_REGNUM, (char *) &vfp.vfp_fpscr);
+ else if (regno >= ARM_D0_REGNUM
+ && regno <= ARM_D0_REGNUM + tdep->vfp_register_count)
+ {
+ regcache->raw_collect (regno,
+ (char *) &vfp.vfp_regs[regno - ARM_D0_REGNUM]);
+ }
+ else
+ warning (_("Invalid register number."));
+
+ ret = ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
+ (PTRACE_TYPE_ARG3) &inferior_fp_registers, lwp);
+
+ if (ret < 0)
+ warning (_("unable to write register %d to inferior"), regno);
+}
+
+static void
+store_fp_regs (const struct regcache *regcache)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
+ int lwp = regcache->ptid ().lwp ();
+ if (tdep->vfp_register_count == 0)
+ return;
+
+ struct fpreg fpregs;
+ for (int regno = 0; regno <= tdep->vfp_register_count; regno++)
+ regcache->raw_collect
+ (regno + ARM_D0_REGNUM, (char *) &fpregs.fpr_vfp.vfp_regs[regno]);
+
+ regcache->raw_collect (ARM_FPSCR_REGNUM,
+ (char *) &fpregs.fpr_vfp.vfp_fpscr);
+
+ int ret = ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
+ (PTRACE_TYPE_ARG3) &fpregs, lwp);
+
+ if (ret < 0)
+ warning (_("unable to store floating-point registers"));
+}
+
+void
+arm_netbsd_nat_target::store_registers (struct regcache *regcache, int regno)
+{
+ if (regno >= 0)
+ {
+ if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
+ store_register (regcache, regno);
+ else
+ store_fp_register (regcache, regno);
+ }
+ else
+ {
+ store_regs (regcache);
+ store_fp_regs (regcache);
+ }
+}
+
+const struct target_desc *
+arm_netbsd_nat_target::read_description ()
+{
+ int flag;
+ size_t len = sizeof (flag);
+
+ if (sysctlbyname("machdep.fpu_present", &flag, &len, NULL, 0) != 0
+ || !flag)
+ return arm_read_description (ARM_FP_TYPE_NONE);
+
+ len = sizeof(flag);
+ if (sysctlbyname("machdep.neon_present", &flag, &len, NULL, 0) == 0 && flag)
+ return aarch32_read_description ();
+
+ return arm_read_description (ARM_FP_TYPE_VFPV3);
+}
+
+void _initialize_arm_netbsd_nat ();
+void
+_initialize_arm_netbsd_nat ()
+{
+ add_inf_child_target (&the_arm_netbsd_nat_target);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/arm.
+
+ Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "osabi.h"
+
+#include "arch/arm.h"
+#include "arm-netbsd-tdep.h"
+#include "netbsd-tdep.h"
+#include "arm-tdep.h"
+#include "regset.h"
+#include "solib-svr4.h"
+
+/* Description of the longjmp buffer. */
+#define ARM_NBSD_JB_PC 24
+#define ARM_NBSD_JB_ELEMENT_SIZE ARM_INT_REGISTER_SIZE
+
+/* For compatibility with previous implementations of GDB on arm/NetBSD,
+ override the default little-endian breakpoint. */
+static const gdb_byte arm_nbsd_arm_le_breakpoint[] = {0x11, 0x00, 0x00, 0xe6};
+static const gdb_byte arm_nbsd_arm_be_breakpoint[] = {0xe6, 0x00, 0x00, 0x11};
+static const gdb_byte arm_nbsd_thumb_le_breakpoint[] = {0xfe, 0xde};
+static const gdb_byte arm_nbsd_thumb_be_breakpoint[] = {0xde, 0xfe};
+
+/* This matches struct reg from NetBSD's sys/arch/arm/include/reg.h:
+ https://github.com/NetBSD/src/blob/7c13e6e6773bb171f4ed3ed53013e9d24b3c1eac/sys/arch/arm/include/reg.h#L39
+ */
+struct arm_nbsd_reg
+{
+ uint32_t reg[13];
+ uint32_t sp;
+ uint32_t lr;
+ uint32_t pc;
+ uint32_t cpsr;
+};
+
+void
+arm_nbsd_supply_gregset (const struct regset *regset, struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ const arm_nbsd_reg *gregset = static_cast<const arm_nbsd_reg *>(gregs);
+ gdb_assert (len >= sizeof (arm_nbsd_reg));
+
+ /* Integer registers. */
+ for (int i = ARM_A1_REGNUM; i < ARM_SP_REGNUM; i++)
+ if (regnum == -1 || regnum == i)
+ regcache->raw_supply (i, (char *) &gregset->reg[i]);
+
+ if (regnum == -1 || regnum == ARM_SP_REGNUM)
+ regcache->raw_supply (ARM_SP_REGNUM, (char *) &gregset->sp);
+
+ if (regnum == -1 || regnum == ARM_LR_REGNUM)
+ regcache->raw_supply (ARM_LR_REGNUM, (char *) &gregset->lr);
+
+ if (regnum == -1 || regnum == ARM_PC_REGNUM)
+ {
+ CORE_ADDR r_pc = gdbarch_addr_bits_remove (regcache->arch (), gregset->pc);
+ regcache->raw_supply (ARM_PC_REGNUM, (char *) &r_pc);
+ }
+
+ if (regnum == -1 || regnum == ARM_PS_REGNUM)
+ {
+ if (arm_apcs_32)
+ regcache->raw_supply (ARM_PS_REGNUM, (char *) &gregset->cpsr);
+ else
+ regcache->raw_supply (ARM_PS_REGNUM, (char *) &gregset->pc);
+ }
+}
+
+static const struct regset arm_nbsd_regset = {
+ nullptr,
+ arm_nbsd_supply_gregset,
+ /* We don't need a collect function because we only use this reading registers
+ (via iterate_over_regset_sections and fetch_regs/fetch_register). */
+ nullptr,
+ 0
+};
+
+static void
+arm_nbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ cb (".reg", sizeof (arm_nbsd_reg), sizeof (arm_nbsd_reg), &arm_nbsd_regset,
+ NULL, cb_data);
+ /* cbiesinger/2020-02-12 -- as far as I can tell, ARM/NetBSD does
+ not write any floating point registers into the core file (tested
+ with NetBSD 9.1_RC1). When it does, this function will need to read them,
+ and the arm-netbsd gdbarch will need a core_read_description function
+ to return the right description for them. */
+}
+
+static void
+arm_netbsd_init_abi_common (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ tdep->lowest_pc = 0x8000;
+ switch (info.byte_order)
+ {
+ case BFD_ENDIAN_LITTLE:
+ tdep->arm_breakpoint = arm_nbsd_arm_le_breakpoint;
+ tdep->thumb_breakpoint = arm_nbsd_thumb_le_breakpoint;
+ tdep->arm_breakpoint_size = sizeof (arm_nbsd_arm_le_breakpoint);
+ tdep->thumb_breakpoint_size = sizeof (arm_nbsd_thumb_le_breakpoint);
+ break;
+
+ case BFD_ENDIAN_BIG:
+ tdep->arm_breakpoint = arm_nbsd_arm_be_breakpoint;
+ tdep->thumb_breakpoint = arm_nbsd_thumb_be_breakpoint;
+ tdep->arm_breakpoint_size = sizeof (arm_nbsd_arm_be_breakpoint);
+ tdep->thumb_breakpoint_size = sizeof (arm_nbsd_thumb_be_breakpoint);
+ break;
+
+ default:
+ internal_error (__FILE__, __LINE__,
+ _("arm_gdbarch_init: bad byte order for float format"));
+ }
+
+ tdep->jb_pc = ARM_NBSD_JB_PC;
+ tdep->jb_elt_size = ARM_NBSD_JB_ELEMENT_SIZE;
+
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, arm_nbsd_iterate_over_regset_sections);
+ /* Single stepping. */
+ set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
+}
+
+static void
+arm_netbsd_elf_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ arm_netbsd_init_abi_common (info, gdbarch);
+
+ nbsd_init_abi (info, gdbarch);
+
+ if (tdep->fp_model == ARM_FLOAT_AUTO)
+ tdep->fp_model = ARM_FLOAT_SOFT_VFP;
+
+ /* NetBSD ELF uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+
+void _initialize_arm_netbsd_tdep ();
+void
+_initialize_arm_netbsd_tdep ()
+{
+ gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_NETBSD,
+ arm_netbsd_elf_init_abi);
+}
--- /dev/null
+/* NetBSD/ARM support.
+
+ Copyright (C) 2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef ARM_NBSD_TDEP_H
+#define ARM_NBSD_TDEP_H
+
+void arm_nbsd_supply_gregset
+ (const struct regset *regset, struct regcache *regcache,
+ int regnum, const void *gregs, size_t len);
+
+#endif
;;
mips)
# Host: NetBSD/mips
- NATDEPFILES="${NATDEPFILES} mips-nbsd-nat.o"
+ NATDEPFILES="${NATDEPFILES} mips-netbsd-nat.o"
;;
pa)
# Host: NetBSD/hppa
- NATDEPFILES="${NATDEPFILES} nbsd-nat.o hppa-nbsd-nat.o"
+ NATDEPFILES="${NATDEPFILES} netbsd-nat.o hppa-netbsd-nat.o"
;;
powerpc)
# Host: NetBSD/powerpc
- NATDEPFILES="${NATDEPFILES} ppc-nbsd-nat.o bsd-kvm.o"
+ NATDEPFILES="${NATDEPFILES} ppc-netbsd-nat.o bsd-kvm.o"
LOADLIBES='-lkvm'
;;
sh)
# Host: NetBSD/sh
- NATDEPFILES="${NATDEPFILES} sh-nbsd-nat.o"
+ NATDEPFILES="${NATDEPFILES} sh-netbsd-nat.o"
;;
esac
case ${gdb_host_cpu} in
i386)
# Host: NetBSD/amd64
- NATDEPFILES="${NATDEPFILES} nbsd-nat.o amd64-nat.o x86-nat.o \
- nat/x86-dregs.o x86-bsd-nat.o amd64-bsd-nat.o amd64-nbsd-nat.o"
+ NATDEPFILES="${NATDEPFILES} netbsd-nat.o amd64-nat.o x86-nat.o \
+ nat/x86-dregs.o x86-bsd-nat.o amd64-bsd-nat.o amd64-netbsd-nat.o"
;;
sparc)
# Host: NetBSD/sparc64
- NATDEPFILES="${NATDEPFILES} sparc64-nbsd-nat.o sparc-nat.o \
+ NATDEPFILES="${NATDEPFILES} sparc64-netbsd-nat.o sparc-nat.o \
bsd-kvm.o"
LOADLIBES='-lkvm'
;;
case ${gdb_host_cpu} in
arm)
# Host: NetBSD/arm
- NATDEPFILES="${NATDEPFILES} arm-nbsd-nat.o"
+ NATDEPFILES="${NATDEPFILES} arm-netbsd-nat.o"
;;
i386)
# Host: NetBSD/i386 ELF
- NATDEPFILES="${NATDEPFILES} nbsd-nat.o x86-nat.o \
+ NATDEPFILES="${NATDEPFILES} netbsd-nat.o x86-nat.o \
nat/x86-dregs.o \
- x86-bsd-nat.o i386-bsd-nat.o i386-nbsd-nat.o bsd-kvm.o"
+ x86-bsd-nat.o i386-bsd-nat.o i386-netbsd-nat.o bsd-kvm.o"
LOADLIBES='-lkvm'
;;
m68k)
;;
sparc)
# Host: NetBSD/sparc ELF
- NATDEPFILES="${NATDEPFILES} sparc-nat.o sparc-nbsd-nat.o \
+ NATDEPFILES="${NATDEPFILES} sparc-nat.o sparc-netbsd-nat.o \
bsd-kvm.o"
LOADLIBES='-lkvm'
;;
alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu)
# Target: NetBSD/alpha
gdb_target_obs="alpha-mdebug-tdep.o alpha-bsd-tdep.o \
- alpha-nbsd-tdep.o"
+ alpha-netbsd-tdep.o"
;;
alpha*-*-openbsd*)
# Target: OpenBSD/alpha
gdb_target_obs="alpha-mdebug-tdep.o alpha-bsd-tdep.o \
- alpha-nbsd-tdep.o alpha-obsd-tdep.o nbsd-tdep.o"
+ alpha-netbsd-tdep.o alpha-obsd-tdep.o nbsd-tdep.o"
;;
am33_2.0*-*-linux*)
;;
arm*-*-netbsd* | arm*-*-knetbsd*-gnu)
# Target: NetBSD/arm
- gdb_target_obs="arm-nbsd-tdep.o"
+ gdb_target_obs="arm-netbsd-tdep.o"
;;
arm*-*-openbsd*)
# Target: OpenBSD/arm
;;
hppa*-*-netbsd*)
# Target: NetBSD/hppa
- gdb_target_obs="hppa-bsd-tdep.o hppa-nbsd-tdep.o solib-svr4.o"
+ gdb_target_obs="hppa-bsd-tdep.o hppa-netbsd-tdep.o solib-svr4.o"
;;
hppa*-*-openbsd*)
# Target: OpenBSD/hppa
;;
i[34567]86-*-netbsd* | i[34567]86-*-knetbsd*-gnu)
# Target: NetBSD/i386
- gdb_target_obs="i386-bsd-tdep.o i386-nbsd-tdep.o "
+ gdb_target_obs="i386-bsd-tdep.o i386-netbsd-tdep.o "
;;
i[34567]86-*-openbsd*)
# Target: OpenBSD/i386
;;
mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
# Target: MIPS running NetBSD
- gdb_target_obs="mips-tdep.o mips-nbsd-tdep.o"
+ gdb_target_obs="mips-tdep.o mips-netbsd-tdep.o"
gdb_sim=../sim/mips/libsim.a
;;
mips*-*-freebsd*)
powerpc-*-netbsd* | powerpc-*-knetbsd*-gnu)
# Target: NetBSD/powerpc
- gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc-nbsd-tdep.o \
+ gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc-netbsd-tdep.o \
ravenscar-thread.o ppc-ravenscar-thread.o"
gdb_sim=../sim/ppc/libsim.a
;;
;;
sh*-*-netbsdelf* | sh*-*-knetbsd*-gnu)
# Target: NetBSD/sh
- gdb_target_obs="sh-tdep.o sh-nbsd-tdep.o"
+ gdb_target_obs="sh-tdep.o sh-netbsd-tdep.o"
gdb_sim=../sim/sh/libsim.a
;;
sh*-*-openbsd*)
# Target: OpenBSD/sh
- gdb_target_obs="sh-tdep.o sh-nbsd-tdep.o"
+ gdb_target_obs="sh-tdep.o sh-netbsd-tdep.o"
;;
sh*)
# Target: Embedded Renesas Super-H processor
;;
sparc-*-netbsd* | sparc-*-knetbsd*-gnu)
# Target: NetBSD/sparc
- gdb_target_obs="sparc-tdep.o sparc-nbsd-tdep.o \
+ gdb_target_obs="sparc-tdep.o sparc-netbsd-tdep.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc64-*-netbsd* | sparc64-*-knetbsd*-gnu)
# Target: NetBSD/sparc64
- gdb_target_obs="sparc64-tdep.o sparc64-nbsd-tdep.o sparc-tdep.o \
- sparc-nbsd-tdep.o \
+ gdb_target_obs="sparc64-tdep.o sparc64-netbsd-tdep.o sparc-tdep.o \
+ sparc-netbsd-tdep.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc-*-openbsd*)
# Target: OpenBSD/sparc
- gdb_target_obs="sparc-tdep.o sparc-nbsd-tdep.o sparc-obsd-tdep.o \
+ gdb_target_obs="sparc-tdep.o sparc-netbsd-tdep.o sparc-obsd-tdep.o \
nbsd-tdep.o bsd-uthread.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc64-*-openbsd*)
# Target: OpenBSD/sparc64
- gdb_target_obs="sparc64-tdep.o sparc64-nbsd-tdep.o sparc64-obsd-tdep.o \
- sparc-tdep.o sparc-nbsd-tdep.o sparc-obsd-tdep.o \
+ gdb_target_obs="sparc64-tdep.o sparc64-netbsd-tdep.o sparc64-obsd-tdep.o \
+ sparc-tdep.o sparc-netbsd-tdep.o sparc-obsd-tdep.o \
nbsd-tdep.o bsd-uthread.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
;;
x86_64-*-netbsd* | x86_64-*-knetbsd*-gnu)
# Target: NetBSD/amd64
- gdb_target_obs="amd64-nbsd-tdep.o ${i386_tobjs}"
+ gdb_target_obs="amd64-netbsd-tdep.o ${i386_tobjs}"
;;
x86_64-*-openbsd*)
# Target: OpenBSD/amd64
+++ /dev/null
-/* Native-dependent code for NetBSD/hppa.
-
- Copyright (C) 2008-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "inferior.h"
-#include "regcache.h"
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-#include "hppa-tdep.h"
-#include "inf-ptrace.h"
-
-#include "nbsd-nat.h"
-
-class hppa_nbsd_nat_target final : public nbsd_nat_target
-{
- void fetch_registers (struct regcache *, int) override;
- void store_registers (struct regcache *, int) override;
-};
-
-static hppa_nbsd_nat_target the_hppa_nbsd_nat_target;
-
-static int
-hppanbsd_gregset_supplies_p (int regnum)
-{
- return ((regnum >= HPPA_R0_REGNUM && regnum <= HPPA_R31_REGNUM) ||
- (regnum >= HPPA_SAR_REGNUM && regnum <= HPPA_PCSQ_TAIL_REGNUM) ||
- regnum == HPPA_IPSW_REGNUM ||
- (regnum >= HPPA_SR4_REGNUM && regnum <= HPPA_SR4_REGNUM + 5));
-}
-
-static int
-hppanbsd_fpregset_supplies_p (int regnum)
-{
- return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM);
-}
-
-/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
-
-static void
-hppanbsd_supply_gregset (struct regcache *regcache, const void *gregs)
-{
- const char *regs = gregs;
- const int *r = gregs;
- int regnum;
-
- for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
- regcache->raw_supply (regnum, regs + regnum * 4);
-
- regcache->raw_supply (HPPA_SAR_REGNUM, regs + 32 * 4);
- regcache->raw_supply (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
- regcache->raw_supply (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
- regcache->raw_supply (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
- regcache->raw_supply (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
- regcache->raw_supply (HPPA_IPSW_REGNUM, regs);
- regcache->raw_supply (HPPA_SR4_REGNUM, regs + 41 * 4);
- regcache->raw_supply (HPPA_SR4_REGNUM + 1, regs + 37 * 4);
- regcache->raw_supply (HPPA_SR4_REGNUM + 2, regs + 38 * 4);
- regcache->raw_supply (HPPA_SR4_REGNUM + 3, regs + 39 * 4);
- regcache->raw_supply (HPPA_SR4_REGNUM + 4, regs + 40 * 4);
-}
-
-/* Supply the floating-point registers stored in FPREGS to REGCACHE. */
-
-static void
-hppanbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
-{
- const char *regs = fpregs;
- int regnum;
-
- for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM;
- regnum += 2, regs += 8)
- {
- regcache->raw_supply (regnum, regs);
- regcache->raw_supply (regnum + 1, regs + 4);
- }
-}
-
-/* Collect the general-purpose registers from REGCACHE and store them
- in GREGS. */
-
-static void
-hppanbsd_collect_gregset (const struct regcache *regcache,
- void *gregs, int regnum)
-{
- char *regs = gregs;
- int *r = gregs;
- int i;
-
- for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
- {
- if (regnum == -1 || regnum == i)
- regcache->raw_collect (i, regs + i * 4);
- }
-
- if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
- regcache->raw_collect (HPPA_IPSW_REGNUM, regs);
- if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
- regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
- if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
- regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
-
- if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
- regcache->raw_collect (HPPA_SAR_REGNUM, regs + 32 * 4);
- if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
- regcache->raw_collect (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
- if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
- regcache->raw_collect (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
- if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
- regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
- if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
- regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
- if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
- regcache->raw_collect (HPPA_IPSW_REGNUM, regs);
- if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
- regcache->raw_collect (HPPA_SR4_REGNUM, regs + 41 * 4);
- if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 1)
- regcache->raw_collect (HPPA_SR4_REGNUM + 1, regs + 37 * 4);
- if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 2)
- regcache->raw_collect (HPPA_SR4_REGNUM + 2, regs + 38 * 4);
- if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 3)
- regcache->raw_collect (HPPA_SR4_REGNUM + 3, regs + 39 * 4);
- if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 4)
- regcache->raw_collect (HPPA_SR4_REGNUM + 4, regs + 40 * 4);
-}
-
-/* Collect the floating-point registers from REGCACHE and store them
- in FPREGS. */
-
-static void
-hppanbsd_collect_fpregset (struct regcache *regcache,
- void *fpregs, int regnum)
-{
- char *regs = fpregs;
- int i;
-
- for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8)
- {
- if (regnum == -1 || regnum == i || regnum == i + 1)
- {
- regcache->raw_collect (i, regs);
- regcache->raw_collect (i + 1, regs + 4);
- }
- }
-}
-\f
-
-/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
- for all registers (including the floating-point registers). */
-
-void
-hppa_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
-
-{
- pid_t pid = regcache->ptid ().pid ();
- int lwp = regcache->ptid ().lwp ();
-
- if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- hppanbsd_supply_gregset (regcache, ®s);
- }
-
- if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- hppanbsd_supply_fpregset (regcache, &fpregs);
- }
-}
-
-/* Store register REGNUM back into the inferior. If REGNUM is -1, do
- this for all registers (including the floating-point registers). */
-
-void
-hppa_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
-{
- pid_t pid = regcache->ptid ().pid ();
- int lwp = regcache->ptid ().lwp ();
-
- if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- hppanbsd_collect_gregset (regcache, ®s, regnum);
-
- if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1)
- perror_with_name (_("Couldn't write registers"));
- }
-
- if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- hppanbsd_collect_fpregset (regcache, &fpregs, regnum);
-
- if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
- perror_with_name (_("Couldn't write floating point status"));
- }
-}
-
-void _initialize_hppanbsd_nat ();
-void
-_initialize_hppanbsd_nat ()
-{
- add_inf_child_target (&the_hppa_nbsd_nat_target);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/hppa
-
- Copyright (C) 2008-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-
-#include "trad-frame.h"
-#include "tramp-frame.h"
-
-#include "hppa-tdep.h"
-#include "hppa-bsd-tdep.h"
-#include "nbsd-tdep.h"
-#include "gdbarch.h"
-
-/* From <machine/mcontext.h>. */
-static int hppanbsd_mc_reg_offset[] =
-{
- /* r0 ... r31 */
- -1, 1 * 4, 2 * 4, 3 * 4,
- 4 * 4, 5 * 4, 6 * 4, 7 * 4,
- 8 * 4, 9 * 4, 10 * 4, 11 * 4,
- 12 * 4, 13 * 4, 14 * 4, 15 * 4,
- 16 * 4, 17 * 4, 18 * 4, 19 * 4,
- 20 * 4, 21 * 4, 22 * 4, 23 * 4,
- 24 * 4, 25 * 4, 26 * 4, 27 * 4,
- 28 * 4, 29 * 4, 30 * 4, 31 * 4,
-
- 32 * 4, /* HPPA_SAR_REGNUM */
- 35 * 4, /* HPPA_PCOQ_HEAD_REGNUM */
- 33 * 4, /* HPPA_PCSQ_HEAD_REGNUM */
- 36 * 4, /* HPPA_PCOQ_TAIL_REGNUM */
- 34 * 4, /* HPPA_PCSQ_TAIL_REGNUM */
- -1, /* HPPA_EIEM_REGNUM */
- -1, /* HPPA_IIR_REGNUM */
- -1, /* HPPA_ISR_REGNUM */
- -1, /* HPPA_IOR_REGNUM */
- 0 * 4, /* HPPA_IPSW_REGNUM */
- -1, /* spare? */
- 41 * 4, /* HPPA_SR4_REGNUM */
- 37 * 4, /* sr0 */
- 38 * 4, /* sr1 */
- 39 * 4, /* sr2 */
- 40 * 4, /* sr3 */
-
- /* more tbd */
-};
-
-static void hppanbsd_sigtramp_cache_init (const struct tramp_frame *,
- struct frame_info *,
- struct trad_frame_cache *,
- CORE_ADDR);
-
-static const struct tramp_frame hppanbsd_sigtramp_si4 =
-{
- SIGTRAMP_FRAME,
- 4,
- {
- { 0xc7d7c012, ULONGEST_MAX }, /* bb,>=,n %arg3, 30, 1f */
- { 0xd6e01c1e, ULONGEST_MAX }, /* depwi 0,31,2,%arg3 */
- { 0x0ee81093, ULONGEST_MAX }, /* ldw 4(%arg3), %r19 */
- { 0x0ee01097, ULONGEST_MAX }, /* ldw 0(%arg3), %arg3 */
- /* 1: */
- { 0xe8404000, ULONGEST_MAX }, /* blr %r0, %rp */
- { 0xeae0c002, ULONGEST_MAX }, /* bv,n %r0(%arg3) */
- { 0x08000240, ULONGEST_MAX }, /* nop */
-
- { 0x0803025a, ULONGEST_MAX }, /* copy %r3, %arg0 */
- { 0x20200801, ULONGEST_MAX }, /* ldil -40000000, %r1 */
- { 0xe420e008, ULONGEST_MAX }, /* be,l 4(%sr7, %r1), %sr0, %r31 */
- { 0x34160268, ULONGEST_MAX }, /* ldi 134, %t1 ; SYS_setcontext */
-
- { 0x081c025a, ULONGEST_MAX }, /* copy ret0, %arg0 */
- { 0x20200801, ULONGEST_MAX }, /* ldil -40000000, %r1 */
- { 0xe420e008, ULONGEST_MAX }, /* be,l 4(%sr7, %r1), %sr0, %r31 */
- { 0x34160002, ULONGEST_MAX }, /* ldi 1, %t1 ; SYS_exit */
- { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
- },
- hppanbsd_sigtramp_cache_init
-};
-
-
-static void
-hppanbsd_sigtramp_cache_init (const struct tramp_frame *self,
- struct frame_info *this_frame,
- struct trad_frame_cache *this_cache,
- CORE_ADDR func)
-{
- CORE_ADDR sp = get_frame_register_unsigned (this_frame, HPPA_SP_REGNUM);
- CORE_ADDR base;
- int *reg_offset;
- int num_regs;
- int i;
-
- reg_offset = hppanbsd_mc_reg_offset;
- num_regs = ARRAY_SIZE (hppanbsd_mc_reg_offset);
-
- /* frame pointer */
- base = sp - 0x280;
- /* offsetof(struct sigframe_siginfo, sf_uc) = 128 */
- base += 128;
- /* offsetof(ucontext_t, uc_mcontext) == 40 */
- base += 40;
-
- for (i = 0; i < num_regs; i++)
- if (reg_offset[i] != -1)
- trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]);
-
- /* Construct the frame ID using the function start. */
- trad_frame_set_id (this_cache, frame_id_build (sp, func));
-}
-
-/* Core file support. */
-
-/* Sizeof `struct reg' in <machine/reg.h>. */
-#define HPPANBSD_SIZEOF_GREGS (44 * 4)
-
-static int hppanbsd_reg_offset[] =
-{
- /* r0 ... r31 */
- -1, 1 * 4, 2 * 4, 3 * 4,
- 4 * 4, 5 * 4, 6 * 4, 7 * 4,
- 8 * 4, 9 * 4, 10 * 4, 11 * 4,
- 12 * 4, 13 * 4, 14 * 4, 15 * 4,
- 16 * 4, 17 * 4, 18 * 4, 19 * 4,
- 20 * 4, 21 * 4, 22 * 4, 23 * 4,
- 24 * 4, 25 * 4, 26 * 4, 27 * 4,
- 28 * 4, 29 * 4, 30 * 4, 31 * 4,
-
- 32 * 4, /* HPPA_SAR_REGNUM */
- 35 * 4, /* HPPA_PCOQ_HEAD_REGNUM */
- 33 * 4, /* HPPA_PCSQ_HEAD_REGNUM */
- 36 * 4, /* HPPA_PCOQ_TAIL_REGNUM */
- 34 * 4, /* HPPA_PCSQ_TAIL_REGNUM */
- -1, /* HPPA_EIEM_REGNUM */
- -1, /* HPPA_IIR_REGNUM */
- -1, /* HPPA_ISR_REGNUM */
- -1, /* HPPA_IOR_REGNUM */
- 0 * 4, /* HPPA_IPSW_REGNUM */
-};
-
-/* Supply register REGNUM from the buffer specified by GREGS and LEN
- in the general-purpose register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-hppanbsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
-{
- const gdb_byte *regs = (const gdb_byte *) gregs;
- int i;
-
- gdb_assert (len >= HPPANBSD_SIZEOF_GREGS);
-
- for (i = 0; i < ARRAY_SIZE (hppanbsd_reg_offset); i++)
- if (hppanbsd_reg_offset[i] != -1)
- if (regnum == -1 || regnum == i)
- regcache->raw_supply (i, regs + hppanbsd_reg_offset[i]);
-}
-
-/* NetBSD/hppa register set. */
-
-static const struct regset hppanbsd_gregset =
-{
- NULL,
- hppanbsd_supply_gregset
-};
-
-/* Iterate over supported core file register note sections. */
-
-static void
-hppanbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- cb (".reg", HPPANBSD_SIZEOF_GREGS, HPPANBSD_SIZEOF_GREGS, &hppanbsd_gregset,
- NULL, cb_data);
-}
-\f
-static void
-hppanbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- /* Obviously NetBSD is BSD-based. */
- hppabsd_init_abi (info, gdbarch);
-
- nbsd_init_abi (info, gdbarch);
-
- /* Core file support. */
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, hppanbsd_iterate_over_regset_sections);
-
- tramp_frame_prepend_unwinder (gdbarch, &hppanbsd_sigtramp_si4);
-}
-
-void _initialize_hppanbsd_tdep ();
-void
-_initialize_hppanbsd_tdep ()
-{
- gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_NETBSD,
- hppanbsd_init_abi);
-}
--- /dev/null
+/* Native-dependent code for NetBSD/hppa.
+
+ Copyright (C) 2008-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "hppa-tdep.h"
+#include "inf-ptrace.h"
+
+#include "netbsd-nat.h"
+
+class hppa_nbsd_nat_target final : public nbsd_nat_target
+{
+ void fetch_registers (struct regcache *, int) override;
+ void store_registers (struct regcache *, int) override;
+};
+
+static hppa_nbsd_nat_target the_hppa_nbsd_nat_target;
+
+static int
+hppanbsd_gregset_supplies_p (int regnum)
+{
+ return ((regnum >= HPPA_R0_REGNUM && regnum <= HPPA_R31_REGNUM) ||
+ (regnum >= HPPA_SAR_REGNUM && regnum <= HPPA_PCSQ_TAIL_REGNUM) ||
+ regnum == HPPA_IPSW_REGNUM ||
+ (regnum >= HPPA_SR4_REGNUM && regnum <= HPPA_SR4_REGNUM + 5));
+}
+
+static int
+hppanbsd_fpregset_supplies_p (int regnum)
+{
+ return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM);
+}
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
+
+static void
+hppanbsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+ const char *regs = gregs;
+ const int *r = gregs;
+ int regnum;
+
+ for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
+ regcache->raw_supply (regnum, regs + regnum * 4);
+
+ regcache->raw_supply (HPPA_SAR_REGNUM, regs + 32 * 4);
+ regcache->raw_supply (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
+ regcache->raw_supply (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
+ regcache->raw_supply (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
+ regcache->raw_supply (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
+ regcache->raw_supply (HPPA_IPSW_REGNUM, regs);
+ regcache->raw_supply (HPPA_SR4_REGNUM, regs + 41 * 4);
+ regcache->raw_supply (HPPA_SR4_REGNUM + 1, regs + 37 * 4);
+ regcache->raw_supply (HPPA_SR4_REGNUM + 2, regs + 38 * 4);
+ regcache->raw_supply (HPPA_SR4_REGNUM + 3, regs + 39 * 4);
+ regcache->raw_supply (HPPA_SR4_REGNUM + 4, regs + 40 * 4);
+}
+
+/* Supply the floating-point registers stored in FPREGS to REGCACHE. */
+
+static void
+hppanbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
+{
+ const char *regs = fpregs;
+ int regnum;
+
+ for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM;
+ regnum += 2, regs += 8)
+ {
+ regcache->raw_supply (regnum, regs);
+ regcache->raw_supply (regnum + 1, regs + 4);
+ }
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+ in GREGS. */
+
+static void
+hppanbsd_collect_gregset (const struct regcache *regcache,
+ void *gregs, int regnum)
+{
+ char *regs = gregs;
+ int *r = gregs;
+ int i;
+
+ for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache->raw_collect (i, regs + i * 4);
+ }
+
+ if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
+ regcache->raw_collect (HPPA_IPSW_REGNUM, regs);
+ if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
+ regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
+ if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
+ regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
+
+ if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
+ regcache->raw_collect (HPPA_SAR_REGNUM, regs + 32 * 4);
+ if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
+ regcache->raw_collect (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
+ if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
+ regcache->raw_collect (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
+ if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
+ regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
+ if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
+ regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
+ if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
+ regcache->raw_collect (HPPA_IPSW_REGNUM, regs);
+ if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
+ regcache->raw_collect (HPPA_SR4_REGNUM, regs + 41 * 4);
+ if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 1)
+ regcache->raw_collect (HPPA_SR4_REGNUM + 1, regs + 37 * 4);
+ if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 2)
+ regcache->raw_collect (HPPA_SR4_REGNUM + 2, regs + 38 * 4);
+ if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 3)
+ regcache->raw_collect (HPPA_SR4_REGNUM + 3, regs + 39 * 4);
+ if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 4)
+ regcache->raw_collect (HPPA_SR4_REGNUM + 4, regs + 40 * 4);
+}
+
+/* Collect the floating-point registers from REGCACHE and store them
+ in FPREGS. */
+
+static void
+hppanbsd_collect_fpregset (struct regcache *regcache,
+ void *fpregs, int regnum)
+{
+ char *regs = fpregs;
+ int i;
+
+ for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8)
+ {
+ if (regnum == -1 || regnum == i || regnum == i + 1)
+ {
+ regcache->raw_collect (i, regs);
+ regcache->raw_collect (i + 1, regs + 4);
+ }
+ }
+}
+\f
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers (including the floating-point registers). */
+
+void
+hppa_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
+
+{
+ pid_t pid = regcache->ptid ().pid ();
+ int lwp = regcache->ptid ().lwp ();
+
+ if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ hppanbsd_supply_gregset (regcache, ®s);
+ }
+
+ if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ hppanbsd_supply_fpregset (regcache, &fpregs);
+ }
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers (including the floating-point registers). */
+
+void
+hppa_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
+{
+ pid_t pid = regcache->ptid ().pid ();
+ int lwp = regcache->ptid ().lwp ();
+
+ if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ hppanbsd_collect_gregset (regcache, ®s, regnum);
+
+ if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1)
+ perror_with_name (_("Couldn't write registers"));
+ }
+
+ if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ hppanbsd_collect_fpregset (regcache, &fpregs, regnum);
+
+ if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
+ perror_with_name (_("Couldn't write floating point status"));
+ }
+}
+
+void _initialize_hppanbsd_nat ();
+void
+_initialize_hppanbsd_nat ()
+{
+ add_inf_child_target (&the_hppa_nbsd_nat_target);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/hppa
+
+ Copyright (C) 2008-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+
+#include "trad-frame.h"
+#include "tramp-frame.h"
+
+#include "hppa-tdep.h"
+#include "hppa-bsd-tdep.h"
+#include "netbsd-tdep.h"
+#include "gdbarch.h"
+
+/* From <machine/mcontext.h>. */
+static int hppanbsd_mc_reg_offset[] =
+{
+ /* r0 ... r31 */
+ -1, 1 * 4, 2 * 4, 3 * 4,
+ 4 * 4, 5 * 4, 6 * 4, 7 * 4,
+ 8 * 4, 9 * 4, 10 * 4, 11 * 4,
+ 12 * 4, 13 * 4, 14 * 4, 15 * 4,
+ 16 * 4, 17 * 4, 18 * 4, 19 * 4,
+ 20 * 4, 21 * 4, 22 * 4, 23 * 4,
+ 24 * 4, 25 * 4, 26 * 4, 27 * 4,
+ 28 * 4, 29 * 4, 30 * 4, 31 * 4,
+
+ 32 * 4, /* HPPA_SAR_REGNUM */
+ 35 * 4, /* HPPA_PCOQ_HEAD_REGNUM */
+ 33 * 4, /* HPPA_PCSQ_HEAD_REGNUM */
+ 36 * 4, /* HPPA_PCOQ_TAIL_REGNUM */
+ 34 * 4, /* HPPA_PCSQ_TAIL_REGNUM */
+ -1, /* HPPA_EIEM_REGNUM */
+ -1, /* HPPA_IIR_REGNUM */
+ -1, /* HPPA_ISR_REGNUM */
+ -1, /* HPPA_IOR_REGNUM */
+ 0 * 4, /* HPPA_IPSW_REGNUM */
+ -1, /* spare? */
+ 41 * 4, /* HPPA_SR4_REGNUM */
+ 37 * 4, /* sr0 */
+ 38 * 4, /* sr1 */
+ 39 * 4, /* sr2 */
+ 40 * 4, /* sr3 */
+
+ /* more tbd */
+};
+
+static void hppanbsd_sigtramp_cache_init (const struct tramp_frame *,
+ struct frame_info *,
+ struct trad_frame_cache *,
+ CORE_ADDR);
+
+static const struct tramp_frame hppanbsd_sigtramp_si4 =
+{
+ SIGTRAMP_FRAME,
+ 4,
+ {
+ { 0xc7d7c012, ULONGEST_MAX }, /* bb,>=,n %arg3, 30, 1f */
+ { 0xd6e01c1e, ULONGEST_MAX }, /* depwi 0,31,2,%arg3 */
+ { 0x0ee81093, ULONGEST_MAX }, /* ldw 4(%arg3), %r19 */
+ { 0x0ee01097, ULONGEST_MAX }, /* ldw 0(%arg3), %arg3 */
+ /* 1: */
+ { 0xe8404000, ULONGEST_MAX }, /* blr %r0, %rp */
+ { 0xeae0c002, ULONGEST_MAX }, /* bv,n %r0(%arg3) */
+ { 0x08000240, ULONGEST_MAX }, /* nop */
+
+ { 0x0803025a, ULONGEST_MAX }, /* copy %r3, %arg0 */
+ { 0x20200801, ULONGEST_MAX }, /* ldil -40000000, %r1 */
+ { 0xe420e008, ULONGEST_MAX }, /* be,l 4(%sr7, %r1), %sr0, %r31 */
+ { 0x34160268, ULONGEST_MAX }, /* ldi 134, %t1 ; SYS_setcontext */
+
+ { 0x081c025a, ULONGEST_MAX }, /* copy ret0, %arg0 */
+ { 0x20200801, ULONGEST_MAX }, /* ldil -40000000, %r1 */
+ { 0xe420e008, ULONGEST_MAX }, /* be,l 4(%sr7, %r1), %sr0, %r31 */
+ { 0x34160002, ULONGEST_MAX }, /* ldi 1, %t1 ; SYS_exit */
+ { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
+ },
+ hppanbsd_sigtramp_cache_init
+};
+
+
+static void
+hppanbsd_sigtramp_cache_init (const struct tramp_frame *self,
+ struct frame_info *this_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func)
+{
+ CORE_ADDR sp = get_frame_register_unsigned (this_frame, HPPA_SP_REGNUM);
+ CORE_ADDR base;
+ int *reg_offset;
+ int num_regs;
+ int i;
+
+ reg_offset = hppanbsd_mc_reg_offset;
+ num_regs = ARRAY_SIZE (hppanbsd_mc_reg_offset);
+
+ /* frame pointer */
+ base = sp - 0x280;
+ /* offsetof(struct sigframe_siginfo, sf_uc) = 128 */
+ base += 128;
+ /* offsetof(ucontext_t, uc_mcontext) == 40 */
+ base += 40;
+
+ for (i = 0; i < num_regs; i++)
+ if (reg_offset[i] != -1)
+ trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]);
+
+ /* Construct the frame ID using the function start. */
+ trad_frame_set_id (this_cache, frame_id_build (sp, func));
+}
+
+/* Core file support. */
+
+/* Sizeof `struct reg' in <machine/reg.h>. */
+#define HPPANBSD_SIZEOF_GREGS (44 * 4)
+
+static int hppanbsd_reg_offset[] =
+{
+ /* r0 ... r31 */
+ -1, 1 * 4, 2 * 4, 3 * 4,
+ 4 * 4, 5 * 4, 6 * 4, 7 * 4,
+ 8 * 4, 9 * 4, 10 * 4, 11 * 4,
+ 12 * 4, 13 * 4, 14 * 4, 15 * 4,
+ 16 * 4, 17 * 4, 18 * 4, 19 * 4,
+ 20 * 4, 21 * 4, 22 * 4, 23 * 4,
+ 24 * 4, 25 * 4, 26 * 4, 27 * 4,
+ 28 * 4, 29 * 4, 30 * 4, 31 * 4,
+
+ 32 * 4, /* HPPA_SAR_REGNUM */
+ 35 * 4, /* HPPA_PCOQ_HEAD_REGNUM */
+ 33 * 4, /* HPPA_PCSQ_HEAD_REGNUM */
+ 36 * 4, /* HPPA_PCOQ_TAIL_REGNUM */
+ 34 * 4, /* HPPA_PCSQ_TAIL_REGNUM */
+ -1, /* HPPA_EIEM_REGNUM */
+ -1, /* HPPA_IIR_REGNUM */
+ -1, /* HPPA_ISR_REGNUM */
+ -1, /* HPPA_IOR_REGNUM */
+ 0 * 4, /* HPPA_IPSW_REGNUM */
+};
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+ in the general-purpose register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+hppanbsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ const gdb_byte *regs = (const gdb_byte *) gregs;
+ int i;
+
+ gdb_assert (len >= HPPANBSD_SIZEOF_GREGS);
+
+ for (i = 0; i < ARRAY_SIZE (hppanbsd_reg_offset); i++)
+ if (hppanbsd_reg_offset[i] != -1)
+ if (regnum == -1 || regnum == i)
+ regcache->raw_supply (i, regs + hppanbsd_reg_offset[i]);
+}
+
+/* NetBSD/hppa register set. */
+
+static const struct regset hppanbsd_gregset =
+{
+ NULL,
+ hppanbsd_supply_gregset
+};
+
+/* Iterate over supported core file register note sections. */
+
+static void
+hppanbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ cb (".reg", HPPANBSD_SIZEOF_GREGS, HPPANBSD_SIZEOF_GREGS, &hppanbsd_gregset,
+ NULL, cb_data);
+}
+\f
+static void
+hppanbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* Obviously NetBSD is BSD-based. */
+ hppabsd_init_abi (info, gdbarch);
+
+ nbsd_init_abi (info, gdbarch);
+
+ /* Core file support. */
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, hppanbsd_iterate_over_regset_sections);
+
+ tramp_frame_prepend_unwinder (gdbarch, &hppanbsd_sigtramp_si4);
+}
+
+void _initialize_hppanbsd_tdep ();
+void
+_initialize_hppanbsd_tdep ()
+{
+ gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_NETBSD,
+ hppanbsd_init_abi);
+}
+++ /dev/null
-/* Native-dependent code for NetBSD/i386.
-
- Copyright (C) 2004-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "target.h"
-
-#include "i386-tdep.h"
-#include "i386-bsd-nat.h"
-
-/* Support for debugging kernel virtual memory images. */
-
-#include <sys/types.h>
-#include <machine/frame.h>
-#include <machine/pcb.h>
-
-#include "nbsd-nat.h"
-#include "bsd-kvm.h"
-
-static int
-i386nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- struct switchframe sf;
-
- /* The following is true for NetBSD 1.6.2:
-
- The pcb contains %esp and %ebp at the point of the context switch
- in cpu_switch(). At that point we have a stack frame as
- described by `struct switchframe', which for NetBSD 1.6.2 has the
- following layout:
-
- interrupt level
- %edi
- %esi
- %ebx
- %eip
-
- we reconstruct the register state as it would look when we just
- returned from cpu_switch(). */
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_esp == 0)
- return 0;
-
- read_memory (pcb->pcb_esp, (gdb_byte *)&sf, sizeof sf);
- pcb->pcb_esp += sizeof (struct switchframe);
- regcache->raw_supply (I386_EDI_REGNUM, &sf.sf_edi);
- regcache->raw_supply (I386_ESI_REGNUM, &sf.sf_esi);
- regcache->raw_supply (I386_EBP_REGNUM, &pcb->pcb_ebp);
- regcache->raw_supply (I386_ESP_REGNUM, &pcb->pcb_esp);
- regcache->raw_supply (I386_EBX_REGNUM, &sf.sf_ebx);
- regcache->raw_supply (I386_EIP_REGNUM, &sf.sf_eip);
-
- return 1;
-}
-
-static i386_bsd_nat_target<nbsd_nat_target> the_i386_nbsd_nat_target;
-
-void _initialize_i386nbsd_nat ();
-void
-_initialize_i386nbsd_nat ()
-{
- add_inf_child_target (&the_i386_nbsd_nat_target);
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (i386nbsd_supply_pcb);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/i386.
-
- Copyright (C) 1988-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "arch-utils.h"
-#include "frame.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "regset.h"
-#include "osabi.h"
-#include "symtab.h"
-#include "trad-frame.h"
-#include "tramp-frame.h"
-
-#include "i386-tdep.h"
-#include "i387-tdep.h"
-#include "nbsd-tdep.h"
-#include "solib-svr4.h"
-
-/* From <machine/reg.h>. */
-static int i386nbsd_r_reg_offset[] =
-{
- 0 * 4, /* %eax */
- 1 * 4, /* %ecx */
- 2 * 4, /* %edx */
- 3 * 4, /* %ebx */
- 4 * 4, /* %esp */
- 5 * 4, /* %ebp */
- 6 * 4, /* %esi */
- 7 * 4, /* %edi */
- 8 * 4, /* %eip */
- 9 * 4, /* %eflags */
- 10 * 4, /* %cs */
- 11 * 4, /* %ss */
- 12 * 4, /* %ds */
- 13 * 4, /* %es */
- 14 * 4, /* %fs */
- 15 * 4 /* %gs */
-};
-
-/* From <machine/signal.h>. */
-static int i386nbsd_sc_reg_offset[] =
-{
- 10 * 4, /* %eax */
- 9 * 4, /* %ecx */
- 8 * 4, /* %edx */
- 7 * 4, /* %ebx */
- 14 * 4, /* %esp */
- 6 * 4, /* %ebp */
- 5 * 4, /* %esi */
- 4 * 4, /* %edi */
- 11 * 4, /* %eip */
- 13 * 4, /* %eflags */
- 12 * 4, /* %cs */
- 15 * 4, /* %ss */
- 3 * 4, /* %ds */
- 2 * 4, /* %es */
- 1 * 4, /* %fs */
- 0 * 4 /* %gs */
-};
-
-/* From <machine/mcontext.h>. */
-int i386nbsd_mc_reg_offset[] =
-{
- 11 * 4, /* %eax */
- 10 * 4, /* %ecx */
- 9 * 4, /* %edx */
- 8 * 4, /* %ebx */
- 7 * 4, /* %esp */
- 6 * 4, /* %ebp */
- 5 * 4, /* %esi */
- 4 * 4, /* %edi */
- 14 * 4, /* %eip */
- 16 * 4, /* %eflags */
- 15 * 4, /* %cs */
- 18 * 4, /* %ss */
- 3 * 4, /* %ds */
- 2 * 4, /* %es */
- 1 * 4, /* %fs */
- 0 * 4 /* %gs */
-};
-
-static void i386nbsd_sigtramp_cache_init (const struct tramp_frame *,
- struct frame_info *,
- struct trad_frame_cache *,
- CORE_ADDR);
-
-static const struct tramp_frame i386nbsd_sigtramp_sc16 =
-{
- SIGTRAMP_FRAME,
- 1,
- {
- /* leal 0x10(%esp), %eax */
- { 0x8d, ULONGEST_MAX },
- { 0x44, ULONGEST_MAX },
- { 0x24, ULONGEST_MAX },
- { 0x10, ULONGEST_MAX },
-
- /* pushl %eax */
- { 0x50, ULONGEST_MAX },
-
- /* pushl %eax */
- { 0x50, ULONGEST_MAX },
-
- /* movl $0x127, %eax # __sigreturn14 */
- { 0xb8, ULONGEST_MAX },
- { 0x27, ULONGEST_MAX },
- {0x01, ULONGEST_MAX },
- {0x00, ULONGEST_MAX },
- {0x00, ULONGEST_MAX },
-
- /* int $0x80 */
- { 0xcd, ULONGEST_MAX },
- { 0x80, ULONGEST_MAX},
-
- /* movl $0x1, %eax # exit */
- { 0xb8, ULONGEST_MAX },
- { 0x01, ULONGEST_MAX },
- {0x00, ULONGEST_MAX },
- {0x00, ULONGEST_MAX },
- {0x00, ULONGEST_MAX },
-
- /* int $0x80 */
- { 0xcd, ULONGEST_MAX },
- { 0x80, ULONGEST_MAX},
-
- { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
- },
- i386nbsd_sigtramp_cache_init
-};
-
-static const struct tramp_frame i386nbsd_sigtramp_sc2 =
-{
- SIGTRAMP_FRAME,
- 1,
- {
- /* leal 0x0c(%esp), %eax */
- { 0x8d, ULONGEST_MAX },
- { 0x44, ULONGEST_MAX },
- { 0x24, ULONGEST_MAX },
- { 0x0c, ULONGEST_MAX },
- /* movl %eax, 0x4(%esp) */
- { 0x89, ULONGEST_MAX },
- { 0x44, ULONGEST_MAX },
- { 0x24, ULONGEST_MAX },
- { 0x04, ULONGEST_MAX },
- /* movl $0x127, %eax # __sigreturn14 */
- { 0xb8, ULONGEST_MAX },
- { 0x27, ULONGEST_MAX },
- {0x01, ULONGEST_MAX },
- {0x00, ULONGEST_MAX },
- {0x00, ULONGEST_MAX },
- /* int $0x80 */
- { 0xcd, ULONGEST_MAX },
- { 0x80, ULONGEST_MAX},
- /* movl %eax, 0x4(%esp) */
- { 0x89, ULONGEST_MAX },
- { 0x44, ULONGEST_MAX },
- { 0x24, ULONGEST_MAX },
- { 0x04, ULONGEST_MAX },
- /* movl $0x1, %eax */
- { 0xb8, ULONGEST_MAX },
- { 0x01, ULONGEST_MAX },
- {0x00, ULONGEST_MAX },
- {0x00, ULONGEST_MAX },
- {0x00, ULONGEST_MAX },
- /* int $0x80 */
- { 0xcd, ULONGEST_MAX },
- { 0x80, ULONGEST_MAX},
- { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
- },
- i386nbsd_sigtramp_cache_init
-};
-
-static const struct tramp_frame i386nbsd_sigtramp_si2 =
-{
- SIGTRAMP_FRAME,
- 1,
- {
- /* movl 8(%esp),%eax */
- { 0x8b, ULONGEST_MAX },
- { 0x44, ULONGEST_MAX },
- { 0x24, ULONGEST_MAX },
- { 0x08, ULONGEST_MAX },
- /* movl %eax, 0x4(%esp) */
- { 0x89, ULONGEST_MAX },
- { 0x44, ULONGEST_MAX },
- { 0x24, ULONGEST_MAX },
- { 0x04, ULONGEST_MAX },
- /* movl $0x134, %eax # setcontext */
- { 0xb8, ULONGEST_MAX },
- { 0x34, ULONGEST_MAX },
- { 0x01, ULONGEST_MAX },
- { 0x00, ULONGEST_MAX },
- { 0x00, ULONGEST_MAX },
- /* int $0x80 */
- { 0xcd, ULONGEST_MAX },
- { 0x80, ULONGEST_MAX },
- /* movl %eax, 0x4(%esp) */
- { 0x89, ULONGEST_MAX },
- { 0x44, ULONGEST_MAX },
- { 0x24, ULONGEST_MAX },
- { 0x04, ULONGEST_MAX },
- /* movl $0x1, %eax */
- { 0xb8, ULONGEST_MAX },
- { 0x01, ULONGEST_MAX },
- { 0x00, ULONGEST_MAX },
- { 0x00, ULONGEST_MAX },
- { 0x00, ULONGEST_MAX },
- /* int $0x80 */
- { 0xcd, ULONGEST_MAX },
- { 0x80, ULONGEST_MAX },
- { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
- },
- i386nbsd_sigtramp_cache_init
-};
-
-static const struct tramp_frame i386nbsd_sigtramp_si31 =
-{
- SIGTRAMP_FRAME,
- 1,
- {
- /* leal 0x8c(%esp), %eax */
- { 0x8d, ULONGEST_MAX },
- { 0x84, ULONGEST_MAX },
- { 0x24, ULONGEST_MAX },
- { 0x8c, ULONGEST_MAX },
- { 0x00, ULONGEST_MAX },
- { 0x00, ULONGEST_MAX },
- { 0x00, ULONGEST_MAX },
- /* movl %eax, 0x4(%esp) */
- { 0x89, ULONGEST_MAX },
- { 0x44, ULONGEST_MAX },
- { 0x24, ULONGEST_MAX },
- { 0x04, ULONGEST_MAX },
- /* movl $0x134, %eax # setcontext */
- { 0xb8, ULONGEST_MAX },
- { 0x34, ULONGEST_MAX },
- { 0x01, ULONGEST_MAX },
- { 0x00, ULONGEST_MAX },
- { 0x00, ULONGEST_MAX },
- /* int $0x80 */
- { 0xcd, ULONGEST_MAX },
- { 0x80, ULONGEST_MAX},
- /* movl %eax, 0x4(%esp) */
- { 0x89, ULONGEST_MAX },
- { 0x44, ULONGEST_MAX },
- { 0x24, ULONGEST_MAX },
- { 0x04, ULONGEST_MAX },
- /* movl $0x1, %eax */
- { 0xb8, ULONGEST_MAX },
- { 0x01, ULONGEST_MAX },
- {0x00, ULONGEST_MAX },
- {0x00, ULONGEST_MAX },
- {0x00, ULONGEST_MAX },
- /* int $0x80 */
- { 0xcd, ULONGEST_MAX },
- { 0x80, ULONGEST_MAX},
- { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
- },
- i386nbsd_sigtramp_cache_init
-};
-
-static const struct tramp_frame i386nbsd_sigtramp_si4 =
-{
- SIGTRAMP_FRAME,
- 1,
- {
- /* leal 0x8c(%esp), %eax */
- { 0x8d, ULONGEST_MAX },
- { 0x84, ULONGEST_MAX },
- { 0x24, ULONGEST_MAX },
- { 0x8c, ULONGEST_MAX },
- { 0x00, ULONGEST_MAX },
- { 0x00, ULONGEST_MAX },
- { 0x00, ULONGEST_MAX },
- /* movl %eax, 0x4(%esp) */
- { 0x89, ULONGEST_MAX },
- { 0x44, ULONGEST_MAX },
- { 0x24, ULONGEST_MAX },
- { 0x04, ULONGEST_MAX },
- /* movl $0x134, %eax # setcontext */
- { 0xb8, ULONGEST_MAX },
- { 0x34, ULONGEST_MAX },
- { 0x01, ULONGEST_MAX },
- { 0x00, ULONGEST_MAX },
- { 0x00, ULONGEST_MAX },
- /* int $0x80 */
- { 0xcd, ULONGEST_MAX },
- { 0x80, ULONGEST_MAX},
- /* movl $0xffffffff,0x4(%esp) */
- { 0xc7, ULONGEST_MAX },
- { 0x44, ULONGEST_MAX },
- { 0x24, ULONGEST_MAX },
- { 0x04, ULONGEST_MAX },
- { 0xff, ULONGEST_MAX },
- { 0xff, ULONGEST_MAX },
- { 0xff, ULONGEST_MAX },
- { 0xff, ULONGEST_MAX },
- /* movl $0x1, %eax */
- { 0xb8, ULONGEST_MAX },
- { 0x01, ULONGEST_MAX },
- {0x00, ULONGEST_MAX },
- {0x00, ULONGEST_MAX },
- {0x00, ULONGEST_MAX },
- /* int $0x80 */
- { 0xcd, ULONGEST_MAX },
- { 0x80, ULONGEST_MAX},
- { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
- },
- i386nbsd_sigtramp_cache_init
-};
-
-static void
-i386nbsd_sigtramp_cache_init (const struct tramp_frame *self,
- struct frame_info *this_frame,
- struct trad_frame_cache *this_cache,
- CORE_ADDR func)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM);
- CORE_ADDR base;
- int *reg_offset;
- int num_regs;
- int i;
-
- if (self == &i386nbsd_sigtramp_sc16 || self == &i386nbsd_sigtramp_sc2)
- {
- reg_offset = i386nbsd_sc_reg_offset;
- num_regs = ARRAY_SIZE (i386nbsd_sc_reg_offset);
-
- /* Read in the sigcontext address. */
- base = read_memory_unsigned_integer (sp + 8, 4, byte_order);
- }
- else
- {
- reg_offset = i386nbsd_mc_reg_offset;
- num_regs = ARRAY_SIZE (i386nbsd_mc_reg_offset);
-
- /* Read in the ucontext address. */
- base = read_memory_unsigned_integer (sp + 8, 4, byte_order);
- /* offsetof(ucontext_t, uc_mcontext) == 36 */
- base += 36;
- }
-
- for (i = 0; i < num_regs; i++)
- if (reg_offset[i] != -1)
- trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]);
-
- /* Construct the frame ID using the function start. */
- trad_frame_set_id (this_cache, frame_id_build (sp, func));
-}
-\f
-
-static void
-i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* Obviously NetBSD is BSD-based. */
- i386bsd_init_abi (info, gdbarch);
-
- nbsd_init_abi (info, gdbarch);
-
- /* NetBSD has a different `struct reg'. */
- tdep->gregset_reg_offset = i386nbsd_r_reg_offset;
- tdep->gregset_num_regs = ARRAY_SIZE (i386nbsd_r_reg_offset);
- tdep->sizeof_gregset = 16 * 4;
-
- /* NetBSD uses -freg-struct-return by default. */
- tdep->struct_return = reg_struct_return;
-
- /* NetBSD uses tramp_frame sniffers for signal trampolines. */
- tdep->sigcontext_addr= 0;
- tdep->sigtramp_start = 0;
- tdep->sigtramp_end = 0;
- tdep->sigtramp_p = 0;
- tdep->sc_reg_offset = 0;
- tdep->sc_num_regs = 0;
-
- tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_sc16);
- tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_sc2);
- tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si2);
- tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si31);
- tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si4);
-}
-
-/* NetBSD ELF. */
-
-static void
-i386nbsdelf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* It's still NetBSD. */
- i386nbsd_init_abi (info, gdbarch);
-
- /* But ELF-based. */
- i386_elf_init_abi (info, gdbarch);
-
- /* NetBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-
- /* NetBSD ELF uses -fpcc-struct-return by default. */
- tdep->struct_return = pcc_struct_return;
-}
-
-void _initialize_i386nbsd_tdep ();
-void
-_initialize_i386nbsd_tdep ()
-{
- gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_NETBSD,
- i386nbsdelf_init_abi);
-}
--- /dev/null
+/* Native-dependent code for NetBSD/i386.
+
+ Copyright (C) 2004-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "target.h"
+
+#include "i386-tdep.h"
+#include "i386-bsd-nat.h"
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <sys/types.h>
+#include <machine/frame.h>
+#include <machine/pcb.h>
+
+#include "netbsd-nat.h"
+#include "bsd-kvm.h"
+
+static int
+i386nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ struct switchframe sf;
+
+ /* The following is true for NetBSD 1.6.2:
+
+ The pcb contains %esp and %ebp at the point of the context switch
+ in cpu_switch(). At that point we have a stack frame as
+ described by `struct switchframe', which for NetBSD 1.6.2 has the
+ following layout:
+
+ interrupt level
+ %edi
+ %esi
+ %ebx
+ %eip
+
+ we reconstruct the register state as it would look when we just
+ returned from cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_esp == 0)
+ return 0;
+
+ read_memory (pcb->pcb_esp, (gdb_byte *)&sf, sizeof sf);
+ pcb->pcb_esp += sizeof (struct switchframe);
+ regcache->raw_supply (I386_EDI_REGNUM, &sf.sf_edi);
+ regcache->raw_supply (I386_ESI_REGNUM, &sf.sf_esi);
+ regcache->raw_supply (I386_EBP_REGNUM, &pcb->pcb_ebp);
+ regcache->raw_supply (I386_ESP_REGNUM, &pcb->pcb_esp);
+ regcache->raw_supply (I386_EBX_REGNUM, &sf.sf_ebx);
+ regcache->raw_supply (I386_EIP_REGNUM, &sf.sf_eip);
+
+ return 1;
+}
+
+static i386_bsd_nat_target<nbsd_nat_target> the_i386_nbsd_nat_target;
+
+void _initialize_i386nbsd_nat ();
+void
+_initialize_i386nbsd_nat ()
+{
+ add_inf_child_target (&the_i386_nbsd_nat_target);
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (i386nbsd_supply_pcb);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/i386.
+
+ Copyright (C) 1988-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "frame.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "regset.h"
+#include "osabi.h"
+#include "symtab.h"
+#include "trad-frame.h"
+#include "tramp-frame.h"
+
+#include "i386-tdep.h"
+#include "i387-tdep.h"
+#include "netbsd-tdep.h"
+#include "solib-svr4.h"
+
+/* From <machine/reg.h>. */
+static int i386nbsd_r_reg_offset[] =
+{
+ 0 * 4, /* %eax */
+ 1 * 4, /* %ecx */
+ 2 * 4, /* %edx */
+ 3 * 4, /* %ebx */
+ 4 * 4, /* %esp */
+ 5 * 4, /* %ebp */
+ 6 * 4, /* %esi */
+ 7 * 4, /* %edi */
+ 8 * 4, /* %eip */
+ 9 * 4, /* %eflags */
+ 10 * 4, /* %cs */
+ 11 * 4, /* %ss */
+ 12 * 4, /* %ds */
+ 13 * 4, /* %es */
+ 14 * 4, /* %fs */
+ 15 * 4 /* %gs */
+};
+
+/* From <machine/signal.h>. */
+static int i386nbsd_sc_reg_offset[] =
+{
+ 10 * 4, /* %eax */
+ 9 * 4, /* %ecx */
+ 8 * 4, /* %edx */
+ 7 * 4, /* %ebx */
+ 14 * 4, /* %esp */
+ 6 * 4, /* %ebp */
+ 5 * 4, /* %esi */
+ 4 * 4, /* %edi */
+ 11 * 4, /* %eip */
+ 13 * 4, /* %eflags */
+ 12 * 4, /* %cs */
+ 15 * 4, /* %ss */
+ 3 * 4, /* %ds */
+ 2 * 4, /* %es */
+ 1 * 4, /* %fs */
+ 0 * 4 /* %gs */
+};
+
+/* From <machine/mcontext.h>. */
+int i386nbsd_mc_reg_offset[] =
+{
+ 11 * 4, /* %eax */
+ 10 * 4, /* %ecx */
+ 9 * 4, /* %edx */
+ 8 * 4, /* %ebx */
+ 7 * 4, /* %esp */
+ 6 * 4, /* %ebp */
+ 5 * 4, /* %esi */
+ 4 * 4, /* %edi */
+ 14 * 4, /* %eip */
+ 16 * 4, /* %eflags */
+ 15 * 4, /* %cs */
+ 18 * 4, /* %ss */
+ 3 * 4, /* %ds */
+ 2 * 4, /* %es */
+ 1 * 4, /* %fs */
+ 0 * 4 /* %gs */
+};
+
+static void i386nbsd_sigtramp_cache_init (const struct tramp_frame *,
+ struct frame_info *,
+ struct trad_frame_cache *,
+ CORE_ADDR);
+
+static const struct tramp_frame i386nbsd_sigtramp_sc16 =
+{
+ SIGTRAMP_FRAME,
+ 1,
+ {
+ /* leal 0x10(%esp), %eax */
+ { 0x8d, ULONGEST_MAX },
+ { 0x44, ULONGEST_MAX },
+ { 0x24, ULONGEST_MAX },
+ { 0x10, ULONGEST_MAX },
+
+ /* pushl %eax */
+ { 0x50, ULONGEST_MAX },
+
+ /* pushl %eax */
+ { 0x50, ULONGEST_MAX },
+
+ /* movl $0x127, %eax # __sigreturn14 */
+ { 0xb8, ULONGEST_MAX },
+ { 0x27, ULONGEST_MAX },
+ {0x01, ULONGEST_MAX },
+ {0x00, ULONGEST_MAX },
+ {0x00, ULONGEST_MAX },
+
+ /* int $0x80 */
+ { 0xcd, ULONGEST_MAX },
+ { 0x80, ULONGEST_MAX},
+
+ /* movl $0x1, %eax # exit */
+ { 0xb8, ULONGEST_MAX },
+ { 0x01, ULONGEST_MAX },
+ {0x00, ULONGEST_MAX },
+ {0x00, ULONGEST_MAX },
+ {0x00, ULONGEST_MAX },
+
+ /* int $0x80 */
+ { 0xcd, ULONGEST_MAX },
+ { 0x80, ULONGEST_MAX},
+
+ { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
+ },
+ i386nbsd_sigtramp_cache_init
+};
+
+static const struct tramp_frame i386nbsd_sigtramp_sc2 =
+{
+ SIGTRAMP_FRAME,
+ 1,
+ {
+ /* leal 0x0c(%esp), %eax */
+ { 0x8d, ULONGEST_MAX },
+ { 0x44, ULONGEST_MAX },
+ { 0x24, ULONGEST_MAX },
+ { 0x0c, ULONGEST_MAX },
+ /* movl %eax, 0x4(%esp) */
+ { 0x89, ULONGEST_MAX },
+ { 0x44, ULONGEST_MAX },
+ { 0x24, ULONGEST_MAX },
+ { 0x04, ULONGEST_MAX },
+ /* movl $0x127, %eax # __sigreturn14 */
+ { 0xb8, ULONGEST_MAX },
+ { 0x27, ULONGEST_MAX },
+ {0x01, ULONGEST_MAX },
+ {0x00, ULONGEST_MAX },
+ {0x00, ULONGEST_MAX },
+ /* int $0x80 */
+ { 0xcd, ULONGEST_MAX },
+ { 0x80, ULONGEST_MAX},
+ /* movl %eax, 0x4(%esp) */
+ { 0x89, ULONGEST_MAX },
+ { 0x44, ULONGEST_MAX },
+ { 0x24, ULONGEST_MAX },
+ { 0x04, ULONGEST_MAX },
+ /* movl $0x1, %eax */
+ { 0xb8, ULONGEST_MAX },
+ { 0x01, ULONGEST_MAX },
+ {0x00, ULONGEST_MAX },
+ {0x00, ULONGEST_MAX },
+ {0x00, ULONGEST_MAX },
+ /* int $0x80 */
+ { 0xcd, ULONGEST_MAX },
+ { 0x80, ULONGEST_MAX},
+ { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
+ },
+ i386nbsd_sigtramp_cache_init
+};
+
+static const struct tramp_frame i386nbsd_sigtramp_si2 =
+{
+ SIGTRAMP_FRAME,
+ 1,
+ {
+ /* movl 8(%esp),%eax */
+ { 0x8b, ULONGEST_MAX },
+ { 0x44, ULONGEST_MAX },
+ { 0x24, ULONGEST_MAX },
+ { 0x08, ULONGEST_MAX },
+ /* movl %eax, 0x4(%esp) */
+ { 0x89, ULONGEST_MAX },
+ { 0x44, ULONGEST_MAX },
+ { 0x24, ULONGEST_MAX },
+ { 0x04, ULONGEST_MAX },
+ /* movl $0x134, %eax # setcontext */
+ { 0xb8, ULONGEST_MAX },
+ { 0x34, ULONGEST_MAX },
+ { 0x01, ULONGEST_MAX },
+ { 0x00, ULONGEST_MAX },
+ { 0x00, ULONGEST_MAX },
+ /* int $0x80 */
+ { 0xcd, ULONGEST_MAX },
+ { 0x80, ULONGEST_MAX },
+ /* movl %eax, 0x4(%esp) */
+ { 0x89, ULONGEST_MAX },
+ { 0x44, ULONGEST_MAX },
+ { 0x24, ULONGEST_MAX },
+ { 0x04, ULONGEST_MAX },
+ /* movl $0x1, %eax */
+ { 0xb8, ULONGEST_MAX },
+ { 0x01, ULONGEST_MAX },
+ { 0x00, ULONGEST_MAX },
+ { 0x00, ULONGEST_MAX },
+ { 0x00, ULONGEST_MAX },
+ /* int $0x80 */
+ { 0xcd, ULONGEST_MAX },
+ { 0x80, ULONGEST_MAX },
+ { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
+ },
+ i386nbsd_sigtramp_cache_init
+};
+
+static const struct tramp_frame i386nbsd_sigtramp_si31 =
+{
+ SIGTRAMP_FRAME,
+ 1,
+ {
+ /* leal 0x8c(%esp), %eax */
+ { 0x8d, ULONGEST_MAX },
+ { 0x84, ULONGEST_MAX },
+ { 0x24, ULONGEST_MAX },
+ { 0x8c, ULONGEST_MAX },
+ { 0x00, ULONGEST_MAX },
+ { 0x00, ULONGEST_MAX },
+ { 0x00, ULONGEST_MAX },
+ /* movl %eax, 0x4(%esp) */
+ { 0x89, ULONGEST_MAX },
+ { 0x44, ULONGEST_MAX },
+ { 0x24, ULONGEST_MAX },
+ { 0x04, ULONGEST_MAX },
+ /* movl $0x134, %eax # setcontext */
+ { 0xb8, ULONGEST_MAX },
+ { 0x34, ULONGEST_MAX },
+ { 0x01, ULONGEST_MAX },
+ { 0x00, ULONGEST_MAX },
+ { 0x00, ULONGEST_MAX },
+ /* int $0x80 */
+ { 0xcd, ULONGEST_MAX },
+ { 0x80, ULONGEST_MAX},
+ /* movl %eax, 0x4(%esp) */
+ { 0x89, ULONGEST_MAX },
+ { 0x44, ULONGEST_MAX },
+ { 0x24, ULONGEST_MAX },
+ { 0x04, ULONGEST_MAX },
+ /* movl $0x1, %eax */
+ { 0xb8, ULONGEST_MAX },
+ { 0x01, ULONGEST_MAX },
+ {0x00, ULONGEST_MAX },
+ {0x00, ULONGEST_MAX },
+ {0x00, ULONGEST_MAX },
+ /* int $0x80 */
+ { 0xcd, ULONGEST_MAX },
+ { 0x80, ULONGEST_MAX},
+ { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
+ },
+ i386nbsd_sigtramp_cache_init
+};
+
+static const struct tramp_frame i386nbsd_sigtramp_si4 =
+{
+ SIGTRAMP_FRAME,
+ 1,
+ {
+ /* leal 0x8c(%esp), %eax */
+ { 0x8d, ULONGEST_MAX },
+ { 0x84, ULONGEST_MAX },
+ { 0x24, ULONGEST_MAX },
+ { 0x8c, ULONGEST_MAX },
+ { 0x00, ULONGEST_MAX },
+ { 0x00, ULONGEST_MAX },
+ { 0x00, ULONGEST_MAX },
+ /* movl %eax, 0x4(%esp) */
+ { 0x89, ULONGEST_MAX },
+ { 0x44, ULONGEST_MAX },
+ { 0x24, ULONGEST_MAX },
+ { 0x04, ULONGEST_MAX },
+ /* movl $0x134, %eax # setcontext */
+ { 0xb8, ULONGEST_MAX },
+ { 0x34, ULONGEST_MAX },
+ { 0x01, ULONGEST_MAX },
+ { 0x00, ULONGEST_MAX },
+ { 0x00, ULONGEST_MAX },
+ /* int $0x80 */
+ { 0xcd, ULONGEST_MAX },
+ { 0x80, ULONGEST_MAX},
+ /* movl $0xffffffff,0x4(%esp) */
+ { 0xc7, ULONGEST_MAX },
+ { 0x44, ULONGEST_MAX },
+ { 0x24, ULONGEST_MAX },
+ { 0x04, ULONGEST_MAX },
+ { 0xff, ULONGEST_MAX },
+ { 0xff, ULONGEST_MAX },
+ { 0xff, ULONGEST_MAX },
+ { 0xff, ULONGEST_MAX },
+ /* movl $0x1, %eax */
+ { 0xb8, ULONGEST_MAX },
+ { 0x01, ULONGEST_MAX },
+ {0x00, ULONGEST_MAX },
+ {0x00, ULONGEST_MAX },
+ {0x00, ULONGEST_MAX },
+ /* int $0x80 */
+ { 0xcd, ULONGEST_MAX },
+ { 0x80, ULONGEST_MAX},
+ { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
+ },
+ i386nbsd_sigtramp_cache_init
+};
+
+static void
+i386nbsd_sigtramp_cache_init (const struct tramp_frame *self,
+ struct frame_info *this_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ CORE_ADDR sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM);
+ CORE_ADDR base;
+ int *reg_offset;
+ int num_regs;
+ int i;
+
+ if (self == &i386nbsd_sigtramp_sc16 || self == &i386nbsd_sigtramp_sc2)
+ {
+ reg_offset = i386nbsd_sc_reg_offset;
+ num_regs = ARRAY_SIZE (i386nbsd_sc_reg_offset);
+
+ /* Read in the sigcontext address. */
+ base = read_memory_unsigned_integer (sp + 8, 4, byte_order);
+ }
+ else
+ {
+ reg_offset = i386nbsd_mc_reg_offset;
+ num_regs = ARRAY_SIZE (i386nbsd_mc_reg_offset);
+
+ /* Read in the ucontext address. */
+ base = read_memory_unsigned_integer (sp + 8, 4, byte_order);
+ /* offsetof(ucontext_t, uc_mcontext) == 36 */
+ base += 36;
+ }
+
+ for (i = 0; i < num_regs; i++)
+ if (reg_offset[i] != -1)
+ trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]);
+
+ /* Construct the frame ID using the function start. */
+ trad_frame_set_id (this_cache, frame_id_build (sp, func));
+}
+\f
+
+static void
+i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* Obviously NetBSD is BSD-based. */
+ i386bsd_init_abi (info, gdbarch);
+
+ nbsd_init_abi (info, gdbarch);
+
+ /* NetBSD has a different `struct reg'. */
+ tdep->gregset_reg_offset = i386nbsd_r_reg_offset;
+ tdep->gregset_num_regs = ARRAY_SIZE (i386nbsd_r_reg_offset);
+ tdep->sizeof_gregset = 16 * 4;
+
+ /* NetBSD uses -freg-struct-return by default. */
+ tdep->struct_return = reg_struct_return;
+
+ /* NetBSD uses tramp_frame sniffers for signal trampolines. */
+ tdep->sigcontext_addr= 0;
+ tdep->sigtramp_start = 0;
+ tdep->sigtramp_end = 0;
+ tdep->sigtramp_p = 0;
+ tdep->sc_reg_offset = 0;
+ tdep->sc_num_regs = 0;
+
+ tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_sc16);
+ tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_sc2);
+ tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si2);
+ tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si31);
+ tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si4);
+}
+
+/* NetBSD ELF. */
+
+static void
+i386nbsdelf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* It's still NetBSD. */
+ i386nbsd_init_abi (info, gdbarch);
+
+ /* But ELF-based. */
+ i386_elf_init_abi (info, gdbarch);
+
+ /* NetBSD ELF uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+ /* NetBSD ELF uses -fpcc-struct-return by default. */
+ tdep->struct_return = pcc_struct_return;
+}
+
+void _initialize_i386nbsd_tdep ();
+void
+_initialize_i386nbsd_tdep ()
+{
+ gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_NETBSD,
+ i386nbsdelf_init_abi);
+}
#include "m68k-tdep.h"
#include "inf-ptrace.h"
-#include "nbsd-nat.h"
+#include "netbsd-nat.h"
struct m68k_bsd_nat_target final : public nbsd_nat_target
{
+++ /dev/null
-/* Native-dependent code for MIPS systems running NetBSD.
-
- Copyright (C) 2000-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-/* We define this to get types like register_t. */
-#define _KERNTYPES
-#include "defs.h"
-#include "inferior.h"
-#include "regcache.h"
-#include "target.h"
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-#include "mips-tdep.h"
-#include "mips-nbsd-tdep.h"
-#include "inf-ptrace.h"
-
-class mips_nbsd_nat_target final : public inf_ptrace_target
-{
- void fetch_registers (struct regcache *, int) override;
- void store_registers (struct regcache *, int) override;
-};
-
-static mips_nbsd_nat_target the_mips_nbsd_nat_target;
-
-/* Determine if PT_GETREGS fetches this register. */
-static int
-getregs_supplies (struct gdbarch *gdbarch, int regno)
-{
- return ((regno) >= MIPS_ZERO_REGNUM
- && (regno) <= gdbarch_pc_regnum (gdbarch));
-}
-
-void
-mips_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
-{
- pid_t pid = regcache->ptid ().pid ();
-
- struct gdbarch *gdbarch = regcache->arch ();
- if (regno == -1 || getregs_supplies (gdbarch, regno))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- mipsnbsd_supply_reg (regcache, (char *) ®s, regno);
- if (regno != -1)
- return;
- }
-
- if (regno == -1
- || regno >= gdbarch_fp0_regnum (regcache->arch ()))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- mipsnbsd_supply_fpreg (regcache, (char *) &fpregs, regno);
- }
-}
-
-void
-mips_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
-{
- pid_t pid = regcache->ptid ().pid ();
-
- struct gdbarch *gdbarch = regcache->arch ();
- if (regno == -1 || getregs_supplies (gdbarch, regno))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- mipsnbsd_fill_reg (regcache, (char *) ®s, regno);
-
- if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1)
- perror_with_name (_("Couldn't write registers"));
-
- if (regno != -1)
- return;
- }
-
- if (regno == -1
- || regno >= gdbarch_fp0_regnum (regcache->arch ()))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't get floating point status"));
-
- mipsnbsd_fill_fpreg (regcache, (char *) &fpregs, regno);
-
- if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
- perror_with_name (_("Couldn't write floating point status"));
- }
-}
-
-void _initialize_mipsnbsd_nat ();
-void
-_initialize_mipsnbsd_nat ()
-{
- add_inf_child_target (&the_mips_nbsd_nat_target);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/mips.
-
- Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "regset.h"
-#include "target.h"
-#include "value.h"
-#include "osabi.h"
-
-#include "nbsd-tdep.h"
-#include "mips-nbsd-tdep.h"
-#include "mips-tdep.h"
-
-#include "solib-svr4.h"
-
-/* Shorthand for some register numbers used below. */
-#define MIPS_PC_REGNUM MIPS_EMBED_PC_REGNUM
-#define MIPS_FP0_REGNUM MIPS_EMBED_FP0_REGNUM
-#define MIPS_FSR_REGNUM MIPS_EMBED_FP0_REGNUM + 32
-
-/* Core file support. */
-
-/* Number of registers in `struct reg' from <machine/reg.h>. */
-#define MIPSNBSD_NUM_GREGS 38
-
-/* Number of registers in `struct fpreg' from <machine/reg.h>. */
-#define MIPSNBSD_NUM_FPREGS 33
-
-/* Supply register REGNUM from the buffer specified by FPREGS and LEN
- in the floating-point register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-mipsnbsd_supply_fpregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *fpregs, size_t len)
-{
- size_t regsize = mips_isa_regsize (regcache->arch ());
- const char *regs = (const char *) fpregs;
- int i;
-
- gdb_assert (len >= MIPSNBSD_NUM_FPREGS * regsize);
-
- for (i = MIPS_FP0_REGNUM; i <= MIPS_FSR_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- regcache->raw_supply (i, regs + (i - MIPS_FP0_REGNUM) * regsize);
- }
-}
-
-/* Supply register REGNUM from the buffer specified by GREGS and LEN
- in the general-purpose register set REGSET to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-static void
-mipsnbsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache, int regnum,
- const void *gregs, size_t len)
-{
- size_t regsize = mips_isa_regsize (regcache->arch ());
- const char *regs = (const char *) gregs;
- int i;
-
- gdb_assert (len >= MIPSNBSD_NUM_GREGS * regsize);
-
- for (i = 0; i <= MIPS_PC_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- regcache->raw_supply (i, regs + i * regsize);
- }
-
- if (len >= (MIPSNBSD_NUM_GREGS + MIPSNBSD_NUM_FPREGS) * regsize)
- {
- regs += MIPSNBSD_NUM_GREGS * regsize;
- len -= MIPSNBSD_NUM_GREGS * regsize;
- mipsnbsd_supply_fpregset (regset, regcache, regnum, regs, len);
- }
-}
-
-/* NetBSD/mips register sets. */
-
-static const struct regset mipsnbsd_gregset =
-{
- NULL,
- mipsnbsd_supply_gregset,
- NULL,
- REGSET_VARIABLE_SIZE
-};
-
-static const struct regset mipsnbsd_fpregset =
-{
- NULL,
- mipsnbsd_supply_fpregset
-};
-
-/* Iterate over core file register note sections. */
-
-static void
-mipsnbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- size_t regsize = mips_isa_regsize (gdbarch);
-
- cb (".reg", MIPSNBSD_NUM_GREGS * regsize, MIPSNBSD_NUM_GREGS * regsize,
- &mipsnbsd_gregset, NULL, cb_data);
- cb (".reg2", MIPSNBSD_NUM_FPREGS * regsize, MIPSNBSD_NUM_FPREGS * regsize,
- &mipsnbsd_fpregset, NULL, cb_data);
-}
-\f
-
-/* Conveniently, GDB uses the same register numbering as the
- ptrace register structure used by NetBSD/mips. */
-
-void
-mipsnbsd_supply_reg (struct regcache *regcache, const char *regs, int regno)
-{
- struct gdbarch *gdbarch = regcache->arch ();
- int i;
-
- for (i = 0; i <= gdbarch_pc_regnum (gdbarch); i++)
- {
- if (regno == i || regno == -1)
- {
- if (gdbarch_cannot_fetch_register (gdbarch, i))
- regcache->raw_supply (i, NULL);
- else
- regcache->raw_supply
- (i, regs + (i * mips_isa_regsize (gdbarch)));
- }
- }
-}
-
-void
-mipsnbsd_fill_reg (const struct regcache *regcache, char *regs, int regno)
-{
- struct gdbarch *gdbarch = regcache->arch ();
- int i;
-
- for (i = 0; i <= gdbarch_pc_regnum (gdbarch); i++)
- if ((regno == i || regno == -1)
- && ! gdbarch_cannot_store_register (gdbarch, i))
- regcache->raw_collect (i, regs + (i * mips_isa_regsize (gdbarch)));
-}
-
-void
-mipsnbsd_supply_fpreg (struct regcache *regcache,
- const char *fpregs, int regno)
-{
- struct gdbarch *gdbarch = regcache->arch ();
- int i;
-
- for (i = gdbarch_fp0_regnum (gdbarch);
- i <= mips_regnum (gdbarch)->fp_implementation_revision;
- i++)
- {
- if (regno == i || regno == -1)
- {
- if (gdbarch_cannot_fetch_register (gdbarch, i))
- regcache->raw_supply (i, NULL);
- else
- regcache->raw_supply (i,
- fpregs
- + ((i - gdbarch_fp0_regnum (gdbarch))
- * mips_isa_regsize (gdbarch)));
- }
- }
-}
-
-void
-mipsnbsd_fill_fpreg (const struct regcache *regcache, char *fpregs, int regno)
-{
- struct gdbarch *gdbarch = regcache->arch ();
- int i;
-
- for (i = gdbarch_fp0_regnum (gdbarch);
- i <= mips_regnum (gdbarch)->fp_control_status;
- i++)
- if ((regno == i || regno == -1)
- && ! gdbarch_cannot_store_register (gdbarch, i))
- regcache->raw_collect
- (i, (fpregs + ((i - gdbarch_fp0_regnum (gdbarch))
- * mips_isa_regsize (gdbarch))));
-}
-
-#if 0
-
-/* Under NetBSD/mips, signal handler invocations can be identified by the
- designated code sequence that is used to return from a signal handler.
- In particular, the return address of a signal handler points to the
- following code sequence:
-
- addu a0, sp, 16
- li v0, 295 # __sigreturn14
- syscall
-
- Each instruction has a unique encoding, so we simply attempt to match
- the instruction the PC is pointing to with any of the above instructions.
- If there is a hit, we know the offset to the start of the designated
- sequence and can then check whether we really are executing in the
- signal trampoline. If not, -1 is returned, otherwise the offset from the
- start of the return sequence is returned. */
-
-#define RETCODE_NWORDS 3
-#define RETCODE_SIZE (RETCODE_NWORDS * 4)
-
-static const unsigned char sigtramp_retcode_mipsel[RETCODE_SIZE] =
-{
- 0x10, 0x00, 0xa4, 0x27, /* addu a0, sp, 16 */
- 0x27, 0x01, 0x02, 0x24, /* li v0, 295 */
- 0x0c, 0x00, 0x00, 0x00, /* syscall */
-};
-
-static const unsigned char sigtramp_retcode_mipseb[RETCODE_SIZE] =
-{
- 0x27, 0xa4, 0x00, 0x10, /* addu a0, sp, 16 */
- 0x24, 0x02, 0x01, 0x27, /* li v0, 295 */
- 0x00, 0x00, 0x00, 0x0c, /* syscall */
-};
-
-#endif
-
-/* Figure out where the longjmp will land. We expect that we have
- just entered longjmp and haven't yet setup the stack frame, so the
- args are still in the argument regs. MIPS_A0_REGNUM points at the
- jmp_buf structure from which we extract the PC that we will land
- at. The PC is copied into *pc. This routine returns true on
- success. */
-
-#define NBSD_MIPS_JB_PC (2 * 4)
-#define NBSD_MIPS_JB_ELEMENT_SIZE(gdbarch) mips_isa_regsize (gdbarch)
-#define NBSD_MIPS_JB_OFFSET(gdbarch) (NBSD_MIPS_JB_PC * \
- NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch))
-
-static int
-mipsnbsd_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
-{
- struct gdbarch *gdbarch = get_frame_arch (frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR jb_addr;
- gdb_byte *buf;
-
- buf = (gdb_byte *) alloca (NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch));
-
- jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM);
-
- if (target_read_memory (jb_addr + NBSD_MIPS_JB_OFFSET (gdbarch), buf,
- NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch)))
- return 0;
-
- *pc = extract_unsigned_integer (buf, NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch),
- byte_order);
- return 1;
-}
-
-static int
-mipsnbsd_cannot_fetch_register (struct gdbarch *gdbarch, int regno)
-{
- return (regno == MIPS_ZERO_REGNUM
- || regno == mips_regnum (gdbarch)->fp_implementation_revision);
-}
-
-static int
-mipsnbsd_cannot_store_register (struct gdbarch *gdbarch, int regno)
-{
- return (regno == MIPS_ZERO_REGNUM
- || regno == mips_regnum (gdbarch)->fp_implementation_revision);
-}
-
-/* Shared library support. */
-
-/* NetBSD/mips uses a slightly different `struct link_map' than the
- other NetBSD platforms. */
-
-static struct link_map_offsets *
-mipsnbsd_ilp32_fetch_link_map_offsets (void)
-{
- static struct link_map_offsets lmo;
- static struct link_map_offsets *lmp = NULL;
-
- if (lmp == NULL)
- {
- lmp = &lmo;
-
- lmo.r_version_offset = 0;
- lmo.r_version_size = 4;
- lmo.r_map_offset = 4;
- lmo.r_brk_offset = 8;
- lmo.r_ldsomap_offset = -1;
-
- /* Everything we need is in the first 24 bytes. */
- lmo.link_map_size = 24;
- lmo.l_addr_offset = 4;
- lmo.l_name_offset = 8;
- lmo.l_ld_offset = 12;
- lmo.l_next_offset = 16;
- lmo.l_prev_offset = 20;
- }
-
- return lmp;
-}
-
-static struct link_map_offsets *
-mipsnbsd_lp64_fetch_link_map_offsets (void)
-{
- static struct link_map_offsets lmo;
- static struct link_map_offsets *lmp = NULL;
-
- if (lmp == NULL)
- {
- lmp = &lmo;
-
- lmo.r_version_offset = 0;
- lmo.r_version_size = 4;
- lmo.r_map_offset = 8;
- lmo.r_brk_offset = 16;
- lmo.r_ldsomap_offset = -1;
-
- /* Everything we need is in the first 40 bytes. */
- lmo.link_map_size = 48;
- lmo.l_addr_offset = 0;
- lmo.l_name_offset = 16;
- lmo.l_ld_offset = 24;
- lmo.l_next_offset = 32;
- lmo.l_prev_offset = 40;
- }
-
- return lmp;
-}
-\f
-
-static void
-mipsnbsd_init_abi (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-{
- nbsd_init_abi (info, gdbarch);
-
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, mipsnbsd_iterate_over_regset_sections);
-
- set_gdbarch_get_longjmp_target (gdbarch, mipsnbsd_get_longjmp_target);
-
- set_gdbarch_cannot_fetch_register (gdbarch, mipsnbsd_cannot_fetch_register);
- set_gdbarch_cannot_store_register (gdbarch, mipsnbsd_cannot_store_register);
-
- set_gdbarch_software_single_step (gdbarch, mips_software_single_step);
-
- /* NetBSD/mips has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 ?
- mipsnbsd_ilp32_fetch_link_map_offsets :
- mipsnbsd_lp64_fetch_link_map_offsets));
-}
-
-void _initialize_mipsnbsd_tdep ();
-void
-_initialize_mipsnbsd_tdep ()
-{
- gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_NETBSD,
- mipsnbsd_init_abi);
-}
+++ /dev/null
-/* Common target dependent code for GDB on MIPS systems running NetBSD.
-
- Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#ifndef MIPS_NBSD_TDEP_H
-#define MIPS_NBSD_TDEP_H
-
-void mipsnbsd_supply_reg (struct regcache *, const char *, int);
-void mipsnbsd_fill_reg (const struct regcache *, char *, int);
-
-void mipsnbsd_supply_fpreg (struct regcache *, const char *, int);
-void mipsnbsd_fill_fpreg (const struct regcache *, char *, int);
-
-#endif /* MIPS_NBSD_TDEP_H */
--- /dev/null
+/* Native-dependent code for MIPS systems running NetBSD.
+
+ Copyright (C) 2000-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+/* We define this to get types like register_t. */
+#define _KERNTYPES
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "target.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "mips-tdep.h"
+#include "mips-netbsd-tdep.h"
+#include "inf-ptrace.h"
+
+class mips_nbsd_nat_target final : public inf_ptrace_target
+{
+ void fetch_registers (struct regcache *, int) override;
+ void store_registers (struct regcache *, int) override;
+};
+
+static mips_nbsd_nat_target the_mips_nbsd_nat_target;
+
+/* Determine if PT_GETREGS fetches this register. */
+static int
+getregs_supplies (struct gdbarch *gdbarch, int regno)
+{
+ return ((regno) >= MIPS_ZERO_REGNUM
+ && (regno) <= gdbarch_pc_regnum (gdbarch));
+}
+
+void
+mips_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
+{
+ pid_t pid = regcache->ptid ().pid ();
+
+ struct gdbarch *gdbarch = regcache->arch ();
+ if (regno == -1 || getregs_supplies (gdbarch, regno))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ mipsnbsd_supply_reg (regcache, (char *) ®s, regno);
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1
+ || regno >= gdbarch_fp0_regnum (regcache->arch ()))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ mipsnbsd_supply_fpreg (regcache, (char *) &fpregs, regno);
+ }
+}
+
+void
+mips_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
+{
+ pid_t pid = regcache->ptid ().pid ();
+
+ struct gdbarch *gdbarch = regcache->arch ();
+ if (regno == -1 || getregs_supplies (gdbarch, regno))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ mipsnbsd_fill_reg (regcache, (char *) ®s, regno);
+
+ if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't write registers"));
+
+ if (regno != -1)
+ return;
+ }
+
+ if (regno == -1
+ || regno >= gdbarch_fp0_regnum (regcache->arch ()))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
+
+ mipsnbsd_fill_fpreg (regcache, (char *) &fpregs, regno);
+
+ if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't write floating point status"));
+ }
+}
+
+void _initialize_mipsnbsd_nat ();
+void
+_initialize_mipsnbsd_nat ()
+{
+ add_inf_child_target (&the_mips_nbsd_nat_target);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/mips.
+
+ Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "regset.h"
+#include "target.h"
+#include "value.h"
+#include "osabi.h"
+
+#include "netbsd-tdep.h"
+#include "mips-netbsd-tdep.h"
+#include "mips-tdep.h"
+
+#include "solib-svr4.h"
+
+/* Shorthand for some register numbers used below. */
+#define MIPS_PC_REGNUM MIPS_EMBED_PC_REGNUM
+#define MIPS_FP0_REGNUM MIPS_EMBED_FP0_REGNUM
+#define MIPS_FSR_REGNUM MIPS_EMBED_FP0_REGNUM + 32
+
+/* Core file support. */
+
+/* Number of registers in `struct reg' from <machine/reg.h>. */
+#define MIPSNBSD_NUM_GREGS 38
+
+/* Number of registers in `struct fpreg' from <machine/reg.h>. */
+#define MIPSNBSD_NUM_FPREGS 33
+
+/* Supply register REGNUM from the buffer specified by FPREGS and LEN
+ in the floating-point register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+mipsnbsd_supply_fpregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *fpregs, size_t len)
+{
+ size_t regsize = mips_isa_regsize (regcache->arch ());
+ const char *regs = (const char *) fpregs;
+ int i;
+
+ gdb_assert (len >= MIPSNBSD_NUM_FPREGS * regsize);
+
+ for (i = MIPS_FP0_REGNUM; i <= MIPS_FSR_REGNUM; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache->raw_supply (i, regs + (i - MIPS_FP0_REGNUM) * regsize);
+ }
+}
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+ in the general-purpose register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+mipsnbsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache, int regnum,
+ const void *gregs, size_t len)
+{
+ size_t regsize = mips_isa_regsize (regcache->arch ());
+ const char *regs = (const char *) gregs;
+ int i;
+
+ gdb_assert (len >= MIPSNBSD_NUM_GREGS * regsize);
+
+ for (i = 0; i <= MIPS_PC_REGNUM; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache->raw_supply (i, regs + i * regsize);
+ }
+
+ if (len >= (MIPSNBSD_NUM_GREGS + MIPSNBSD_NUM_FPREGS) * regsize)
+ {
+ regs += MIPSNBSD_NUM_GREGS * regsize;
+ len -= MIPSNBSD_NUM_GREGS * regsize;
+ mipsnbsd_supply_fpregset (regset, regcache, regnum, regs, len);
+ }
+}
+
+/* NetBSD/mips register sets. */
+
+static const struct regset mipsnbsd_gregset =
+{
+ NULL,
+ mipsnbsd_supply_gregset,
+ NULL,
+ REGSET_VARIABLE_SIZE
+};
+
+static const struct regset mipsnbsd_fpregset =
+{
+ NULL,
+ mipsnbsd_supply_fpregset
+};
+
+/* Iterate over core file register note sections. */
+
+static void
+mipsnbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ size_t regsize = mips_isa_regsize (gdbarch);
+
+ cb (".reg", MIPSNBSD_NUM_GREGS * regsize, MIPSNBSD_NUM_GREGS * regsize,
+ &mipsnbsd_gregset, NULL, cb_data);
+ cb (".reg2", MIPSNBSD_NUM_FPREGS * regsize, MIPSNBSD_NUM_FPREGS * regsize,
+ &mipsnbsd_fpregset, NULL, cb_data);
+}
+\f
+
+/* Conveniently, GDB uses the same register numbering as the
+ ptrace register structure used by NetBSD/mips. */
+
+void
+mipsnbsd_supply_reg (struct regcache *regcache, const char *regs, int regno)
+{
+ struct gdbarch *gdbarch = regcache->arch ();
+ int i;
+
+ for (i = 0; i <= gdbarch_pc_regnum (gdbarch); i++)
+ {
+ if (regno == i || regno == -1)
+ {
+ if (gdbarch_cannot_fetch_register (gdbarch, i))
+ regcache->raw_supply (i, NULL);
+ else
+ regcache->raw_supply
+ (i, regs + (i * mips_isa_regsize (gdbarch)));
+ }
+ }
+}
+
+void
+mipsnbsd_fill_reg (const struct regcache *regcache, char *regs, int regno)
+{
+ struct gdbarch *gdbarch = regcache->arch ();
+ int i;
+
+ for (i = 0; i <= gdbarch_pc_regnum (gdbarch); i++)
+ if ((regno == i || regno == -1)
+ && ! gdbarch_cannot_store_register (gdbarch, i))
+ regcache->raw_collect (i, regs + (i * mips_isa_regsize (gdbarch)));
+}
+
+void
+mipsnbsd_supply_fpreg (struct regcache *regcache,
+ const char *fpregs, int regno)
+{
+ struct gdbarch *gdbarch = regcache->arch ();
+ int i;
+
+ for (i = gdbarch_fp0_regnum (gdbarch);
+ i <= mips_regnum (gdbarch)->fp_implementation_revision;
+ i++)
+ {
+ if (regno == i || regno == -1)
+ {
+ if (gdbarch_cannot_fetch_register (gdbarch, i))
+ regcache->raw_supply (i, NULL);
+ else
+ regcache->raw_supply (i,
+ fpregs
+ + ((i - gdbarch_fp0_regnum (gdbarch))
+ * mips_isa_regsize (gdbarch)));
+ }
+ }
+}
+
+void
+mipsnbsd_fill_fpreg (const struct regcache *regcache, char *fpregs, int regno)
+{
+ struct gdbarch *gdbarch = regcache->arch ();
+ int i;
+
+ for (i = gdbarch_fp0_regnum (gdbarch);
+ i <= mips_regnum (gdbarch)->fp_control_status;
+ i++)
+ if ((regno == i || regno == -1)
+ && ! gdbarch_cannot_store_register (gdbarch, i))
+ regcache->raw_collect
+ (i, (fpregs + ((i - gdbarch_fp0_regnum (gdbarch))
+ * mips_isa_regsize (gdbarch))));
+}
+
+#if 0
+
+/* Under NetBSD/mips, signal handler invocations can be identified by the
+ designated code sequence that is used to return from a signal handler.
+ In particular, the return address of a signal handler points to the
+ following code sequence:
+
+ addu a0, sp, 16
+ li v0, 295 # __sigreturn14
+ syscall
+
+ Each instruction has a unique encoding, so we simply attempt to match
+ the instruction the PC is pointing to with any of the above instructions.
+ If there is a hit, we know the offset to the start of the designated
+ sequence and can then check whether we really are executing in the
+ signal trampoline. If not, -1 is returned, otherwise the offset from the
+ start of the return sequence is returned. */
+
+#define RETCODE_NWORDS 3
+#define RETCODE_SIZE (RETCODE_NWORDS * 4)
+
+static const unsigned char sigtramp_retcode_mipsel[RETCODE_SIZE] =
+{
+ 0x10, 0x00, 0xa4, 0x27, /* addu a0, sp, 16 */
+ 0x27, 0x01, 0x02, 0x24, /* li v0, 295 */
+ 0x0c, 0x00, 0x00, 0x00, /* syscall */
+};
+
+static const unsigned char sigtramp_retcode_mipseb[RETCODE_SIZE] =
+{
+ 0x27, 0xa4, 0x00, 0x10, /* addu a0, sp, 16 */
+ 0x24, 0x02, 0x01, 0x27, /* li v0, 295 */
+ 0x00, 0x00, 0x00, 0x0c, /* syscall */
+};
+
+#endif
+
+/* Figure out where the longjmp will land. We expect that we have
+ just entered longjmp and haven't yet setup the stack frame, so the
+ args are still in the argument regs. MIPS_A0_REGNUM points at the
+ jmp_buf structure from which we extract the PC that we will land
+ at. The PC is copied into *pc. This routine returns true on
+ success. */
+
+#define NBSD_MIPS_JB_PC (2 * 4)
+#define NBSD_MIPS_JB_ELEMENT_SIZE(gdbarch) mips_isa_regsize (gdbarch)
+#define NBSD_MIPS_JB_OFFSET(gdbarch) (NBSD_MIPS_JB_PC * \
+ NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch))
+
+static int
+mipsnbsd_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ CORE_ADDR jb_addr;
+ gdb_byte *buf;
+
+ buf = (gdb_byte *) alloca (NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch));
+
+ jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM);
+
+ if (target_read_memory (jb_addr + NBSD_MIPS_JB_OFFSET (gdbarch), buf,
+ NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch)))
+ return 0;
+
+ *pc = extract_unsigned_integer (buf, NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch),
+ byte_order);
+ return 1;
+}
+
+static int
+mipsnbsd_cannot_fetch_register (struct gdbarch *gdbarch, int regno)
+{
+ return (regno == MIPS_ZERO_REGNUM
+ || regno == mips_regnum (gdbarch)->fp_implementation_revision);
+}
+
+static int
+mipsnbsd_cannot_store_register (struct gdbarch *gdbarch, int regno)
+{
+ return (regno == MIPS_ZERO_REGNUM
+ || regno == mips_regnum (gdbarch)->fp_implementation_revision);
+}
+
+/* Shared library support. */
+
+/* NetBSD/mips uses a slightly different `struct link_map' than the
+ other NetBSD platforms. */
+
+static struct link_map_offsets *
+mipsnbsd_ilp32_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = NULL;
+
+ if (lmp == NULL)
+ {
+ lmp = &lmo;
+
+ lmo.r_version_offset = 0;
+ lmo.r_version_size = 4;
+ lmo.r_map_offset = 4;
+ lmo.r_brk_offset = 8;
+ lmo.r_ldsomap_offset = -1;
+
+ /* Everything we need is in the first 24 bytes. */
+ lmo.link_map_size = 24;
+ lmo.l_addr_offset = 4;
+ lmo.l_name_offset = 8;
+ lmo.l_ld_offset = 12;
+ lmo.l_next_offset = 16;
+ lmo.l_prev_offset = 20;
+ }
+
+ return lmp;
+}
+
+static struct link_map_offsets *
+mipsnbsd_lp64_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = NULL;
+
+ if (lmp == NULL)
+ {
+ lmp = &lmo;
+
+ lmo.r_version_offset = 0;
+ lmo.r_version_size = 4;
+ lmo.r_map_offset = 8;
+ lmo.r_brk_offset = 16;
+ lmo.r_ldsomap_offset = -1;
+
+ /* Everything we need is in the first 40 bytes. */
+ lmo.link_map_size = 48;
+ lmo.l_addr_offset = 0;
+ lmo.l_name_offset = 16;
+ lmo.l_ld_offset = 24;
+ lmo.l_next_offset = 32;
+ lmo.l_prev_offset = 40;
+ }
+
+ return lmp;
+}
+\f
+
+static void
+mipsnbsd_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ nbsd_init_abi (info, gdbarch);
+
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, mipsnbsd_iterate_over_regset_sections);
+
+ set_gdbarch_get_longjmp_target (gdbarch, mipsnbsd_get_longjmp_target);
+
+ set_gdbarch_cannot_fetch_register (gdbarch, mipsnbsd_cannot_fetch_register);
+ set_gdbarch_cannot_store_register (gdbarch, mipsnbsd_cannot_store_register);
+
+ set_gdbarch_software_single_step (gdbarch, mips_software_single_step);
+
+ /* NetBSD/mips has SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 ?
+ mipsnbsd_ilp32_fetch_link_map_offsets :
+ mipsnbsd_lp64_fetch_link_map_offsets));
+}
+
+void _initialize_mipsnbsd_tdep ();
+void
+_initialize_mipsnbsd_tdep ()
+{
+ gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_NETBSD,
+ mipsnbsd_init_abi);
+}
--- /dev/null
+/* Common target dependent code for GDB on MIPS systems running NetBSD.
+
+ Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef MIPS_NBSD_TDEP_H
+#define MIPS_NBSD_TDEP_H
+
+void mipsnbsd_supply_reg (struct regcache *, const char *, int);
+void mipsnbsd_fill_reg (const struct regcache *, char *, int);
+
+void mipsnbsd_supply_fpreg (struct regcache *, const char *, int);
+void mipsnbsd_fill_fpreg (const struct regcache *, char *, int);
+
+#endif /* MIPS_NBSD_TDEP_H */
+++ /dev/null
-/* Native-dependent code for NetBSD.
-
- Copyright (C) 2006-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-
-#include "nbsd-nat.h"
-#include "nat/netbsd-nat.h"
-#include "gdbthread.h"
-#include "nbsd-tdep.h"
-#include "inferior.h"
-#include "gdbarch.h"
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <sys/sysctl.h>
-#include <sys/wait.h>
-
-/* Return the name of a file that can be opened to get the symbols for
- the child process identified by PID. */
-
-char *
-nbsd_nat_target::pid_to_exec_file (int pid)
-{
- return const_cast<char *> (netbsd_nat::pid_to_exec_file (pid));
-}
-
-/* Return the current directory for the process identified by PID. */
-
-static std::string
-nbsd_pid_to_cwd (int pid)
-{
- char buf[PATH_MAX];
- size_t buflen;
- int mib[4] = {CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_CWD};
- buflen = sizeof (buf);
- if (sysctl (mib, ARRAY_SIZE (mib), buf, &buflen, NULL, 0))
- return "";
- return buf;
-}
-
-/* Return the kinfo_proc2 structure for the process identified by PID. */
-
-static bool
-nbsd_pid_to_kinfo_proc2 (pid_t pid, struct kinfo_proc2 *kp)
-{
- gdb_assert (kp != nullptr);
-
- size_t size = sizeof (*kp);
- int mib[6] = {CTL_KERN, KERN_PROC2, KERN_PROC_PID, pid,
- static_cast<int> (size), 1};
- return !sysctl (mib, ARRAY_SIZE (mib), kp, &size, NULL, 0);
-}
-
-/* Return the command line for the process identified by PID. */
-
-static gdb::unique_xmalloc_ptr<char[]>
-nbsd_pid_to_cmdline (int pid)
-{
- int mib[4] = {CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_ARGV};
-
- size_t size = 0;
- if (::sysctl (mib, ARRAY_SIZE (mib), NULL, &size, NULL, 0) == -1 || size == 0)
- return nullptr;
-
- gdb::unique_xmalloc_ptr<char[]> args (XNEWVAR (char, size));
-
- if (::sysctl (mib, ARRAY_SIZE (mib), args.get (), &size, NULL, 0) == -1
- || size == 0)
- return nullptr;
-
- /* Arguments are returned as a flattened string with NUL separators.
- Join the arguments with spaces to form a single string. */
- for (size_t i = 0; i < size - 1; i++)
- if (args[i] == '\0')
- args[i] = ' ';
- args[size - 1] = '\0';
-
- return args;
-}
-
-/* Return true if PTID is still active in the inferior. */
-
-bool
-nbsd_nat_target::thread_alive (ptid_t ptid)
-{
- return netbsd_nat::thread_alive (ptid);
-}
-
-/* Return the name assigned to a thread by an application. Returns
- the string in a static buffer. */
-
-const char *
-nbsd_nat_target::thread_name (struct thread_info *thr)
-{
- ptid_t ptid = thr->ptid;
- return netbsd_nat::thread_name (ptid);
-}
-
-/* Implement the "post_attach" target_ops method. */
-
-static void
-nbsd_add_threads (nbsd_nat_target *target, pid_t pid)
-{
- auto fn
- = [&target] (ptid_t ptid)
- {
- if (!in_thread_list (target, ptid))
- {
- if (inferior_ptid.lwp () == 0)
- thread_change_ptid (target, inferior_ptid, ptid);
- else
- add_thread (target, ptid);
- }
- };
-
- netbsd_nat::for_each_thread (pid, fn);
-}
-
-/* Implement the "post_startup_inferior" target_ops method. */
-
-void
-nbsd_nat_target::post_startup_inferior (ptid_t ptid)
-{
- netbsd_nat::enable_proc_events (ptid.pid ());
-}
-
-/* Implement the "post_attach" target_ops method. */
-
-void
-nbsd_nat_target::post_attach (int pid)
-{
- netbsd_nat::enable_proc_events (pid);
- nbsd_add_threads (this, pid);
-}
-
-/* Implement the "update_thread_list" target_ops method. */
-
-void
-nbsd_nat_target::update_thread_list ()
-{
- delete_exited_threads ();
-}
-
-/* Convert PTID to a string. */
-
-std::string
-nbsd_nat_target::pid_to_str (ptid_t ptid)
-{
- int lwp = ptid.lwp ();
-
- if (lwp != 0)
- {
- pid_t pid = ptid.pid ();
-
- return string_printf ("LWP %d of process %d", lwp, pid);
- }
-
- return normal_pid_to_str (ptid);
-}
-
-/* Retrieve all the memory regions in the specified process. */
-
-static gdb::unique_xmalloc_ptr<struct kinfo_vmentry[]>
-nbsd_kinfo_get_vmmap (pid_t pid, size_t *size)
-{
- int mib[5] = {CTL_VM, VM_PROC, VM_PROC_MAP, pid,
- sizeof (struct kinfo_vmentry)};
-
- size_t length = 0;
- if (sysctl (mib, ARRAY_SIZE (mib), NULL, &length, NULL, 0))
- {
- *size = 0;
- return NULL;
- }
-
- /* Prereserve more space. The length argument is volatile and can change
- between the sysctl(3) calls as this function can be called against a
- running process. */
- length = length * 5 / 3;
-
- gdb::unique_xmalloc_ptr<struct kinfo_vmentry[]> kiv
- (XNEWVAR (kinfo_vmentry, length));
-
- if (sysctl (mib, ARRAY_SIZE (mib), kiv.get (), &length, NULL, 0))
- {
- *size = 0;
- return NULL;
- }
-
- *size = length / sizeof (struct kinfo_vmentry);
- return kiv;
-}
-
-/* Iterate over all the memory regions in the current inferior,
- calling FUNC for each memory region. OBFD is passed as the last
- argument to FUNC. */
-
-int
-nbsd_nat_target::find_memory_regions (find_memory_region_ftype func,
- void *data)
-{
- pid_t pid = inferior_ptid.pid ();
-
- size_t nitems;
- gdb::unique_xmalloc_ptr<struct kinfo_vmentry[]> vmentl
- = nbsd_kinfo_get_vmmap (pid, &nitems);
- if (vmentl == NULL)
- perror_with_name (_("Couldn't fetch VM map entries."));
-
- for (size_t i = 0; i < nitems; i++)
- {
- struct kinfo_vmentry *kve = &vmentl[i];
-
- /* Skip unreadable segments and those where MAP_NOCORE has been set. */
- if (!(kve->kve_protection & KVME_PROT_READ)
- || kve->kve_flags & KVME_FLAG_NOCOREDUMP)
- continue;
-
- /* Skip segments with an invalid type. */
- switch (kve->kve_type)
- {
- case KVME_TYPE_VNODE:
- case KVME_TYPE_ANON:
- case KVME_TYPE_SUBMAP:
- case KVME_TYPE_OBJECT:
- break;
- default:
- continue;
- }
-
- size_t size = kve->kve_end - kve->kve_start;
- if (info_verbose)
- {
- fprintf_filtered (gdb_stdout,
- "Save segment, %ld bytes at %s (%c%c%c)\n",
- (long) size,
- paddress (target_gdbarch (), kve->kve_start),
- kve->kve_protection & KVME_PROT_READ ? 'r' : '-',
- kve->kve_protection & KVME_PROT_WRITE ? 'w' : '-',
- kve->kve_protection & KVME_PROT_EXEC ? 'x' : '-');
- }
-
- /* Invoke the callback function to create the corefile segment.
- Pass MODIFIED as true, we do not know the real modification state. */
- func (kve->kve_start, size, kve->kve_protection & KVME_PROT_READ,
- kve->kve_protection & KVME_PROT_WRITE,
- kve->kve_protection & KVME_PROT_EXEC, 1, data);
- }
- return 0;
-}
-
-/* Implement the "info_proc" target_ops method. */
-
-bool
-nbsd_nat_target::info_proc (const char *args, enum info_proc_what what)
-{
- pid_t pid;
- bool do_cmdline = false;
- bool do_cwd = false;
- bool do_exe = false;
- bool do_mappings = false;
- bool do_status = false;
-
- switch (what)
- {
- case IP_MINIMAL:
- do_cmdline = true;
- do_cwd = true;
- do_exe = true;
- break;
- case IP_STAT:
- case IP_STATUS:
- do_status = true;
- break;
- case IP_MAPPINGS:
- do_mappings = true;
- break;
- case IP_CMDLINE:
- do_cmdline = true;
- break;
- case IP_EXE:
- do_exe = true;
- break;
- case IP_CWD:
- do_cwd = true;
- break;
- case IP_ALL:
- do_cmdline = true;
- do_cwd = true;
- do_exe = true;
- do_mappings = true;
- do_status = true;
- break;
- default:
- error (_("Not supported on this target."));
- }
-
- gdb_argv built_argv (args);
- if (built_argv.count () == 0)
- {
- pid = inferior_ptid.pid ();
- if (pid == 0)
- error (_("No current process: you must name one."));
- }
- else if (built_argv.count () == 1 && isdigit (built_argv[0][0]))
- pid = strtol (built_argv[0], NULL, 10);
- else
- error (_("Invalid arguments."));
-
- printf_filtered (_("process %d\n"), pid);
-
- if (do_cmdline)
- {
- gdb::unique_xmalloc_ptr<char[]> cmdline = nbsd_pid_to_cmdline (pid);
- if (cmdline != nullptr)
- printf_filtered ("cmdline = '%s'\n", cmdline.get ());
- else
- warning (_("unable to fetch command line"));
- }
- if (do_cwd)
- {
- std::string cwd = nbsd_pid_to_cwd (pid);
- if (cwd != "")
- printf_filtered ("cwd = '%s'\n", cwd.c_str ());
- else
- warning (_("unable to fetch current working directory"));
- }
- if (do_exe)
- {
- const char *exe = pid_to_exec_file (pid);
- if (exe != nullptr)
- printf_filtered ("exe = '%s'\n", exe);
- else
- warning (_("unable to fetch executable path name"));
- }
- if (do_mappings)
- {
- size_t nvment;
- gdb::unique_xmalloc_ptr<struct kinfo_vmentry[]> vmentl
- = nbsd_kinfo_get_vmmap (pid, &nvment);
-
- if (vmentl != nullptr)
- {
- int addr_bit = TARGET_CHAR_BIT * sizeof (void *);
- nbsd_info_proc_mappings_header (addr_bit);
-
- struct kinfo_vmentry *kve = vmentl.get ();
- for (int i = 0; i < nvment; i++, kve++)
- nbsd_info_proc_mappings_entry (addr_bit, kve->kve_start,
- kve->kve_end, kve->kve_offset,
- kve->kve_flags, kve->kve_protection,
- kve->kve_path);
- }
- else
- warning (_("unable to fetch virtual memory map"));
- }
- if (do_status)
- {
- struct kinfo_proc2 kp;
- if (!nbsd_pid_to_kinfo_proc2 (pid, &kp))
- warning (_("Failed to fetch process information"));
- else
- {
- auto process_status
- = [] (int8_t stat)
- {
- switch (stat)
- {
- case SIDL:
- return "IDL";
- case SACTIVE:
- return "ACTIVE";
- case SDYING:
- return "DYING";
- case SSTOP:
- return "STOP";
- case SZOMB:
- return "ZOMB";
- case SDEAD:
- return "DEAD";
- default:
- return "? (unknown)";
- }
- };
-
- printf_filtered ("Name: %s\n", kp.p_comm);
- printf_filtered ("State: %s\n", process_status(kp.p_realstat));
- printf_filtered ("Parent process: %" PRId32 "\n", kp.p_ppid);
- printf_filtered ("Process group: %" PRId32 "\n", kp.p__pgid);
- printf_filtered ("Session id: %" PRId32 "\n", kp.p_sid);
- printf_filtered ("TTY: %" PRId32 "\n", kp.p_tdev);
- printf_filtered ("TTY owner process group: %" PRId32 "\n", kp.p_tpgid);
- printf_filtered ("User IDs (real, effective, saved): "
- "%" PRIu32 " %" PRIu32 " %" PRIu32 "\n",
- kp.p_ruid, kp.p_uid, kp.p_svuid);
- printf_filtered ("Group IDs (real, effective, saved): "
- "%" PRIu32 " %" PRIu32 " %" PRIu32 "\n",
- kp.p_rgid, kp.p_gid, kp.p_svgid);
-
- printf_filtered ("Groups:");
- for (int i = 0; i < kp.p_ngroups; i++)
- printf_filtered (" %" PRIu32, kp.p_groups[i]);
- printf_filtered ("\n");
- printf_filtered ("Minor faults (no memory page): %" PRIu64 "\n",
- kp.p_uru_minflt);
- printf_filtered ("Major faults (memory page faults): %" PRIu64 "\n",
- kp.p_uru_majflt);
- printf_filtered ("utime: %" PRIu32 ".%06" PRIu32 "\n",
- kp.p_uutime_sec, kp.p_uutime_usec);
- printf_filtered ("stime: %" PRIu32 ".%06" PRIu32 "\n",
- kp.p_ustime_sec, kp.p_ustime_usec);
- printf_filtered ("utime+stime, children: %" PRIu32 ".%06" PRIu32 "\n",
- kp.p_uctime_sec, kp.p_uctime_usec);
- printf_filtered ("'nice' value: %" PRIu8 "\n", kp.p_nice);
- printf_filtered ("Start time: %" PRIu32 ".%06" PRIu32 "\n",
- kp.p_ustart_sec, kp.p_ustart_usec);
- int pgtok = getpagesize () / 1024;
- printf_filtered ("Data size: %" PRIuMAX " kB\n",
- (uintmax_t) kp.p_vm_dsize * pgtok);
- printf_filtered ("Stack size: %" PRIuMAX " kB\n",
- (uintmax_t) kp.p_vm_ssize * pgtok);
- printf_filtered ("Text size: %" PRIuMAX " kB\n",
- (uintmax_t) kp.p_vm_tsize * pgtok);
- printf_filtered ("Resident set size: %" PRIuMAX " kB\n",
- (uintmax_t) kp.p_vm_rssize * pgtok);
- printf_filtered ("Maximum RSS: %" PRIu64 " kB\n", kp.p_uru_maxrss);
- printf_filtered ("Pending Signals:");
- for (size_t i = 0; i < ARRAY_SIZE (kp.p_siglist.__bits); i++)
- printf_filtered (" %08" PRIx32, kp.p_siglist.__bits[i]);
- printf_filtered ("\n");
- printf_filtered ("Ignored Signals:");
- for (size_t i = 0; i < ARRAY_SIZE (kp.p_sigignore.__bits); i++)
- printf_filtered (" %08" PRIx32, kp.p_sigignore.__bits[i]);
- printf_filtered ("\n");
- printf_filtered ("Caught Signals:");
- for (size_t i = 0; i < ARRAY_SIZE (kp.p_sigcatch.__bits); i++)
- printf_filtered (" %08" PRIx32, kp.p_sigcatch.__bits[i]);
- printf_filtered ("\n");
- }
- }
-
- return true;
-}
-
-/* Resume execution of a specified PTID, that points to a process or a thread
- within a process. If one thread is specified, all other threads are
- suspended. If STEP is nonzero, single-step it. If SIGNAL is nonzero,
- give it that signal. */
-
-static void
-nbsd_resume(nbsd_nat_target *target, ptid_t ptid, int step,
- enum gdb_signal signal)
-{
- int request;
-
- gdb_assert (minus_one_ptid != ptid);
-
- if (ptid.lwp_p ())
- {
- /* If ptid is a specific LWP, suspend all other LWPs in the process. */
- inferior *inf = find_inferior_ptid (target, ptid);
-
- for (thread_info *tp : inf->non_exited_threads ())
- {
- if (tp->ptid.lwp () == ptid.lwp ())
- request = PT_RESUME;
- else
- request = PT_SUSPEND;
-
- if (ptrace (request, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
- perror_with_name (("ptrace"));
- }
- }
- else
- {
- /* If ptid is a wildcard, resume all matching threads (they won't run
- until the process is continued however). */
- for (thread_info *tp : all_non_exited_threads (target, ptid))
- if (ptrace (PT_RESUME, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
- perror_with_name (("ptrace"));
- }
-
- if (step)
- {
- for (thread_info *tp : all_non_exited_threads (target, ptid))
- if (ptrace (PT_SETSTEP, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
- perror_with_name (("ptrace"));
- }
- else
- {
- for (thread_info *tp : all_non_exited_threads (target, ptid))
- if (ptrace (PT_CLEARSTEP, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
- perror_with_name (("ptrace"));
- }
-
- if (catch_syscall_enabled () > 0)
- request = PT_SYSCALL;
- else
- request = PT_CONTINUE;
-
- /* An address of (void *)1 tells ptrace to continue from
- where it was. If GDB wanted it to start some other way, we have
- already written a new program counter value to the child. */
- if (ptrace (request, ptid.pid (), (void *)1, gdb_signal_to_host (signal)) == -1)
- perror_with_name (("ptrace"));
-}
-
-/* Resume execution of thread PTID, or all threads of all inferiors
- if PTID is -1. If STEP is nonzero, single-step it. If SIGNAL is nonzero,
- give it that signal. */
-
-void
-nbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
-{
- if (minus_one_ptid != ptid)
- nbsd_resume (this, ptid, step, signal);
- else
- {
- for (inferior *inf : all_non_exited_inferiors (this))
- nbsd_resume (this, ptid_t (inf->pid, 0, 0), step, signal);
- }
-}
-
-/* Implement a safe wrapper around waitpid(). */
-
-static pid_t
-nbsd_wait (ptid_t ptid, struct target_waitstatus *ourstatus,
- target_wait_flags options)
-{
- pid_t pid;
- int status;
-
- set_sigint_trap ();
-
- do
- {
- /* The common code passes WNOHANG that leads to crashes, overwrite it. */
- pid = waitpid (ptid.pid (), &status, 0);
- }
- while (pid == -1 && errno == EINTR);
-
- clear_sigint_trap ();
-
- if (pid == -1)
- perror_with_name (_("Child process unexpectedly missing"));
-
- store_waitstatus (ourstatus, status);
- return pid;
-}
-
-/* Wait for the child specified by PTID to do something. Return the
- process ID of the child, or MINUS_ONE_PTID in case of error; store
- the status in *OURSTATUS. */
-
-ptid_t
-nbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
- target_wait_flags target_options)
-{
- pid_t pid = nbsd_wait (ptid, ourstatus, target_options);
- ptid_t wptid = ptid_t (pid);
-
- /* If the child stopped, keep investigating its status. */
- if (ourstatus->kind != TARGET_WAITKIND_STOPPED)
- return wptid;
-
- /* Extract the event and thread that received a signal. */
- ptrace_siginfo_t psi;
- if (ptrace (PT_GET_SIGINFO, pid, &psi, sizeof (psi)) == -1)
- perror_with_name (("ptrace"));
-
- /* Pick child's siginfo_t. */
- siginfo_t *si = &psi.psi_siginfo;
-
- int lwp = psi.psi_lwpid;
-
- int signo = si->si_signo;
- const int code = si->si_code;
-
- /* Construct PTID with a specified thread that received the event.
- If a signal was targeted to the whole process, lwp is 0. */
- wptid = ptid_t (pid, lwp, 0);
-
- /* Bail out on non-debugger oriented signals.. */
- if (signo != SIGTRAP)
- return wptid;
-
- /* Stop examining non-debugger oriented SIGTRAP codes. */
- if (code <= SI_USER || code == SI_NOINFO)
- return wptid;
-
- /* Process state for threading events */
- ptrace_state_t pst = {};
- if (code == TRAP_LWP)
- {
- if (ptrace (PT_GET_PROCESS_STATE, pid, &pst, sizeof (pst)) == -1)
- perror_with_name (("ptrace"));
- }
-
- if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_EXIT)
- {
- /* If GDB attaches to a multi-threaded process, exiting
- threads might be skipped during post_attach that
- have not yet reported their PTRACE_LWP_EXIT event.
- Ignore exited events for an unknown LWP. */
- thread_info *thr = find_thread_ptid (this, wptid);
- if (thr == nullptr)
- ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
- else
- {
- ourstatus->kind = TARGET_WAITKIND_THREAD_EXITED;
- /* NetBSD does not store an LWP exit status. */
- ourstatus->value.integer = 0;
-
- if (print_thread_events)
- printf_unfiltered (_("[%s exited]\n"),
- target_pid_to_str (wptid).c_str ());
- delete_thread (thr);
- }
-
- /* The GDB core expects that the rest of the threads are running. */
- if (ptrace (PT_CONTINUE, pid, (void *) 1, 0) == -1)
- perror_with_name (("ptrace"));
-
- return wptid;
- }
-
- if (in_thread_list (this, ptid_t (pid)))
- thread_change_ptid (this, ptid_t (pid), wptid);
-
- if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_CREATE)
- {
- /* If GDB attaches to a multi-threaded process, newborn
- threads might be added by nbsd_add_threads that have
- not yet reported their PTRACE_LWP_CREATE event. Ignore
- born events for an already-known LWP. */
- if (in_thread_list (this, wptid))
- ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
- else
- {
- add_thread (this, wptid);
- ourstatus->kind = TARGET_WAITKIND_THREAD_CREATED;
- }
- return wptid;
- }
-
- if (code == TRAP_EXEC)
- {
- ourstatus->kind = TARGET_WAITKIND_EXECD;
- ourstatus->value.execd_pathname = xstrdup (pid_to_exec_file (pid));
- return wptid;
- }
-
- if (code == TRAP_TRACE)
- {
- /* Unhandled at this level. */
- return wptid;
- }
-
- if (code == TRAP_SCE || code == TRAP_SCX)
- {
- int sysnum = si->si_sysnum;
-
- if (!catch_syscall_enabled () || !catching_syscall_number (sysnum))
- {
- /* If the core isn't interested in this event, ignore it. */
- ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
- return wptid;
- }
-
- ourstatus->kind =
- (code == TRAP_SCE) ? TARGET_WAITKIND_SYSCALL_ENTRY :
- TARGET_WAITKIND_SYSCALL_RETURN;
- ourstatus->value.syscall_number = sysnum;
- return wptid;
- }
-
- if (code == TRAP_BRKPT)
- {
- /* Unhandled at this level. */
- return wptid;
- }
-
- /* Unclassified SIGTRAP event. */
- ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
- return wptid;
-}
-
-/* Implement the "insert_exec_catchpoint" target_ops method. */
-
-int
-nbsd_nat_target::insert_exec_catchpoint (int pid)
-{
- /* Nothing to do. */
- return 0;
-}
-
-/* Implement the "remove_exec_catchpoint" target_ops method. */
-
-int
-nbsd_nat_target::remove_exec_catchpoint (int pid)
-{
- /* Nothing to do. */
- return 0;
-}
-
-/* Implement the "set_syscall_catchpoint" target_ops method. */
-
-int
-nbsd_nat_target::set_syscall_catchpoint (int pid, bool needed,
- int any_count,
- gdb::array_view<const int> syscall_counts)
-{
- /* Ignore the arguments. inf-ptrace.c will use PT_SYSCALL which
- will catch all system call entries and exits. The system calls
- are filtered by GDB rather than the kernel. */
- return 0;
-}
-
-/* Implement the "supports_multi_process" target_ops method. */
-
-bool
-nbsd_nat_target::supports_multi_process ()
-{
- return true;
-}
-
-/* Implement the "xfer_partial" target_ops method. */
-
-enum target_xfer_status
-nbsd_nat_target::xfer_partial (enum target_object object,
- const char *annex, gdb_byte *readbuf,
- const gdb_byte *writebuf,
- ULONGEST offset, ULONGEST len,
- ULONGEST *xfered_len)
-{
- pid_t pid = inferior_ptid.pid ();
-
- switch (object)
- {
- case TARGET_OBJECT_SIGNAL_INFO:
- {
- len = netbsd_nat::qxfer_siginfo(pid, annex, readbuf, writebuf, offset,
- len);
-
- if (len == -1)
- return TARGET_XFER_E_IO;
-
- *xfered_len = len;
- return TARGET_XFER_OK;
- }
- case TARGET_OBJECT_MEMORY:
- {
- size_t xfered;
- int res;
- if (writebuf != nullptr)
- res = netbsd_nat::write_memory (pid, writebuf, offset, len, &xfered);
- else
- res = netbsd_nat::read_memory (pid, readbuf, offset, len, &xfered);
- if (res != 0)
- {
- if (res == EACCES)
- fprintf_unfiltered (gdb_stderr, "Cannot %s process at %s (%s). "
- "Is PaX MPROTECT active? See security(7), "
- "sysctl(7), paxctl(8)\n",
- (writebuf ? "write to" : "read from"),
- pulongest (offset), safe_strerror (errno));
- return TARGET_XFER_E_IO;
- }
- if (xfered == 0)
- return TARGET_XFER_EOF;
- *xfered_len = (ULONGEST) xfered;
- return TARGET_XFER_OK;
- }
- default:
- return inf_ptrace_target::xfer_partial (object, annex,
- readbuf, writebuf, offset,
- len, xfered_len);
- }
-}
-
-/* Implement the "supports_dumpcore" target_ops method. */
-
-bool
-nbsd_nat_target::supports_dumpcore ()
-{
- return true;
-}
-
-/* Implement the "dumpcore" target_ops method. */
-
-void
-nbsd_nat_target::dumpcore (const char *filename)
-{
- pid_t pid = inferior_ptid.pid ();
-
- if (ptrace (PT_DUMPCORE, pid, const_cast<char *>(filename),
- strlen (filename)) == -1)
- perror_with_name (("ptrace"));
-}
+++ /dev/null
-/* Native-dependent code for NetBSD.
-
- Copyright (C) 2006-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#ifndef NBSD_NAT_H
-#define NBSD_NAT_H
-
-#include "inf-ptrace.h"
-
-struct thread_info;
-
-/* A prototype NetBSD target. */
-
-struct nbsd_nat_target : public inf_ptrace_target
-{
- char *pid_to_exec_file (int pid) override;
-
- bool thread_alive (ptid_t ptid) override;
- const char *thread_name (struct thread_info *thr) override;
- void post_startup_inferior (ptid_t ptid) override;
- void post_attach (int pid) override;
- void update_thread_list () override;
- std::string pid_to_str (ptid_t ptid) override;
-
- int find_memory_regions (find_memory_region_ftype func, void *data) override;
- bool info_proc (const char *, enum info_proc_what) override;
-
- void resume (ptid_t, int, enum gdb_signal) override;
- ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
- int insert_exec_catchpoint (int pid) override;
- int remove_exec_catchpoint (int pid) override;
- int set_syscall_catchpoint (int pid, bool needed, int any_count,
- gdb::array_view<const int> syscall_counts)
- override;
-
- bool supports_multi_process () override;
- enum target_xfer_status xfer_partial (enum target_object object,
- const char *annex,
- gdb_byte *readbuf,
- const gdb_byte *writebuf,
- ULONGEST offset, ULONGEST len,
- ULONGEST *xfered_len) override;
- bool supports_dumpcore () override;
- void dumpcore (const char *filename) override;
-};
-
-#endif /* nbsd-nat.h */
+++ /dev/null
-/* Common target-dependent code for NetBSD systems.
-
- Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "auxv.h"
-#include "solib-svr4.h"
-#include "nbsd-tdep.h"
-#include "gdbarch.h"
-#include "objfiles.h"
-#include "xml-syscall.h"
-
-/* Flags in the 'kve_protection' field in struct kinfo_vmentry. These
- match the KVME_PROT_* constants in <sys/sysctl.h>. */
-
-#define KINFO_VME_PROT_READ 0x00000001
-#define KINFO_VME_PROT_WRITE 0x00000002
-#define KINFO_VME_PROT_EXEC 0x00000004
-
-/* Flags in the 'kve_flags' field in struct kinfo_vmentry. These
- match the KVME_FLAG_* constants in <sys/sysctl.h>. */
-
-#define KINFO_VME_FLAG_COW 0x00000001
-#define KINFO_VME_FLAG_NEEDS_COPY 0x00000002
-#define KINFO_VME_FLAG_NOCOREDUMP 0x00000004
-#define KINFO_VME_FLAG_PAGEABLE 0x00000008
-#define KINFO_VME_FLAG_GROWS_UP 0x00000010
-#define KINFO_VME_FLAG_GROWS_DOWN 0x00000020
-
-/* FIXME: kettenis/20060115: We should really eliminate the next two
- functions completely. */
-
-struct link_map_offsets *
-nbsd_ilp32_solib_svr4_fetch_link_map_offsets (void)
-{
- return svr4_ilp32_fetch_link_map_offsets ();
-}
-
-struct link_map_offsets *
-nbsd_lp64_solib_svr4_fetch_link_map_offsets (void)
-{
- return svr4_lp64_fetch_link_map_offsets ();
-}
-
-int
-nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *func_name)
-{
- /* Check for libc-provided signal trampoline. All such trampolines
- have function names which begin with "__sigtramp". */
-
- return (func_name != NULL
- && startswith (func_name, "__sigtramp"));
-}
-
-/* This enum is derived from NETBSD's <sys/signal.h>. */
-
-enum
- {
- NBSD_SIGHUP = 1,
- NBSD_SIGINT = 2,
- NBSD_SIGQUIT = 3,
- NBSD_SIGILL = 4,
- NBSD_SIGTRAP = 5,
- NBSD_SIGABRT = 6,
- NBSD_SIGEMT = 7,
- NBSD_SIGFPE = 8,
- NBSD_SIGKILL = 9,
- NBSD_SIGBUS = 10,
- NBSD_SIGSEGV = 11,
- NBSD_SIGSYS = 12,
- NBSD_SIGPIPE = 13,
- NBSD_SIGALRM = 14,
- NBSD_SIGTERM = 15,
- NBSD_SIGURG = 16,
- NBSD_SIGSTOP = 17,
- NBSD_SIGTSTP = 18,
- NBSD_SIGCONT = 19,
- NBSD_SIGCHLD = 20,
- NBSD_SIGTTIN = 21,
- NBSD_SIGTTOU = 22,
- NBSD_SIGIO = 23,
- NBSD_SIGXCPU = 24,
- NBSD_SIGXFSZ = 25,
- NBSD_SIGVTALRM = 26,
- NBSD_SIGPROF = 27,
- NBSD_SIGWINCH = 28,
- NBSD_SIGINFO = 29,
- NBSD_SIGUSR1 = 30,
- NBSD_SIGUSR2 = 31,
- NBSD_SIGPWR = 32,
- NBSD_SIGRTMIN = 33,
- NBSD_SIGRTMAX = 63,
- };
-
-/* Implement the "gdb_signal_from_target" gdbarch method. */
-
-static enum gdb_signal
-nbsd_gdb_signal_from_target (struct gdbarch *gdbarch, int signal)
-{
- switch (signal)
- {
- case 0:
- return GDB_SIGNAL_0;
-
- case NBSD_SIGHUP:
- return GDB_SIGNAL_HUP;
-
- case NBSD_SIGINT:
- return GDB_SIGNAL_INT;
-
- case NBSD_SIGQUIT:
- return GDB_SIGNAL_QUIT;
-
- case NBSD_SIGILL:
- return GDB_SIGNAL_ILL;
-
- case NBSD_SIGTRAP:
- return GDB_SIGNAL_TRAP;
-
- case NBSD_SIGABRT:
- return GDB_SIGNAL_ABRT;
-
- case NBSD_SIGEMT:
- return GDB_SIGNAL_EMT;
-
- case NBSD_SIGFPE:
- return GDB_SIGNAL_FPE;
-
- case NBSD_SIGKILL:
- return GDB_SIGNAL_KILL;
-
- case NBSD_SIGBUS:
- return GDB_SIGNAL_BUS;
-
- case NBSD_SIGSEGV:
- return GDB_SIGNAL_SEGV;
-
- case NBSD_SIGSYS:
- return GDB_SIGNAL_SYS;
-
- case NBSD_SIGPIPE:
- return GDB_SIGNAL_PIPE;
-
- case NBSD_SIGALRM:
- return GDB_SIGNAL_ALRM;
-
- case NBSD_SIGTERM:
- return GDB_SIGNAL_TERM;
-
- case NBSD_SIGURG:
- return GDB_SIGNAL_URG;
-
- case NBSD_SIGSTOP:
- return GDB_SIGNAL_STOP;
-
- case NBSD_SIGTSTP:
- return GDB_SIGNAL_TSTP;
-
- case NBSD_SIGCONT:
- return GDB_SIGNAL_CONT;
-
- case NBSD_SIGCHLD:
- return GDB_SIGNAL_CHLD;
-
- case NBSD_SIGTTIN:
- return GDB_SIGNAL_TTIN;
-
- case NBSD_SIGTTOU:
- return GDB_SIGNAL_TTOU;
-
- case NBSD_SIGIO:
- return GDB_SIGNAL_IO;
-
- case NBSD_SIGXCPU:
- return GDB_SIGNAL_XCPU;
-
- case NBSD_SIGXFSZ:
- return GDB_SIGNAL_XFSZ;
-
- case NBSD_SIGVTALRM:
- return GDB_SIGNAL_VTALRM;
-
- case NBSD_SIGPROF:
- return GDB_SIGNAL_PROF;
-
- case NBSD_SIGWINCH:
- return GDB_SIGNAL_WINCH;
-
- case NBSD_SIGINFO:
- return GDB_SIGNAL_INFO;
-
- case NBSD_SIGUSR1:
- return GDB_SIGNAL_USR1;
-
- case NBSD_SIGUSR2:
- return GDB_SIGNAL_USR2;
-
- case NBSD_SIGPWR:
- return GDB_SIGNAL_PWR;
-
- /* SIGRTMIN and SIGRTMAX are not continuous in <gdb/signals.def>,
- therefore we have to handle them here. */
- case NBSD_SIGRTMIN:
- return GDB_SIGNAL_REALTIME_33;
-
- case NBSD_SIGRTMAX:
- return GDB_SIGNAL_REALTIME_63;
- }
-
- if (signal >= NBSD_SIGRTMIN + 1 && signal <= NBSD_SIGRTMAX - 1)
- {
- int offset = signal - NBSD_SIGRTMIN + 1;
-
- return (enum gdb_signal) ((int) GDB_SIGNAL_REALTIME_34 + offset);
- }
-
- return GDB_SIGNAL_UNKNOWN;
-}
-
-/* Implement the "gdb_signal_to_target" gdbarch method. */
-
-static int
-nbsd_gdb_signal_to_target (struct gdbarch *gdbarch,
- enum gdb_signal signal)
-{
- switch (signal)
- {
- case GDB_SIGNAL_0:
- return 0;
-
- case GDB_SIGNAL_HUP:
- return NBSD_SIGHUP;
-
- case GDB_SIGNAL_INT:
- return NBSD_SIGINT;
-
- case GDB_SIGNAL_QUIT:
- return NBSD_SIGQUIT;
-
- case GDB_SIGNAL_ILL:
- return NBSD_SIGILL;
-
- case GDB_SIGNAL_TRAP:
- return NBSD_SIGTRAP;
-
- case GDB_SIGNAL_ABRT:
- return NBSD_SIGABRT;
-
- case GDB_SIGNAL_EMT:
- return NBSD_SIGEMT;
-
- case GDB_SIGNAL_FPE:
- return NBSD_SIGFPE;
-
- case GDB_SIGNAL_KILL:
- return NBSD_SIGKILL;
-
- case GDB_SIGNAL_BUS:
- return NBSD_SIGBUS;
-
- case GDB_SIGNAL_SEGV:
- return NBSD_SIGSEGV;
-
- case GDB_SIGNAL_SYS:
- return NBSD_SIGSYS;
-
- case GDB_SIGNAL_PIPE:
- return NBSD_SIGPIPE;
-
- case GDB_SIGNAL_ALRM:
- return NBSD_SIGALRM;
-
- case GDB_SIGNAL_TERM:
- return NBSD_SIGTERM;
-
- case GDB_SIGNAL_URG:
- return NBSD_SIGSTOP;
-
- case GDB_SIGNAL_TSTP:
- return NBSD_SIGTSTP;
-
- case GDB_SIGNAL_CONT:
- return NBSD_SIGCONT;
-
- case GDB_SIGNAL_CHLD:
- return NBSD_SIGCHLD;
-
- case GDB_SIGNAL_TTIN:
- return NBSD_SIGTTIN;
-
- case GDB_SIGNAL_TTOU:
- return NBSD_SIGTTOU;
-
- case GDB_SIGNAL_IO:
- return NBSD_SIGIO;
-
- case GDB_SIGNAL_XCPU:
- return NBSD_SIGXCPU;
-
- case GDB_SIGNAL_XFSZ:
- return NBSD_SIGXFSZ;
-
- case GDB_SIGNAL_VTALRM:
- return NBSD_SIGVTALRM;
-
- case GDB_SIGNAL_PROF:
- return NBSD_SIGPROF;
-
- case GDB_SIGNAL_WINCH:
- return NBSD_SIGWINCH;
-
- case GDB_SIGNAL_INFO:
- return NBSD_SIGINFO;
-
- case GDB_SIGNAL_USR1:
- return NBSD_SIGUSR1;
-
- case GDB_SIGNAL_USR2:
- return NBSD_SIGUSR2;
-
- case GDB_SIGNAL_PWR:
- return NBSD_SIGPWR;
-
- /* GDB_SIGNAL_REALTIME_33 is not continuous in <gdb/signals.def>,
- therefore we have to handle it here. */
- case GDB_SIGNAL_REALTIME_33:
- return NBSD_SIGRTMIN;
-
- /* Same comment applies to _64. */
- case GDB_SIGNAL_REALTIME_63:
- return NBSD_SIGRTMAX;
- }
-
- if (signal >= GDB_SIGNAL_REALTIME_34
- && signal <= GDB_SIGNAL_REALTIME_62)
- {
- int offset = signal - GDB_SIGNAL_REALTIME_32;
-
- return NBSD_SIGRTMIN + 1 + offset;
- }
-
- return -1;
-}
-
-/* Shared library resolver handling. */
-
-static CORE_ADDR
-nbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
-{
- struct bound_minimal_symbol msym;
-
- msym = lookup_minimal_symbol ("_rtld_bind_start", NULL, NULL);
- if (msym.minsym && BMSYMBOL_VALUE_ADDRESS (msym) == pc)
- return frame_unwind_caller_pc (get_current_frame ());
- else
- return find_solib_trampoline_target (get_current_frame (), pc);
-}
-
-static struct gdbarch_data *nbsd_gdbarch_data_handle;
-
-struct nbsd_gdbarch_data
-{
- struct type *siginfo_type;
-};
-
-static void *
-init_nbsd_gdbarch_data (struct gdbarch *gdbarch)
-{
- return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct nbsd_gdbarch_data);
-}
-
-static struct nbsd_gdbarch_data *
-get_nbsd_gdbarch_data (struct gdbarch *gdbarch)
-{
- return ((struct nbsd_gdbarch_data *)
- gdbarch_data (gdbarch, nbsd_gdbarch_data_handle));
-}
-
-/* Implement the "get_siginfo_type" gdbarch method. */
-
-static struct type *
-nbsd_get_siginfo_type (struct gdbarch *gdbarch)
-{
- nbsd_gdbarch_data *nbsd_gdbarch_data = get_nbsd_gdbarch_data (gdbarch);
- if (nbsd_gdbarch_data->siginfo_type != NULL)
- return nbsd_gdbarch_data->siginfo_type;
-
- type *char_type = builtin_type (gdbarch)->builtin_char;
- type *int_type = builtin_type (gdbarch)->builtin_int;
- type *long_type = builtin_type (gdbarch)->builtin_long;
-
- type *void_ptr_type
- = lookup_pointer_type (builtin_type (gdbarch)->builtin_void);
-
- type *int32_type = builtin_type (gdbarch)->builtin_int32;
- type *uint32_type = builtin_type (gdbarch)->builtin_uint32;
- type *uint64_type = builtin_type (gdbarch)->builtin_uint64;
-
- bool lp64 = TYPE_LENGTH (void_ptr_type) == 8;
- size_t char_bits = gdbarch_addressable_memory_unit_size (gdbarch) * 8;
-
- /* pid_t */
- type *pid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
- TYPE_LENGTH (int32_type) * char_bits, "pid_t");
- TYPE_TARGET_TYPE (pid_type) = int32_type;
-
- /* uid_t */
- type *uid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
- TYPE_LENGTH (uint32_type) * char_bits, "uid_t");
- TYPE_TARGET_TYPE (uid_type) = uint32_type;
-
- /* clock_t */
- type *clock_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
- TYPE_LENGTH (int_type) * char_bits, "clock_t");
- TYPE_TARGET_TYPE (clock_type) = int_type;
-
- /* lwpid_t */
- type *lwpid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
- TYPE_LENGTH (int32_type) * char_bits,
- "lwpid_t");
- TYPE_TARGET_TYPE (lwpid_type) = int32_type;
-
- /* union sigval */
- type *sigval_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
- sigval_type->set_name (gdbarch_obstack_strdup (gdbarch, "sigval"));
- append_composite_type_field (sigval_type, "sival_int", int_type);
- append_composite_type_field (sigval_type, "sival_ptr", void_ptr_type);
-
- /* union _option */
- type *option_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
- option_type->set_name (gdbarch_obstack_strdup (gdbarch, "_option"));
- append_composite_type_field (option_type, "_pe_other_pid", pid_type);
- append_composite_type_field (option_type, "_pe_lwp", lwpid_type);
-
- /* union _reason */
- type *reason_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
-
- /* _rt */
- type *t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
- append_composite_type_field (t, "_pid", pid_type);
- append_composite_type_field (t, "_uid", uid_type);
- append_composite_type_field (t, "_value", sigval_type);
- append_composite_type_field (reason_type, "_rt", t);
-
- /* _child */
- t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
- append_composite_type_field (t, "_pid", pid_type);
- append_composite_type_field (t, "_uid", uid_type);
- append_composite_type_field (t, "_status", int_type);
- append_composite_type_field (t, "_utime", clock_type);
- append_composite_type_field (t, "_stime", clock_type);
- append_composite_type_field (reason_type, "_child", t);
-
- /* _fault */
- t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
- append_composite_type_field (t, "_addr", void_ptr_type);
- append_composite_type_field (t, "_trap", int_type);
- append_composite_type_field (t, "_trap2", int_type);
- append_composite_type_field (t, "_trap3", int_type);
- append_composite_type_field (reason_type, "_fault", t);
-
- /* _poll */
- t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
- append_composite_type_field (t, "_band", long_type);
- append_composite_type_field (t, "_fd", int_type);
- append_composite_type_field (reason_type, "_poll", t);
-
- /* _syscall */
- t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
- append_composite_type_field (t, "_sysnum", int_type);
- append_composite_type_field (t, "_retval",
- init_vector_type (int_type, 2));
- append_composite_type_field (t, "_error", int_type);
- append_composite_type_field (t, "_args",
- init_vector_type (uint64_type, 8));
- append_composite_type_field (reason_type, "_syscall", t);
-
- /* _ptrace_state */
- t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
- append_composite_type_field (t, "_pe_report_event", int_type);
- append_composite_type_field (t, "_option", option_type);
- append_composite_type_field (reason_type, "_ptrace_state", t);
-
- /* struct _ksiginfo */
- type *ksiginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
- ksiginfo_type->set_name (gdbarch_obstack_strdup (gdbarch, "_ksiginfo"));
- append_composite_type_field (ksiginfo_type, "_signo", int_type);
- append_composite_type_field (ksiginfo_type, "_code", int_type);
- append_composite_type_field (ksiginfo_type, "_errno", int_type);
- if (lp64)
- append_composite_type_field (ksiginfo_type, "_pad", int_type);
- append_composite_type_field (ksiginfo_type, "_reason", reason_type);
-
- /* union siginfo */
- type *siginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
- siginfo_type->set_name (gdbarch_obstack_strdup (gdbarch, "siginfo"));
- append_composite_type_field (siginfo_type, "si_pad",
- init_vector_type (char_type, 128));
- append_composite_type_field (siginfo_type, "_info", ksiginfo_type);
-
- nbsd_gdbarch_data->siginfo_type = siginfo_type;
-
- return siginfo_type;
-}
-
-/* See nbsd-tdep.h. */
-
-void
-nbsd_info_proc_mappings_header (int addr_bit)
-{
- printf_filtered (_("Mapped address spaces:\n\n"));
- if (addr_bit == 64)
- {
- printf_filtered (" %18s %18s %10s %10s %9s %s\n",
- "Start Addr",
- " End Addr",
- " Size", " Offset", "Flags ", "File");
- }
- else
- {
- printf_filtered ("\t%10s %10s %10s %10s %9s %s\n",
- "Start Addr",
- " End Addr",
- " Size", " Offset", "Flags ", "File");
- }
-}
-
-/* Helper function to generate mappings flags for a single VM map
- entry in 'info proc mappings'. */
-
-static const char *
-nbsd_vm_map_entry_flags (int kve_flags, int kve_protection)
-{
- static char vm_flags[9];
-
- vm_flags[0] = (kve_protection & KINFO_VME_PROT_READ) ? 'r' : '-';
- vm_flags[1] = (kve_protection & KINFO_VME_PROT_WRITE) ? 'w' : '-';
- vm_flags[2] = (kve_protection & KINFO_VME_PROT_EXEC) ? 'x' : '-';
- vm_flags[3] = ' ';
- vm_flags[4] = (kve_flags & KINFO_VME_FLAG_COW) ? 'C' : '-';
- vm_flags[5] = (kve_flags & KINFO_VME_FLAG_NEEDS_COPY) ? 'N' : '-';
- vm_flags[6] = (kve_flags & KINFO_VME_FLAG_PAGEABLE) ? 'P' : '-';
- vm_flags[7] = (kve_flags & KINFO_VME_FLAG_GROWS_UP) ? 'U'
- : (kve_flags & KINFO_VME_FLAG_GROWS_DOWN) ? 'D' : '-';
- vm_flags[8] = '\0';
-
- return vm_flags;
-}
-
-void
-nbsd_info_proc_mappings_entry (int addr_bit, ULONGEST kve_start,
- ULONGEST kve_end, ULONGEST kve_offset,
- int kve_flags, int kve_protection,
- const char *kve_path)
-{
- if (addr_bit == 64)
- {
- printf_filtered (" %18s %18s %10s %10s %9s %s\n",
- hex_string (kve_start),
- hex_string (kve_end),
- hex_string (kve_end - kve_start),
- hex_string (kve_offset),
- nbsd_vm_map_entry_flags (kve_flags, kve_protection),
- kve_path);
- }
- else
- {
- printf_filtered ("\t%10s %10s %10s %10s %9s %s\n",
- hex_string (kve_start),
- hex_string (kve_end),
- hex_string (kve_end - kve_start),
- hex_string (kve_offset),
- nbsd_vm_map_entry_flags (kve_flags, kve_protection),
- kve_path);
- }
-}
-
-/* Implement the "get_syscall_number" gdbarch method. */
-
-static LONGEST
-nbsd_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread)
-{
-
- /* NetBSD doesn't use gdbarch_get_syscall_number since NetBSD
- native targets fetch the system call number from the
- 'si_sysnum' member of siginfo_t in nbsd_nat_target::wait.
- However, system call catching requires this function to be
- set. */
-
- internal_error (__FILE__, __LINE__, _("nbsd_get_sycall_number called"));
-}
-
-/* See nbsd-tdep.h. */
-
-void
-nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- set_gdbarch_gdb_signal_from_target (gdbarch, nbsd_gdb_signal_from_target);
- set_gdbarch_gdb_signal_to_target (gdbarch, nbsd_gdb_signal_to_target);
- set_gdbarch_skip_solib_resolver (gdbarch, nbsd_skip_solib_resolver);
- set_gdbarch_auxv_parse (gdbarch, svr4_auxv_parse);
- set_gdbarch_get_siginfo_type (gdbarch, nbsd_get_siginfo_type);
-
- /* `catch syscall' */
- set_xml_syscall_file_name (gdbarch, "syscalls/netbsd.xml");
- set_gdbarch_get_syscall_number (gdbarch, nbsd_get_syscall_number);
-}
-
-void _initialize_nbsd_tdep ();
-void
-_initialize_nbsd_tdep ()
-{
- nbsd_gdbarch_data_handle
- = gdbarch_data_register_post_init (init_nbsd_gdbarch_data);
-}
+++ /dev/null
-/* Common target-dependent definitions for NetBSD systems.
- Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#ifndef NBSD_TDEP_H
-#define NBSD_TDEP_H
-
-struct link_map_offsets *nbsd_ilp32_solib_svr4_fetch_link_map_offsets (void);
-struct link_map_offsets *nbsd_lp64_solib_svr4_fetch_link_map_offsets (void);
-
-int nbsd_pc_in_sigtramp (CORE_ADDR, const char *);
-
-/* NetBSD specific set of ABI-related routines. */
-
-void nbsd_init_abi (struct gdbarch_info, struct gdbarch *);
-
-/* Output the header for "info proc mappings". ADDR_BIT is the size
- of a virtual address in bits. */
-
-extern void nbsd_info_proc_mappings_header (int addr_bit);
-
-/* Output description of a single memory range for "info proc
- mappings". ADDR_BIT is the size of a virtual address in bits. The
- KVE_START, KVE_END, KVE_OFFSET, KVE_FLAGS, and KVE_PROTECTION
- parameters should contain the value of the corresponding fields in
- a 'struct kinfo_vmentry'. The KVE_PATH parameter should contain a
- pointer to the 'kve_path' field in a 'struct kinfo_vmentry'. */
-
-extern void nbsd_info_proc_mappings_entry (int addr_bit, ULONGEST kve_start,
- ULONGEST kve_end,
- ULONGEST kve_offset,
- int kve_flags, int kve_protection,
- const char *kve_path);
-
-#endif /* NBSD_TDEP_H */
--- /dev/null
+/* Native-dependent code for NetBSD.
+
+ Copyright (C) 2006-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+
+#include "netbsd-nat.h"
+#include "nat/netbsd-nat.h"
+#include "gdbthread.h"
+#include "netbsd-tdep.h"
+#include "inferior.h"
+#include "gdbarch.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+
+/* Return the name of a file that can be opened to get the symbols for
+ the child process identified by PID. */
+
+char *
+nbsd_nat_target::pid_to_exec_file (int pid)
+{
+ return const_cast<char *> (netbsd_nat::pid_to_exec_file (pid));
+}
+
+/* Return the current directory for the process identified by PID. */
+
+static std::string
+nbsd_pid_to_cwd (int pid)
+{
+ char buf[PATH_MAX];
+ size_t buflen;
+ int mib[4] = {CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_CWD};
+ buflen = sizeof (buf);
+ if (sysctl (mib, ARRAY_SIZE (mib), buf, &buflen, NULL, 0))
+ return "";
+ return buf;
+}
+
+/* Return the kinfo_proc2 structure for the process identified by PID. */
+
+static bool
+nbsd_pid_to_kinfo_proc2 (pid_t pid, struct kinfo_proc2 *kp)
+{
+ gdb_assert (kp != nullptr);
+
+ size_t size = sizeof (*kp);
+ int mib[6] = {CTL_KERN, KERN_PROC2, KERN_PROC_PID, pid,
+ static_cast<int> (size), 1};
+ return !sysctl (mib, ARRAY_SIZE (mib), kp, &size, NULL, 0);
+}
+
+/* Return the command line for the process identified by PID. */
+
+static gdb::unique_xmalloc_ptr<char[]>
+nbsd_pid_to_cmdline (int pid)
+{
+ int mib[4] = {CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_ARGV};
+
+ size_t size = 0;
+ if (::sysctl (mib, ARRAY_SIZE (mib), NULL, &size, NULL, 0) == -1 || size == 0)
+ return nullptr;
+
+ gdb::unique_xmalloc_ptr<char[]> args (XNEWVAR (char, size));
+
+ if (::sysctl (mib, ARRAY_SIZE (mib), args.get (), &size, NULL, 0) == -1
+ || size == 0)
+ return nullptr;
+
+ /* Arguments are returned as a flattened string with NUL separators.
+ Join the arguments with spaces to form a single string. */
+ for (size_t i = 0; i < size - 1; i++)
+ if (args[i] == '\0')
+ args[i] = ' ';
+ args[size - 1] = '\0';
+
+ return args;
+}
+
+/* Return true if PTID is still active in the inferior. */
+
+bool
+nbsd_nat_target::thread_alive (ptid_t ptid)
+{
+ return netbsd_nat::thread_alive (ptid);
+}
+
+/* Return the name assigned to a thread by an application. Returns
+ the string in a static buffer. */
+
+const char *
+nbsd_nat_target::thread_name (struct thread_info *thr)
+{
+ ptid_t ptid = thr->ptid;
+ return netbsd_nat::thread_name (ptid);
+}
+
+/* Implement the "post_attach" target_ops method. */
+
+static void
+nbsd_add_threads (nbsd_nat_target *target, pid_t pid)
+{
+ auto fn
+ = [&target] (ptid_t ptid)
+ {
+ if (!in_thread_list (target, ptid))
+ {
+ if (inferior_ptid.lwp () == 0)
+ thread_change_ptid (target, inferior_ptid, ptid);
+ else
+ add_thread (target, ptid);
+ }
+ };
+
+ netbsd_nat::for_each_thread (pid, fn);
+}
+
+/* Implement the "post_startup_inferior" target_ops method. */
+
+void
+nbsd_nat_target::post_startup_inferior (ptid_t ptid)
+{
+ netbsd_nat::enable_proc_events (ptid.pid ());
+}
+
+/* Implement the "post_attach" target_ops method. */
+
+void
+nbsd_nat_target::post_attach (int pid)
+{
+ netbsd_nat::enable_proc_events (pid);
+ nbsd_add_threads (this, pid);
+}
+
+/* Implement the "update_thread_list" target_ops method. */
+
+void
+nbsd_nat_target::update_thread_list ()
+{
+ delete_exited_threads ();
+}
+
+/* Convert PTID to a string. */
+
+std::string
+nbsd_nat_target::pid_to_str (ptid_t ptid)
+{
+ int lwp = ptid.lwp ();
+
+ if (lwp != 0)
+ {
+ pid_t pid = ptid.pid ();
+
+ return string_printf ("LWP %d of process %d", lwp, pid);
+ }
+
+ return normal_pid_to_str (ptid);
+}
+
+/* Retrieve all the memory regions in the specified process. */
+
+static gdb::unique_xmalloc_ptr<struct kinfo_vmentry[]>
+nbsd_kinfo_get_vmmap (pid_t pid, size_t *size)
+{
+ int mib[5] = {CTL_VM, VM_PROC, VM_PROC_MAP, pid,
+ sizeof (struct kinfo_vmentry)};
+
+ size_t length = 0;
+ if (sysctl (mib, ARRAY_SIZE (mib), NULL, &length, NULL, 0))
+ {
+ *size = 0;
+ return NULL;
+ }
+
+ /* Prereserve more space. The length argument is volatile and can change
+ between the sysctl(3) calls as this function can be called against a
+ running process. */
+ length = length * 5 / 3;
+
+ gdb::unique_xmalloc_ptr<struct kinfo_vmentry[]> kiv
+ (XNEWVAR (kinfo_vmentry, length));
+
+ if (sysctl (mib, ARRAY_SIZE (mib), kiv.get (), &length, NULL, 0))
+ {
+ *size = 0;
+ return NULL;
+ }
+
+ *size = length / sizeof (struct kinfo_vmentry);
+ return kiv;
+}
+
+/* Iterate over all the memory regions in the current inferior,
+ calling FUNC for each memory region. OBFD is passed as the last
+ argument to FUNC. */
+
+int
+nbsd_nat_target::find_memory_regions (find_memory_region_ftype func,
+ void *data)
+{
+ pid_t pid = inferior_ptid.pid ();
+
+ size_t nitems;
+ gdb::unique_xmalloc_ptr<struct kinfo_vmentry[]> vmentl
+ = nbsd_kinfo_get_vmmap (pid, &nitems);
+ if (vmentl == NULL)
+ perror_with_name (_("Couldn't fetch VM map entries."));
+
+ for (size_t i = 0; i < nitems; i++)
+ {
+ struct kinfo_vmentry *kve = &vmentl[i];
+
+ /* Skip unreadable segments and those where MAP_NOCORE has been set. */
+ if (!(kve->kve_protection & KVME_PROT_READ)
+ || kve->kve_flags & KVME_FLAG_NOCOREDUMP)
+ continue;
+
+ /* Skip segments with an invalid type. */
+ switch (kve->kve_type)
+ {
+ case KVME_TYPE_VNODE:
+ case KVME_TYPE_ANON:
+ case KVME_TYPE_SUBMAP:
+ case KVME_TYPE_OBJECT:
+ break;
+ default:
+ continue;
+ }
+
+ size_t size = kve->kve_end - kve->kve_start;
+ if (info_verbose)
+ {
+ fprintf_filtered (gdb_stdout,
+ "Save segment, %ld bytes at %s (%c%c%c)\n",
+ (long) size,
+ paddress (target_gdbarch (), kve->kve_start),
+ kve->kve_protection & KVME_PROT_READ ? 'r' : '-',
+ kve->kve_protection & KVME_PROT_WRITE ? 'w' : '-',
+ kve->kve_protection & KVME_PROT_EXEC ? 'x' : '-');
+ }
+
+ /* Invoke the callback function to create the corefile segment.
+ Pass MODIFIED as true, we do not know the real modification state. */
+ func (kve->kve_start, size, kve->kve_protection & KVME_PROT_READ,
+ kve->kve_protection & KVME_PROT_WRITE,
+ kve->kve_protection & KVME_PROT_EXEC, 1, data);
+ }
+ return 0;
+}
+
+/* Implement the "info_proc" target_ops method. */
+
+bool
+nbsd_nat_target::info_proc (const char *args, enum info_proc_what what)
+{
+ pid_t pid;
+ bool do_cmdline = false;
+ bool do_cwd = false;
+ bool do_exe = false;
+ bool do_mappings = false;
+ bool do_status = false;
+
+ switch (what)
+ {
+ case IP_MINIMAL:
+ do_cmdline = true;
+ do_cwd = true;
+ do_exe = true;
+ break;
+ case IP_STAT:
+ case IP_STATUS:
+ do_status = true;
+ break;
+ case IP_MAPPINGS:
+ do_mappings = true;
+ break;
+ case IP_CMDLINE:
+ do_cmdline = true;
+ break;
+ case IP_EXE:
+ do_exe = true;
+ break;
+ case IP_CWD:
+ do_cwd = true;
+ break;
+ case IP_ALL:
+ do_cmdline = true;
+ do_cwd = true;
+ do_exe = true;
+ do_mappings = true;
+ do_status = true;
+ break;
+ default:
+ error (_("Not supported on this target."));
+ }
+
+ gdb_argv built_argv (args);
+ if (built_argv.count () == 0)
+ {
+ pid = inferior_ptid.pid ();
+ if (pid == 0)
+ error (_("No current process: you must name one."));
+ }
+ else if (built_argv.count () == 1 && isdigit (built_argv[0][0]))
+ pid = strtol (built_argv[0], NULL, 10);
+ else
+ error (_("Invalid arguments."));
+
+ printf_filtered (_("process %d\n"), pid);
+
+ if (do_cmdline)
+ {
+ gdb::unique_xmalloc_ptr<char[]> cmdline = nbsd_pid_to_cmdline (pid);
+ if (cmdline != nullptr)
+ printf_filtered ("cmdline = '%s'\n", cmdline.get ());
+ else
+ warning (_("unable to fetch command line"));
+ }
+ if (do_cwd)
+ {
+ std::string cwd = nbsd_pid_to_cwd (pid);
+ if (cwd != "")
+ printf_filtered ("cwd = '%s'\n", cwd.c_str ());
+ else
+ warning (_("unable to fetch current working directory"));
+ }
+ if (do_exe)
+ {
+ const char *exe = pid_to_exec_file (pid);
+ if (exe != nullptr)
+ printf_filtered ("exe = '%s'\n", exe);
+ else
+ warning (_("unable to fetch executable path name"));
+ }
+ if (do_mappings)
+ {
+ size_t nvment;
+ gdb::unique_xmalloc_ptr<struct kinfo_vmentry[]> vmentl
+ = nbsd_kinfo_get_vmmap (pid, &nvment);
+
+ if (vmentl != nullptr)
+ {
+ int addr_bit = TARGET_CHAR_BIT * sizeof (void *);
+ nbsd_info_proc_mappings_header (addr_bit);
+
+ struct kinfo_vmentry *kve = vmentl.get ();
+ for (int i = 0; i < nvment; i++, kve++)
+ nbsd_info_proc_mappings_entry (addr_bit, kve->kve_start,
+ kve->kve_end, kve->kve_offset,
+ kve->kve_flags, kve->kve_protection,
+ kve->kve_path);
+ }
+ else
+ warning (_("unable to fetch virtual memory map"));
+ }
+ if (do_status)
+ {
+ struct kinfo_proc2 kp;
+ if (!nbsd_pid_to_kinfo_proc2 (pid, &kp))
+ warning (_("Failed to fetch process information"));
+ else
+ {
+ auto process_status
+ = [] (int8_t stat)
+ {
+ switch (stat)
+ {
+ case SIDL:
+ return "IDL";
+ case SACTIVE:
+ return "ACTIVE";
+ case SDYING:
+ return "DYING";
+ case SSTOP:
+ return "STOP";
+ case SZOMB:
+ return "ZOMB";
+ case SDEAD:
+ return "DEAD";
+ default:
+ return "? (unknown)";
+ }
+ };
+
+ printf_filtered ("Name: %s\n", kp.p_comm);
+ printf_filtered ("State: %s\n", process_status(kp.p_realstat));
+ printf_filtered ("Parent process: %" PRId32 "\n", kp.p_ppid);
+ printf_filtered ("Process group: %" PRId32 "\n", kp.p__pgid);
+ printf_filtered ("Session id: %" PRId32 "\n", kp.p_sid);
+ printf_filtered ("TTY: %" PRId32 "\n", kp.p_tdev);
+ printf_filtered ("TTY owner process group: %" PRId32 "\n", kp.p_tpgid);
+ printf_filtered ("User IDs (real, effective, saved): "
+ "%" PRIu32 " %" PRIu32 " %" PRIu32 "\n",
+ kp.p_ruid, kp.p_uid, kp.p_svuid);
+ printf_filtered ("Group IDs (real, effective, saved): "
+ "%" PRIu32 " %" PRIu32 " %" PRIu32 "\n",
+ kp.p_rgid, kp.p_gid, kp.p_svgid);
+
+ printf_filtered ("Groups:");
+ for (int i = 0; i < kp.p_ngroups; i++)
+ printf_filtered (" %" PRIu32, kp.p_groups[i]);
+ printf_filtered ("\n");
+ printf_filtered ("Minor faults (no memory page): %" PRIu64 "\n",
+ kp.p_uru_minflt);
+ printf_filtered ("Major faults (memory page faults): %" PRIu64 "\n",
+ kp.p_uru_majflt);
+ printf_filtered ("utime: %" PRIu32 ".%06" PRIu32 "\n",
+ kp.p_uutime_sec, kp.p_uutime_usec);
+ printf_filtered ("stime: %" PRIu32 ".%06" PRIu32 "\n",
+ kp.p_ustime_sec, kp.p_ustime_usec);
+ printf_filtered ("utime+stime, children: %" PRIu32 ".%06" PRIu32 "\n",
+ kp.p_uctime_sec, kp.p_uctime_usec);
+ printf_filtered ("'nice' value: %" PRIu8 "\n", kp.p_nice);
+ printf_filtered ("Start time: %" PRIu32 ".%06" PRIu32 "\n",
+ kp.p_ustart_sec, kp.p_ustart_usec);
+ int pgtok = getpagesize () / 1024;
+ printf_filtered ("Data size: %" PRIuMAX " kB\n",
+ (uintmax_t) kp.p_vm_dsize * pgtok);
+ printf_filtered ("Stack size: %" PRIuMAX " kB\n",
+ (uintmax_t) kp.p_vm_ssize * pgtok);
+ printf_filtered ("Text size: %" PRIuMAX " kB\n",
+ (uintmax_t) kp.p_vm_tsize * pgtok);
+ printf_filtered ("Resident set size: %" PRIuMAX " kB\n",
+ (uintmax_t) kp.p_vm_rssize * pgtok);
+ printf_filtered ("Maximum RSS: %" PRIu64 " kB\n", kp.p_uru_maxrss);
+ printf_filtered ("Pending Signals:");
+ for (size_t i = 0; i < ARRAY_SIZE (kp.p_siglist.__bits); i++)
+ printf_filtered (" %08" PRIx32, kp.p_siglist.__bits[i]);
+ printf_filtered ("\n");
+ printf_filtered ("Ignored Signals:");
+ for (size_t i = 0; i < ARRAY_SIZE (kp.p_sigignore.__bits); i++)
+ printf_filtered (" %08" PRIx32, kp.p_sigignore.__bits[i]);
+ printf_filtered ("\n");
+ printf_filtered ("Caught Signals:");
+ for (size_t i = 0; i < ARRAY_SIZE (kp.p_sigcatch.__bits); i++)
+ printf_filtered (" %08" PRIx32, kp.p_sigcatch.__bits[i]);
+ printf_filtered ("\n");
+ }
+ }
+
+ return true;
+}
+
+/* Resume execution of a specified PTID, that points to a process or a thread
+ within a process. If one thread is specified, all other threads are
+ suspended. If STEP is nonzero, single-step it. If SIGNAL is nonzero,
+ give it that signal. */
+
+static void
+nbsd_resume(nbsd_nat_target *target, ptid_t ptid, int step,
+ enum gdb_signal signal)
+{
+ int request;
+
+ gdb_assert (minus_one_ptid != ptid);
+
+ if (ptid.lwp_p ())
+ {
+ /* If ptid is a specific LWP, suspend all other LWPs in the process. */
+ inferior *inf = find_inferior_ptid (target, ptid);
+
+ for (thread_info *tp : inf->non_exited_threads ())
+ {
+ if (tp->ptid.lwp () == ptid.lwp ())
+ request = PT_RESUME;
+ else
+ request = PT_SUSPEND;
+
+ if (ptrace (request, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
+ perror_with_name (("ptrace"));
+ }
+ }
+ else
+ {
+ /* If ptid is a wildcard, resume all matching threads (they won't run
+ until the process is continued however). */
+ for (thread_info *tp : all_non_exited_threads (target, ptid))
+ if (ptrace (PT_RESUME, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
+ perror_with_name (("ptrace"));
+ }
+
+ if (step)
+ {
+ for (thread_info *tp : all_non_exited_threads (target, ptid))
+ if (ptrace (PT_SETSTEP, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
+ perror_with_name (("ptrace"));
+ }
+ else
+ {
+ for (thread_info *tp : all_non_exited_threads (target, ptid))
+ if (ptrace (PT_CLEARSTEP, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
+ perror_with_name (("ptrace"));
+ }
+
+ if (catch_syscall_enabled () > 0)
+ request = PT_SYSCALL;
+ else
+ request = PT_CONTINUE;
+
+ /* An address of (void *)1 tells ptrace to continue from
+ where it was. If GDB wanted it to start some other way, we have
+ already written a new program counter value to the child. */
+ if (ptrace (request, ptid.pid (), (void *)1, gdb_signal_to_host (signal)) == -1)
+ perror_with_name (("ptrace"));
+}
+
+/* Resume execution of thread PTID, or all threads of all inferiors
+ if PTID is -1. If STEP is nonzero, single-step it. If SIGNAL is nonzero,
+ give it that signal. */
+
+void
+nbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
+{
+ if (minus_one_ptid != ptid)
+ nbsd_resume (this, ptid, step, signal);
+ else
+ {
+ for (inferior *inf : all_non_exited_inferiors (this))
+ nbsd_resume (this, ptid_t (inf->pid, 0, 0), step, signal);
+ }
+}
+
+/* Implement a safe wrapper around waitpid(). */
+
+static pid_t
+nbsd_wait (ptid_t ptid, struct target_waitstatus *ourstatus,
+ target_wait_flags options)
+{
+ pid_t pid;
+ int status;
+
+ set_sigint_trap ();
+
+ do
+ {
+ /* The common code passes WNOHANG that leads to crashes, overwrite it. */
+ pid = waitpid (ptid.pid (), &status, 0);
+ }
+ while (pid == -1 && errno == EINTR);
+
+ clear_sigint_trap ();
+
+ if (pid == -1)
+ perror_with_name (_("Child process unexpectedly missing"));
+
+ store_waitstatus (ourstatus, status);
+ return pid;
+}
+
+/* Wait for the child specified by PTID to do something. Return the
+ process ID of the child, or MINUS_ONE_PTID in case of error; store
+ the status in *OURSTATUS. */
+
+ptid_t
+nbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
+ target_wait_flags target_options)
+{
+ pid_t pid = nbsd_wait (ptid, ourstatus, target_options);
+ ptid_t wptid = ptid_t (pid);
+
+ /* If the child stopped, keep investigating its status. */
+ if (ourstatus->kind != TARGET_WAITKIND_STOPPED)
+ return wptid;
+
+ /* Extract the event and thread that received a signal. */
+ ptrace_siginfo_t psi;
+ if (ptrace (PT_GET_SIGINFO, pid, &psi, sizeof (psi)) == -1)
+ perror_with_name (("ptrace"));
+
+ /* Pick child's siginfo_t. */
+ siginfo_t *si = &psi.psi_siginfo;
+
+ int lwp = psi.psi_lwpid;
+
+ int signo = si->si_signo;
+ const int code = si->si_code;
+
+ /* Construct PTID with a specified thread that received the event.
+ If a signal was targeted to the whole process, lwp is 0. */
+ wptid = ptid_t (pid, lwp, 0);
+
+ /* Bail out on non-debugger oriented signals.. */
+ if (signo != SIGTRAP)
+ return wptid;
+
+ /* Stop examining non-debugger oriented SIGTRAP codes. */
+ if (code <= SI_USER || code == SI_NOINFO)
+ return wptid;
+
+ /* Process state for threading events */
+ ptrace_state_t pst = {};
+ if (code == TRAP_LWP)
+ {
+ if (ptrace (PT_GET_PROCESS_STATE, pid, &pst, sizeof (pst)) == -1)
+ perror_with_name (("ptrace"));
+ }
+
+ if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_EXIT)
+ {
+ /* If GDB attaches to a multi-threaded process, exiting
+ threads might be skipped during post_attach that
+ have not yet reported their PTRACE_LWP_EXIT event.
+ Ignore exited events for an unknown LWP. */
+ thread_info *thr = find_thread_ptid (this, wptid);
+ if (thr == nullptr)
+ ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+ else
+ {
+ ourstatus->kind = TARGET_WAITKIND_THREAD_EXITED;
+ /* NetBSD does not store an LWP exit status. */
+ ourstatus->value.integer = 0;
+
+ if (print_thread_events)
+ printf_unfiltered (_("[%s exited]\n"),
+ target_pid_to_str (wptid).c_str ());
+ delete_thread (thr);
+ }
+
+ /* The GDB core expects that the rest of the threads are running. */
+ if (ptrace (PT_CONTINUE, pid, (void *) 1, 0) == -1)
+ perror_with_name (("ptrace"));
+
+ return wptid;
+ }
+
+ if (in_thread_list (this, ptid_t (pid)))
+ thread_change_ptid (this, ptid_t (pid), wptid);
+
+ if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_CREATE)
+ {
+ /* If GDB attaches to a multi-threaded process, newborn
+ threads might be added by nbsd_add_threads that have
+ not yet reported their PTRACE_LWP_CREATE event. Ignore
+ born events for an already-known LWP. */
+ if (in_thread_list (this, wptid))
+ ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+ else
+ {
+ add_thread (this, wptid);
+ ourstatus->kind = TARGET_WAITKIND_THREAD_CREATED;
+ }
+ return wptid;
+ }
+
+ if (code == TRAP_EXEC)
+ {
+ ourstatus->kind = TARGET_WAITKIND_EXECD;
+ ourstatus->value.execd_pathname = xstrdup (pid_to_exec_file (pid));
+ return wptid;
+ }
+
+ if (code == TRAP_TRACE)
+ {
+ /* Unhandled at this level. */
+ return wptid;
+ }
+
+ if (code == TRAP_SCE || code == TRAP_SCX)
+ {
+ int sysnum = si->si_sysnum;
+
+ if (!catch_syscall_enabled () || !catching_syscall_number (sysnum))
+ {
+ /* If the core isn't interested in this event, ignore it. */
+ ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+ return wptid;
+ }
+
+ ourstatus->kind =
+ (code == TRAP_SCE) ? TARGET_WAITKIND_SYSCALL_ENTRY :
+ TARGET_WAITKIND_SYSCALL_RETURN;
+ ourstatus->value.syscall_number = sysnum;
+ return wptid;
+ }
+
+ if (code == TRAP_BRKPT)
+ {
+ /* Unhandled at this level. */
+ return wptid;
+ }
+
+ /* Unclassified SIGTRAP event. */
+ ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+ return wptid;
+}
+
+/* Implement the "insert_exec_catchpoint" target_ops method. */
+
+int
+nbsd_nat_target::insert_exec_catchpoint (int pid)
+{
+ /* Nothing to do. */
+ return 0;
+}
+
+/* Implement the "remove_exec_catchpoint" target_ops method. */
+
+int
+nbsd_nat_target::remove_exec_catchpoint (int pid)
+{
+ /* Nothing to do. */
+ return 0;
+}
+
+/* Implement the "set_syscall_catchpoint" target_ops method. */
+
+int
+nbsd_nat_target::set_syscall_catchpoint (int pid, bool needed,
+ int any_count,
+ gdb::array_view<const int> syscall_counts)
+{
+ /* Ignore the arguments. inf-ptrace.c will use PT_SYSCALL which
+ will catch all system call entries and exits. The system calls
+ are filtered by GDB rather than the kernel. */
+ return 0;
+}
+
+/* Implement the "supports_multi_process" target_ops method. */
+
+bool
+nbsd_nat_target::supports_multi_process ()
+{
+ return true;
+}
+
+/* Implement the "xfer_partial" target_ops method. */
+
+enum target_xfer_status
+nbsd_nat_target::xfer_partial (enum target_object object,
+ const char *annex, gdb_byte *readbuf,
+ const gdb_byte *writebuf,
+ ULONGEST offset, ULONGEST len,
+ ULONGEST *xfered_len)
+{
+ pid_t pid = inferior_ptid.pid ();
+
+ switch (object)
+ {
+ case TARGET_OBJECT_SIGNAL_INFO:
+ {
+ len = netbsd_nat::qxfer_siginfo(pid, annex, readbuf, writebuf, offset,
+ len);
+
+ if (len == -1)
+ return TARGET_XFER_E_IO;
+
+ *xfered_len = len;
+ return TARGET_XFER_OK;
+ }
+ case TARGET_OBJECT_MEMORY:
+ {
+ size_t xfered;
+ int res;
+ if (writebuf != nullptr)
+ res = netbsd_nat::write_memory (pid, writebuf, offset, len, &xfered);
+ else
+ res = netbsd_nat::read_memory (pid, readbuf, offset, len, &xfered);
+ if (res != 0)
+ {
+ if (res == EACCES)
+ fprintf_unfiltered (gdb_stderr, "Cannot %s process at %s (%s). "
+ "Is PaX MPROTECT active? See security(7), "
+ "sysctl(7), paxctl(8)\n",
+ (writebuf ? "write to" : "read from"),
+ pulongest (offset), safe_strerror (errno));
+ return TARGET_XFER_E_IO;
+ }
+ if (xfered == 0)
+ return TARGET_XFER_EOF;
+ *xfered_len = (ULONGEST) xfered;
+ return TARGET_XFER_OK;
+ }
+ default:
+ return inf_ptrace_target::xfer_partial (object, annex,
+ readbuf, writebuf, offset,
+ len, xfered_len);
+ }
+}
+
+/* Implement the "supports_dumpcore" target_ops method. */
+
+bool
+nbsd_nat_target::supports_dumpcore ()
+{
+ return true;
+}
+
+/* Implement the "dumpcore" target_ops method. */
+
+void
+nbsd_nat_target::dumpcore (const char *filename)
+{
+ pid_t pid = inferior_ptid.pid ();
+
+ if (ptrace (PT_DUMPCORE, pid, const_cast<char *>(filename),
+ strlen (filename)) == -1)
+ perror_with_name (("ptrace"));
+}
--- /dev/null
+/* Native-dependent code for NetBSD.
+
+ Copyright (C) 2006-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef NBSD_NAT_H
+#define NBSD_NAT_H
+
+#include "inf-ptrace.h"
+
+struct thread_info;
+
+/* A prototype NetBSD target. */
+
+struct nbsd_nat_target : public inf_ptrace_target
+{
+ char *pid_to_exec_file (int pid) override;
+
+ bool thread_alive (ptid_t ptid) override;
+ const char *thread_name (struct thread_info *thr) override;
+ void post_startup_inferior (ptid_t ptid) override;
+ void post_attach (int pid) override;
+ void update_thread_list () override;
+ std::string pid_to_str (ptid_t ptid) override;
+
+ int find_memory_regions (find_memory_region_ftype func, void *data) override;
+ bool info_proc (const char *, enum info_proc_what) override;
+
+ void resume (ptid_t, int, enum gdb_signal) override;
+ ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
+ int insert_exec_catchpoint (int pid) override;
+ int remove_exec_catchpoint (int pid) override;
+ int set_syscall_catchpoint (int pid, bool needed, int any_count,
+ gdb::array_view<const int> syscall_counts)
+ override;
+
+ bool supports_multi_process () override;
+ enum target_xfer_status xfer_partial (enum target_object object,
+ const char *annex,
+ gdb_byte *readbuf,
+ const gdb_byte *writebuf,
+ ULONGEST offset, ULONGEST len,
+ ULONGEST *xfered_len) override;
+ bool supports_dumpcore () override;
+ void dumpcore (const char *filename) override;
+};
+
+#endif /* netbsd-nat.h */
--- /dev/null
+/* Common target-dependent code for NetBSD systems.
+
+ Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "auxv.h"
+#include "solib-svr4.h"
+#include "netbsd-tdep.h"
+#include "gdbarch.h"
+#include "objfiles.h"
+#include "xml-syscall.h"
+
+/* Flags in the 'kve_protection' field in struct kinfo_vmentry. These
+ match the KVME_PROT_* constants in <sys/sysctl.h>. */
+
+#define KINFO_VME_PROT_READ 0x00000001
+#define KINFO_VME_PROT_WRITE 0x00000002
+#define KINFO_VME_PROT_EXEC 0x00000004
+
+/* Flags in the 'kve_flags' field in struct kinfo_vmentry. These
+ match the KVME_FLAG_* constants in <sys/sysctl.h>. */
+
+#define KINFO_VME_FLAG_COW 0x00000001
+#define KINFO_VME_FLAG_NEEDS_COPY 0x00000002
+#define KINFO_VME_FLAG_NOCOREDUMP 0x00000004
+#define KINFO_VME_FLAG_PAGEABLE 0x00000008
+#define KINFO_VME_FLAG_GROWS_UP 0x00000010
+#define KINFO_VME_FLAG_GROWS_DOWN 0x00000020
+
+/* FIXME: kettenis/20060115: We should really eliminate the next two
+ functions completely. */
+
+struct link_map_offsets *
+nbsd_ilp32_solib_svr4_fetch_link_map_offsets (void)
+{
+ return svr4_ilp32_fetch_link_map_offsets ();
+}
+
+struct link_map_offsets *
+nbsd_lp64_solib_svr4_fetch_link_map_offsets (void)
+{
+ return svr4_lp64_fetch_link_map_offsets ();
+}
+
+int
+nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *func_name)
+{
+ /* Check for libc-provided signal trampoline. All such trampolines
+ have function names which begin with "__sigtramp". */
+
+ return (func_name != NULL
+ && startswith (func_name, "__sigtramp"));
+}
+
+/* This enum is derived from NETBSD's <sys/signal.h>. */
+
+enum
+ {
+ NBSD_SIGHUP = 1,
+ NBSD_SIGINT = 2,
+ NBSD_SIGQUIT = 3,
+ NBSD_SIGILL = 4,
+ NBSD_SIGTRAP = 5,
+ NBSD_SIGABRT = 6,
+ NBSD_SIGEMT = 7,
+ NBSD_SIGFPE = 8,
+ NBSD_SIGKILL = 9,
+ NBSD_SIGBUS = 10,
+ NBSD_SIGSEGV = 11,
+ NBSD_SIGSYS = 12,
+ NBSD_SIGPIPE = 13,
+ NBSD_SIGALRM = 14,
+ NBSD_SIGTERM = 15,
+ NBSD_SIGURG = 16,
+ NBSD_SIGSTOP = 17,
+ NBSD_SIGTSTP = 18,
+ NBSD_SIGCONT = 19,
+ NBSD_SIGCHLD = 20,
+ NBSD_SIGTTIN = 21,
+ NBSD_SIGTTOU = 22,
+ NBSD_SIGIO = 23,
+ NBSD_SIGXCPU = 24,
+ NBSD_SIGXFSZ = 25,
+ NBSD_SIGVTALRM = 26,
+ NBSD_SIGPROF = 27,
+ NBSD_SIGWINCH = 28,
+ NBSD_SIGINFO = 29,
+ NBSD_SIGUSR1 = 30,
+ NBSD_SIGUSR2 = 31,
+ NBSD_SIGPWR = 32,
+ NBSD_SIGRTMIN = 33,
+ NBSD_SIGRTMAX = 63,
+ };
+
+/* Implement the "gdb_signal_from_target" gdbarch method. */
+
+static enum gdb_signal
+nbsd_gdb_signal_from_target (struct gdbarch *gdbarch, int signal)
+{
+ switch (signal)
+ {
+ case 0:
+ return GDB_SIGNAL_0;
+
+ case NBSD_SIGHUP:
+ return GDB_SIGNAL_HUP;
+
+ case NBSD_SIGINT:
+ return GDB_SIGNAL_INT;
+
+ case NBSD_SIGQUIT:
+ return GDB_SIGNAL_QUIT;
+
+ case NBSD_SIGILL:
+ return GDB_SIGNAL_ILL;
+
+ case NBSD_SIGTRAP:
+ return GDB_SIGNAL_TRAP;
+
+ case NBSD_SIGABRT:
+ return GDB_SIGNAL_ABRT;
+
+ case NBSD_SIGEMT:
+ return GDB_SIGNAL_EMT;
+
+ case NBSD_SIGFPE:
+ return GDB_SIGNAL_FPE;
+
+ case NBSD_SIGKILL:
+ return GDB_SIGNAL_KILL;
+
+ case NBSD_SIGBUS:
+ return GDB_SIGNAL_BUS;
+
+ case NBSD_SIGSEGV:
+ return GDB_SIGNAL_SEGV;
+
+ case NBSD_SIGSYS:
+ return GDB_SIGNAL_SYS;
+
+ case NBSD_SIGPIPE:
+ return GDB_SIGNAL_PIPE;
+
+ case NBSD_SIGALRM:
+ return GDB_SIGNAL_ALRM;
+
+ case NBSD_SIGTERM:
+ return GDB_SIGNAL_TERM;
+
+ case NBSD_SIGURG:
+ return GDB_SIGNAL_URG;
+
+ case NBSD_SIGSTOP:
+ return GDB_SIGNAL_STOP;
+
+ case NBSD_SIGTSTP:
+ return GDB_SIGNAL_TSTP;
+
+ case NBSD_SIGCONT:
+ return GDB_SIGNAL_CONT;
+
+ case NBSD_SIGCHLD:
+ return GDB_SIGNAL_CHLD;
+
+ case NBSD_SIGTTIN:
+ return GDB_SIGNAL_TTIN;
+
+ case NBSD_SIGTTOU:
+ return GDB_SIGNAL_TTOU;
+
+ case NBSD_SIGIO:
+ return GDB_SIGNAL_IO;
+
+ case NBSD_SIGXCPU:
+ return GDB_SIGNAL_XCPU;
+
+ case NBSD_SIGXFSZ:
+ return GDB_SIGNAL_XFSZ;
+
+ case NBSD_SIGVTALRM:
+ return GDB_SIGNAL_VTALRM;
+
+ case NBSD_SIGPROF:
+ return GDB_SIGNAL_PROF;
+
+ case NBSD_SIGWINCH:
+ return GDB_SIGNAL_WINCH;
+
+ case NBSD_SIGINFO:
+ return GDB_SIGNAL_INFO;
+
+ case NBSD_SIGUSR1:
+ return GDB_SIGNAL_USR1;
+
+ case NBSD_SIGUSR2:
+ return GDB_SIGNAL_USR2;
+
+ case NBSD_SIGPWR:
+ return GDB_SIGNAL_PWR;
+
+ /* SIGRTMIN and SIGRTMAX are not continuous in <gdb/signals.def>,
+ therefore we have to handle them here. */
+ case NBSD_SIGRTMIN:
+ return GDB_SIGNAL_REALTIME_33;
+
+ case NBSD_SIGRTMAX:
+ return GDB_SIGNAL_REALTIME_63;
+ }
+
+ if (signal >= NBSD_SIGRTMIN + 1 && signal <= NBSD_SIGRTMAX - 1)
+ {
+ int offset = signal - NBSD_SIGRTMIN + 1;
+
+ return (enum gdb_signal) ((int) GDB_SIGNAL_REALTIME_34 + offset);
+ }
+
+ return GDB_SIGNAL_UNKNOWN;
+}
+
+/* Implement the "gdb_signal_to_target" gdbarch method. */
+
+static int
+nbsd_gdb_signal_to_target (struct gdbarch *gdbarch,
+ enum gdb_signal signal)
+{
+ switch (signal)
+ {
+ case GDB_SIGNAL_0:
+ return 0;
+
+ case GDB_SIGNAL_HUP:
+ return NBSD_SIGHUP;
+
+ case GDB_SIGNAL_INT:
+ return NBSD_SIGINT;
+
+ case GDB_SIGNAL_QUIT:
+ return NBSD_SIGQUIT;
+
+ case GDB_SIGNAL_ILL:
+ return NBSD_SIGILL;
+
+ case GDB_SIGNAL_TRAP:
+ return NBSD_SIGTRAP;
+
+ case GDB_SIGNAL_ABRT:
+ return NBSD_SIGABRT;
+
+ case GDB_SIGNAL_EMT:
+ return NBSD_SIGEMT;
+
+ case GDB_SIGNAL_FPE:
+ return NBSD_SIGFPE;
+
+ case GDB_SIGNAL_KILL:
+ return NBSD_SIGKILL;
+
+ case GDB_SIGNAL_BUS:
+ return NBSD_SIGBUS;
+
+ case GDB_SIGNAL_SEGV:
+ return NBSD_SIGSEGV;
+
+ case GDB_SIGNAL_SYS:
+ return NBSD_SIGSYS;
+
+ case GDB_SIGNAL_PIPE:
+ return NBSD_SIGPIPE;
+
+ case GDB_SIGNAL_ALRM:
+ return NBSD_SIGALRM;
+
+ case GDB_SIGNAL_TERM:
+ return NBSD_SIGTERM;
+
+ case GDB_SIGNAL_URG:
+ return NBSD_SIGSTOP;
+
+ case GDB_SIGNAL_TSTP:
+ return NBSD_SIGTSTP;
+
+ case GDB_SIGNAL_CONT:
+ return NBSD_SIGCONT;
+
+ case GDB_SIGNAL_CHLD:
+ return NBSD_SIGCHLD;
+
+ case GDB_SIGNAL_TTIN:
+ return NBSD_SIGTTIN;
+
+ case GDB_SIGNAL_TTOU:
+ return NBSD_SIGTTOU;
+
+ case GDB_SIGNAL_IO:
+ return NBSD_SIGIO;
+
+ case GDB_SIGNAL_XCPU:
+ return NBSD_SIGXCPU;
+
+ case GDB_SIGNAL_XFSZ:
+ return NBSD_SIGXFSZ;
+
+ case GDB_SIGNAL_VTALRM:
+ return NBSD_SIGVTALRM;
+
+ case GDB_SIGNAL_PROF:
+ return NBSD_SIGPROF;
+
+ case GDB_SIGNAL_WINCH:
+ return NBSD_SIGWINCH;
+
+ case GDB_SIGNAL_INFO:
+ return NBSD_SIGINFO;
+
+ case GDB_SIGNAL_USR1:
+ return NBSD_SIGUSR1;
+
+ case GDB_SIGNAL_USR2:
+ return NBSD_SIGUSR2;
+
+ case GDB_SIGNAL_PWR:
+ return NBSD_SIGPWR;
+
+ /* GDB_SIGNAL_REALTIME_33 is not continuous in <gdb/signals.def>,
+ therefore we have to handle it here. */
+ case GDB_SIGNAL_REALTIME_33:
+ return NBSD_SIGRTMIN;
+
+ /* Same comment applies to _64. */
+ case GDB_SIGNAL_REALTIME_63:
+ return NBSD_SIGRTMAX;
+ }
+
+ if (signal >= GDB_SIGNAL_REALTIME_34
+ && signal <= GDB_SIGNAL_REALTIME_62)
+ {
+ int offset = signal - GDB_SIGNAL_REALTIME_32;
+
+ return NBSD_SIGRTMIN + 1 + offset;
+ }
+
+ return -1;
+}
+
+/* Shared library resolver handling. */
+
+static CORE_ADDR
+nbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+ struct bound_minimal_symbol msym;
+
+ msym = lookup_minimal_symbol ("_rtld_bind_start", NULL, NULL);
+ if (msym.minsym && BMSYMBOL_VALUE_ADDRESS (msym) == pc)
+ return frame_unwind_caller_pc (get_current_frame ());
+ else
+ return find_solib_trampoline_target (get_current_frame (), pc);
+}
+
+static struct gdbarch_data *nbsd_gdbarch_data_handle;
+
+struct nbsd_gdbarch_data
+{
+ struct type *siginfo_type;
+};
+
+static void *
+init_nbsd_gdbarch_data (struct gdbarch *gdbarch)
+{
+ return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct nbsd_gdbarch_data);
+}
+
+static struct nbsd_gdbarch_data *
+get_nbsd_gdbarch_data (struct gdbarch *gdbarch)
+{
+ return ((struct nbsd_gdbarch_data *)
+ gdbarch_data (gdbarch, nbsd_gdbarch_data_handle));
+}
+
+/* Implement the "get_siginfo_type" gdbarch method. */
+
+static struct type *
+nbsd_get_siginfo_type (struct gdbarch *gdbarch)
+{
+ nbsd_gdbarch_data *nbsd_gdbarch_data = get_nbsd_gdbarch_data (gdbarch);
+ if (nbsd_gdbarch_data->siginfo_type != NULL)
+ return nbsd_gdbarch_data->siginfo_type;
+
+ type *char_type = builtin_type (gdbarch)->builtin_char;
+ type *int_type = builtin_type (gdbarch)->builtin_int;
+ type *long_type = builtin_type (gdbarch)->builtin_long;
+
+ type *void_ptr_type
+ = lookup_pointer_type (builtin_type (gdbarch)->builtin_void);
+
+ type *int32_type = builtin_type (gdbarch)->builtin_int32;
+ type *uint32_type = builtin_type (gdbarch)->builtin_uint32;
+ type *uint64_type = builtin_type (gdbarch)->builtin_uint64;
+
+ bool lp64 = TYPE_LENGTH (void_ptr_type) == 8;
+ size_t char_bits = gdbarch_addressable_memory_unit_size (gdbarch) * 8;
+
+ /* pid_t */
+ type *pid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+ TYPE_LENGTH (int32_type) * char_bits, "pid_t");
+ TYPE_TARGET_TYPE (pid_type) = int32_type;
+
+ /* uid_t */
+ type *uid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+ TYPE_LENGTH (uint32_type) * char_bits, "uid_t");
+ TYPE_TARGET_TYPE (uid_type) = uint32_type;
+
+ /* clock_t */
+ type *clock_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+ TYPE_LENGTH (int_type) * char_bits, "clock_t");
+ TYPE_TARGET_TYPE (clock_type) = int_type;
+
+ /* lwpid_t */
+ type *lwpid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+ TYPE_LENGTH (int32_type) * char_bits,
+ "lwpid_t");
+ TYPE_TARGET_TYPE (lwpid_type) = int32_type;
+
+ /* union sigval */
+ type *sigval_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+ sigval_type->set_name (gdbarch_obstack_strdup (gdbarch, "sigval"));
+ append_composite_type_field (sigval_type, "sival_int", int_type);
+ append_composite_type_field (sigval_type, "sival_ptr", void_ptr_type);
+
+ /* union _option */
+ type *option_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+ option_type->set_name (gdbarch_obstack_strdup (gdbarch, "_option"));
+ append_composite_type_field (option_type, "_pe_other_pid", pid_type);
+ append_composite_type_field (option_type, "_pe_lwp", lwpid_type);
+
+ /* union _reason */
+ type *reason_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+
+ /* _rt */
+ type *t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+ append_composite_type_field (t, "_pid", pid_type);
+ append_composite_type_field (t, "_uid", uid_type);
+ append_composite_type_field (t, "_value", sigval_type);
+ append_composite_type_field (reason_type, "_rt", t);
+
+ /* _child */
+ t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+ append_composite_type_field (t, "_pid", pid_type);
+ append_composite_type_field (t, "_uid", uid_type);
+ append_composite_type_field (t, "_status", int_type);
+ append_composite_type_field (t, "_utime", clock_type);
+ append_composite_type_field (t, "_stime", clock_type);
+ append_composite_type_field (reason_type, "_child", t);
+
+ /* _fault */
+ t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+ append_composite_type_field (t, "_addr", void_ptr_type);
+ append_composite_type_field (t, "_trap", int_type);
+ append_composite_type_field (t, "_trap2", int_type);
+ append_composite_type_field (t, "_trap3", int_type);
+ append_composite_type_field (reason_type, "_fault", t);
+
+ /* _poll */
+ t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+ append_composite_type_field (t, "_band", long_type);
+ append_composite_type_field (t, "_fd", int_type);
+ append_composite_type_field (reason_type, "_poll", t);
+
+ /* _syscall */
+ t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+ append_composite_type_field (t, "_sysnum", int_type);
+ append_composite_type_field (t, "_retval",
+ init_vector_type (int_type, 2));
+ append_composite_type_field (t, "_error", int_type);
+ append_composite_type_field (t, "_args",
+ init_vector_type (uint64_type, 8));
+ append_composite_type_field (reason_type, "_syscall", t);
+
+ /* _ptrace_state */
+ t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+ append_composite_type_field (t, "_pe_report_event", int_type);
+ append_composite_type_field (t, "_option", option_type);
+ append_composite_type_field (reason_type, "_ptrace_state", t);
+
+ /* struct _ksiginfo */
+ type *ksiginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+ ksiginfo_type->set_name (gdbarch_obstack_strdup (gdbarch, "_ksiginfo"));
+ append_composite_type_field (ksiginfo_type, "_signo", int_type);
+ append_composite_type_field (ksiginfo_type, "_code", int_type);
+ append_composite_type_field (ksiginfo_type, "_errno", int_type);
+ if (lp64)
+ append_composite_type_field (ksiginfo_type, "_pad", int_type);
+ append_composite_type_field (ksiginfo_type, "_reason", reason_type);
+
+ /* union siginfo */
+ type *siginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+ siginfo_type->set_name (gdbarch_obstack_strdup (gdbarch, "siginfo"));
+ append_composite_type_field (siginfo_type, "si_pad",
+ init_vector_type (char_type, 128));
+ append_composite_type_field (siginfo_type, "_info", ksiginfo_type);
+
+ nbsd_gdbarch_data->siginfo_type = siginfo_type;
+
+ return siginfo_type;
+}
+
+/* See nbsd-tdep.h. */
+
+void
+nbsd_info_proc_mappings_header (int addr_bit)
+{
+ printf_filtered (_("Mapped address spaces:\n\n"));
+ if (addr_bit == 64)
+ {
+ printf_filtered (" %18s %18s %10s %10s %9s %s\n",
+ "Start Addr",
+ " End Addr",
+ " Size", " Offset", "Flags ", "File");
+ }
+ else
+ {
+ printf_filtered ("\t%10s %10s %10s %10s %9s %s\n",
+ "Start Addr",
+ " End Addr",
+ " Size", " Offset", "Flags ", "File");
+ }
+}
+
+/* Helper function to generate mappings flags for a single VM map
+ entry in 'info proc mappings'. */
+
+static const char *
+nbsd_vm_map_entry_flags (int kve_flags, int kve_protection)
+{
+ static char vm_flags[9];
+
+ vm_flags[0] = (kve_protection & KINFO_VME_PROT_READ) ? 'r' : '-';
+ vm_flags[1] = (kve_protection & KINFO_VME_PROT_WRITE) ? 'w' : '-';
+ vm_flags[2] = (kve_protection & KINFO_VME_PROT_EXEC) ? 'x' : '-';
+ vm_flags[3] = ' ';
+ vm_flags[4] = (kve_flags & KINFO_VME_FLAG_COW) ? 'C' : '-';
+ vm_flags[5] = (kve_flags & KINFO_VME_FLAG_NEEDS_COPY) ? 'N' : '-';
+ vm_flags[6] = (kve_flags & KINFO_VME_FLAG_PAGEABLE) ? 'P' : '-';
+ vm_flags[7] = (kve_flags & KINFO_VME_FLAG_GROWS_UP) ? 'U'
+ : (kve_flags & KINFO_VME_FLAG_GROWS_DOWN) ? 'D' : '-';
+ vm_flags[8] = '\0';
+
+ return vm_flags;
+}
+
+void
+nbsd_info_proc_mappings_entry (int addr_bit, ULONGEST kve_start,
+ ULONGEST kve_end, ULONGEST kve_offset,
+ int kve_flags, int kve_protection,
+ const char *kve_path)
+{
+ if (addr_bit == 64)
+ {
+ printf_filtered (" %18s %18s %10s %10s %9s %s\n",
+ hex_string (kve_start),
+ hex_string (kve_end),
+ hex_string (kve_end - kve_start),
+ hex_string (kve_offset),
+ nbsd_vm_map_entry_flags (kve_flags, kve_protection),
+ kve_path);
+ }
+ else
+ {
+ printf_filtered ("\t%10s %10s %10s %10s %9s %s\n",
+ hex_string (kve_start),
+ hex_string (kve_end),
+ hex_string (kve_end - kve_start),
+ hex_string (kve_offset),
+ nbsd_vm_map_entry_flags (kve_flags, kve_protection),
+ kve_path);
+ }
+}
+
+/* Implement the "get_syscall_number" gdbarch method. */
+
+static LONGEST
+nbsd_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread)
+{
+
+ /* NetBSD doesn't use gdbarch_get_syscall_number since NetBSD
+ native targets fetch the system call number from the
+ 'si_sysnum' member of siginfo_t in nbsd_nat_target::wait.
+ However, system call catching requires this function to be
+ set. */
+
+ internal_error (__FILE__, __LINE__, _("nbsd_get_sycall_number called"));
+}
+
+/* See nbsd-tdep.h. */
+
+void
+nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ set_gdbarch_gdb_signal_from_target (gdbarch, nbsd_gdb_signal_from_target);
+ set_gdbarch_gdb_signal_to_target (gdbarch, nbsd_gdb_signal_to_target);
+ set_gdbarch_skip_solib_resolver (gdbarch, nbsd_skip_solib_resolver);
+ set_gdbarch_auxv_parse (gdbarch, svr4_auxv_parse);
+ set_gdbarch_get_siginfo_type (gdbarch, nbsd_get_siginfo_type);
+
+ /* `catch syscall' */
+ set_xml_syscall_file_name (gdbarch, "syscalls/netbsd.xml");
+ set_gdbarch_get_syscall_number (gdbarch, nbsd_get_syscall_number);
+}
+
+void _initialize_nbsd_tdep ();
+void
+_initialize_nbsd_tdep ()
+{
+ nbsd_gdbarch_data_handle
+ = gdbarch_data_register_post_init (init_nbsd_gdbarch_data);
+}
--- /dev/null
+/* Common target-dependent definitions for NetBSD systems.
+ Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef NBSD_TDEP_H
+#define NBSD_TDEP_H
+
+struct link_map_offsets *nbsd_ilp32_solib_svr4_fetch_link_map_offsets (void);
+struct link_map_offsets *nbsd_lp64_solib_svr4_fetch_link_map_offsets (void);
+
+int nbsd_pc_in_sigtramp (CORE_ADDR, const char *);
+
+/* NetBSD specific set of ABI-related routines. */
+
+void nbsd_init_abi (struct gdbarch_info, struct gdbarch *);
+
+/* Output the header for "info proc mappings". ADDR_BIT is the size
+ of a virtual address in bits. */
+
+extern void nbsd_info_proc_mappings_header (int addr_bit);
+
+/* Output description of a single memory range for "info proc
+ mappings". ADDR_BIT is the size of a virtual address in bits. The
+ KVE_START, KVE_END, KVE_OFFSET, KVE_FLAGS, and KVE_PROTECTION
+ parameters should contain the value of the corresponding fields in
+ a 'struct kinfo_vmentry'. The KVE_PATH parameter should contain a
+ pointer to the 'kve_path' field in a 'struct kinfo_vmentry'. */
+
+extern void nbsd_info_proc_mappings_entry (int addr_bit, ULONGEST kve_start,
+ ULONGEST kve_end,
+ ULONGEST kve_offset,
+ int kve_flags, int kve_protection,
+ const char *kve_path);
+
+#endif /* NBSD_TDEP_H */
+++ /dev/null
-/* Native-dependent code for NetBSD/powerpc.
-
- Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-/* We define this to get types like register_t. */
-#define _KERNTYPES
-#include "defs.h"
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-#include <machine/frame.h>
-#include <machine/pcb.h>
-
-#include "gdbcore.h"
-#include "inferior.h"
-#include "regcache.h"
-
-#include "ppc-tdep.h"
-#include "ppc-nbsd-tdep.h"
-#include "bsd-kvm.h"
-#include "inf-ptrace.h"
-#include "nbsd-nat.h"
-
-struct ppc_nbsd_nat_target final : public nbsd_nat_target
-{
- void fetch_registers (struct regcache *, int) override;
- void store_registers (struct regcache *, int) override;
-};
-
-static ppc_nbsd_nat_target the_ppc_nbsd_nat_target;
-
-/* Returns true if PT_GETREGS fetches this register. */
-
-static int
-getregs_supplies (struct gdbarch *gdbarch, int regnum)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- return ((regnum >= tdep->ppc_gp0_regnum
- && regnum < tdep->ppc_gp0_regnum + ppc_num_gprs)
- || regnum == tdep->ppc_lr_regnum
- || regnum == tdep->ppc_cr_regnum
- || regnum == tdep->ppc_xer_regnum
- || regnum == tdep->ppc_ctr_regnum
- || regnum == gdbarch_pc_regnum (gdbarch));
-}
-
-/* Like above, but for PT_GETFPREGS. */
-
-static int
-getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
- point registers. Traditionally, GDB's register set has still
- listed the floating point registers for such machines, so this
- code is harmless. However, the new E500 port actually omits the
- floating point registers entirely from the register set --- they
- don't even have register numbers assigned to them.
-
- It's not clear to me how best to update this code, so this assert
- will alert the first person to encounter the NetBSD/E500
- combination to the problem. */
- gdb_assert (ppc_floating_point_unit_p (gdbarch));
-
- return ((regnum >= tdep->ppc_fp0_regnum
- && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs)
- || regnum == tdep->ppc_fpscr_regnum);
-}
-
-void
-ppc_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
-{
- struct gdbarch *gdbarch = regcache->arch ();
- pid_t pid = regcache->ptid ().pid ();
- int lwp = regcache->ptid ().lwp ();
-
- if (regnum == -1 || getregs_supplies (gdbarch, regnum))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- ppc_supply_gregset (&ppcnbsd_gregset, regcache,
- regnum, ®s, sizeof regs);
- }
-
- if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
- perror_with_name (_("Couldn't get FP registers"));
-
- ppc_supply_fpregset (&ppcnbsd_fpregset, regcache,
- regnum, &fpregs, sizeof fpregs);
- }
-}
-
-void
-ppc_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
-{
- struct gdbarch *gdbarch = regcache->arch ();
- pid_t pid = regcache->ptid ().pid ();
- int lwp = regcache->ptid ().lwp ();
-
- if (regnum == -1 || getregs_supplies (gdbarch, regnum))
- {
- struct reg regs;
-
- if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- ppc_collect_gregset (&ppcnbsd_gregset, regcache,
- regnum, ®s, sizeof regs);
-
- if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1)
- perror_with_name (_("Couldn't write registers"));
- }
-
- if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
- {
- struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
- perror_with_name (_("Couldn't get FP registers"));
-
- ppc_collect_fpregset (&ppcnbsd_fpregset, regcache,
- regnum, &fpregs, sizeof fpregs);
-
- if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
- perror_with_name (_("Couldn't set FP registers"));
- }
-}
-
-static int
-ppcnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- struct switchframe sf;
- struct callframe cf;
- struct gdbarch *gdbarch = regcache->arch ();
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- int i;
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_sp == 0)
- return 0;
-
- read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
- regcache->raw_supply (tdep->ppc_cr_regnum, &sf.cr);
- regcache->raw_supply (tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
- for (i = 0 ; i < 19 ; i++)
- regcache->raw_supply (tdep->ppc_gp0_regnum + 13 + i, &sf.fixreg[i]);
-
- read_memory(sf.sp, (gdb_byte *)&cf, sizeof(cf));
- regcache->raw_supply (tdep->ppc_gp0_regnum + 30, &cf.r30);
- regcache->raw_supply (tdep->ppc_gp0_regnum + 31, &cf.r31);
- regcache->raw_supply (tdep->ppc_gp0_regnum + 1, &cf.sp);
-
- read_memory(cf.sp, (gdb_byte *)&cf, sizeof(cf));
- regcache->raw_supply (tdep->ppc_lr_regnum, &cf.lr);
- regcache->raw_supply (gdbarch_pc_regnum (gdbarch), &cf.lr);
-
- return 1;
-}
-
-void _initialize_ppcnbsd_nat ();
-void
-_initialize_ppcnbsd_nat ()
-{
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (ppcnbsd_supply_pcb);
-
- add_inf_child_target (&the_ppc_nbsd_nat_target);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/powerpc.
-
- Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbtypes.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-#include "trad-frame.h"
-#include "tramp-frame.h"
-
-#include "ppc-tdep.h"
-#include "nbsd-tdep.h"
-#include "ppc-tdep.h"
-#include "solib-svr4.h"
-
-/* Register offsets from <machine/reg.h>. */
-struct ppc_reg_offsets ppcnbsd_reg_offsets;
-\f
-
-/* Core file support. */
-
-/* NetBSD/powerpc register sets. */
-
-const struct regset ppcnbsd_gregset =
-{
- &ppcnbsd_reg_offsets,
- ppc_supply_gregset
-};
-
-const struct regset ppcnbsd_fpregset =
-{
- &ppcnbsd_reg_offsets,
- ppc_supply_fpregset
-};
-
-/* Iterate over core file register note sections. */
-
-static void
-ppcnbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
-{
- cb (".reg", 148, 148, &ppcnbsd_gregset, NULL, cb_data);
- cb (".reg2", 264, 264, &ppcnbsd_fpregset, NULL, cb_data);
-}
-\f
-
-/* NetBSD is confused. It appears that 1.5 was using the correct SVR4
- convention but, 1.6 switched to the below broken convention. For
- the moment use the broken convention. Ulgh! */
-
-static enum return_value_convention
-ppcnbsd_return_value (struct gdbarch *gdbarch, struct value *function,
- struct type *valtype, struct regcache *regcache,
- gdb_byte *readbuf, const gdb_byte *writebuf)
-{
-#if 0
- if ((valtype->code () == TYPE_CODE_STRUCT
- || valtype->code () == TYPE_CODE_UNION)
- && !((TYPE_LENGTH (valtype) == 16 || TYPE_LENGTH (valtype) == 8)
- && valtype->is_vector ())
- && !(TYPE_LENGTH (valtype) == 1
- || TYPE_LENGTH (valtype) == 2
- || TYPE_LENGTH (valtype) == 4
- || TYPE_LENGTH (valtype) == 8))
- return RETURN_VALUE_STRUCT_CONVENTION;
- else
-#endif
- return ppc_sysv_abi_broken_return_value (gdbarch, function, valtype,
- regcache, readbuf, writebuf);
-}
-\f
-
-/* Signal trampolines. */
-
-extern const struct tramp_frame ppcnbsd2_sigtramp;
-
-static void
-ppcnbsd_sigtramp_cache_init (const struct tramp_frame *self,
- struct frame_info *this_frame,
- struct trad_frame_cache *this_cache,
- CORE_ADDR func)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- CORE_ADDR addr, base;
- int i;
-
- base = get_frame_register_unsigned (this_frame,
- gdbarch_sp_regnum (gdbarch));
- if (self == &ppcnbsd2_sigtramp)
- addr = base + 0x10 + 2 * tdep->wordsize;
- else
- addr = base + 0x18 + 2 * tdep->wordsize;
- for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
- {
- int regnum = i + tdep->ppc_gp0_regnum;
- trad_frame_set_reg_addr (this_cache, regnum, addr);
- }
- trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, addr);
- addr += tdep->wordsize;
- trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, addr);
- addr += tdep->wordsize;
- trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, addr);
- addr += tdep->wordsize;
- trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, addr);
- addr += tdep->wordsize;
- trad_frame_set_reg_addr (this_cache, gdbarch_pc_regnum (gdbarch),
- addr); /* SRR0? */
- addr += tdep->wordsize;
-
- /* Construct the frame ID using the function start. */
- trad_frame_set_id (this_cache, frame_id_build (base, func));
-}
-
-static const struct tramp_frame ppcnbsd_sigtramp =
-{
- SIGTRAMP_FRAME,
- 4,
- {
- { 0x3821fff0, ULONGEST_MAX }, /* add r1,r1,-16 */
- { 0x4e800021, ULONGEST_MAX }, /* blrl */
- { 0x38610018, ULONGEST_MAX }, /* addi r3,r1,24 */
- { 0x38000127, ULONGEST_MAX }, /* li r0,295 */
- { 0x44000002, ULONGEST_MAX }, /* sc */
- { 0x38000001, ULONGEST_MAX }, /* li r0,1 */
- { 0x44000002, ULONGEST_MAX }, /* sc */
- { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
- },
- ppcnbsd_sigtramp_cache_init
-};
-
-/* NetBSD 2.0 introduced a slightly different signal trampoline. */
-
-const struct tramp_frame ppcnbsd2_sigtramp =
-{
- SIGTRAMP_FRAME,
- 4,
- {
- { 0x3821fff0, ULONGEST_MAX }, /* add r1,r1,-16 */
- { 0x4e800021, ULONGEST_MAX }, /* blrl */
- { 0x38610010, ULONGEST_MAX }, /* addi r3,r1,16 */
- { 0x38000127, ULONGEST_MAX }, /* li r0,295 */
- { 0x44000002, ULONGEST_MAX }, /* sc */
- { 0x38000001, ULONGEST_MAX }, /* li r0,1 */
- { 0x44000002, ULONGEST_MAX }, /* sc */
- { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
- },
- ppcnbsd_sigtramp_cache_init
-};
-\f
-
-static void
-ppcnbsd_init_abi (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-{
- nbsd_init_abi (info, gdbarch);
-
- /* For NetBSD, this is an on again, off again thing. Some systems
- do use the broken struct convention, and some don't. */
- set_gdbarch_return_value (gdbarch, ppcnbsd_return_value);
-
- /* NetBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-
- set_gdbarch_iterate_over_regset_sections
- (gdbarch, ppcnbsd_iterate_over_regset_sections);
-
- tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd_sigtramp);
- tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd2_sigtramp);
-}
-
-void _initialize_ppcnbsd_tdep ();
-void
-_initialize_ppcnbsd_tdep ()
-{
- gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_NETBSD,
- ppcnbsd_init_abi);
-
- /* Avoid initializing the register offsets again if they were
- already initialized by ppcnbsd-nat.c. */
- if (ppcnbsd_reg_offsets.pc_offset == 0)
- {
- /* General-purpose registers. */
- ppcnbsd_reg_offsets.r0_offset = 0;
- ppcnbsd_reg_offsets.gpr_size = 4;
- ppcnbsd_reg_offsets.xr_size = 4;
- ppcnbsd_reg_offsets.lr_offset = 128;
- ppcnbsd_reg_offsets.cr_offset = 132;
- ppcnbsd_reg_offsets.xer_offset = 136;
- ppcnbsd_reg_offsets.ctr_offset = 140;
- ppcnbsd_reg_offsets.pc_offset = 144;
- ppcnbsd_reg_offsets.ps_offset = -1;
- ppcnbsd_reg_offsets.mq_offset = -1;
-
- /* Floating-point registers. */
- ppcnbsd_reg_offsets.f0_offset = 0;
- ppcnbsd_reg_offsets.fpscr_offset = 256;
- ppcnbsd_reg_offsets.fpscr_size = 4;
-
- }
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/powerpc.
-
- Copyright (C) 2004-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#ifndef PPC_NBSD_TDEP_H
-#define PPC_NBSD_TDEP_H
-
-struct regset;
-
-/* Register offsets for NetBSD/powerpc. */
-extern struct ppc_reg_offsets ppcnbsd_reg_offsets;
-
-/* Register sets for NetBSD/powerpc. */
-extern const struct regset ppcnbsd_gregset;
-extern const struct regset ppcnbsd_fpregset;
-
-#endif /* PPC_NBSD_TDEP_H */
--- /dev/null
+/* Native-dependent code for NetBSD/powerpc.
+
+ Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+/* We define this to get types like register_t. */
+#define _KERNTYPES
+#include "defs.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+#include <machine/frame.h>
+#include <machine/pcb.h>
+
+#include "gdbcore.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include "ppc-tdep.h"
+#include "ppc-netbsd-tdep.h"
+#include "bsd-kvm.h"
+#include "inf-ptrace.h"
+#include "netbsd-nat.h"
+
+struct ppc_nbsd_nat_target final : public nbsd_nat_target
+{
+ void fetch_registers (struct regcache *, int) override;
+ void store_registers (struct regcache *, int) override;
+};
+
+static ppc_nbsd_nat_target the_ppc_nbsd_nat_target;
+
+/* Returns true if PT_GETREGS fetches this register. */
+
+static int
+getregs_supplies (struct gdbarch *gdbarch, int regnum)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ return ((regnum >= tdep->ppc_gp0_regnum
+ && regnum < tdep->ppc_gp0_regnum + ppc_num_gprs)
+ || regnum == tdep->ppc_lr_regnum
+ || regnum == tdep->ppc_cr_regnum
+ || regnum == tdep->ppc_xer_regnum
+ || regnum == tdep->ppc_ctr_regnum
+ || regnum == gdbarch_pc_regnum (gdbarch));
+}
+
+/* Like above, but for PT_GETFPREGS. */
+
+static int
+getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
+ point registers. Traditionally, GDB's register set has still
+ listed the floating point registers for such machines, so this
+ code is harmless. However, the new E500 port actually omits the
+ floating point registers entirely from the register set --- they
+ don't even have register numbers assigned to them.
+
+ It's not clear to me how best to update this code, so this assert
+ will alert the first person to encounter the NetBSD/E500
+ combination to the problem. */
+ gdb_assert (ppc_floating_point_unit_p (gdbarch));
+
+ return ((regnum >= tdep->ppc_fp0_regnum
+ && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs)
+ || regnum == tdep->ppc_fpscr_regnum);
+}
+
+void
+ppc_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
+{
+ struct gdbarch *gdbarch = regcache->arch ();
+ pid_t pid = regcache->ptid ().pid ();
+ int lwp = regcache->ptid ().lwp ();
+
+ if (regnum == -1 || getregs_supplies (gdbarch, regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ ppc_supply_gregset (&ppcnbsd_gregset, regcache,
+ regnum, ®s, sizeof regs);
+ }
+
+ if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
+ perror_with_name (_("Couldn't get FP registers"));
+
+ ppc_supply_fpregset (&ppcnbsd_fpregset, regcache,
+ regnum, &fpregs, sizeof fpregs);
+ }
+}
+
+void
+ppc_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
+{
+ struct gdbarch *gdbarch = regcache->arch ();
+ pid_t pid = regcache->ptid ().pid ();
+ int lwp = regcache->ptid ().lwp ();
+
+ if (regnum == -1 || getregs_supplies (gdbarch, regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ ppc_collect_gregset (&ppcnbsd_gregset, regcache,
+ regnum, ®s, sizeof regs);
+
+ if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1)
+ perror_with_name (_("Couldn't write registers"));
+ }
+
+ if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
+ perror_with_name (_("Couldn't get FP registers"));
+
+ ppc_collect_fpregset (&ppcnbsd_fpregset, regcache,
+ regnum, &fpregs, sizeof fpregs);
+
+ if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
+ perror_with_name (_("Couldn't set FP registers"));
+ }
+}
+
+static int
+ppcnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ struct switchframe sf;
+ struct callframe cf;
+ struct gdbarch *gdbarch = regcache->arch ();
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int i;
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_sp == 0)
+ return 0;
+
+ read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
+ regcache->raw_supply (tdep->ppc_cr_regnum, &sf.cr);
+ regcache->raw_supply (tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
+ for (i = 0 ; i < 19 ; i++)
+ regcache->raw_supply (tdep->ppc_gp0_regnum + 13 + i, &sf.fixreg[i]);
+
+ read_memory(sf.sp, (gdb_byte *)&cf, sizeof(cf));
+ regcache->raw_supply (tdep->ppc_gp0_regnum + 30, &cf.r30);
+ regcache->raw_supply (tdep->ppc_gp0_regnum + 31, &cf.r31);
+ regcache->raw_supply (tdep->ppc_gp0_regnum + 1, &cf.sp);
+
+ read_memory(cf.sp, (gdb_byte *)&cf, sizeof(cf));
+ regcache->raw_supply (tdep->ppc_lr_regnum, &cf.lr);
+ regcache->raw_supply (gdbarch_pc_regnum (gdbarch), &cf.lr);
+
+ return 1;
+}
+
+void _initialize_ppcnbsd_nat ();
+void
+_initialize_ppcnbsd_nat ()
+{
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (ppcnbsd_supply_pcb);
+
+ add_inf_child_target (&the_ppc_nbsd_nat_target);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/powerpc.
+
+ Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbtypes.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "trad-frame.h"
+#include "tramp-frame.h"
+
+#include "ppc-tdep.h"
+#include "netbsd-tdep.h"
+#include "ppc-tdep.h"
+#include "solib-svr4.h"
+
+/* Register offsets from <machine/reg.h>. */
+struct ppc_reg_offsets ppcnbsd_reg_offsets;
+\f
+
+/* Core file support. */
+
+/* NetBSD/powerpc register sets. */
+
+const struct regset ppcnbsd_gregset =
+{
+ &ppcnbsd_reg_offsets,
+ ppc_supply_gregset
+};
+
+const struct regset ppcnbsd_fpregset =
+{
+ &ppcnbsd_reg_offsets,
+ ppc_supply_fpregset
+};
+
+/* Iterate over core file register note sections. */
+
+static void
+ppcnbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ cb (".reg", 148, 148, &ppcnbsd_gregset, NULL, cb_data);
+ cb (".reg2", 264, 264, &ppcnbsd_fpregset, NULL, cb_data);
+}
+\f
+
+/* NetBSD is confused. It appears that 1.5 was using the correct SVR4
+ convention but, 1.6 switched to the below broken convention. For
+ the moment use the broken convention. Ulgh! */
+
+static enum return_value_convention
+ppcnbsd_return_value (struct gdbarch *gdbarch, struct value *function,
+ struct type *valtype, struct regcache *regcache,
+ gdb_byte *readbuf, const gdb_byte *writebuf)
+{
+#if 0
+ if ((valtype->code () == TYPE_CODE_STRUCT
+ || valtype->code () == TYPE_CODE_UNION)
+ && !((TYPE_LENGTH (valtype) == 16 || TYPE_LENGTH (valtype) == 8)
+ && valtype->is_vector ())
+ && !(TYPE_LENGTH (valtype) == 1
+ || TYPE_LENGTH (valtype) == 2
+ || TYPE_LENGTH (valtype) == 4
+ || TYPE_LENGTH (valtype) == 8))
+ return RETURN_VALUE_STRUCT_CONVENTION;
+ else
+#endif
+ return ppc_sysv_abi_broken_return_value (gdbarch, function, valtype,
+ regcache, readbuf, writebuf);
+}
+\f
+
+/* Signal trampolines. */
+
+extern const struct tramp_frame ppcnbsd2_sigtramp;
+
+static void
+ppcnbsd_sigtramp_cache_init (const struct tramp_frame *self,
+ struct frame_info *this_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ CORE_ADDR addr, base;
+ int i;
+
+ base = get_frame_register_unsigned (this_frame,
+ gdbarch_sp_regnum (gdbarch));
+ if (self == &ppcnbsd2_sigtramp)
+ addr = base + 0x10 + 2 * tdep->wordsize;
+ else
+ addr = base + 0x18 + 2 * tdep->wordsize;
+ for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
+ {
+ int regnum = i + tdep->ppc_gp0_regnum;
+ trad_frame_set_reg_addr (this_cache, regnum, addr);
+ }
+ trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, addr);
+ addr += tdep->wordsize;
+ trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, addr);
+ addr += tdep->wordsize;
+ trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, addr);
+ addr += tdep->wordsize;
+ trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, addr);
+ addr += tdep->wordsize;
+ trad_frame_set_reg_addr (this_cache, gdbarch_pc_regnum (gdbarch),
+ addr); /* SRR0? */
+ addr += tdep->wordsize;
+
+ /* Construct the frame ID using the function start. */
+ trad_frame_set_id (this_cache, frame_id_build (base, func));
+}
+
+static const struct tramp_frame ppcnbsd_sigtramp =
+{
+ SIGTRAMP_FRAME,
+ 4,
+ {
+ { 0x3821fff0, ULONGEST_MAX }, /* add r1,r1,-16 */
+ { 0x4e800021, ULONGEST_MAX }, /* blrl */
+ { 0x38610018, ULONGEST_MAX }, /* addi r3,r1,24 */
+ { 0x38000127, ULONGEST_MAX }, /* li r0,295 */
+ { 0x44000002, ULONGEST_MAX }, /* sc */
+ { 0x38000001, ULONGEST_MAX }, /* li r0,1 */
+ { 0x44000002, ULONGEST_MAX }, /* sc */
+ { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
+ },
+ ppcnbsd_sigtramp_cache_init
+};
+
+/* NetBSD 2.0 introduced a slightly different signal trampoline. */
+
+const struct tramp_frame ppcnbsd2_sigtramp =
+{
+ SIGTRAMP_FRAME,
+ 4,
+ {
+ { 0x3821fff0, ULONGEST_MAX }, /* add r1,r1,-16 */
+ { 0x4e800021, ULONGEST_MAX }, /* blrl */
+ { 0x38610010, ULONGEST_MAX }, /* addi r3,r1,16 */
+ { 0x38000127, ULONGEST_MAX }, /* li r0,295 */
+ { 0x44000002, ULONGEST_MAX }, /* sc */
+ { 0x38000001, ULONGEST_MAX }, /* li r0,1 */
+ { 0x44000002, ULONGEST_MAX }, /* sc */
+ { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
+ },
+ ppcnbsd_sigtramp_cache_init
+};
+\f
+
+static void
+ppcnbsd_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ nbsd_init_abi (info, gdbarch);
+
+ /* For NetBSD, this is an on again, off again thing. Some systems
+ do use the broken struct convention, and some don't. */
+ set_gdbarch_return_value (gdbarch, ppcnbsd_return_value);
+
+ /* NetBSD uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, ppcnbsd_iterate_over_regset_sections);
+
+ tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd_sigtramp);
+ tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd2_sigtramp);
+}
+
+void _initialize_ppcnbsd_tdep ();
+void
+_initialize_ppcnbsd_tdep ()
+{
+ gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_NETBSD,
+ ppcnbsd_init_abi);
+
+ /* Avoid initializing the register offsets again if they were
+ already initialized by ppc-netbsd-nat.c. */
+ if (ppcnbsd_reg_offsets.pc_offset == 0)
+ {
+ /* General-purpose registers. */
+ ppcnbsd_reg_offsets.r0_offset = 0;
+ ppcnbsd_reg_offsets.gpr_size = 4;
+ ppcnbsd_reg_offsets.xr_size = 4;
+ ppcnbsd_reg_offsets.lr_offset = 128;
+ ppcnbsd_reg_offsets.cr_offset = 132;
+ ppcnbsd_reg_offsets.xer_offset = 136;
+ ppcnbsd_reg_offsets.ctr_offset = 140;
+ ppcnbsd_reg_offsets.pc_offset = 144;
+ ppcnbsd_reg_offsets.ps_offset = -1;
+ ppcnbsd_reg_offsets.mq_offset = -1;
+
+ /* Floating-point registers. */
+ ppcnbsd_reg_offsets.f0_offset = 0;
+ ppcnbsd_reg_offsets.fpscr_offset = 256;
+ ppcnbsd_reg_offsets.fpscr_size = 4;
+
+ }
+}
--- /dev/null
+/* Target-dependent code for NetBSD/powerpc.
+
+ Copyright (C) 2004-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef PPC_NBSD_TDEP_H
+#define PPC_NBSD_TDEP_H
+
+struct regset;
+
+/* Register offsets for NetBSD/powerpc. */
+extern struct ppc_reg_offsets ppcnbsd_reg_offsets;
+
+/* Register sets for NetBSD/powerpc. */
+extern const struct regset ppcnbsd_gregset;
+extern const struct regset ppcnbsd_fpregset;
+
+#endif /* PPC_NBSD_TDEP_H */
+++ /dev/null
-/* Native-dependent code for NetBSD/sh.
-
- Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "inferior.h"
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-#include "sh-tdep.h"
-#include "inf-ptrace.h"
-#include "nbsd-nat.h"
-#include "regcache.h"
-
-struct sh_nbsd_nat_target final : public nbsd_nat_target
-{
- void fetch_registers (struct regcache *, int) override;
- void store_registers (struct regcache *, int) override;
-};
-
-static sh_nbsd_nat_target the_sh_nbsd_nat_target;
-
-/* Determine if PT_GETREGS fetches this register. */
-#define GETREGS_SUPPLIES(gdbarch, regno) \
- (((regno) >= R0_REGNUM && (regno) <= (R0_REGNUM + 15)) \
-|| (regno) == gdbarch_pc_regnum (gdbarch) || (regno) == PR_REGNUM \
-|| (regno) == MACH_REGNUM || (regno) == MACL_REGNUM \
-|| (regno) == SR_REGNUM)
-
-/* Sizeof `struct reg' in <machine/reg.h>. */
-#define SHNBSD_SIZEOF_GREGS (21 * 4)
-
-void
-sh_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
-{
- pid_t pid = regcache->ptid ().pid ();
- int lwp = regcache->ptid ().lwp ();
-
- if (regno == -1 || GETREGS_SUPPLIES (regcache->arch (), regno))
- {
- struct reg inferior_registers;
-
- if (ptrace (PT_GETREGS, pid,
- (PTRACE_TYPE_ARG3) &inferior_registers, lwp) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- sh_corefile_supply_regset (&sh_corefile_gregset, regcache, regno,
- (char *) &inferior_registers,
- SHNBSD_SIZEOF_GREGS);
-
- if (regno != -1)
- return;
- }
-}
-
-void
-sh_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
-{
- pid_t pid = regcache->ptid ().pid ();
- int lwp = regcache->ptid ().lwp ();
-
- if (regno == -1 || GETREGS_SUPPLIES (regcache->arch (), regno))
- {
- struct reg inferior_registers;
-
- if (ptrace (PT_GETREGS, pid,
- (PTRACE_TYPE_ARG3) &inferior_registers, lwp) == -1)
- perror_with_name (_("Couldn't get registers"));
-
- sh_corefile_collect_regset (&sh_corefile_gregset, regcache, regno,
- (char *) &inferior_registers,
- SHNBSD_SIZEOF_GREGS);
-
- if (ptrace (PT_SETREGS, pid,
- (PTRACE_TYPE_ARG3) &inferior_registers, lwp) == -1)
- perror_with_name (_("Couldn't set registers"));
-
- if (regno != -1)
- return;
- }
-}
-
-void _initialize_shnbsd_nat ();
-void
-_initialize_shnbsd_nat ()
-{
- add_inf_child_target (&the_sh_nbsd_nat_target);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/sh.
-
- Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "regset.h"
-#include "value.h"
-#include "osabi.h"
-
-#include "sh-tdep.h"
-#include "nbsd-tdep.h"
-#include "solib-svr4.h"
-#include "gdbarch.h"
-
-/* Convert a register number into an offset into a ptrace
- register structure. */
-static const struct sh_corefile_regmap regmap[] =
-{
- {R0_REGNUM, 20 * 4},
- {R0_REGNUM + 1, 19 * 4},
- {R0_REGNUM + 2, 18 * 4},
- {R0_REGNUM + 3, 17 * 4},
- {R0_REGNUM + 4, 16 * 4},
- {R0_REGNUM + 5, 15 * 4},
- {R0_REGNUM + 6, 14 * 4},
- {R0_REGNUM + 7, 13 * 4},
- {R0_REGNUM + 8, 12 * 4},
- {R0_REGNUM + 9, 11 * 4},
- {R0_REGNUM + 10, 10 * 4},
- {R0_REGNUM + 11, 9 * 4},
- {R0_REGNUM + 12, 8 * 4},
- {R0_REGNUM + 13, 7 * 4},
- {R0_REGNUM + 14, 6 * 4},
- {R0_REGNUM + 15, 5 * 4},
- {PC_REGNUM, 0 * 4},
- {SR_REGNUM, 1 * 4},
- {PR_REGNUM, 2 * 4},
- {MACH_REGNUM, 3 * 4},
- {MACL_REGNUM, 4 * 4},
- {-1 /* Terminator. */, 0}
-};
-\f
-
-static void
-shnbsd_init_abi (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- nbsd_init_abi (info, gdbarch);
-
- tdep->core_gregmap = (struct sh_corefile_regmap *)regmap;
- tdep->sizeof_gregset = 84;
-
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-}
-
-void _initialize_shnbsd_tdep ();
-void
-_initialize_shnbsd_tdep ()
-{
- gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_NETBSD,
- shnbsd_init_abi);
- gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_OPENBSD,
- shnbsd_init_abi);
-}
--- /dev/null
+/* Native-dependent code for NetBSD/sh.
+
+ Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "inferior.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "sh-tdep.h"
+#include "inf-ptrace.h"
+#include "netbsd-nat.h"
+#include "regcache.h"
+
+struct sh_nbsd_nat_target final : public nbsd_nat_target
+{
+ void fetch_registers (struct regcache *, int) override;
+ void store_registers (struct regcache *, int) override;
+};
+
+static sh_nbsd_nat_target the_sh_nbsd_nat_target;
+
+/* Determine if PT_GETREGS fetches this register. */
+#define GETREGS_SUPPLIES(gdbarch, regno) \
+ (((regno) >= R0_REGNUM && (regno) <= (R0_REGNUM + 15)) \
+|| (regno) == gdbarch_pc_regnum (gdbarch) || (regno) == PR_REGNUM \
+|| (regno) == MACH_REGNUM || (regno) == MACL_REGNUM \
+|| (regno) == SR_REGNUM)
+
+/* Sizeof `struct reg' in <machine/reg.h>. */
+#define SHNBSD_SIZEOF_GREGS (21 * 4)
+
+void
+sh_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
+{
+ pid_t pid = regcache->ptid ().pid ();
+ int lwp = regcache->ptid ().lwp ();
+
+ if (regno == -1 || GETREGS_SUPPLIES (regcache->arch (), regno))
+ {
+ struct reg inferior_registers;
+
+ if (ptrace (PT_GETREGS, pid,
+ (PTRACE_TYPE_ARG3) &inferior_registers, lwp) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ sh_corefile_supply_regset (&sh_corefile_gregset, regcache, regno,
+ (char *) &inferior_registers,
+ SHNBSD_SIZEOF_GREGS);
+
+ if (regno != -1)
+ return;
+ }
+}
+
+void
+sh_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
+{
+ pid_t pid = regcache->ptid ().pid ();
+ int lwp = regcache->ptid ().lwp ();
+
+ if (regno == -1 || GETREGS_SUPPLIES (regcache->arch (), regno))
+ {
+ struct reg inferior_registers;
+
+ if (ptrace (PT_GETREGS, pid,
+ (PTRACE_TYPE_ARG3) &inferior_registers, lwp) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ sh_corefile_collect_regset (&sh_corefile_gregset, regcache, regno,
+ (char *) &inferior_registers,
+ SHNBSD_SIZEOF_GREGS);
+
+ if (ptrace (PT_SETREGS, pid,
+ (PTRACE_TYPE_ARG3) &inferior_registers, lwp) == -1)
+ perror_with_name (_("Couldn't set registers"));
+
+ if (regno != -1)
+ return;
+ }
+}
+
+void _initialize_shnbsd_nat ();
+void
+_initialize_shnbsd_nat ()
+{
+ add_inf_child_target (&the_sh_nbsd_nat_target);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/sh.
+
+ Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "regset.h"
+#include "value.h"
+#include "osabi.h"
+
+#include "sh-tdep.h"
+#include "netbsd-tdep.h"
+#include "solib-svr4.h"
+#include "gdbarch.h"
+
+/* Convert a register number into an offset into a ptrace
+ register structure. */
+static const struct sh_corefile_regmap regmap[] =
+{
+ {R0_REGNUM, 20 * 4},
+ {R0_REGNUM + 1, 19 * 4},
+ {R0_REGNUM + 2, 18 * 4},
+ {R0_REGNUM + 3, 17 * 4},
+ {R0_REGNUM + 4, 16 * 4},
+ {R0_REGNUM + 5, 15 * 4},
+ {R0_REGNUM + 6, 14 * 4},
+ {R0_REGNUM + 7, 13 * 4},
+ {R0_REGNUM + 8, 12 * 4},
+ {R0_REGNUM + 9, 11 * 4},
+ {R0_REGNUM + 10, 10 * 4},
+ {R0_REGNUM + 11, 9 * 4},
+ {R0_REGNUM + 12, 8 * 4},
+ {R0_REGNUM + 13, 7 * 4},
+ {R0_REGNUM + 14, 6 * 4},
+ {R0_REGNUM + 15, 5 * 4},
+ {PC_REGNUM, 0 * 4},
+ {SR_REGNUM, 1 * 4},
+ {PR_REGNUM, 2 * 4},
+ {MACH_REGNUM, 3 * 4},
+ {MACL_REGNUM, 4 * 4},
+ {-1 /* Terminator. */, 0}
+};
+\f
+
+static void
+shnbsd_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ nbsd_init_abi (info, gdbarch);
+
+ tdep->core_gregmap = (struct sh_corefile_regmap *)regmap;
+ tdep->sizeof_gregset = 84;
+
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+
+void _initialize_shnbsd_tdep ();
+void
+_initialize_shnbsd_tdep ()
+{
+ gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_NETBSD,
+ shnbsd_init_abi);
+ gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_OPENBSD,
+ shnbsd_init_abi);
+}
+++ /dev/null
-/* Native-dependent code for NetBSD/sparc.
-
- Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "regcache.h"
-#include "target.h"
-
-#include "sparc-tdep.h"
-#include "sparc-nat.h"
-
-/* Support for debugging kernel virtual memory images. */
-
-#include <sys/types.h>
-#include <machine/pcb.h>
-
-#include "bsd-kvm.h"
-
-static int
-sparc32nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- /* The following is true for NetBSD 1.6.2:
-
- The pcb contains %sp, %pc, %psr and %wim. From this information
- we reconstruct the register state as it would look when we just
- returned from cpu_switch(). */
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_sp == 0)
- return 0;
-
- regcache->raw_supply (SPARC_SP_REGNUM, &pcb->pcb_sp);
- regcache->raw_supply (SPARC_O7_REGNUM, &pcb->pcb_pc);
- regcache->raw_supply (SPARC32_PSR_REGNUM, &pcb->pcb_psr);
- regcache->raw_supply (SPARC32_WIM_REGNUM, &pcb->pcb_wim);
- regcache->raw_supply (SPARC32_PC_REGNUM, &pcb->pcb_pc);
-
- sparc_supply_rwindow (regcache, pcb->pcb_sp, -1);
-
- return 1;
-}
-
-static sparc_target<inf_ptrace_target> the_sparc_nbsd_nat_target;
-
-void _initialize_sparcnbsd_nat ();
-void
-_initialize_sparcnbsd_nat ()
-{
- sparc_gregmap = &sparc32nbsd_gregmap;
- sparc_fpregmap = &sparc32_bsd_fpregmap;
-
- add_inf_child_target (&sparc_nbsd_nat_target);
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (sparc32nbsd_supply_pcb);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/sparc.
-
- Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "frame.h"
-#include "frame-unwind.h"
-#include "gdbcore.h"
-#include "gdbtypes.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-#include "solib-svr4.h"
-#include "symtab.h"
-#include "trad-frame.h"
-#include "gdbarch.h"
-
-#include "sparc-tdep.h"
-#include "nbsd-tdep.h"
-
-/* Macros to extract fields from SPARC instructions. */
-#define X_RS1(i) (((i) >> 14) & 0x1f)
-#define X_RS2(i) ((i) & 0x1f)
-#define X_I(i) (((i) >> 13) & 1)
-
-const struct sparc_gregmap sparc32nbsd_gregmap =
-{
- 0 * 4, /* %psr */
- 1 * 4, /* %pc */
- 2 * 4, /* %npc */
- 3 * 4, /* %y */
- -1, /* %wim */
- -1, /* %tbr */
- 5 * 4, /* %g1 */
- -1 /* %l0 */
-};
-
-static void
-sparc32nbsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
-{
- sparc32_supply_gregset (&sparc32nbsd_gregmap, regcache, regnum, gregs);
-
- /* Traditional NetBSD core files don't use multiple register sets.
- Instead, the general-purpose and floating-point registers are
- lumped together in a single section. */
- if (len >= 212)
- sparc32_supply_fpregset (&sparc32_bsd_fpregmap, regcache, regnum,
- (const char *) gregs + 80);
-}
-
-static void
-sparc32nbsd_supply_fpregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *fpregs, size_t len)
-{
- sparc32_supply_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs);
-}
-
-\f
-/* Signal trampolines. */
-
-/* The following variables describe the location of an on-stack signal
- trampoline. The current values correspond to the memory layout for
- NetBSD 1.3 and up. These shouldn't be necessary for NetBSD 2.0 and
- up, since NetBSD uses signal trampolines provided by libc now. */
-
-static const CORE_ADDR sparc32nbsd_sigtramp_start = 0xeffffef0;
-static const CORE_ADDR sparc32nbsd_sigtramp_end = 0xeffffff0;
-
-static int
-sparc32nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
-{
- if (pc >= sparc32nbsd_sigtramp_start && pc < sparc32nbsd_sigtramp_end)
- return 1;
-
- return nbsd_pc_in_sigtramp (pc, name);
-}
-
-struct trad_frame_saved_reg *
-sparc32nbsd_sigcontext_saved_regs (struct frame_info *this_frame)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct trad_frame_saved_reg *saved_regs;
- CORE_ADDR addr, sigcontext_addr;
- int regnum, delta;
- ULONGEST psr;
-
- saved_regs = trad_frame_alloc_saved_regs (this_frame);
-
- /* We find the appropriate instance of `struct sigcontext' at a
- fixed offset in the signal frame. */
- addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
- sigcontext_addr = addr + 64 + 16;
-
- /* The registers are saved in bits and pieces scattered all over the
- place. The code below records their location on the assumption
- that the part of the signal trampoline that saves the state has
- been executed. */
-
- saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
- saved_regs[SPARC32_PC_REGNUM].addr = sigcontext_addr + 12;
- saved_regs[SPARC32_NPC_REGNUM].addr = sigcontext_addr + 16;
- saved_regs[SPARC32_PSR_REGNUM].addr = sigcontext_addr + 20;
- saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 24;
- saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 28;
-
- /* The remaining `global' registers and %y are saved in the `local'
- registers. */
- delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
- for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
- saved_regs[regnum].realreg = regnum + delta;
- saved_regs[SPARC32_Y_REGNUM].realreg = SPARC_L1_REGNUM;
-
- /* The remaining `out' registers can be found in the current frame's
- `in' registers. */
- delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
- for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
- saved_regs[regnum].realreg = regnum + delta;
- saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM;
-
- /* The `local' and `in' registers have been saved in the register
- save area. */
- addr = saved_regs[SPARC_SP_REGNUM].addr;
- addr = get_frame_memory_unsigned (this_frame, addr, 4);
- for (regnum = SPARC_L0_REGNUM;
- regnum <= SPARC_I7_REGNUM; regnum++, addr += 4)
- saved_regs[regnum].addr = addr;
-
- /* Handle StackGhost. */
- {
- ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
-
- if (wcookie != 0)
- {
- ULONGEST i7;
-
- addr = saved_regs[SPARC_I7_REGNUM].addr;
- i7 = get_frame_memory_unsigned (this_frame, addr, 4);
- trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie);
- }
- }
-
- /* The floating-point registers are only saved if the EF bit in %prs
- has been set. */
-
-#define PSR_EF 0x00001000
-
- addr = saved_regs[SPARC32_PSR_REGNUM].addr;
- psr = get_frame_memory_unsigned (this_frame, addr, 4);
- if (psr & PSR_EF)
- {
- CORE_ADDR sp;
-
- sp = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
- saved_regs[SPARC32_FSR_REGNUM].addr = sp + 96;
- for (regnum = SPARC_F0_REGNUM, addr = sp + 96 + 8;
- regnum <= SPARC_F31_REGNUM; regnum++, addr += 4)
- saved_regs[regnum].addr = addr;
- }
-
- return saved_regs;
-}
-
-static struct sparc_frame_cache *
-sparc32nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
- void **this_cache)
-{
- struct sparc_frame_cache *cache;
- CORE_ADDR addr;
-
- if (*this_cache)
- return (struct sparc_frame_cache *) *this_cache;
-
- cache = sparc_frame_cache (this_frame, this_cache);
- gdb_assert (cache == *this_cache);
-
- /* If we couldn't find the frame's function, we're probably dealing
- with an on-stack signal trampoline. */
- if (cache->pc == 0)
- {
- cache->pc = sparc32nbsd_sigtramp_start;
-
- /* Since we couldn't find the frame's function, the cache was
- initialized under the assumption that we're frameless. */
- sparc_record_save_insn (cache);
- addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
- cache->base = addr;
- }
-
- cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (this_frame);
-
- return cache;
-}
-
-static void
-sparc32nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
- void **this_cache,
- struct frame_id *this_id)
-{
- struct sparc_frame_cache *cache =
- sparc32nbsd_sigcontext_frame_cache (this_frame, this_cache);
-
- (*this_id) = frame_id_build (cache->base, cache->pc);
-}
-
-static struct value *
-sparc32nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
-{
- struct sparc_frame_cache *cache =
- sparc32nbsd_sigcontext_frame_cache (this_frame, this_cache);
-
- return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
-}
-
-static int
-sparc32nbsd_sigcontext_frame_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_cache)
-{
- CORE_ADDR pc = get_frame_pc (this_frame);
- const char *name;
-
- find_pc_partial_function (pc, &name, NULL, NULL);
- if (sparc32nbsd_pc_in_sigtramp (pc, name))
- {
- if (name == NULL || !startswith (name, "__sigtramp_sigcontext"))
- return 1;
- }
-
- return 0;
-}
-
-static const struct frame_unwind sparc32nbsd_sigcontext_frame_unwind =
-{
- SIGTRAMP_FRAME,
- default_frame_unwind_stop_reason,
- sparc32nbsd_sigcontext_frame_this_id,
- sparc32nbsd_sigcontext_frame_prev_register,
- NULL,
- sparc32nbsd_sigcontext_frame_sniffer
-};
-\f
-/* Return the address of a system call's alternative return
- address. */
-
-CORE_ADDR
-sparcnbsd_step_trap (struct frame_info *frame, unsigned long insn)
-{
- if ((X_I (insn) == 0 && X_RS1 (insn) == 0 && X_RS2 (insn) == 0)
- || (X_I (insn) == 1 && X_RS1 (insn) == 0 && (insn & 0x7f) == 0))
- {
- /* "New" system call. */
- ULONGEST number = get_frame_register_unsigned (frame, SPARC_G1_REGNUM);
-
- if (number & 0x400)
- return get_frame_register_unsigned (frame, SPARC_G2_REGNUM);
- if (number & 0x800)
- return get_frame_register_unsigned (frame, SPARC_G7_REGNUM);
- }
-
- return 0;
-}
-\f
-
-static const struct regset sparc32nbsd_gregset =
- {
- NULL, sparc32nbsd_supply_gregset, NULL
- };
-
-static const struct regset sparc32nbsd_fpregset =
- {
- NULL, sparc32nbsd_supply_fpregset, NULL
- };
-
-void
-sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- nbsd_init_abi (info, gdbarch);
-
- /* NetBSD doesn't support the 128-bit `long double' from the psABI. */
- set_gdbarch_long_double_bit (gdbarch, 64);
- set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
-
- tdep->gregset = &sparc32nbsd_gregset;
- tdep->sizeof_gregset = 20 * 4;
-
- tdep->fpregset = &sparc32nbsd_fpregset;
- tdep->sizeof_fpregset = 33 * 4;
-
- /* Make sure we can single-step "new" syscalls. */
- tdep->step_trap = sparcnbsd_step_trap;
-
- frame_unwind_append_unwinder (gdbarch, &sparc32nbsd_sigcontext_frame_unwind);
-
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-}
-
-void _initialize_sparcnbsd_tdep ();
-void
-_initialize_sparcnbsd_tdep ()
-{
- gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD,
- sparc32nbsd_init_abi);
-}
--- /dev/null
+/* Native-dependent code for NetBSD/sparc.
+
+ Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "regcache.h"
+#include "target.h"
+
+#include "sparc-tdep.h"
+#include "sparc-nat.h"
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <sys/types.h>
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+static int
+sparc32nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ /* The following is true for NetBSD 1.6.2:
+
+ The pcb contains %sp, %pc, %psr and %wim. From this information
+ we reconstruct the register state as it would look when we just
+ returned from cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_sp == 0)
+ return 0;
+
+ regcache->raw_supply (SPARC_SP_REGNUM, &pcb->pcb_sp);
+ regcache->raw_supply (SPARC_O7_REGNUM, &pcb->pcb_pc);
+ regcache->raw_supply (SPARC32_PSR_REGNUM, &pcb->pcb_psr);
+ regcache->raw_supply (SPARC32_WIM_REGNUM, &pcb->pcb_wim);
+ regcache->raw_supply (SPARC32_PC_REGNUM, &pcb->pcb_pc);
+
+ sparc_supply_rwindow (regcache, pcb->pcb_sp, -1);
+
+ return 1;
+}
+
+static sparc_target<inf_ptrace_target> the_sparc_nbsd_nat_target;
+
+void _initialize_sparcnbsd_nat ();
+void
+_initialize_sparcnbsd_nat ()
+{
+ sparc_gregmap = &sparc32nbsd_gregmap;
+ sparc_fpregmap = &sparc32_bsd_fpregmap;
+
+ add_inf_child_target (&sparc_nbsd_nat_target);
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (sparc32nbsd_supply_pcb);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/sparc.
+
+ Copyright (C) 2002-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "frame.h"
+#include "frame-unwind.h"
+#include "gdbcore.h"
+#include "gdbtypes.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "solib-svr4.h"
+#include "symtab.h"
+#include "trad-frame.h"
+#include "gdbarch.h"
+
+#include "sparc-tdep.h"
+#include "netbsd-tdep.h"
+
+/* Macros to extract fields from SPARC instructions. */
+#define X_RS1(i) (((i) >> 14) & 0x1f)
+#define X_RS2(i) ((i) & 0x1f)
+#define X_I(i) (((i) >> 13) & 1)
+
+const struct sparc_gregmap sparc32nbsd_gregmap =
+{
+ 0 * 4, /* %psr */
+ 1 * 4, /* %pc */
+ 2 * 4, /* %npc */
+ 3 * 4, /* %y */
+ -1, /* %wim */
+ -1, /* %tbr */
+ 5 * 4, /* %g1 */
+ -1 /* %l0 */
+};
+
+static void
+sparc32nbsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ sparc32_supply_gregset (&sparc32nbsd_gregmap, regcache, regnum, gregs);
+
+ /* Traditional NetBSD core files don't use multiple register sets.
+ Instead, the general-purpose and floating-point registers are
+ lumped together in a single section. */
+ if (len >= 212)
+ sparc32_supply_fpregset (&sparc32_bsd_fpregmap, regcache, regnum,
+ (const char *) gregs + 80);
+}
+
+static void
+sparc32nbsd_supply_fpregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *fpregs, size_t len)
+{
+ sparc32_supply_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs);
+}
+
+\f
+/* Signal trampolines. */
+
+/* The following variables describe the location of an on-stack signal
+ trampoline. The current values correspond to the memory layout for
+ NetBSD 1.3 and up. These shouldn't be necessary for NetBSD 2.0 and
+ up, since NetBSD uses signal trampolines provided by libc now. */
+
+static const CORE_ADDR sparc32nbsd_sigtramp_start = 0xeffffef0;
+static const CORE_ADDR sparc32nbsd_sigtramp_end = 0xeffffff0;
+
+static int
+sparc32nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
+{
+ if (pc >= sparc32nbsd_sigtramp_start && pc < sparc32nbsd_sigtramp_end)
+ return 1;
+
+ return nbsd_pc_in_sigtramp (pc, name);
+}
+
+struct trad_frame_saved_reg *
+sparc32nbsd_sigcontext_saved_regs (struct frame_info *this_frame)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ struct trad_frame_saved_reg *saved_regs;
+ CORE_ADDR addr, sigcontext_addr;
+ int regnum, delta;
+ ULONGEST psr;
+
+ saved_regs = trad_frame_alloc_saved_regs (this_frame);
+
+ /* We find the appropriate instance of `struct sigcontext' at a
+ fixed offset in the signal frame. */
+ addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
+ sigcontext_addr = addr + 64 + 16;
+
+ /* The registers are saved in bits and pieces scattered all over the
+ place. The code below records their location on the assumption
+ that the part of the signal trampoline that saves the state has
+ been executed. */
+
+ saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
+ saved_regs[SPARC32_PC_REGNUM].addr = sigcontext_addr + 12;
+ saved_regs[SPARC32_NPC_REGNUM].addr = sigcontext_addr + 16;
+ saved_regs[SPARC32_PSR_REGNUM].addr = sigcontext_addr + 20;
+ saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 24;
+ saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 28;
+
+ /* The remaining `global' registers and %y are saved in the `local'
+ registers. */
+ delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
+ for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
+ saved_regs[regnum].realreg = regnum + delta;
+ saved_regs[SPARC32_Y_REGNUM].realreg = SPARC_L1_REGNUM;
+
+ /* The remaining `out' registers can be found in the current frame's
+ `in' registers. */
+ delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
+ for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
+ saved_regs[regnum].realreg = regnum + delta;
+ saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM;
+
+ /* The `local' and `in' registers have been saved in the register
+ save area. */
+ addr = saved_regs[SPARC_SP_REGNUM].addr;
+ addr = get_frame_memory_unsigned (this_frame, addr, 4);
+ for (regnum = SPARC_L0_REGNUM;
+ regnum <= SPARC_I7_REGNUM; regnum++, addr += 4)
+ saved_regs[regnum].addr = addr;
+
+ /* Handle StackGhost. */
+ {
+ ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
+
+ if (wcookie != 0)
+ {
+ ULONGEST i7;
+
+ addr = saved_regs[SPARC_I7_REGNUM].addr;
+ i7 = get_frame_memory_unsigned (this_frame, addr, 4);
+ trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie);
+ }
+ }
+
+ /* The floating-point registers are only saved if the EF bit in %prs
+ has been set. */
+
+#define PSR_EF 0x00001000
+
+ addr = saved_regs[SPARC32_PSR_REGNUM].addr;
+ psr = get_frame_memory_unsigned (this_frame, addr, 4);
+ if (psr & PSR_EF)
+ {
+ CORE_ADDR sp;
+
+ sp = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
+ saved_regs[SPARC32_FSR_REGNUM].addr = sp + 96;
+ for (regnum = SPARC_F0_REGNUM, addr = sp + 96 + 8;
+ regnum <= SPARC_F31_REGNUM; regnum++, addr += 4)
+ saved_regs[regnum].addr = addr;
+ }
+
+ return saved_regs;
+}
+
+static struct sparc_frame_cache *
+sparc32nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
+ void **this_cache)
+{
+ struct sparc_frame_cache *cache;
+ CORE_ADDR addr;
+
+ if (*this_cache)
+ return (struct sparc_frame_cache *) *this_cache;
+
+ cache = sparc_frame_cache (this_frame, this_cache);
+ gdb_assert (cache == *this_cache);
+
+ /* If we couldn't find the frame's function, we're probably dealing
+ with an on-stack signal trampoline. */
+ if (cache->pc == 0)
+ {
+ cache->pc = sparc32nbsd_sigtramp_start;
+
+ /* Since we couldn't find the frame's function, the cache was
+ initialized under the assumption that we're frameless. */
+ sparc_record_save_insn (cache);
+ addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
+ cache->base = addr;
+ }
+
+ cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (this_frame);
+
+ return cache;
+}
+
+static void
+sparc32nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
+ void **this_cache,
+ struct frame_id *this_id)
+{
+ struct sparc_frame_cache *cache =
+ sparc32nbsd_sigcontext_frame_cache (this_frame, this_cache);
+
+ (*this_id) = frame_id_build (cache->base, cache->pc);
+}
+
+static struct value *
+sparc32nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
+{
+ struct sparc_frame_cache *cache =
+ sparc32nbsd_sigcontext_frame_cache (this_frame, this_cache);
+
+ return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
+}
+
+static int
+sparc32nbsd_sigcontext_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_cache)
+{
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ const char *name;
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ if (sparc32nbsd_pc_in_sigtramp (pc, name))
+ {
+ if (name == NULL || !startswith (name, "__sigtramp_sigcontext"))
+ return 1;
+ }
+
+ return 0;
+}
+
+static const struct frame_unwind sparc32nbsd_sigcontext_frame_unwind =
+{
+ SIGTRAMP_FRAME,
+ default_frame_unwind_stop_reason,
+ sparc32nbsd_sigcontext_frame_this_id,
+ sparc32nbsd_sigcontext_frame_prev_register,
+ NULL,
+ sparc32nbsd_sigcontext_frame_sniffer
+};
+\f
+/* Return the address of a system call's alternative return
+ address. */
+
+CORE_ADDR
+sparcnbsd_step_trap (struct frame_info *frame, unsigned long insn)
+{
+ if ((X_I (insn) == 0 && X_RS1 (insn) == 0 && X_RS2 (insn) == 0)
+ || (X_I (insn) == 1 && X_RS1 (insn) == 0 && (insn & 0x7f) == 0))
+ {
+ /* "New" system call. */
+ ULONGEST number = get_frame_register_unsigned (frame, SPARC_G1_REGNUM);
+
+ if (number & 0x400)
+ return get_frame_register_unsigned (frame, SPARC_G2_REGNUM);
+ if (number & 0x800)
+ return get_frame_register_unsigned (frame, SPARC_G7_REGNUM);
+ }
+
+ return 0;
+}
+\f
+
+static const struct regset sparc32nbsd_gregset =
+ {
+ NULL, sparc32nbsd_supply_gregset, NULL
+ };
+
+static const struct regset sparc32nbsd_fpregset =
+ {
+ NULL, sparc32nbsd_supply_fpregset, NULL
+ };
+
+void
+sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ nbsd_init_abi (info, gdbarch);
+
+ /* NetBSD doesn't support the 128-bit `long double' from the psABI. */
+ set_gdbarch_long_double_bit (gdbarch, 64);
+ set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
+
+ tdep->gregset = &sparc32nbsd_gregset;
+ tdep->sizeof_gregset = 20 * 4;
+
+ tdep->fpregset = &sparc32nbsd_fpregset;
+ tdep->sizeof_fpregset = 33 * 4;
+
+ /* Make sure we can single-step "new" syscalls. */
+ tdep->step_trap = sparcnbsd_step_trap;
+
+ frame_unwind_append_unwinder (gdbarch, &sparc32nbsd_sigcontext_frame_unwind);
+
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+
+void _initialize_sparcnbsd_tdep ();
+void
+_initialize_sparcnbsd_tdep ()
+{
+ gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD,
+ sparc32nbsd_init_abi);
+}
+++ /dev/null
-/* Native-dependent code for NetBSD/sparc64.
-
- Copyright (C) 2003-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "target.h"
-
-#include "sparc64-tdep.h"
-#include "sparc-nat.h"
-
-/* NetBSD is different from the other OSes that support both SPARC and
- UltraSPARC in that the result of ptrace(2) depends on whether the
- traced process is 32-bit or 64-bit. */
-
-static void
-sparc64nbsd_supply_gregset (const struct sparc_gregmap *gregmap,
- struct regcache *regcache,
- int regnum, const void *gregs)
-{
- int sparc32 = (gdbarch_ptr_bit (regcache->arch ()) == 32);
-
- if (sparc32)
- sparc32_supply_gregset (&sparc32nbsd_gregmap, regcache, regnum, gregs);
- else
- sparc64_supply_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs);
-}
-
-static void
-sparc64nbsd_collect_gregset (const struct sparc_gregmap *gregmap,
- const struct regcache *regcache,
- int regnum, void *gregs)
-{
- int sparc32 = (gdbarch_ptr_bit (regcache->arch ()) == 32);
-
- if (sparc32)
- sparc32_collect_gregset (&sparc32nbsd_gregmap, regcache, regnum, gregs);
- else
- sparc64_collect_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs);
-}
-
-static void
-sparc64nbsd_supply_fpregset (const struct sparc_fpregmap *fpregmap,
- struct regcache *regcache,
- int regnum, const void *fpregs)
-{
- int sparc32 = (gdbarch_ptr_bit (regcache->arch ()) == 32);
-
- if (sparc32)
- sparc32_supply_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs);
- else
- sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
-}
-
-static void
-sparc64nbsd_collect_fpregset (const struct sparc_fpregmap *fpregmap,
- const struct regcache *regcache,
- int regnum, void *fpregs)
-{
- int sparc32 = (gdbarch_ptr_bit (regcache->arch ()) == 32);
-
- if (sparc32)
- sparc32_collect_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs);
- else
- sparc64_collect_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
-}
-
-/* Determine whether `gregset_t' contains register REGNUM. */
-
-static int
-sparc64nbsd_gregset_supplies_p (struct gdbarch *gdbarch, int regnum)
-{
- if (gdbarch_ptr_bit (gdbarch) == 32)
- return sparc32_gregset_supplies_p (gdbarch, regnum);
-
- /* Integer registers. */
- if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM)
- || (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
- || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_L7_REGNUM)
- || (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I7_REGNUM))
- return 1;
-
- /* Control registers. */
- if (regnum == SPARC64_PC_REGNUM
- || regnum == SPARC64_NPC_REGNUM
- || regnum == SPARC64_STATE_REGNUM
- || regnum == SPARC64_Y_REGNUM)
- return 1;
-
- return 0;
-}
-
-/* Determine whether `fpregset_t' contains register REGNUM. */
-
-static int
-sparc64nbsd_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum)
-{
- if (gdbarch_ptr_bit (gdbarch) == 32)
- return sparc32_fpregset_supplies_p (gdbarch, regnum);
-
- /* Floating-point registers. */
- if ((regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
- || (regnum >= SPARC64_F32_REGNUM && regnum <= SPARC64_F62_REGNUM))
- return 1;
-
- /* Control registers. */
- if (regnum == SPARC64_FSR_REGNUM)
- return 1;
-
- return 0;
-}
-\f
-
-/* Support for debugging kernel virtual memory images. */
-
-#include <sys/types.h>
-#include <machine/pcb.h>
-
-#include "bsd-kvm.h"
-
-static int
-sparc64nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
-{
- u_int64_t state;
- int regnum;
-
- /* The following is true for NetBSD 1.6.2:
-
- The pcb contains %sp and %pc, %pstate and %cwp. From this
- information we reconstruct the register state as it would look
- when we just returned from cpu_switch(). */
-
- /* The stack pointer shouldn't be zero. */
- if (pcb->pcb_sp == 0)
- return 0;
-
- /* If the program counter is zero, this is probably a core dump, and
- we can get %pc from the stack. */
- if (pcb->pcb_pc == 0)
- read_memory(pcb->pcb_sp + BIAS - 176 + (11 * 8),
- (gdb_byte *)&pcb->pcb_pc, sizeof pcb->pcb_pc);
-
- regcache->raw_supply (SPARC_SP_REGNUM, &pcb->pcb_sp);
- regcache->raw_supply (SPARC64_PC_REGNUM, &pcb->pcb_pc);
-
- state = pcb->pcb_pstate << 8 | pcb->pcb_cwp;
- regcache->raw_supply (SPARC64_STATE_REGNUM, &state);
-
- sparc_supply_rwindow (regcache, pcb->pcb_sp, -1);
-
- return 1;
-}
-
-/* We've got nothing to add to the generic SPARC target. */
-static sparc_target<inf_ptrace_target> the_sparc64_nbsd_nat_target;
-
-void _initialize_sparc64nbsd_nat ();
-void
-_initialize_sparc64nbsd_nat ()
-{
- sparc_supply_gregset = sparc64nbsd_supply_gregset;
- sparc_collect_gregset = sparc64nbsd_collect_gregset;
- sparc_supply_fpregset = sparc64nbsd_supply_fpregset;
- sparc_collect_fpregset = sparc64nbsd_collect_fpregset;
- sparc_gregset_supplies_p = sparc64nbsd_gregset_supplies_p;
- sparc_fpregset_supplies_p = sparc64nbsd_fpregset_supplies_p;
-
- add_inf_child_target (&the_sparc64_nbsd_nat_target);
-
- /* Support debugging kernel virtual memory images. */
- bsd_kvm_add_target (sparc64nbsd_supply_pcb);
-}
+++ /dev/null
-/* Target-dependent code for NetBSD/sparc64.
-
- Copyright (C) 2002-2020 Free Software Foundation, Inc.
- Based on code 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "frame.h"
-#include "frame-unwind.h"
-#include "gdbcore.h"
-#include "osabi.h"
-#include "regcache.h"
-#include "regset.h"
-#include "symtab.h"
-#include "objfiles.h"
-#include "solib-svr4.h"
-#include "trad-frame.h"
-
-#include "sparc64-tdep.h"
-#include "nbsd-tdep.h"
-
-/* From <machine/reg.h>. */
-const struct sparc_gregmap sparc64nbsd_gregmap =
-{
- 0 * 8, /* "tstate" */
- 1 * 8, /* %pc */
- 2 * 8, /* %npc */
- 3 * 8, /* %y */
- -1, /* %fprs */
- -1,
- 5 * 8, /* %g1 */
- -1, /* %l0 */
- 4 /* sizeof (%y) */
-};
-\f
-
-static void
-sparc64nbsd_supply_gregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
-{
- sparc64_supply_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs);
-}
-
-static void
-sparc64nbsd_supply_fpregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *fpregs, size_t len)
-{
- sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
-}
-\f
-
-/* Signal trampolines. */
-
-/* The following variables describe the location of an on-stack signal
- trampoline. The current values correspond to the memory layout for
- NetBSD 1.3 and up. These shouldn't be necessary for NetBSD 2.0 and
- up, since NetBSD uses signal trampolines provided by libc now. */
-
-static const CORE_ADDR sparc64nbsd_sigtramp_start = 0xffffffffffffdee4ULL;
-static const CORE_ADDR sparc64nbsd_sigtramp_end = 0xffffffffffffe000ULL;
-
-static int
-sparc64nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
-{
- if (pc >= sparc64nbsd_sigtramp_start && pc < sparc64nbsd_sigtramp_end)
- return 1;
-
- return nbsd_pc_in_sigtramp (pc, name);
-}
-
-struct trad_frame_saved_reg *
-sparc64nbsd_sigcontext_saved_regs (CORE_ADDR sigcontext_addr,
- struct frame_info *this_frame)
-{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct trad_frame_saved_reg *saved_regs;
- CORE_ADDR addr, sp;
- int regnum, delta;
-
- saved_regs = trad_frame_alloc_saved_regs (this_frame);
-
- /* The registers are saved in bits and pieces scattered all over the
- place. The code below records their location on the assumption
- that the part of the signal trampoline that saves the state has
- been executed. */
-
- saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
- saved_regs[SPARC64_PC_REGNUM].addr = sigcontext_addr + 16;
- saved_regs[SPARC64_NPC_REGNUM].addr = sigcontext_addr + 24;
- saved_regs[SPARC64_STATE_REGNUM].addr = sigcontext_addr + 32;
- saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 40;
- saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 48;
-
- /* The remaining `global' registers and %y are saved in the `local'
- registers. */
- delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
- for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
- saved_regs[regnum].realreg = regnum + delta;
- saved_regs[SPARC64_Y_REGNUM].realreg = SPARC_L1_REGNUM;
-
- /* The remaining `out' registers can be found in the current frame's
- `in' registers. */
- delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
- for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
- saved_regs[regnum].realreg = regnum + delta;
- saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM;
-
- /* The `local' and `in' registers have been saved in the register
- save area. */
- addr = saved_regs[SPARC_SP_REGNUM].addr;
- sp = get_frame_memory_unsigned (this_frame, addr, 8);
- for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS;
- regnum <= SPARC_I7_REGNUM; regnum++, addr += 8)
- saved_regs[regnum].addr = addr;
-
- /* Handle StackGhost. */
- {
- ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
-
- if (wcookie != 0)
- {
- ULONGEST i7;
-
- addr = saved_regs[SPARC_I7_REGNUM].addr;
- i7 = get_frame_memory_unsigned (this_frame, addr, 8);
- trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie);
- }
- }
-
- /* TODO: Handle the floating-point registers. */
-
- return saved_regs;
-}
-
-static struct sparc_frame_cache *
-sparc64nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
- void **this_cache)
-{
- struct sparc_frame_cache *cache;
- CORE_ADDR addr;
-
- if (*this_cache)
- return (struct sparc_frame_cache *) *this_cache;
-
- cache = sparc_frame_cache (this_frame, this_cache);
- gdb_assert (cache == *this_cache);
-
- /* If we couldn't find the frame's function, we're probably dealing
- with an on-stack signal trampoline. */
- if (cache->pc == 0)
- {
- cache->pc = sparc64nbsd_sigtramp_start;
-
- /* Since we couldn't find the frame's function, the cache was
- initialized under the assumption that we're frameless. */
- sparc_record_save_insn (cache);
- addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
- if (addr & 1)
- addr += BIAS;
- cache->base = addr;
- }
-
- /* We find the appropriate instance of `struct sigcontext' at a
- fixed offset in the signal frame. */
- addr = cache->base + 128 + 8;
- cache->saved_regs = sparc64nbsd_sigcontext_saved_regs (addr, this_frame);
-
- return cache;
-}
-
-static void
-sparc64nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
- void **this_cache,
- struct frame_id *this_id)
-{
- struct sparc_frame_cache *cache =
- sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
-
- (*this_id) = frame_id_build (cache->base, cache->pc);
-}
-
-static struct value *
-sparc64nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
-{
- struct sparc_frame_cache *cache =
- sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
-
- return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
-}
-
-static int
-sparc64nbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_cache)
-{
- CORE_ADDR pc = get_frame_pc (this_frame);
- const char *name;
-
- find_pc_partial_function (pc, &name, NULL, NULL);
- if (sparc64nbsd_pc_in_sigtramp (pc, name))
- {
- if (name == NULL || !startswith (name, "__sigtramp_sigcontext"))
- return 1;
- }
-
- return 0;
-}
-
-static const struct frame_unwind sparc64nbsd_sigcontext_frame_unwind =
-{
- SIGTRAMP_FRAME,
- default_frame_unwind_stop_reason,
- sparc64nbsd_sigcontext_frame_this_id,
- sparc64nbsd_sigcontext_frame_prev_register,
- NULL,
- sparc64nbsd_sigtramp_frame_sniffer
-};
-\f
-
-static const struct regset sparc64nbsd_gregset =
- {
- NULL, sparc64nbsd_supply_gregset, NULL
- };
-
-static const struct regset sparc64nbsd_fpregset =
- {
- NULL, sparc64nbsd_supply_fpregset, NULL
- };
-
-static void
-sparc64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- nbsd_init_abi (info, gdbarch);
-
- tdep->gregset = &sparc64nbsd_gregset;
- tdep->sizeof_gregset = 160;
-
- tdep->fpregset = &sparc64nbsd_fpregset;
- tdep->sizeof_fpregset = 272;
-
- /* Make sure we can single-step "new" syscalls. */
- tdep->step_trap = sparcnbsd_step_trap;
-
- frame_unwind_append_unwinder (gdbarch, &sparc64nbsd_sigcontext_frame_unwind);
-
- sparc64_init_abi (info, gdbarch);
-
- /* NetBSD/sparc64 has SVR4-style shared libraries. */
- set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
-}
-
-void _initialize_sparc64nbsd_tdep ();
-void
-_initialize_sparc64nbsd_tdep ()
-{
- gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
- GDB_OSABI_NETBSD, sparc64nbsd_init_abi);
-}
--- /dev/null
+/* Native-dependent code for NetBSD/sparc64.
+
+ Copyright (C) 2003-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "target.h"
+
+#include "sparc64-tdep.h"
+#include "sparc-nat.h"
+
+/* NetBSD is different from the other OSes that support both SPARC and
+ UltraSPARC in that the result of ptrace(2) depends on whether the
+ traced process is 32-bit or 64-bit. */
+
+static void
+sparc64nbsd_supply_gregset (const struct sparc_gregmap *gregmap,
+ struct regcache *regcache,
+ int regnum, const void *gregs)
+{
+ int sparc32 = (gdbarch_ptr_bit (regcache->arch ()) == 32);
+
+ if (sparc32)
+ sparc32_supply_gregset (&sparc32nbsd_gregmap, regcache, regnum, gregs);
+ else
+ sparc64_supply_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs);
+}
+
+static void
+sparc64nbsd_collect_gregset (const struct sparc_gregmap *gregmap,
+ const struct regcache *regcache,
+ int regnum, void *gregs)
+{
+ int sparc32 = (gdbarch_ptr_bit (regcache->arch ()) == 32);
+
+ if (sparc32)
+ sparc32_collect_gregset (&sparc32nbsd_gregmap, regcache, regnum, gregs);
+ else
+ sparc64_collect_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs);
+}
+
+static void
+sparc64nbsd_supply_fpregset (const struct sparc_fpregmap *fpregmap,
+ struct regcache *regcache,
+ int regnum, const void *fpregs)
+{
+ int sparc32 = (gdbarch_ptr_bit (regcache->arch ()) == 32);
+
+ if (sparc32)
+ sparc32_supply_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs);
+ else
+ sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
+}
+
+static void
+sparc64nbsd_collect_fpregset (const struct sparc_fpregmap *fpregmap,
+ const struct regcache *regcache,
+ int regnum, void *fpregs)
+{
+ int sparc32 = (gdbarch_ptr_bit (regcache->arch ()) == 32);
+
+ if (sparc32)
+ sparc32_collect_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs);
+ else
+ sparc64_collect_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
+}
+
+/* Determine whether `gregset_t' contains register REGNUM. */
+
+static int
+sparc64nbsd_gregset_supplies_p (struct gdbarch *gdbarch, int regnum)
+{
+ if (gdbarch_ptr_bit (gdbarch) == 32)
+ return sparc32_gregset_supplies_p (gdbarch, regnum);
+
+ /* Integer registers. */
+ if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM)
+ || (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
+ || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_L7_REGNUM)
+ || (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I7_REGNUM))
+ return 1;
+
+ /* Control registers. */
+ if (regnum == SPARC64_PC_REGNUM
+ || regnum == SPARC64_NPC_REGNUM
+ || regnum == SPARC64_STATE_REGNUM
+ || regnum == SPARC64_Y_REGNUM)
+ return 1;
+
+ return 0;
+}
+
+/* Determine whether `fpregset_t' contains register REGNUM. */
+
+static int
+sparc64nbsd_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum)
+{
+ if (gdbarch_ptr_bit (gdbarch) == 32)
+ return sparc32_fpregset_supplies_p (gdbarch, regnum);
+
+ /* Floating-point registers. */
+ if ((regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
+ || (regnum >= SPARC64_F32_REGNUM && regnum <= SPARC64_F62_REGNUM))
+ return 1;
+
+ /* Control registers. */
+ if (regnum == SPARC64_FSR_REGNUM)
+ return 1;
+
+ return 0;
+}
+\f
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <sys/types.h>
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+static int
+sparc64nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ u_int64_t state;
+ int regnum;
+
+ /* The following is true for NetBSD 1.6.2:
+
+ The pcb contains %sp and %pc, %pstate and %cwp. From this
+ information we reconstruct the register state as it would look
+ when we just returned from cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_sp == 0)
+ return 0;
+
+ /* If the program counter is zero, this is probably a core dump, and
+ we can get %pc from the stack. */
+ if (pcb->pcb_pc == 0)
+ read_memory(pcb->pcb_sp + BIAS - 176 + (11 * 8),
+ (gdb_byte *)&pcb->pcb_pc, sizeof pcb->pcb_pc);
+
+ regcache->raw_supply (SPARC_SP_REGNUM, &pcb->pcb_sp);
+ regcache->raw_supply (SPARC64_PC_REGNUM, &pcb->pcb_pc);
+
+ state = pcb->pcb_pstate << 8 | pcb->pcb_cwp;
+ regcache->raw_supply (SPARC64_STATE_REGNUM, &state);
+
+ sparc_supply_rwindow (regcache, pcb->pcb_sp, -1);
+
+ return 1;
+}
+
+/* We've got nothing to add to the generic SPARC target. */
+static sparc_target<inf_ptrace_target> the_sparc64_nbsd_nat_target;
+
+void _initialize_sparc64nbsd_nat ();
+void
+_initialize_sparc64nbsd_nat ()
+{
+ sparc_supply_gregset = sparc64nbsd_supply_gregset;
+ sparc_collect_gregset = sparc64nbsd_collect_gregset;
+ sparc_supply_fpregset = sparc64nbsd_supply_fpregset;
+ sparc_collect_fpregset = sparc64nbsd_collect_fpregset;
+ sparc_gregset_supplies_p = sparc64nbsd_gregset_supplies_p;
+ sparc_fpregset_supplies_p = sparc64nbsd_fpregset_supplies_p;
+
+ add_inf_child_target (&the_sparc64_nbsd_nat_target);
+
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (sparc64nbsd_supply_pcb);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/sparc64.
+
+ Copyright (C) 2002-2020 Free Software Foundation, Inc.
+ Based on code 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "frame.h"
+#include "frame-unwind.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "symtab.h"
+#include "objfiles.h"
+#include "solib-svr4.h"
+#include "trad-frame.h"
+
+#include "sparc64-tdep.h"
+#include "netbsd-tdep.h"
+
+/* From <machine/reg.h>. */
+const struct sparc_gregmap sparc64nbsd_gregmap =
+{
+ 0 * 8, /* "tstate" */
+ 1 * 8, /* %pc */
+ 2 * 8, /* %npc */
+ 3 * 8, /* %y */
+ -1, /* %fprs */
+ -1,
+ 5 * 8, /* %g1 */
+ -1, /* %l0 */
+ 4 /* sizeof (%y) */
+};
+\f
+
+static void
+sparc64nbsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ sparc64_supply_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs);
+}
+
+static void
+sparc64nbsd_supply_fpregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *fpregs, size_t len)
+{
+ sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
+}
+\f
+
+/* Signal trampolines. */
+
+/* The following variables describe the location of an on-stack signal
+ trampoline. The current values correspond to the memory layout for
+ NetBSD 1.3 and up. These shouldn't be necessary for NetBSD 2.0 and
+ up, since NetBSD uses signal trampolines provided by libc now. */
+
+static const CORE_ADDR sparc64nbsd_sigtramp_start = 0xffffffffffffdee4ULL;
+static const CORE_ADDR sparc64nbsd_sigtramp_end = 0xffffffffffffe000ULL;
+
+static int
+sparc64nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
+{
+ if (pc >= sparc64nbsd_sigtramp_start && pc < sparc64nbsd_sigtramp_end)
+ return 1;
+
+ return nbsd_pc_in_sigtramp (pc, name);
+}
+
+struct trad_frame_saved_reg *
+sparc64nbsd_sigcontext_saved_regs (CORE_ADDR sigcontext_addr,
+ struct frame_info *this_frame)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ struct trad_frame_saved_reg *saved_regs;
+ CORE_ADDR addr, sp;
+ int regnum, delta;
+
+ saved_regs = trad_frame_alloc_saved_regs (this_frame);
+
+ /* The registers are saved in bits and pieces scattered all over the
+ place. The code below records their location on the assumption
+ that the part of the signal trampoline that saves the state has
+ been executed. */
+
+ saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
+ saved_regs[SPARC64_PC_REGNUM].addr = sigcontext_addr + 16;
+ saved_regs[SPARC64_NPC_REGNUM].addr = sigcontext_addr + 24;
+ saved_regs[SPARC64_STATE_REGNUM].addr = sigcontext_addr + 32;
+ saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 40;
+ saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 48;
+
+ /* The remaining `global' registers and %y are saved in the `local'
+ registers. */
+ delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
+ for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
+ saved_regs[regnum].realreg = regnum + delta;
+ saved_regs[SPARC64_Y_REGNUM].realreg = SPARC_L1_REGNUM;
+
+ /* The remaining `out' registers can be found in the current frame's
+ `in' registers. */
+ delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
+ for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
+ saved_regs[regnum].realreg = regnum + delta;
+ saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM;
+
+ /* The `local' and `in' registers have been saved in the register
+ save area. */
+ addr = saved_regs[SPARC_SP_REGNUM].addr;
+ sp = get_frame_memory_unsigned (this_frame, addr, 8);
+ for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS;
+ regnum <= SPARC_I7_REGNUM; regnum++, addr += 8)
+ saved_regs[regnum].addr = addr;
+
+ /* Handle StackGhost. */
+ {
+ ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
+
+ if (wcookie != 0)
+ {
+ ULONGEST i7;
+
+ addr = saved_regs[SPARC_I7_REGNUM].addr;
+ i7 = get_frame_memory_unsigned (this_frame, addr, 8);
+ trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie);
+ }
+ }
+
+ /* TODO: Handle the floating-point registers. */
+
+ return saved_regs;
+}
+
+static struct sparc_frame_cache *
+sparc64nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
+ void **this_cache)
+{
+ struct sparc_frame_cache *cache;
+ CORE_ADDR addr;
+
+ if (*this_cache)
+ return (struct sparc_frame_cache *) *this_cache;
+
+ cache = sparc_frame_cache (this_frame, this_cache);
+ gdb_assert (cache == *this_cache);
+
+ /* If we couldn't find the frame's function, we're probably dealing
+ with an on-stack signal trampoline. */
+ if (cache->pc == 0)
+ {
+ cache->pc = sparc64nbsd_sigtramp_start;
+
+ /* Since we couldn't find the frame's function, the cache was
+ initialized under the assumption that we're frameless. */
+ sparc_record_save_insn (cache);
+ addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
+ if (addr & 1)
+ addr += BIAS;
+ cache->base = addr;
+ }
+
+ /* We find the appropriate instance of `struct sigcontext' at a
+ fixed offset in the signal frame. */
+ addr = cache->base + 128 + 8;
+ cache->saved_regs = sparc64nbsd_sigcontext_saved_regs (addr, this_frame);
+
+ return cache;
+}
+
+static void
+sparc64nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
+ void **this_cache,
+ struct frame_id *this_id)
+{
+ struct sparc_frame_cache *cache =
+ sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
+
+ (*this_id) = frame_id_build (cache->base, cache->pc);
+}
+
+static struct value *
+sparc64nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
+{
+ struct sparc_frame_cache *cache =
+ sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
+
+ return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
+}
+
+static int
+sparc64nbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_cache)
+{
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ const char *name;
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ if (sparc64nbsd_pc_in_sigtramp (pc, name))
+ {
+ if (name == NULL || !startswith (name, "__sigtramp_sigcontext"))
+ return 1;
+ }
+
+ return 0;
+}
+
+static const struct frame_unwind sparc64nbsd_sigcontext_frame_unwind =
+{
+ SIGTRAMP_FRAME,
+ default_frame_unwind_stop_reason,
+ sparc64nbsd_sigcontext_frame_this_id,
+ sparc64nbsd_sigcontext_frame_prev_register,
+ NULL,
+ sparc64nbsd_sigtramp_frame_sniffer
+};
+\f
+
+static const struct regset sparc64nbsd_gregset =
+ {
+ NULL, sparc64nbsd_supply_gregset, NULL
+ };
+
+static const struct regset sparc64nbsd_fpregset =
+ {
+ NULL, sparc64nbsd_supply_fpregset, NULL
+ };
+
+static void
+sparc64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ nbsd_init_abi (info, gdbarch);
+
+ tdep->gregset = &sparc64nbsd_gregset;
+ tdep->sizeof_gregset = 160;
+
+ tdep->fpregset = &sparc64nbsd_fpregset;
+ tdep->sizeof_fpregset = 272;
+
+ /* Make sure we can single-step "new" syscalls. */
+ tdep->step_trap = sparcnbsd_step_trap;
+
+ frame_unwind_append_unwinder (gdbarch, &sparc64nbsd_sigcontext_frame_unwind);
+
+ sparc64_init_abi (info, gdbarch);
+
+ /* NetBSD/sparc64 has SVR4-style shared libraries. */
+ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_lp64_fetch_link_map_offsets);
+}
+
+void _initialize_sparc64nbsd_tdep ();
+void
+_initialize_sparc64nbsd_tdep ()
+{
+ gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
+ GDB_OSABI_NETBSD, sparc64nbsd_init_abi);
+}
/* Register offsets for FreeBSD/sparc64. */
extern const struct sparc_gregmap sparc64fbsd_gregmap;
-/* Functions and variables exported from sparc64-nbsd-tdep.c. */
+/* Functions and variables exported from sparc64-netbsd-tdep.c. */
/* Register offsets for NetBSD/sparc64. */
extern const struct sparc_gregmap sparc64nbsd_gregmap;
#include "vax-tdep.h"
#include "inf-ptrace.h"
-#include "nbsd-nat.h"
+#include "netbsd-nat.h"
struct vax_bsd_nat_target final : public nbsd_nat_target
{
+++ /dev/null
-/* Target-dependent code for NetBSD/vax.
-
- Copyright (C) 2004-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "arch-utils.h"
-#include "osabi.h"
-
-#include "vax-tdep.h"
-#include "nbsd-tdep.h"
-#include "solib-svr4.h"
-
-/* NetBSD ELF. */
-
-static void
-vaxnbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
- nbsd_init_abi (info, gdbarch);
-
- /* NetBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-}
-
-void _initialize_vaxnbsd_tdep ();
-void
-_initialize_vaxnbsd_tdep ()
-{
- gdbarch_register_osabi (bfd_arch_vax, 0, GDB_OSABI_NETBSD,
- vaxnbsd_elf_init_abi);
-}
--- /dev/null
+/* Target-dependent code for NetBSD/vax.
+
+ Copyright (C) 2004-2020 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "osabi.h"
+
+#include "vax-tdep.h"
+#include "netbsd-tdep.h"
+#include "solib-svr4.h"
+
+/* NetBSD ELF. */
+
+static void
+vaxnbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ nbsd_init_abi (info, gdbarch);
+
+ /* NetBSD ELF uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+
+void _initialize_vaxnbsd_tdep ();
+void
+_initialize_vaxnbsd_tdep ()
+{
+ gdbarch_register_osabi (bfd_arch_vax, 0, GDB_OSABI_NETBSD,
+ vaxnbsd_elf_init_abi);
+}