X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=gdb%2Farm-nbsd-nat.c;h=a8a67e6e85202c71bfeb905d356b3f28f23b6380;hb=f030440daa989ae3dadc1fa4342cfa16d690db3c;hp=9d603b1e0e0a110e91a33651f82b538d103f2d2a;hpb=e2882c85786571175a0b0bfc3bcd2f14620b1ea3;p=thirdparty%2Fbinutils-gdb.git diff --git a/gdb/arm-nbsd-nat.c b/gdb/arm-nbsd-nat.c index 9d603b1e0e0..a8a67e6e852 100644 --- a/gdb/arm-nbsd-nat.c +++ b/gdb/arm-nbsd-nat.c @@ -1,6 +1,6 @@ /* Native-dependent code for BSD Unix running on ARM's, for GDB. - Copyright (C) 1988-2018 Free Software Foundation, Inc. + Copyright (C) 1988-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -17,6 +17,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +/* We define this to get types like register_t. */ +#define _KERNTYPES #include "defs.h" #include "gdbcore.h" #include "inferior.h" @@ -24,51 +26,39 @@ #include "target.h" #include #include +#include #include #include #include "arm-tdep.h" +#include "arm-nbsd-tdep.h" +#include "aarch32-tdep.h" #include "inf-ptrace.h" +#include "nbsd-nat.h" -extern int arm_apcs_32; - -static void -arm_supply_gregset (struct regcache *regcache, struct reg *gregset) +class arm_netbsd_nat_target final : public nbsd_nat_target { - int regno; - CORE_ADDR r_pc; - - /* Integer registers. */ - for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++) - regcache_raw_supply (regcache, regno, (char *) &gregset->r[regno]); - - regcache_raw_supply (regcache, ARM_SP_REGNUM, - (char *) &gregset->r_sp); - regcache_raw_supply (regcache, ARM_LR_REGNUM, - (char *) &gregset->r_lr); - /* This is ok: we're running native... */ - r_pc = gdbarch_addr_bits_remove (regcache->arch (), gregset->r_pc); - regcache_raw_supply (regcache, ARM_PC_REGNUM, (char *) &r_pc); +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; +}; - if (arm_apcs_32) - regcache_raw_supply (regcache, ARM_PS_REGNUM, - (char *) &gregset->r_cpsr); - else - regcache_raw_supply (regcache, ARM_PS_REGNUM, - (char *) &gregset->r_pc); -} +static arm_netbsd_nat_target the_arm_netbsd_nat_target; static void -arm_supply_fparegset (struct regcache *regcache, struct fpreg *fparegset) +arm_supply_vfpregset (struct regcache *regcache, struct fpreg *fpregset) { - int regno; + struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ()); + if (tdep->vfp_register_count == 0) + return; - for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++) - regcache_raw_supply (regcache, regno, - (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]); + 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 (regcache, ARM_FPS_REGNUM, - (char *) &fparegset->fpr_fpsr); + regcache->raw_supply (ARM_FPSCR_REGNUM, (char *) &vfp.vfp_fpscr); } static void @@ -76,80 +66,30 @@ fetch_register (struct regcache *regcache, int regno) { struct reg inferior_registers; int ret; + int lwp = regcache->ptid ().lwp (); - ret = ptrace (PT_GETREGS, ptid_get_pid (regcache_get_ptid (regcache)), - (PTRACE_TYPE_ARG3) &inferior_registers, 0); + ret = ptrace (PT_GETREGS, regcache->ptid ().pid (), + (PTRACE_TYPE_ARG3) &inferior_registers, lwp); if (ret < 0) { warning (_("unable to fetch general register")); return; } - - switch (regno) - { - case ARM_SP_REGNUM: - regcache_raw_supply (regcache, ARM_SP_REGNUM, - (char *) &inferior_registers.r_sp); - break; - - case ARM_LR_REGNUM: - regcache_raw_supply (regcache, ARM_LR_REGNUM, - (char *) &inferior_registers.r_lr); - break; - - case ARM_PC_REGNUM: - /* This is ok: we're running native... */ - inferior_registers.r_pc = gdbarch_addr_bits_remove - (regcache->arch (), - inferior_registers.r_pc); - regcache_raw_supply (regcache, ARM_PC_REGNUM, - (char *) &inferior_registers.r_pc); - break; - - case ARM_PS_REGNUM: - if (arm_apcs_32) - regcache_raw_supply (regcache, ARM_PS_REGNUM, - (char *) &inferior_registers.r_cpsr); - else - regcache_raw_supply (regcache, ARM_PS_REGNUM, - (char *) &inferior_registers.r_pc); - break; - - default: - regcache_raw_supply (regcache, regno, - (char *) &inferior_registers.r[regno]); - break; - } -} - -static void -fetch_regs (struct regcache *regcache) -{ - struct reg inferior_registers; - int ret; - int regno; - - ret = ptrace (PT_GETREGS, ptid_get_pid (regcache_get_ptid (regcache)), - (PTRACE_TYPE_ARG3) &inferior_registers, 0); - - if (ret < 0) - { - warning (_("unable to fetch general registers")); - return; - } - - arm_supply_gregset (regcache, &inferior_registers); + 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 ret; + int lwp = regcache->ptid ().lwp (); - ret = ptrace (PT_GETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)), - (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0); + 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) { @@ -157,29 +97,29 @@ fetch_fp_register (struct regcache *regcache, int regno) return; } - switch (regno) + 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) { - case ARM_FPS_REGNUM: - regcache_raw_supply (regcache, ARM_FPS_REGNUM, - (char *) &inferior_fp_registers.fpr_fpsr); - break; - - default: - regcache_raw_supply (regcache, regno, - (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]); - break; + 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, ptid_get_pid (regcache_get_ptid (regcache)), - (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0); + ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (), + (PTRACE_TYPE_ARG3) &inferior_fp_registers, lwp); if (ret < 0) { @@ -187,12 +127,11 @@ fetch_fp_regs (struct regcache *regcache) return; } - arm_supply_fparegset (regcache, &inferior_fp_registers); + arm_supply_vfpregset (regcache, &inferior_fp_registers); } -static void -armnbsd_fetch_registers (struct target_ops *ops, - struct regcache *regcache, int regno) +void +arm_netbsd_nat_target::fetch_registers (struct regcache *regcache, int regno) { if (regno >= 0) { @@ -203,7 +142,7 @@ armnbsd_fetch_registers (struct target_ops *ops, } else { - fetch_regs (regcache); + fetch_register (regcache, -1); fetch_fp_regs (regcache); } } @@ -214,10 +153,11 @@ 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, ptid_get_pid (regcache_get_ptid (regcache)), - (PTRACE_TYPE_ARG3) &inferior_registers, 0); + ret = ptrace (PT_GETREGS, regcache->ptid ().pid (), + (PTRACE_TYPE_ARG3) &inferior_registers, lwp); if (ret < 0) { @@ -228,25 +168,22 @@ store_register (const struct regcache *regcache, int regno) switch (regno) { case ARM_SP_REGNUM: - regcache_raw_collect (regcache, ARM_SP_REGNUM, - (char *) &inferior_registers.r_sp); + regcache->raw_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp); break; case ARM_LR_REGNUM: - regcache_raw_collect (regcache, ARM_LR_REGNUM, - (char *) &inferior_registers.r_lr); + regcache->raw_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr); break; case ARM_PC_REGNUM: if (arm_apcs_32) - regcache_raw_collect (regcache, ARM_PC_REGNUM, - (char *) &inferior_registers.r_pc); + regcache->raw_collect (ARM_PC_REGNUM, + (char *) &inferior_registers.r_pc); else { unsigned pc_val; - regcache_raw_collect (regcache, ARM_PC_REGNUM, - (char *) &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 @@ -257,14 +194,13 @@ store_register (const struct regcache *regcache, int regno) case ARM_PS_REGNUM: if (arm_apcs_32) - regcache_raw_collect (regcache, ARM_PS_REGNUM, - (char *) &inferior_registers.r_cpsr); + regcache->raw_collect (ARM_PS_REGNUM, + (char *) &inferior_registers.r_cpsr); else { unsigned psr_val; - regcache_raw_collect (regcache, ARM_PS_REGNUM, - (char *) &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 @@ -274,13 +210,12 @@ store_register (const struct regcache *regcache, int regno) break; default: - regcache_raw_collect (regcache, regno, - (char *) &inferior_registers.r[regno]); + regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]); break; } - ret = ptrace (PT_SETREGS, ptid_get_pid (regcache_get_ptid (regcache)), - (PTRACE_TYPE_ARG3) &inferior_registers, 0); + 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); @@ -291,35 +226,30 @@ 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 (regcache, regno, - (char *) &inferior_registers.r[regno]); + regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]); - regcache_raw_collect (regcache, ARM_SP_REGNUM, - (char *) &inferior_registers.r_sp); - regcache_raw_collect (regcache, ARM_LR_REGNUM, - (char *) &inferior_registers.r_lr); + 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 (regcache, ARM_PC_REGNUM, - (char *) &inferior_registers.r_pc); - regcache_raw_collect (regcache, ARM_PS_REGNUM, - (char *) &inferior_registers.r_cpsr); + 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 (regcache, ARM_PC_REGNUM, - (char *) &pc_val); - regcache_raw_collect (regcache, ARM_PS_REGNUM, - (char *) &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); @@ -327,8 +257,8 @@ store_regs (const struct regcache *regcache) inferior_registers.r_pc = pc_val | psr_val; } - ret = ptrace (PT_SETREGS, ptid_get_pid (regcache_get_ptid (regcache)), - (PTRACE_TYPE_ARG3) &inferior_registers, 0); + ret = ptrace (PT_SETREGS, regcache->ptid ().pid (), + (PTRACE_TYPE_ARG3) &inferior_registers, lwp); if (ret < 0) warning (_("unable to store general registers")); @@ -338,10 +268,10 @@ static void store_fp_register (const struct regcache *regcache, int regno) { struct fpreg inferior_fp_registers; - int ret; - - ret = ptrace (PT_GETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)), - (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0); + 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) { @@ -349,21 +279,20 @@ store_fp_register (const struct regcache *regcache, int regno) return; } - switch (regno) + 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) { - case ARM_FPS_REGNUM: - regcache_raw_collect (regcache, ARM_FPS_REGNUM, - (char *) &inferior_fp_registers.fpr_fpsr); - break; - - default: - regcache_raw_collect (regcache, regno, - (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]); - break; + regcache->raw_collect (regno, + (char *) &vfp.vfp_regs[regno - ARM_D0_REGNUM]); } + else + warning (_("Invalid register number.")); - ret = ptrace (PT_SETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)), - (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0); + 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); @@ -372,28 +301,28 @@ store_fp_register (const struct regcache *regcache, int regno) static void store_fp_regs (const struct regcache *regcache) { - struct fpreg inferior_fp_registers; - int ret; - int regno; - + struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ()); + int lwp = regcache->ptid ().lwp (); + if (tdep->vfp_register_count == 0) + return; - for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++) - regcache_raw_collect (regcache, regno, - (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]); + 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 (regcache, ARM_FPS_REGNUM, - (char *) &inferior_fp_registers.fpr_fpsr); + regcache->raw_collect (ARM_FPSCR_REGNUM, + (char *) &fpregs.fpr_vfp.vfp_fpscr); - ret = ptrace (PT_SETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)), - (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0); + int ret = ptrace (PT_SETFPREGS, regcache->ptid ().pid (), + (PTRACE_TYPE_ARG3) &fpregs, lwp); if (ret < 0) warning (_("unable to store floating-point registers")); } -static void -armnbsd_store_registers (struct target_ops *ops, - struct regcache *regcache, int regno) +void +arm_netbsd_nat_target::store_registers (struct regcache *regcache, int regno) { if (regno >= 0) { @@ -409,64 +338,26 @@ armnbsd_store_registers (struct target_ops *ops, } } -static void -fetch_elfcore_registers (struct regcache *regcache, - char *core_reg_sect, unsigned core_reg_size, - int which, CORE_ADDR ignore) +const struct target_desc * +arm_netbsd_nat_target::read_description () { - struct reg gregset; - struct fpreg fparegset; + int flag; + size_t len = sizeof (flag); - switch (which) - { - case 0: /* Integer registers. */ - if (core_reg_size != sizeof (struct reg)) - warning (_("wrong size of register set in core file")); - else - { - /* The memcpy may be unnecessary, but we can't really be sure - of the alignment of the data in the core file. */ - memcpy (&gregset, core_reg_sect, sizeof (gregset)); - arm_supply_gregset (regcache, &gregset); - } - break; + if (sysctlbyname("machdep.fpu_present", &flag, &len, NULL, 0) != 0 + || !flag) + return arm_read_description (ARM_FP_TYPE_NONE); - case 2: - if (core_reg_size != sizeof (struct fpreg)) - warning (_("wrong size of FPA register set in core file")); - else - { - /* The memcpy may be unnecessary, but we can't really be sure - of the alignment of the data in the core file. */ - memcpy (&fparegset, core_reg_sect, sizeof (fparegset)); - arm_supply_fparegset (regcache, &fparegset); - } - break; + len = sizeof(flag); + if (sysctlbyname("machdep.neon_present", &flag, &len, NULL, 0) == 0 && flag) + return aarch32_read_description (); - default: - /* Don't know what kind of register request this is; just ignore it. */ - break; - } + return arm_read_description (ARM_FP_TYPE_VFPV3); } -static struct core_fns arm_netbsd_elfcore_fns = -{ - bfd_target_elf_flavour, /* core_flovour. */ - default_check_format, /* check_format. */ - default_core_sniffer, /* core_sniffer. */ - fetch_elfcore_registers, /* core_read_registers. */ - NULL -}; - +void _initialize_arm_netbsd_nat (); void -_initialize_arm_netbsd_nat (void) +_initialize_arm_netbsd_nat () { - struct target_ops *t; - - t = inf_ptrace_target (); - t->to_fetch_registers = armnbsd_fetch_registers; - t->to_store_registers = armnbsd_store_registers; - add_target (t); - - deprecated_add_core_fns (&arm_netbsd_elfcore_fns); + add_inf_child_target (&the_arm_netbsd_nat_target); }