hppa-obsd-nat.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /* Native-dependent code for OpenBSD/hppa.
  2. Copyright (C) 2004-2022 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. #include "obsd-nat.h"
  24. struct hppa_obsd_nat_target final : public obsd_nat_target
  25. {
  26. void fetch_registers (struct regcache *, int) override;
  27. void store_registers (struct regcache *, int) override;
  28. };
  29. static hppa_obsd_nat_target the_hppa_obsd_nat_target;
  30. static int
  31. hppaobsd_gregset_supplies_p (int regnum)
  32. {
  33. return (regnum >= HPPA_R0_REGNUM && regnum <= HPPA_CR27_REGNUM);
  34. }
  35. static int
  36. hppaobsd_fpregset_supplies_p (int regnum)
  37. {
  38. return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM);
  39. }
  40. /* Supply the general-purpose registers stored in GREGS to REGCACHE. */
  41. static void
  42. hppaobsd_supply_gregset (struct regcache *regcache, const void *gregs)
  43. {
  44. gdb_byte zero[4] = { 0 };
  45. const char *regs = gregs;
  46. int regnum;
  47. regcache->raw_supply (HPPA_R0_REGNUM, &zero);
  48. for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
  49. regcache->raw_supply (regnum, regs + regnum * 4);
  50. if (sizeof(struct reg) >= 46 * 4)
  51. {
  52. regcache->raw_supply (HPPA_IPSW_REGNUM, regs);
  53. regcache->raw_supply (HPPA_SAR_REGNUM, regs + 32 * 4);
  54. regcache->raw_supply (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
  55. regcache->raw_supply (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
  56. regcache->raw_supply (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
  57. regcache->raw_supply (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
  58. regcache->raw_supply (HPPA_SR0_REGNUM, regs + 37 * 4);
  59. regcache->raw_supply (HPPA_SR1_REGNUM, regs + 38 * 4);
  60. regcache->raw_supply (HPPA_SR2_REGNUM, regs + 39 * 4);
  61. regcache->raw_supply (HPPA_SR3_REGNUM, regs + 40 * 4);
  62. regcache->raw_supply (HPPA_SR4_REGNUM, regs + 41 * 4);
  63. regcache->raw_supply (HPPA_SR5_REGNUM, regs + 42 * 4);
  64. regcache->raw_supply (HPPA_SR6_REGNUM, regs + 43 * 4);
  65. regcache->raw_supply (HPPA_SR7_REGNUM, regs + 44 * 4);
  66. regcache->raw_supply (HPPA_CR26_REGNUM, regs + 45 * 4);
  67. regcache->raw_supply (HPPA_CR27_REGNUM, regs + 46 * 4);
  68. }
  69. else
  70. {
  71. regcache->raw_supply (HPPA_SAR_REGNUM, regs);
  72. regcache->raw_supply (HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
  73. regcache->raw_supply (HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
  74. }
  75. }
  76. /* Supply the floating-point registers stored in FPREGS to REGCACHE. */
  77. static void
  78. hppaobsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
  79. {
  80. const char *regs = fpregs;
  81. int regnum;
  82. for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM;
  83. regnum += 2, regs += 8)
  84. {
  85. regcache->raw_supply (regnum, regs);
  86. regcache->raw_supply (regnum + 1, regs + 4);
  87. }
  88. }
  89. /* Collect the general-purpose registers from REGCACHE and store them
  90. in GREGS. */
  91. static void
  92. hppaobsd_collect_gregset (const struct regcache *regcache,
  93. void *gregs, int regnum)
  94. {
  95. char *regs = gregs;
  96. int i;
  97. for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
  98. {
  99. if (regnum == -1 || regnum == i)
  100. regcache->raw_collect (i, regs + i * 4);
  101. }
  102. if (sizeof(struct reg) >= 46 * 4)
  103. {
  104. if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
  105. regcache->raw_collect (HPPA_IPSW_REGNUM, regs);
  106. if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
  107. regcache->raw_collect (HPPA_SAR_REGNUM, regs + 32 * 4);
  108. if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
  109. regcache->raw_collect (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
  110. if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
  111. regcache->raw_collect (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
  112. if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
  113. regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
  114. if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
  115. regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
  116. if (regnum == -1 || regnum == HPPA_SR0_REGNUM)
  117. regcache->raw_collect (HPPA_SR0_REGNUM, regs + 37 * 4);
  118. if (regnum == -1 || regnum == HPPA_SR1_REGNUM)
  119. regcache->raw_collect (HPPA_SR1_REGNUM, regs + 38 * 4);
  120. if (regnum == -1 || regnum == HPPA_SR2_REGNUM)
  121. regcache->raw_collect (HPPA_SR2_REGNUM, regs + 39 * 4);
  122. if (regnum == -1 || regnum == HPPA_SR3_REGNUM)
  123. regcache->raw_collect (HPPA_SR3_REGNUM, regs + 40 * 4);
  124. if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
  125. regcache->raw_collect (HPPA_SR4_REGNUM, regs + 41 * 4);
  126. if (regnum == -1 || regnum == HPPA_SR5_REGNUM)
  127. regcache->raw_collect (HPPA_SR5_REGNUM, regs + 42 * 4);
  128. if (regnum == -1 || regnum == HPPA_SR6_REGNUM)
  129. regcache->raw_collect (HPPA_SR6_REGNUM, regs + 43 * 4);
  130. if (regnum == -1 || regnum == HPPA_SR7_REGNUM)
  131. regcache->raw_collect (HPPA_SR7_REGNUM, regs + 44 * 4);
  132. if (regnum == -1 || regnum == HPPA_CR26_REGNUM)
  133. regcache->raw_collect (HPPA_CR26_REGNUM, regs + 45 * 4);
  134. if (regnum == -1 || regnum == HPPA_CR27_REGNUM)
  135. regcache->raw_collect (HPPA_CR27_REGNUM, regs + 46 * 4);
  136. }
  137. else
  138. {
  139. if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
  140. regcache->raw_collect (HPPA_SAR_REGNUM, regs);
  141. if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
  142. regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
  143. if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
  144. regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
  145. }
  146. }
  147. /* Collect the floating-point registers from REGCACHE and store them
  148. in FPREGS. */
  149. static void
  150. hppaobsd_collect_fpregset (struct regcache *regcache,
  151. void *fpregs, int regnum)
  152. {
  153. char *regs = fpregs;
  154. int i;
  155. for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8)
  156. {
  157. if (regnum == -1 || regnum == i || regnum == i + 1)
  158. {
  159. regcache->raw_collect (i, regs);
  160. regcache->raw_collect (i + 1, regs + 4);
  161. }
  162. }
  163. }
  164. /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
  165. for all registers (including the floating-point registers). */
  166. void
  167. hppa_obsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
  168. {
  169. pid_t pid = regcache->ptid ().pid ();
  170. if (regnum == -1 || hppaobsd_gregset_supplies_p (regnum))
  171. {
  172. struct reg regs;
  173. if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
  174. perror_with_name (_("Couldn't get registers"));
  175. hppaobsd_supply_gregset (regcache, &regs);
  176. }
  177. if (regnum == -1 || hppaobsd_fpregset_supplies_p (regnum))
  178. {
  179. struct fpreg fpregs;
  180. if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
  181. perror_with_name (_("Couldn't get floating point status"));
  182. hppaobsd_supply_fpregset (regcache, &fpregs);
  183. }
  184. }
  185. /* Store register REGNUM back into the inferior. If REGNUM is -1, do
  186. this for all registers (including the floating-point registers). */
  187. void
  188. hppa_obsd_nat_target::store_registers (struct regcache *regcache, int regnum)
  189. {
  190. if (regnum == -1 || hppaobsd_gregset_supplies_p (regnum))
  191. {
  192. struct reg regs;
  193. if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
  194. perror_with_name (_("Couldn't get registers"));
  195. hppaobsd_collect_gregset (regcache, &regs, regnum);
  196. if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
  197. perror_with_name (_("Couldn't write registers"));
  198. }
  199. if (regnum == -1 || hppaobsd_fpregset_supplies_p (regnum))
  200. {
  201. struct fpreg fpregs;
  202. if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
  203. perror_with_name (_("Couldn't get floating point status"));
  204. hppaobsd_collect_fpregset (regcache, &fpregs, regnum);
  205. if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
  206. perror_with_name (_("Couldn't write floating point status"));
  207. }
  208. }
  209. void _initialize_hppaobsd_nat ();
  210. void
  211. _initialize_hppaobsd_nat ()
  212. {
  213. add_inf_child_target (&the_hppa_obsd_nat_target);
  214. }