]> Git Repo - binutils.git/blob - gdb/arc-linux-nat.c
gdb: move go_language class declaration into header file
[binutils.git] / gdb / arc-linux-nat.c
1 /* Native-dependent code for GNU/Linux ARC.
2
3    Copyright 2020 Free Software Foundation, Inc.
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"
21 #include "frame.h"
22 #include "inferior.h"
23 #include "gdbcore.h"
24 #include "regcache.h"
25 #include "gdbsupport/gdb_assert.h"
26 #include "target.h"
27 #include "linux-nat.h"
28 #include "nat/gdb_ptrace.h"
29
30 #include <stdint.h>
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <signal.h>
34 #include <sys/user.h>
35 #include <sys/ioctl.h>
36 #include "gdbsupport/gdb_wait.h"
37 #include <fcntl.h>
38 #include <sys/procfs.h>
39 #include <linux/elf.h>
40
41 #include "gregset.h"
42 #include "arc-tdep.h"
43 #include "arc-linux-tdep.h"
44 #include "arch/arc.h"
45
46 /* Defines ps_err_e, struct ps_prochandle.  */
47 #include "gdb_proc_service.h"
48
49 /* Linux starting with 4.12 supports NT_ARC_V2 note type, which adds R30,
50    R58 and R59 registers, which are specific to ARC HS and aren't
51    available in ARC 700.  */
52 #if defined (NT_ARC_V2) && defined (__ARCHS__)
53 #define ARC_HAS_V2_REGSET
54 #endif
55
56 class arc_linux_nat_target final : public linux_nat_target
57 {
58 public:
59   /* Add ARC register access methods.  */
60   void fetch_registers (struct regcache *, int) override;
61   void store_registers (struct regcache *, int) override;
62
63   const struct target_desc *read_description () override;
64
65   /* Handle threads  */
66   void low_prepare_to_resume (struct lwp_info *lp) override;
67 };
68
69 static arc_linux_nat_target the_arc_linux_nat_target;
70
71 /* Read general registers from target process/thread (via ptrace)
72    into REGCACHE.  */
73
74 static void
75 fetch_gregs (struct regcache *regcache, int regnum)
76 {
77   const int tid = get_ptrace_pid (regcache->ptid ());
78   struct iovec iov;
79   gdb_gregset_t regs;
80
81   iov.iov_base = &regs;
82   iov.iov_len = sizeof (gdb_gregset_t);
83
84   if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, (void *) &iov) < 0)
85     perror_with_name (_("Couldn't get general registers"));
86   else
87     arc_linux_supply_gregset (NULL, regcache, regnum, &regs, 0);
88 }
89
90 #ifdef ARC_HAS_V2_REGSET
91 /* Read ARC v2 registers from target process/thread (via ptrace)
92    into REGCACHE.  */
93
94 static void
95 fetch_v2_regs (struct regcache *regcache, int regnum)
96 {
97   const int tid = get_ptrace_pid (regcache->ptid ());
98   struct iovec iov;
99   bfd_byte v2_buffer[ARC_LINUX_SIZEOF_V2_REGSET];
100
101   iov.iov_base = &v2_buffer;
102   iov.iov_len = ARC_LINUX_SIZEOF_V2_REGSET;
103
104   if (ptrace (PTRACE_GETREGSET, tid, NT_ARC_V2, (void *) &iov) < 0)
105     perror_with_name (_("Couldn't get ARC HS registers"));
106   else
107     arc_linux_supply_v2_regset (NULL, regcache, regnum, v2_buffer, 0);
108 }
109 #endif
110
111 /* Store general registers from REGCACHE into the target process/thread.  */
112
113 static void
114 store_gregs (const struct regcache *regcache, int regnum)
115 {
116   const int tid = get_ptrace_pid (regcache->ptid ());
117   struct iovec iov;
118   gdb_gregset_t regs;
119
120   iov.iov_base = &regs;
121   iov.iov_len = sizeof (gdb_gregset_t);
122
123   if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, (void *) &iov) < 0)
124     perror_with_name (_("Couldn't get general registers"));
125   else
126     {
127       arc_linux_collect_gregset (NULL, regcache, regnum, regs, 0);
128
129       if (ptrace (PTRACE_SETREGSET, tid, NT_PRSTATUS, (void *) &iov) < 0)
130         perror_with_name (_("Couldn't write general registers"));
131     }
132 }
133
134 #ifdef ARC_HAS_V2_REGSET
135 /* Store ARC v2 registers from REGCACHE into the target process/thread.  */
136
137 static void
138 store_v2_regs (const struct regcache *regcache, int regnum)
139 {
140   const int tid = get_ptrace_pid (regcache->ptid ());
141   struct iovec iov;
142   bfd_byte v2_buffer[ARC_LINUX_SIZEOF_V2_REGSET];
143
144   iov.iov_base = &v2_buffer;
145   iov.iov_len = ARC_LINUX_SIZEOF_V2_REGSET;
146
147   if (ptrace (PTRACE_GETREGSET, tid, NT_ARC_V2, (void *) &iov) < 0)
148     perror_with_name (_("Couldn't get ARC HS registers"));
149   else
150     {
151       arc_linux_collect_v2_regset (NULL, regcache, regnum, v2_buffer, 0);
152
153       if (ptrace (PTRACE_SETREGSET, tid, NT_ARC_V2, (void *) &iov) < 0)
154         perror_with_name (_("Couldn't write ARC HS registers"));
155     }
156 }
157 #endif
158
159 /* Target operation: Read REGNUM register (all registers if REGNUM == -1)
160    from target process into REGCACHE.  */
161
162 void
163 arc_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
164 {
165
166   if (regnum == -1 || regnum <= ARC_LAST_REGNUM)
167     fetch_gregs (regcache, regnum);
168
169 #ifdef ARC_HAS_V2_REGSET
170   if (regnum == -1
171       || regnum == ARC_R30_REGNUM
172       || regnum == ARC_R58_REGNUM
173       || regnum == ARC_R59_REGNUM)
174       fetch_v2_regs (regcache, regnum);
175 #endif
176 }
177
178 /* Target operation: Store REGNUM register (all registers if REGNUM == -1)
179    to the target process from REGCACHE.  */
180
181 void
182 arc_linux_nat_target::store_registers (struct regcache *regcache, int regnum)
183 {
184   if (regnum == -1 || regnum <= ARC_LAST_REGNUM)
185     store_gregs (regcache, regnum);
186
187 #ifdef ARC_HAS_V2_REGSET
188   if (regnum == -1
189       || regnum == ARC_R30_REGNUM
190       || regnum == ARC_R58_REGNUM
191       || regnum == ARC_R59_REGNUM)
192     store_v2_regs (regcache, regnum);
193 #endif
194 }
195
196 /* Copy general purpose register(s) from REGCACHE into regset GREGS.
197    This function is exported to proc-service.c  */
198
199 void
200 fill_gregset (const struct regcache *regcache,
201               gdb_gregset_t *gregs, int regnum)
202 {
203   arc_linux_collect_gregset (NULL, regcache, regnum, gregs, 0);
204 }
205
206 /* Copy all the general purpose registers from regset GREGS into REGCACHE.
207    This function is exported to proc-service.c.  */
208
209 void
210 supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregs)
211 {
212   arc_linux_supply_gregset (NULL, regcache, -1, gregs, 0);
213 }
214
215 /* ARC doesn't have separate FP registers.  This function is exported
216    to proc-service.c.  */
217
218 void
219 fill_fpregset (const struct regcache *regcache,
220                gdb_fpregset_t *fpregsetp, int regnum)
221 {
222   if (arc_debug)
223     debug_printf ("arc-linux-nat: fill_fpregset called.");
224   return;
225 }
226
227 /* ARC doesn't have separate FP registers.  This function is exported
228    to proc-service.c.  */
229
230 void
231 supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
232 {
233   if (arc_debug)
234     debug_printf ("arc-linux-nat: supply_fpregset called.");
235   return;
236 }
237
238 /* Implement the "read_description" method of linux_nat_target.  */
239
240 const struct target_desc *
241 arc_linux_nat_target::read_description ()
242 {
243   /* This is a native target, hence description is hardcoded.  */
244 #ifdef __ARCHS__
245   arc_arch_features features (4, ARC_ISA_ARCV2);
246 #else
247   arc_arch_features features (4, ARC_ISA_ARCV1);
248 #endif
249   return arc_lookup_target_description (features);
250 }
251
252 /* As described in arc_linux_collect_gregset(), we need to write resume-PC
253    to ERET.  However by default GDB for native targets doesn't write
254    registers if they haven't been changed.  This is a callback called by
255    generic GDB, and in this callback we have to rewrite PC value so it
256    would force rewrite of register on target.  It seems that the only
257    other arch that utilizes this hook is x86/x86-64 for HW breakpoint
258    support.  But then, AFAIK no other arch has this stop_pc/eret
259    complexity.
260
261    No better way was found, other than this fake write of register value,
262    to force GDB into writing register to target.  Is there any?  */
263
264 void
265 arc_linux_nat_target::low_prepare_to_resume (struct lwp_info *lwp)
266 {
267   /* When new processes and threads are created we do not have the address
268      space for them and calling get_thread_regcache will cause an internal
269      error in GDB.  It looks like that checking for last_resume_kind is the
270      sensible way to determine processes for which we cannot get regcache.
271      Ultimately, a better way would be removing the need for
272      low_prepare_to_resume in the first place.  */
273   if (lwp->last_resume_kind == resume_stop)
274     return;
275
276   struct regcache *regcache = get_thread_regcache (this, lwp->ptid);
277   struct gdbarch *gdbarch = regcache->arch ();
278
279   /* Read current PC value, then write it back.  It is required to call
280      invalidate(), otherwise GDB will note that new value is equal to old
281      value and will skip write.  */
282   ULONGEST new_pc;
283   regcache_cooked_read_unsigned (regcache, gdbarch_pc_regnum (gdbarch),
284                                  &new_pc);
285   regcache->invalidate (gdbarch_pc_regnum (gdbarch));
286   regcache_cooked_write_unsigned (regcache, gdbarch_pc_regnum (gdbarch),
287                                   new_pc);
288 }
289
290 /* Fetch the thread-local storage pointer for libthread_db.  Note that
291    this function is not called from GDB, but is called from libthread_db.
292    This is required to debug multithreaded applications with NPTL.  */
293
294 ps_err_e
295 ps_get_thread_area (struct ps_prochandle *ph, lwpid_t lwpid, int idx,
296                     void **base)
297 {
298   if (arc_debug >= 2)
299     debug_printf ("arc-linux-nat: ps_get_thread_area called");
300
301   if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
302     return PS_ERR;
303
304   /* IDX is the bias from the thread pointer to the beginning of the
305      thread descriptor.  It has to be subtracted due to implementation
306      quirks in libthread_db.  */
307   *base = (void *) ((char *) *base - idx);
308
309   return PS_OK;
310 }
311
312 /* Suppress warning from -Wmissing-prototypes.  */
313 void _initialize_arc_linux_nat ();
314 void
315 _initialize_arc_linux_nat ()
316 {
317   /* Register the target.  */
318   linux_target = &the_arc_linux_nat_target;
319   add_inf_child_target (&the_arc_linux_nat_target);
320 }
This page took 0.042484 seconds and 4 git commands to generate.