]>
Commit | Line | Data |
---|---|---|
4f9d9906 JB |
1 | /* Native-dependent code for FreeBSD/arm. |
2 | ||
42a4f53d | 3 | Copyright (C) 2017-2019 Free Software Foundation, Inc. |
4f9d9906 JB |
4 | |
5 | This file is part of GDB. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #include "defs.h" | |
4de283e4 | 21 | #include "target.h" |
4f9d9906 | 22 | |
d55e5aa6 | 23 | #include <sys/types.h> |
4de283e4 TT |
24 | #include <sys/ptrace.h> |
25 | #include <machine/reg.h> | |
4f9d9906 | 26 | |
d55e5aa6 | 27 | #include "fbsd-nat.h" |
4de283e4 TT |
28 | #include "arm-tdep.h" |
29 | #include "arm-fbsd-tdep.h" | |
4f9d9906 JB |
30 | #include "inf-ptrace.h" |
31 | ||
f6ac5f3d PA |
32 | struct arm_fbsd_nat_target : public fbsd_nat_target |
33 | { | |
34 | void fetch_registers (struct regcache *, int) override; | |
35 | void store_registers (struct regcache *, int) override; | |
36 | const struct target_desc *read_description () override; | |
37 | }; | |
38 | ||
39 | static arm_fbsd_nat_target the_arm_fbsd_nat_target; | |
40 | ||
4f9d9906 JB |
41 | /* Determine if PT_GETREGS fetches REGNUM. */ |
42 | ||
43 | static bool | |
44 | getregs_supplies (struct gdbarch *gdbarch, int regnum) | |
45 | { | |
46 | return ((regnum >= ARM_A1_REGNUM && regnum <= ARM_PC_REGNUM) | |
47 | || regnum == ARM_PS_REGNUM); | |
48 | } | |
49 | ||
50 | #ifdef PT_GETVFPREGS | |
51 | /* Determine if PT_GETVFPREGS fetches REGNUM. */ | |
52 | ||
53 | static bool | |
54 | getvfpregs_supplies (struct gdbarch *gdbarch, int regnum) | |
55 | { | |
56 | return ((regnum >= ARM_D0_REGNUM && regnum <= ARM_D31_REGNUM) | |
57 | || regnum == ARM_FPSCR_REGNUM); | |
58 | } | |
59 | #endif | |
60 | ||
61 | /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this | |
62 | for all registers. */ | |
63 | ||
f6ac5f3d PA |
64 | void |
65 | arm_fbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum) | |
4f9d9906 | 66 | { |
222312d3 | 67 | pid_t pid = get_ptrace_pid (regcache->ptid ()); |
4f9d9906 | 68 | |
ac7936df | 69 | struct gdbarch *gdbarch = regcache->arch (); |
4f9d9906 JB |
70 | if (regnum == -1 || getregs_supplies (gdbarch, regnum)) |
71 | { | |
72 | struct reg regs; | |
73 | ||
74 | if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1) | |
75 | perror_with_name (_("Couldn't get registers")); | |
76 | ||
77 | regcache->supply_regset (&arm_fbsd_gregset, regnum, ®s, | |
78 | sizeof (regs)); | |
79 | } | |
80 | ||
81 | #ifdef PT_GETVFPREGS | |
82 | if (regnum == -1 || getvfpregs_supplies (gdbarch, regnum)) | |
83 | { | |
84 | struct vfpreg vfpregs; | |
85 | ||
86 | if (ptrace (PT_GETVFPREGS, pid, (PTRACE_TYPE_ARG3) &vfpregs, 0) == -1) | |
87 | perror_with_name (_("Couldn't get floating point status")); | |
88 | ||
89 | regcache->supply_regset (&arm_fbsd_vfpregset, regnum, &vfpregs, | |
90 | sizeof (vfpregs)); | |
91 | } | |
92 | #endif | |
93 | } | |
94 | ||
95 | /* Store register REGNUM back into the inferior. If REGNUM is -1, do | |
96 | this for all registers. */ | |
97 | ||
f6ac5f3d PA |
98 | void |
99 | arm_fbsd_nat_target::store_registers (struct regcache *regcache, int regnum) | |
4f9d9906 | 100 | { |
222312d3 | 101 | pid_t pid = get_ptrace_pid (regcache->ptid ()); |
4f9d9906 | 102 | |
ac7936df | 103 | struct gdbarch *gdbarch = regcache->arch (); |
4f9d9906 JB |
104 | if (regnum == -1 || getregs_supplies (gdbarch, regnum)) |
105 | { | |
106 | struct reg regs; | |
107 | ||
108 | if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1) | |
109 | perror_with_name (_("Couldn't get registers")); | |
110 | ||
111 | regcache->collect_regset (&arm_fbsd_gregset, regnum, ®s, | |
112 | sizeof (regs)); | |
113 | ||
114 | if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1) | |
115 | perror_with_name (_("Couldn't write registers")); | |
116 | } | |
117 | ||
118 | #ifdef PT_GETVFPREGS | |
119 | if (regnum == -1 || getvfpregs_supplies (gdbarch, regnum)) | |
120 | { | |
121 | struct vfpreg vfpregs; | |
122 | ||
123 | if (ptrace (PT_GETVFPREGS, pid, (PTRACE_TYPE_ARG3) &vfpregs, 0) == -1) | |
124 | perror_with_name (_("Couldn't get floating point status")); | |
125 | ||
126 | regcache->collect_regset (&arm_fbsd_vfpregset, regnum, &vfpregs, | |
127 | sizeof (vfpregs)); | |
128 | ||
129 | if (ptrace (PT_SETVFPREGS, pid, (PTRACE_TYPE_ARG3) &vfpregs, 0) == -1) | |
130 | perror_with_name (_("Couldn't write floating point status")); | |
131 | } | |
132 | #endif | |
133 | } | |
134 | ||
135 | /* Implement the to_read_description method. */ | |
136 | ||
f6ac5f3d PA |
137 | const struct target_desc * |
138 | arm_fbsd_nat_target::read_description () | |
4f9d9906 JB |
139 | { |
140 | const struct target_desc *desc; | |
141 | ||
f6ac5f3d | 142 | desc = arm_fbsd_read_description_auxv (this); |
4f9d9906 | 143 | if (desc == NULL) |
4360561f | 144 | desc = this->beneath ()->read_description (); |
4f9d9906 JB |
145 | return desc; |
146 | } | |
147 | ||
148 | void | |
149 | _initialize_arm_fbsd_nat (void) | |
150 | { | |
d9f719f1 | 151 | add_inf_child_target (&the_arm_fbsd_nat_target); |
4f9d9906 | 152 | } |