diff options
author | Kamil Rytarowski <n54@gmx.com> | 2020-10-06 21:36:22 +0200 |
---|---|---|
committer | Kamil Rytarowski <kamil@moritz.systems> | 2020-10-13 13:33:35 +0200 |
commit | 1b71cfcfdc3e13a655fefa6566b5564cec044c10 (patch) | |
tree | 774c4a2694be59e0d9075bee00fbc9045776fef5 /gdb/mips-netbsd-tdep.c | |
parent | d7a78e5c41c77ad32de668b0b2fde74deeb8190d (diff) | |
download | gdb-1b71cfcfdc3e13a655fefa6566b5564cec044c10.zip gdb-1b71cfcfdc3e13a655fefa6566b5564cec044c10.tar.gz gdb-1b71cfcfdc3e13a655fefa6566b5564cec044c10.tar.bz2 |
Normalize names of the NetBSD files
The files used to be named 'nbsd', which incorrectly reflects
the name of the OS and confuses it with other BSD derived OSes.
gdb/ChangeLog:
* 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.
Diffstat (limited to 'gdb/mips-netbsd-tdep.c')
-rw-r--r-- | gdb/mips-netbsd-tdep.c | 382 |
1 files changed, 382 insertions, 0 deletions
diff --git a/gdb/mips-netbsd-tdep.c b/gdb/mips-netbsd-tdep.c new file mode 100644 index 0000000..b6f8773 --- /dev/null +++ b/gdb/mips-netbsd-tdep.c @@ -0,0 +1,382 @@ +/* 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); +} + + +/* 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; +} + + +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); +} |