gdb/armnbsd-nat.c - gdb

Global variables defined

Data types defined

Functions defined

Source code

  1. /* Native-dependent code for BSD Unix running on ARM's, for GDB.

  2.    Copyright (C) 1988-2015 Free Software Foundation, Inc.

  3.    This file is part of GDB.

  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 3 of the License, or
  7.    (at your option) any later version.

  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.

  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  14. #include "defs.h"
  15. #include "gdbcore.h"
  16. #include "inferior.h"
  17. #include "regcache.h"
  18. #include "target.h"
  19. #include <sys/types.h>
  20. #include <sys/ptrace.h>
  21. #include <machine/reg.h>
  22. #include <machine/frame.h>

  23. #include "arm-tdep.h"
  24. #include "inf-ptrace.h"

  25. extern int arm_apcs_32;

  26. static void
  27. arm_supply_gregset (struct regcache *regcache, struct reg *gregset)
  28. {
  29.   int regno;
  30.   CORE_ADDR r_pc;

  31.   /* Integer registers.  */
  32.   for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
  33.     regcache_raw_supply (regcache, regno, (char *) &gregset->r[regno]);

  34.   regcache_raw_supply (regcache, ARM_SP_REGNUM,
  35.                        (char *) &gregset->r_sp);
  36.   regcache_raw_supply (regcache, ARM_LR_REGNUM,
  37.                        (char *) &gregset->r_lr);
  38.   /* This is ok: we're running native...  */
  39.   r_pc = gdbarch_addr_bits_remove (get_regcache_arch (regcache), gregset->r_pc);
  40.   regcache_raw_supply (regcache, ARM_PC_REGNUM, (char *) &r_pc);

  41.   if (arm_apcs_32)
  42.     regcache_raw_supply (regcache, ARM_PS_REGNUM,
  43.                          (char *) &gregset->r_cpsr);
  44.   else
  45.     regcache_raw_supply (regcache, ARM_PS_REGNUM,
  46.                          (char *) &gregset->r_pc);
  47. }

  48. static void
  49. arm_supply_fparegset (struct regcache *regcache, struct fpreg *fparegset)
  50. {
  51.   int regno;

  52.   for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
  53.     regcache_raw_supply (regcache, regno,
  54.                          (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);

  55.   regcache_raw_supply (regcache, ARM_FPS_REGNUM,
  56.                        (char *) &fparegset->fpr_fpsr);
  57. }

  58. static void
  59. fetch_register (struct regcache *regcache, int regno)
  60. {
  61.   struct reg inferior_registers;
  62.   int ret;

  63.   ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
  64.                 (PTRACE_TYPE_ARG3) &inferior_registers, 0);

  65.   if (ret < 0)
  66.     {
  67.       warning (_("unable to fetch general register"));
  68.       return;
  69.     }

  70.   switch (regno)
  71.     {
  72.     case ARM_SP_REGNUM:
  73.       regcache_raw_supply (regcache, ARM_SP_REGNUM,
  74.                            (char *) &inferior_registers.r_sp);
  75.       break;

  76.     case ARM_LR_REGNUM:
  77.       regcache_raw_supply (regcache, ARM_LR_REGNUM,
  78.                            (char *) &inferior_registers.r_lr);
  79.       break;

  80.     case ARM_PC_REGNUM:
  81.       /* This is ok: we're running native...  */
  82.       inferior_registers.r_pc = gdbarch_addr_bits_remove
  83.                                   (get_regcache_arch (regcache),
  84.                                    inferior_registers.r_pc);
  85.       regcache_raw_supply (regcache, ARM_PC_REGNUM,
  86.                            (char *) &inferior_registers.r_pc);
  87.       break;

  88.     case ARM_PS_REGNUM:
  89.       if (arm_apcs_32)
  90.         regcache_raw_supply (regcache, ARM_PS_REGNUM,
  91.                              (char *) &inferior_registers.r_cpsr);
  92.       else
  93.         regcache_raw_supply (regcache, ARM_PS_REGNUM,
  94.                              (char *) &inferior_registers.r_pc);
  95.       break;

  96.     default:
  97.       regcache_raw_supply (regcache, regno,
  98.                            (char *) &inferior_registers.r[regno]);
  99.       break;
  100.     }
  101. }

  102. static void
  103. fetch_regs (struct regcache *regcache)
  104. {
  105.   struct reg inferior_registers;
  106.   int ret;
  107.   int regno;

  108.   ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
  109.                 (PTRACE_TYPE_ARG3) &inferior_registers, 0);

  110.   if (ret < 0)
  111.     {
  112.       warning (_("unable to fetch general registers"));
  113.       return;
  114.     }

  115.   arm_supply_gregset (regcache, &inferior_registers);
  116. }

  117. static void
  118. fetch_fp_register (struct regcache *regcache, int regno)
  119. {
  120.   struct fpreg inferior_fp_registers;
  121.   int ret;

  122.   ret = ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
  123.                 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);

  124.   if (ret < 0)
  125.     {
  126.       warning (_("unable to fetch floating-point register"));
  127.       return;
  128.     }

  129.   switch (regno)
  130.     {
  131.     case ARM_FPS_REGNUM:
  132.       regcache_raw_supply (regcache, ARM_FPS_REGNUM,
  133.                            (char *) &inferior_fp_registers.fpr_fpsr);
  134.       break;

  135.     default:
  136.       regcache_raw_supply (regcache, regno,
  137.                            (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
  138.       break;
  139.     }
  140. }

  141. static void
  142. fetch_fp_regs (struct regcache *regcache)
  143. {
  144.   struct fpreg inferior_fp_registers;
  145.   int ret;
  146.   int regno;

  147.   ret = ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
  148.                 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);

  149.   if (ret < 0)
  150.     {
  151.       warning (_("unable to fetch general registers"));
  152.       return;
  153.     }

  154.   arm_supply_fparegset (regcache, &inferior_fp_registers);
  155. }

  156. static void
  157. armnbsd_fetch_registers (struct target_ops *ops,
  158.                          struct regcache *regcache, int regno)
  159. {
  160.   if (regno >= 0)
  161.     {
  162.       if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
  163.         fetch_register (regcache, regno);
  164.       else
  165.         fetch_fp_register (regcache, regno);
  166.     }
  167.   else
  168.     {
  169.       fetch_regs (regcache);
  170.       fetch_fp_regs (regcache);
  171.     }
  172. }


  173. static void
  174. store_register (const struct regcache *regcache, int regno)
  175. {
  176.   struct gdbarch *gdbarch = get_regcache_arch (regcache);
  177.   struct reg inferior_registers;
  178.   int ret;

  179.   ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
  180.                 (PTRACE_TYPE_ARG3) &inferior_registers, 0);

  181.   if (ret < 0)
  182.     {
  183.       warning (_("unable to fetch general registers"));
  184.       return;
  185.     }

  186.   switch (regno)
  187.     {
  188.     case ARM_SP_REGNUM:
  189.       regcache_raw_collect (regcache, ARM_SP_REGNUM,
  190.                             (char *) &inferior_registers.r_sp);
  191.       break;

  192.     case ARM_LR_REGNUM:
  193.       regcache_raw_collect (regcache, ARM_LR_REGNUM,
  194.                             (char *) &inferior_registers.r_lr);
  195.       break;

  196.     case ARM_PC_REGNUM:
  197.       if (arm_apcs_32)
  198.         regcache_raw_collect (regcache, ARM_PC_REGNUM,
  199.                               (char *) &inferior_registers.r_pc);
  200.       else
  201.         {
  202.           unsigned pc_val;

  203.           regcache_raw_collect (regcache, ARM_PC_REGNUM,
  204.                                 (char *) &pc_val);

  205.           pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
  206.           inferior_registers.r_pc ^= gdbarch_addr_bits_remove
  207.                                        (gdbarch, inferior_registers.r_pc);
  208.           inferior_registers.r_pc |= pc_val;
  209.         }
  210.       break;

  211.     case ARM_PS_REGNUM:
  212.       if (arm_apcs_32)
  213.         regcache_raw_collect (regcache, ARM_PS_REGNUM,
  214.                               (char *) &inferior_registers.r_cpsr);
  215.       else
  216.         {
  217.           unsigned psr_val;

  218.           regcache_raw_collect (regcache, ARM_PS_REGNUM,
  219.                                 (char *) &psr_val);

  220.           psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
  221.           inferior_registers.r_pc = gdbarch_addr_bits_remove
  222.                                       (gdbarch, inferior_registers.r_pc);
  223.           inferior_registers.r_pc |= psr_val;
  224.         }
  225.       break;

  226.     default:
  227.       regcache_raw_collect (regcache, regno,
  228.                             (char *) &inferior_registers.r[regno]);
  229.       break;
  230.     }

  231.   ret = ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
  232.                 (PTRACE_TYPE_ARG3) &inferior_registers, 0);

  233.   if (ret < 0)
  234.     warning (_("unable to write register %d to inferior"), regno);
  235. }

  236. static void
  237. store_regs (const struct regcache *regcache)
  238. {
  239.   struct gdbarch *gdbarch = get_regcache_arch (regcache);
  240.   struct reg inferior_registers;
  241.   int ret;
  242.   int regno;


  243.   for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
  244.     regcache_raw_collect (regcache, regno,
  245.                           (char *) &inferior_registers.r[regno]);

  246.   regcache_raw_collect (regcache, ARM_SP_REGNUM,
  247.                         (char *) &inferior_registers.r_sp);
  248.   regcache_raw_collect (regcache, ARM_LR_REGNUM,
  249.                         (char *) &inferior_registers.r_lr);

  250.   if (arm_apcs_32)
  251.     {
  252.       regcache_raw_collect (regcache, ARM_PC_REGNUM,
  253.                             (char *) &inferior_registers.r_pc);
  254.       regcache_raw_collect (regcache, ARM_PS_REGNUM,
  255.                             (char *) &inferior_registers.r_cpsr);
  256.     }
  257.   else
  258.     {
  259.       unsigned pc_val;
  260.       unsigned psr_val;

  261.       regcache_raw_collect (regcache, ARM_PC_REGNUM,
  262.                             (char *) &pc_val);
  263.       regcache_raw_collect (regcache, ARM_PS_REGNUM,
  264.                             (char *) &psr_val);

  265.       pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
  266.       psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);

  267.       inferior_registers.r_pc = pc_val | psr_val;
  268.     }

  269.   ret = ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
  270.                 (PTRACE_TYPE_ARG3) &inferior_registers, 0);

  271.   if (ret < 0)
  272.     warning (_("unable to store general registers"));
  273. }

  274. static void
  275. store_fp_register (const struct regcache *regcache, int regno)
  276. {
  277.   struct fpreg inferior_fp_registers;
  278.   int ret;

  279.   ret = ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
  280.                 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);

  281.   if (ret < 0)
  282.     {
  283.       warning (_("unable to fetch floating-point registers"));
  284.       return;
  285.     }

  286.   switch (regno)
  287.     {
  288.     case ARM_FPS_REGNUM:
  289.       regcache_raw_collect (regcache, ARM_FPS_REGNUM,
  290.                             (char *) &inferior_fp_registers.fpr_fpsr);
  291.       break;

  292.     default:
  293.       regcache_raw_collect (regcache, regno,
  294.                             (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
  295.       break;
  296.     }

  297.   ret = ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
  298.                 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);

  299.   if (ret < 0)
  300.     warning (_("unable to write register %d to inferior"), regno);
  301. }

  302. static void
  303. store_fp_regs (const struct regcache *regcache)
  304. {
  305.   struct fpreg inferior_fp_registers;
  306.   int ret;
  307.   int regno;


  308.   for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
  309.     regcache_raw_collect (regcache, regno,
  310.                           (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);

  311.   regcache_raw_collect (regcache, ARM_FPS_REGNUM,
  312.                         (char *) &inferior_fp_registers.fpr_fpsr);

  313.   ret = ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
  314.                 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);

  315.   if (ret < 0)
  316.     warning (_("unable to store floating-point registers"));
  317. }

  318. static void
  319. armnbsd_store_registers (struct target_ops *ops,
  320.                          struct regcache *regcache, int regno)
  321. {
  322.   if (regno >= 0)
  323.     {
  324.       if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
  325.         store_register (regcache, regno);
  326.       else
  327.         store_fp_register (regcache, regno);
  328.     }
  329.   else
  330.     {
  331.       store_regs (regcache);
  332.       store_fp_regs (regcache);
  333.     }
  334. }

  335. struct md_core
  336. {
  337.   struct reg intreg;
  338.   struct fpreg freg;
  339. };

  340. static void
  341. fetch_core_registers (struct regcache *regcache,
  342.                       char *core_reg_sect, unsigned core_reg_size,
  343.                       int which, CORE_ADDR ignore)
  344. {
  345.   struct md_core *core_reg = (struct md_core *) core_reg_sect;
  346.   int regno;
  347.   CORE_ADDR r_pc;

  348.   arm_supply_gregset (regcache, &core_reg->intreg);
  349.   arm_supply_fparegset (regcache, &core_reg->freg);
  350. }

  351. static void
  352. fetch_elfcore_registers (struct regcache *regcache,
  353.                          char *core_reg_sect, unsigned core_reg_size,
  354.                          int which, CORE_ADDR ignore)
  355. {
  356.   struct reg gregset;
  357.   struct fpreg fparegset;

  358.   switch (which)
  359.     {
  360.     case 0:        /* Integer registers.  */
  361.       if (core_reg_size != sizeof (struct reg))
  362.         warning (_("wrong size of register set in core file"));
  363.       else
  364.         {
  365.           /* The memcpy may be unnecessary, but we can't really be sure
  366.              of the alignment of the data in the core file.  */
  367.           memcpy (&gregset, core_reg_sect, sizeof (gregset));
  368.           arm_supply_gregset (regcache, &gregset);
  369.         }
  370.       break;

  371.     case 2:
  372.       if (core_reg_size != sizeof (struct fpreg))
  373.         warning (_("wrong size of FPA register set in core file"));
  374.       else
  375.         {
  376.           /* The memcpy may be unnecessary, but we can't really be sure
  377.              of the alignment of the data in the core file.  */
  378.           memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
  379.           arm_supply_fparegset (regcache, &fparegset);
  380.         }
  381.       break;

  382.     default:
  383.       /* Don't know what kind of register request this is; just ignore it.  */
  384.       break;
  385.     }
  386. }

  387. static struct core_fns arm_netbsd_core_fns =
  388. {
  389.   bfd_target_unknown_flavour,                /* core_flovour.  */
  390.   default_check_format,                        /* check_format.  */
  391.   default_core_sniffer,                        /* core_sniffer.  */
  392.   fetch_core_registers,                        /* core_read_registers.  */
  393.   NULL
  394. };

  395. static struct core_fns arm_netbsd_elfcore_fns =
  396. {
  397.   bfd_target_elf_flavour,                /* core_flovour.  */
  398.   default_check_format,                        /* check_format.  */
  399.   default_core_sniffer,                        /* core_sniffer.  */
  400.   fetch_elfcore_registers,                /* core_read_registers.  */
  401.   NULL
  402. };

  403. void
  404. _initialize_arm_netbsd_nat (void)
  405. {
  406.   struct target_ops *t;

  407.   t = inf_ptrace_target ();
  408.   t->to_fetch_registers = armnbsd_fetch_registers;
  409.   t->to_store_registers = armnbsd_store_registers;
  410.   add_target (t);

  411.   deprecated_add_core_fns (&arm_netbsd_core_fns);
  412.   deprecated_add_core_fns (&arm_netbsd_elfcore_fns);
  413. }