gdb/hppabsd-nat.c - gdb

Functions defined

Source code

  1. /* Native-dependent code for HP PA-RISC BSD's.

  2.    Copyright (C) 2004-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 "inferior.h"
  16. #include "regcache.h"
  17. #include "target.h"

  18. #include <sys/types.h>
  19. #include <sys/ptrace.h>
  20. #include <machine/reg.h>

  21. #include "hppa-tdep.h"
  22. #include "inf-ptrace.h"

  23. static int
  24. hppabsd_gregset_supplies_p (int regnum)
  25. {
  26.   return (regnum >= HPPA_R0_REGNUM && regnum <= HPPA_CR27_REGNUM);
  27. }

  28. static int
  29. hppabsd_fpregset_supplies_p (int regnum)
  30. {
  31.   return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM);
  32. }

  33. /* Supply the general-purpose registers stored in GREGS to REGCACHE.  */

  34. static void
  35. hppabsd_supply_gregset (struct regcache *regcache, const void *gregs)
  36. {
  37.   gdb_byte zero[4] = { 0 };
  38.   const char *regs = gregs;
  39.   int regnum;

  40.   regcache_raw_supply (regcache, HPPA_R0_REGNUM, &zero);
  41.   for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
  42.     regcache_raw_supply (regcache, regnum, regs + regnum * 4);

  43.   if (sizeof(struct reg) >= 46 * 4)
  44.     {
  45.       regcache_raw_supply (regcache, HPPA_IPSW_REGNUM, regs);
  46.       regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
  47.       regcache_raw_supply (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
  48.       regcache_raw_supply (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
  49.       regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
  50.       regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
  51.       regcache_raw_supply (regcache, HPPA_SR0_REGNUM, regs + 37 * 4);
  52.       regcache_raw_supply (regcache, HPPA_SR1_REGNUM, regs + 38 * 4);
  53.       regcache_raw_supply (regcache, HPPA_SR2_REGNUM, regs + 39 * 4);
  54.       regcache_raw_supply (regcache, HPPA_SR3_REGNUM, regs + 40 * 4);
  55.       regcache_raw_supply (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
  56.       regcache_raw_supply (regcache, HPPA_SR5_REGNUM, regs + 42 * 4);
  57.       regcache_raw_supply (regcache, HPPA_SR6_REGNUM, regs + 43 * 4);
  58.       regcache_raw_supply (regcache, HPPA_SR7_REGNUM, regs + 44 * 4);
  59.       regcache_raw_supply (regcache, HPPA_CR26_REGNUM, regs + 45 * 4);
  60.       regcache_raw_supply (regcache, HPPA_CR27_REGNUM, regs + 46 * 4);
  61.     }
  62.   else
  63.     {
  64.       regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs);
  65.       regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
  66.       regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
  67.     }
  68. }

  69. /* Supply the floating-point registers stored in FPREGS to REGCACHE.  */

  70. static void
  71. hppabsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
  72. {
  73.   const char *regs = fpregs;
  74.   int regnum;

  75.   for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM;
  76.        regnum += 2, regs += 8)
  77.     {
  78.       regcache_raw_supply (regcache, regnum, regs);
  79.       regcache_raw_supply (regcache, regnum + 1, regs + 4);
  80.     }
  81. }

  82. /* Collect the general-purpose registers from REGCACHE and store them
  83.    in GREGS.  */

  84. static void
  85. hppabsd_collect_gregset (const struct regcache *regcache,
  86.                           void *gregs, int regnum)
  87. {
  88.   char *regs = gregs;
  89.   int i;

  90.   for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
  91.     {
  92.       if (regnum == -1 || regnum == i)
  93.         regcache_raw_collect (regcache, i, regs + i * 4);
  94.     }

  95.   if (sizeof(struct reg) >= 46 * 4)
  96.     {
  97.       if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
  98.         regcache_raw_collect (regcache, HPPA_IPSW_REGNUM, regs);
  99.       if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
  100.         regcache_raw_collect (regcache, HPPA_SAR_REGNUM, regs + 32 * 4);
  101.       if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
  102.         regcache_raw_collect (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
  103.       if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
  104.         regcache_raw_collect (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
  105.       if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
  106.         regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
  107.       if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
  108.         regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
  109.       if (regnum == -1 || regnum == HPPA_SR0_REGNUM)
  110.         regcache_raw_collect (regcache, HPPA_SR0_REGNUM, regs + 37 * 4);
  111.       if (regnum == -1 || regnum == HPPA_SR1_REGNUM)
  112.         regcache_raw_collect (regcache, HPPA_SR1_REGNUM, regs + 38 * 4);
  113.       if (regnum == -1 || regnum == HPPA_SR2_REGNUM)
  114.         regcache_raw_collect (regcache, HPPA_SR2_REGNUM, regs + 39 * 4);
  115.       if (regnum == -1 || regnum == HPPA_SR3_REGNUM)
  116.         regcache_raw_collect (regcache, HPPA_SR3_REGNUM, regs + 40 * 4);
  117.       if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
  118.         regcache_raw_collect (regcache, HPPA_SR4_REGNUM, regs + 41 * 4);
  119.       if (regnum == -1 || regnum == HPPA_SR5_REGNUM)
  120.         regcache_raw_collect (regcache, HPPA_SR5_REGNUM, regs + 42 * 4);
  121.       if (regnum == -1 || regnum == HPPA_SR6_REGNUM)
  122.         regcache_raw_collect (regcache, HPPA_SR6_REGNUM, regs + 43 * 4);
  123.       if (regnum == -1 || regnum == HPPA_SR7_REGNUM)
  124.         regcache_raw_collect (regcache, HPPA_SR7_REGNUM, regs + 44 * 4);
  125.       if (regnum == -1 || regnum == HPPA_CR26_REGNUM)
  126.         regcache_raw_collect (regcache, HPPA_CR26_REGNUM, regs + 45 * 4);
  127.       if (regnum == -1 || regnum == HPPA_CR27_REGNUM)
  128.         regcache_raw_collect (regcache, HPPA_CR27_REGNUM, regs + 46 * 4);
  129.     }
  130.   else
  131.     {
  132.       if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
  133.         regcache_raw_collect (regcache, HPPA_SAR_REGNUM, regs);
  134.       if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
  135.         regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
  136.       if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
  137.         regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
  138.     }
  139. }

  140. /* Collect the floating-point registers from REGCACHE and store them
  141.    in FPREGS.  */

  142. static void
  143. hppabsd_collect_fpregset (struct regcache *regcache,
  144.                           void *fpregs, int regnum)
  145. {
  146.   char *regs = fpregs;
  147.   int i;

  148.   for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8)
  149.     {
  150.       if (regnum == -1 || regnum == i || regnum == i + 1)
  151.         {
  152.           regcache_raw_collect (regcache, i, regs);
  153.           regcache_raw_collect (regcache, i + 1, regs + 4);
  154.         }
  155.     }
  156. }


  157. /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
  158.    for all registers (including the floating-point registers).  */

  159. static void
  160. hppabsd_fetch_registers (struct target_ops *ops,
  161.                          struct regcache *regcache, int regnum)
  162. {
  163.   if (regnum == -1 || hppabsd_gregset_supplies_p (regnum))
  164.     {
  165.       struct reg regs;

  166.       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
  167.                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
  168.         perror_with_name (_("Couldn't get registers"));

  169.       hppabsd_supply_gregset (regcache, &regs);
  170.     }

  171.   if (regnum == -1 || hppabsd_fpregset_supplies_p (regnum))
  172.     {
  173.       struct fpreg fpregs;

  174.       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
  175.                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
  176.         perror_with_name (_("Couldn't get floating point status"));

  177.       hppabsd_supply_fpregset (regcache, &fpregs);
  178.     }
  179. }

  180. /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
  181.    this for all registers (including the floating-point registers).  */

  182. static void
  183. hppabsd_store_registers (struct target_ops *ops,
  184.                          struct regcache *regcache, int regnum)
  185. {
  186.   if (regnum == -1 || hppabsd_gregset_supplies_p (regnum))
  187.     {
  188.       struct reg regs;

  189.       if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
  190.                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
  191.         perror_with_name (_("Couldn't get registers"));

  192.       hppabsd_collect_gregset (regcache, &regs, regnum);

  193.       if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
  194.                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
  195.         perror_with_name (_("Couldn't write registers"));
  196.     }

  197.   if (regnum == -1 || hppabsd_fpregset_supplies_p (regnum))
  198.     {
  199.       struct fpreg fpregs;

  200.       if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
  201.                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
  202.         perror_with_name (_("Couldn't get floating point status"));

  203.       hppabsd_collect_fpregset (regcache, &fpregs, regnum);

  204.       if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
  205.                   (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
  206.         perror_with_name (_("Couldn't write floating point status"));
  207.     }
  208. }

  209. /* Provide a prototype to silence -Wmissing-prototypes.  */
  210. void _initialize_hppabsd_nat (void);

  211. void
  212. _initialize_hppabsd_nat (void)
  213. {
  214.   struct target_ops *t;

  215.   /* Add in local overrides.  */
  216.   t = inf_ptrace_target ();
  217.   t->to_fetch_registers = hppabsd_fetch_registers;
  218.   t->to_store_registers = hppabsd_store_registers;
  219.   add_target (t);
  220. }