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