xref: /netbsd-src/external/gpl3/gdb/dist/gdbserver/linux-arc-low.cc (revision 64f917f5a88990e32dd65fcd4348042fa7f852b9)
1 /* Target dependent code for the remote server for GNU/Linux ARC.
2 
3    Copyright 2020-2024 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 "regdef.h"
21 #include "linux-low.h"
22 #include "tdesc.h"
23 #include "arch/arc.h"
24 
25 #include <linux/elf.h>
26 #include <arpa/inet.h>
27 
28 /* Linux starting with 4.12 supports NT_ARC_V2 note type, which adds R30,
29    R58 and R59 registers.  */
30 #ifdef NT_ARC_V2
31 #define ARC_HAS_V2_REGSET
32 #endif
33 
34 /* The encoding of the instruction "TRAP_S 1" (endianness agnostic).  */
35 #define TRAP_S_1_OPCODE	0x783e
36 #define TRAP_S_1_SIZE	2
37 
38 /* Using a mere "uint16_t arc_linux_traps_s = TRAP_S_1_OPCODE" would
39    work as well, because the endianness will end up correctly when
40    the code is compiled for the same endianness as the target (see
41    the notes for "low_breakpoint_at" in this file).  However, this
42    illustrates how the __BIG_ENDIAN__ macro can be used to make
43    easy-to-understand codes.  */
44 #if defined(__BIG_ENDIAN__)
45 /* 0x78, 0x3e.  */
46 static gdb_byte arc_linux_trap_s[TRAP_S_1_SIZE]
47 	= {TRAP_S_1_OPCODE >> 8, TRAP_S_1_OPCODE & 0xFF};
48 #else
49 /* 0x3e, 0x78.  */
50 static gdb_byte arc_linux_trap_s[TRAP_S_1_SIZE]
51 	= {TRAP_S_1_OPCODE && 0xFF, TRAP_S_1_OPCODE >> 8};
52 #endif
53 
54 /* Linux target op definitions for the ARC architecture.
55    Note for future: in case of adding the protected method low_get_next_pcs(),
56    the public method supports_software_single_step() should be added to return
57    "true".  */
58 
59 class arc_target : public linux_process_target
60 {
61 public:
62 
63   const regs_info *get_regs_info () override;
64 
65   const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override;
66 
67 protected:
68 
69   void low_arch_setup () override;
70 
71   bool low_cannot_fetch_register (int regno) override;
72 
73   bool low_cannot_store_register (int regno) override;
74 
75   bool low_supports_breakpoints () override;
76 
77   CORE_ADDR low_get_pc (regcache *regcache) override;
78 
79   void low_set_pc (regcache *regcache, CORE_ADDR newpc) override;
80 
81   bool low_breakpoint_at (CORE_ADDR where) override;
82 };
83 
84 /* The singleton target ops object.  */
85 
86 static arc_target the_arc_target;
87 
88 bool
89 arc_target::low_supports_breakpoints ()
90 {
91   return true;
92 }
93 
94 CORE_ADDR
95 arc_target::low_get_pc (regcache *regcache)
96 {
97   return linux_get_pc_32bit (regcache);
98 }
99 
100 void
101 arc_target::low_set_pc (regcache *regcache, CORE_ADDR pc)
102 {
103   linux_set_pc_32bit (regcache, pc);
104 }
105 
106 static const struct target_desc *
107 arc_linux_read_description (void)
108 {
109 #ifdef __ARC700__
110   arc_arch_features features (4, ARC_ISA_ARCV1);
111 #else
112   arc_arch_features features (4, ARC_ISA_ARCV2);
113 #endif
114   target_desc_up tdesc = arc_create_target_description (features);
115 
116   static const char *expedite_regs[] = { "sp", "status32", nullptr };
117   init_target_desc (tdesc.get (), expedite_regs);
118 
119   return tdesc.release ();
120 }
121 
122 void
123 arc_target::low_arch_setup ()
124 {
125   current_process ()->tdesc = arc_linux_read_description ();
126 }
127 
128 bool
129 arc_target::low_cannot_fetch_register (int regno)
130 {
131   return (regno >= current_process ()->tdesc->reg_defs.size ());
132 }
133 
134 bool
135 arc_target::low_cannot_store_register (int regno)
136 {
137   return (regno >= current_process ()->tdesc->reg_defs.size ());
138 }
139 
140 /* This works for both endianness.  Below you see an illustration of how
141    the "trap_s 1" instruction encoded for both endianness in the memory
142    will end up as the TRAP_S_1_OPCODE constant:
143 
144    BE: 0x78 0x3e --> at INSN addr: 0x78 0x3e --> INSN = 0x783e
145    LE: 0x3e 0x78 --> at INSN addr: 0x3e 0x78 --> INSN = 0x783e
146 
147    One can employ "memcmp()" for comparing the arrays too.  */
148 
149 bool
150 arc_target::low_breakpoint_at (CORE_ADDR where)
151 {
152   uint16_t insn;
153 
154   /* "the_target" global variable is the current object at hand.  */
155   this->read_memory (where, (gdb_byte *) &insn, TRAP_S_1_SIZE);
156   return (insn == TRAP_S_1_OPCODE);
157 }
158 
159 /* PTRACE_GETREGSET/NT_PRSTATUS and PTRACE_SETREGSET/NT_PRSTATUS work with
160    regsets in a struct, "user_regs_struct", defined in the
161    linux/arch/arc/include/uapi/asm/ptrace.h header.  This code supports
162    ARC Linux ABI v3 and v4.  */
163 
164 /* Populate a ptrace NT_PRSTATUS regset from a regcache.
165 
166    This appears to be a unique approach to populating the buffer, but
167    being name, rather than offset based, it is robust to future API
168    changes, as there is no need to create a regmap of registers in the
169    user_regs_struct.  */
170 
171 static void
172 arc_fill_gregset (struct regcache *regcache, void *buf)
173 {
174   struct user_regs_struct *regbuf = (struct user_regs_struct *) buf;
175 
176   /* Core registers.  */
177   collect_register_by_name (regcache, "r0", &(regbuf->scratch.r0));
178   collect_register_by_name (regcache, "r1", &(regbuf->scratch.r1));
179   collect_register_by_name (regcache, "r2", &(regbuf->scratch.r2));
180   collect_register_by_name (regcache, "r3", &(regbuf->scratch.r3));
181   collect_register_by_name (regcache, "r4", &(regbuf->scratch.r4));
182   collect_register_by_name (regcache, "r5", &(regbuf->scratch.r5));
183   collect_register_by_name (regcache, "r6", &(regbuf->scratch.r6));
184   collect_register_by_name (regcache, "r7", &(regbuf->scratch.r7));
185   collect_register_by_name (regcache, "r8", &(regbuf->scratch.r8));
186   collect_register_by_name (regcache, "r9", &(regbuf->scratch.r9));
187   collect_register_by_name (regcache, "r10", &(regbuf->scratch.r10));
188   collect_register_by_name (regcache, "r11", &(regbuf->scratch.r11));
189   collect_register_by_name (regcache, "r12", &(regbuf->scratch.r12));
190   collect_register_by_name (regcache, "r13", &(regbuf->callee.r13));
191   collect_register_by_name (regcache, "r14", &(regbuf->callee.r14));
192   collect_register_by_name (regcache, "r15", &(regbuf->callee.r15));
193   collect_register_by_name (regcache, "r16", &(regbuf->callee.r16));
194   collect_register_by_name (regcache, "r17", &(regbuf->callee.r17));
195   collect_register_by_name (regcache, "r18", &(regbuf->callee.r18));
196   collect_register_by_name (regcache, "r19", &(regbuf->callee.r19));
197   collect_register_by_name (regcache, "r20", &(regbuf->callee.r20));
198   collect_register_by_name (regcache, "r21", &(regbuf->callee.r21));
199   collect_register_by_name (regcache, "r22", &(regbuf->callee.r22));
200   collect_register_by_name (regcache, "r23", &(regbuf->callee.r23));
201   collect_register_by_name (regcache, "r24", &(regbuf->callee.r24));
202   collect_register_by_name (regcache, "r25", &(regbuf->callee.r25));
203   collect_register_by_name (regcache, "gp", &(regbuf->scratch.gp));
204   collect_register_by_name (regcache, "fp", &(regbuf->scratch.fp));
205   collect_register_by_name (regcache, "sp", &(regbuf->scratch.sp));
206   collect_register_by_name (regcache, "blink", &(regbuf->scratch.blink));
207 
208   /* Loop registers.  */
209   collect_register_by_name (regcache, "lp_count", &(regbuf->scratch.lp_count));
210   collect_register_by_name (regcache, "lp_start", &(regbuf->scratch.lp_start));
211   collect_register_by_name (regcache, "lp_end", &(regbuf->scratch.lp_end));
212 
213   /* The current "pc" value must be written to "eret" (exception return
214      address) register, because that is the address that the kernel code
215      will jump back to after a breakpoint exception has been raised.
216      The "pc_stop" value is ignored by the genregs_set() in
217      linux/arch/arc/kernel/ptrace.c.  */
218   collect_register_by_name (regcache, "pc", &(regbuf->scratch.ret));
219 
220   /* Currently ARC Linux ptrace doesn't allow writes to status32 because
221      some of its bits are kernel mode-only and shoudn't be writable from
222      user-space.  Writing status32 from debugger could be useful, though,
223      so ability to write non-privileged bits will be added to kernel
224      sooner or later.  */
225 
226   /* BTA.  */
227   collect_register_by_name (regcache, "bta", &(regbuf->scratch.bta));
228 }
229 
230 /* Populate a regcache from a ptrace NT_PRSTATUS regset.  */
231 
232 static void
233 arc_store_gregset (struct regcache *regcache, const void *buf)
234 {
235   const struct user_regs_struct *regbuf = (const struct user_regs_struct *) buf;
236 
237   /* Core registers.  */
238   supply_register_by_name (regcache, "r0", &(regbuf->scratch.r0));
239   supply_register_by_name (regcache, "r1", &(regbuf->scratch.r1));
240   supply_register_by_name (regcache, "r2", &(regbuf->scratch.r2));
241   supply_register_by_name (regcache, "r3", &(regbuf->scratch.r3));
242   supply_register_by_name (regcache, "r4", &(regbuf->scratch.r4));
243   supply_register_by_name (regcache, "r5", &(regbuf->scratch.r5));
244   supply_register_by_name (regcache, "r6", &(regbuf->scratch.r6));
245   supply_register_by_name (regcache, "r7", &(regbuf->scratch.r7));
246   supply_register_by_name (regcache, "r8", &(regbuf->scratch.r8));
247   supply_register_by_name (regcache, "r9", &(regbuf->scratch.r9));
248   supply_register_by_name (regcache, "r10", &(regbuf->scratch.r10));
249   supply_register_by_name (regcache, "r11", &(regbuf->scratch.r11));
250   supply_register_by_name (regcache, "r12", &(regbuf->scratch.r12));
251   supply_register_by_name (regcache, "r13", &(regbuf->callee.r13));
252   supply_register_by_name (regcache, "r14", &(regbuf->callee.r14));
253   supply_register_by_name (regcache, "r15", &(regbuf->callee.r15));
254   supply_register_by_name (regcache, "r16", &(regbuf->callee.r16));
255   supply_register_by_name (regcache, "r17", &(regbuf->callee.r17));
256   supply_register_by_name (regcache, "r18", &(regbuf->callee.r18));
257   supply_register_by_name (regcache, "r19", &(regbuf->callee.r19));
258   supply_register_by_name (regcache, "r20", &(regbuf->callee.r20));
259   supply_register_by_name (regcache, "r21", &(regbuf->callee.r21));
260   supply_register_by_name (regcache, "r22", &(regbuf->callee.r22));
261   supply_register_by_name (regcache, "r23", &(regbuf->callee.r23));
262   supply_register_by_name (regcache, "r24", &(regbuf->callee.r24));
263   supply_register_by_name (regcache, "r25", &(regbuf->callee.r25));
264   supply_register_by_name (regcache, "gp", &(regbuf->scratch.gp));
265   supply_register_by_name (regcache, "fp", &(regbuf->scratch.fp));
266   supply_register_by_name (regcache, "sp", &(regbuf->scratch.sp));
267   supply_register_by_name (regcache, "blink", &(regbuf->scratch.blink));
268 
269   /* Loop registers.  */
270   supply_register_by_name (regcache, "lp_count", &(regbuf->scratch.lp_count));
271   supply_register_by_name (regcache, "lp_start", &(regbuf->scratch.lp_start));
272   supply_register_by_name (regcache, "lp_end", &(regbuf->scratch.lp_end));
273 
274   /* The genregs_get() in linux/arch/arc/kernel/ptrace.c populates the
275      pseudo register "stop_pc" with the "efa" (exception fault address)
276      register.  This was deemed necessary, because the breakpoint
277      instruction, "trap_s 1", is a committing one; i.e. the "eret"
278      (exception return address) register will be pointing to the next
279      instruction, while "efa" points to the address that raised the
280      breakpoint.  */
281   supply_register_by_name (regcache, "pc", &(regbuf->stop_pc));
282   unsigned long pcl = regbuf->stop_pc & ~3L;
283   supply_register_by_name (regcache, "pcl", &pcl);
284 
285   /* Other auxilliary registers.  */
286   supply_register_by_name (regcache, "status32", &(regbuf->scratch.status32));
287 
288   /* BTA.  */
289   supply_register_by_name (regcache, "bta", &(regbuf->scratch.bta));
290 }
291 
292 #ifdef ARC_HAS_V2_REGSET
293 
294 /* Look through a regcache's TDESC for a register named NAME.
295    If found, return true; false, otherwise.  */
296 
297 static bool
298 is_reg_name_available_p (const struct target_desc *tdesc,
299 			 const char *name)
300 {
301   for (const gdb::reg &reg : tdesc->reg_defs)
302     if (strcmp (name, reg.name) == 0)
303       return true;
304   return false;
305 }
306 
307 /* Copy registers from regcache to user_regs_arcv2.  */
308 
309 static void
310 arc_fill_v2_regset (struct regcache *regcache, void *buf)
311 {
312   struct user_regs_arcv2 *regbuf = (struct user_regs_arcv2 *) buf;
313 
314   if (is_reg_name_available_p (regcache->tdesc, "r30"))
315     collect_register_by_name (regcache, "r30", &(regbuf->r30));
316 
317   if (is_reg_name_available_p (regcache->tdesc, "r58"))
318     collect_register_by_name (regcache, "r58", &(regbuf->r58));
319 
320   if (is_reg_name_available_p (regcache->tdesc, "r59"))
321     collect_register_by_name (regcache, "r59", &(regbuf->r59));
322 }
323 
324 /* Copy registers from user_regs_arcv2 to regcache.  */
325 
326 static void
327 arc_store_v2_regset (struct regcache *regcache, const void *buf)
328 {
329   struct user_regs_arcv2 *regbuf = (struct user_regs_arcv2 *) buf;
330 
331   if (is_reg_name_available_p (regcache->tdesc, "r30"))
332     supply_register_by_name (regcache, "r30", &(regbuf->r30));
333 
334   if (is_reg_name_available_p (regcache->tdesc, "r58"))
335     supply_register_by_name (regcache, "r58", &(regbuf->r58));
336 
337   if (is_reg_name_available_p (regcache->tdesc, "r59"))
338     supply_register_by_name (regcache, "r59", &(regbuf->r59));
339 }
340 
341 #endif
342 
343 /* Fetch the thread-local storage pointer for libthread_db.  Note that
344    this function is not called from GDB, but is called from libthread_db.
345 
346    This is the same function as for other architectures, for example in
347    linux-arm-low.c.  */
348 
349 ps_err_e
350 ps_get_thread_area (struct ps_prochandle *ph, lwpid_t lwpid,
351 		    int idx, void **base)
352 {
353   if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, nullptr, base) != 0)
354     return PS_ERR;
355 
356   /* IDX is the bias from the thread pointer to the beginning of the
357      thread descriptor.  It has to be subtracted due to implementation
358      quirks in libthread_db.  */
359   *base = (void *) ((char *) *base - idx);
360 
361   return PS_OK;
362 }
363 
364 static struct regset_info arc_regsets[] =
365 {
366   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS,
367     sizeof (struct user_regs_struct), GENERAL_REGS,
368     arc_fill_gregset, arc_store_gregset
369   },
370 #ifdef ARC_HAS_V2_REGSET
371   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARC_V2,
372     sizeof (struct user_regs_arcv2), GENERAL_REGS,
373     arc_fill_v2_regset, arc_store_v2_regset
374   },
375 #endif
376   NULL_REGSET
377 };
378 
379 static struct regsets_info arc_regsets_info =
380 {
381   arc_regsets,	/* regsets */
382   0,		/* num_regsets */
383   nullptr,	/* disabled regsets */
384 };
385 
386 static struct regs_info arc_regs_info =
387 {
388   nullptr,	/* regset_bitmap */
389   nullptr,	/* usrregs */
390   &arc_regsets_info
391 };
392 
393 const regs_info *
394 arc_target::get_regs_info ()
395 {
396   return &arc_regs_info;
397 }
398 
399 /* One of the methods necessary for Z0 packet support.  */
400 
401 const gdb_byte *
402 arc_target::sw_breakpoint_from_kind (int kind, int *size)
403 {
404   gdb_assert (kind == TRAP_S_1_SIZE);
405   *size = kind;
406   return arc_linux_trap_s;
407 }
408 
409 /* The linux target ops object.  */
410 
411 linux_process_target *the_linux_target = &the_arc_target;
412 
413 void
414 initialize_low_arch (void)
415 {
416   initialize_regsets_info (&arc_regsets_info);
417 }
418