1 /* Target dependent code 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 /* GDB header files.  */
21 #include "linux-tdep.h"
22 #include "objfiles.h"
23 #include "opcode/arc.h"
24 #include "osabi.h"
25 #include "solib-svr4.h"
26 #include "disasm.h"
27 
28 /* ARC header files.  */
29 #include "opcodes/arc-dis.h"
30 #include "arc-linux-tdep.h"
31 #include "arc-tdep.h"
32 #include "arch/arc.h"
33 
34 /* Print an "arc-linux" debug statement.  */
35 
36 #define arc_linux_debug_printf(fmt, ...) \
37   debug_prefixed_printf_cond (arc_debug, "arc-linux", fmt, ##__VA_ARGS__)
38 
39 #define REGOFF(offset) (offset * ARC_REGISTER_SIZE)
40 
41 /* arc_linux_sc_reg_offsets[i] is the offset of register i in the `struct
42    sigcontext'.  Array index is an internal GDB register number, as defined in
43    arc-tdep.h:arc_regnum.
44 
45    From <include/uapi/asm/sigcontext.h> and <include/uapi/asm/ptrace.h>.
46 
47    The layout of this struct is tightly bound to "arc_regnum" enum
48    in arc-tdep.h.  Any change of order in there, must be reflected
49    here as well.  */
50 static const int arc_linux_sc_reg_offsets[] = {
51   /* R0 - R12.  */
52   REGOFF (22), REGOFF (21), REGOFF (20), REGOFF (19),
53   REGOFF (18), REGOFF (17), REGOFF (16), REGOFF (15),
54   REGOFF (14), REGOFF (13), REGOFF (12), REGOFF (11),
55   REGOFF (10),
56 
57   /* R13 - R25.  */
58   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
59   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
60   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
61   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
62   ARC_OFFSET_NO_REGISTER,
63 
64   REGOFF (9),                           /* R26 (GP) */
65   REGOFF (8),                           /* FP */
66   REGOFF (23),                          /* SP */
67   ARC_OFFSET_NO_REGISTER,     /* ILINK */
68   ARC_OFFSET_NO_REGISTER,     /* R30 */
69   REGOFF (7),                           /* BLINK */
70 
71   /* R32 - R59.  */
72   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
73   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
74   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
75   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
76   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
77   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
78   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
79   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
80   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
81   ARC_OFFSET_NO_REGISTER,
82 
83   REGOFF (4),                           /* LP_COUNT */
84   ARC_OFFSET_NO_REGISTER,     /* RESERVED */
85   ARC_OFFSET_NO_REGISTER,     /* LIMM */
86   ARC_OFFSET_NO_REGISTER,     /* PCL */
87 
88   REGOFF (6),                           /* PC  */
89   REGOFF (5),                           /* STATUS32 */
90   REGOFF (2),                           /* LP_START */
91   REGOFF (3),                           /* LP_END */
92   REGOFF (1),                           /* BTA */
93 };
94 
95 /* arc_linux_core_reg_offsets[i] is the offset in the .reg section of GDB
96    regnum i.  Array index is an internal GDB register number, as defined in
97    arc-tdep.h:arc_regnum.
98 
99    From include/uapi/asm/ptrace.h in the ARC Linux sources.  */
100 
101 /* The layout of this struct is tightly bound to "arc_regnum" enum
102    in arc-tdep.h.  Any change of order in there, must be reflected
103    here as well.  */
104 static const int arc_linux_core_reg_offsets[] = {
105   /* R0 - R12.  */
106   REGOFF (22), REGOFF (21), REGOFF (20), REGOFF (19),
107   REGOFF (18), REGOFF (17), REGOFF (16), REGOFF (15),
108   REGOFF (14), REGOFF (13), REGOFF (12), REGOFF (11),
109   REGOFF (10),
110 
111   /* R13 - R25.  */
112   REGOFF (37), REGOFF (36), REGOFF (35), REGOFF (34),
113   REGOFF (33), REGOFF (32), REGOFF (31), REGOFF (30),
114   REGOFF (29), REGOFF (28), REGOFF (27), REGOFF (26),
115   REGOFF (25),
116 
117   REGOFF (9),                           /* R26 (GP) */
118   REGOFF (8),                           /* FP */
119   REGOFF (23),                          /* SP */
120   ARC_OFFSET_NO_REGISTER,     /* ILINK */
121   ARC_OFFSET_NO_REGISTER,     /* R30 */
122   REGOFF (7),                           /* BLINK */
123 
124   /* R32 - R59.  */
125   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
126   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
127   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
128   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
129   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
130   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
131   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
132   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
133   ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
134   ARC_OFFSET_NO_REGISTER,
135 
136   REGOFF (4),                           /* LP_COUNT */
137   ARC_OFFSET_NO_REGISTER,     /* RESERVED */
138   ARC_OFFSET_NO_REGISTER,     /* LIMM */
139   ARC_OFFSET_NO_REGISTER,     /* PCL */
140 
141   REGOFF (39),                          /* PC  */
142   REGOFF (5),                           /* STATUS32 */
143   REGOFF (2),                           /* LP_START */
144   REGOFF (3),                           /* LP_END */
145   REGOFF (1),                           /* BTA */
146   REGOFF (6)                            /* ERET */
147 };
148 
149 /* Is THIS_FRAME a sigtramp function - the function that returns from
150    signal handler into normal execution flow? This is the case if the PC is
151    either at the start of, or in the middle of the two instructions:
152 
153      mov r8, __NR_rt_sigreturn ; __NR_rt_sigreturn == 139
154      trap_s 0 ; `swi' for ARC700
155 
156    On ARC uClibc Linux this function is called __default_rt_sa_restorer.
157 
158    Returns TRUE if this is a sigtramp frame.  */
159 
160 static bool
arc_linux_is_sigtramp(const frame_info_ptr & this_frame)161 arc_linux_is_sigtramp (const frame_info_ptr &this_frame)
162 {
163   struct gdbarch *gdbarch = get_frame_arch (this_frame);
164   CORE_ADDR pc = get_frame_pc (this_frame);
165 
166   arc_linux_debug_printf ("pc=%s", paddress(gdbarch, pc));
167 
168   static const gdb_byte insns_be_hs[] = {
169     0x20, 0x8a, 0x12, 0xc2,   /* mov  r8,nr_rt_sigreturn */
170     0x78, 0x1e                          /* trap_s 0 */
171   };
172   static const gdb_byte insns_be_700[] = {
173     0x20, 0x8a, 0x12, 0xc2,   /* mov  r8,nr_rt_sigreturn */
174     0x22, 0x6f, 0x00, 0x3f    /* swi */
175   };
176 
177   constexpr size_t max_insn_sz = std::max (sizeof (insns_be_hs),
178                                                      sizeof (insns_be_700));
179 
180   gdb_byte arc_sigtramp_insns[sizeof (insns_be_700)];
181   size_t insns_sz;
182   if (arc_mach_is_arcv2 (gdbarch))
183     {
184       insns_sz = sizeof (insns_be_hs);
185       memcpy (arc_sigtramp_insns, insns_be_hs, insns_sz);
186     }
187   else
188     {
189       insns_sz = sizeof (insns_be_700);
190       memcpy (arc_sigtramp_insns, insns_be_700, insns_sz);
191     }
192   if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
193     {
194       /* On little endian targets, ARC code section is in what is called
195            "middle endian", where half-words are in the big-endian order,
196            only bytes inside the halfwords are in the little endian order.
197            As a result it is very easy to convert big endian instruction to
198            little endian, since it is needed to swap bytes in the halfwords,
199            so there is no need to have information on whether that is a
200            4-byte instruction or 2-byte.  */
201       gdb_assert ((insns_sz % 2) == 0);
202       for (int i = 0; i < insns_sz; i += 2)
203           std::swap (arc_sigtramp_insns[i], arc_sigtramp_insns[i+1]);
204     }
205 
206   gdb_assert (insns_sz <= max_insn_sz);
207   gdb_byte buf[max_insn_sz];
208 
209   /* Read the memory at the PC.  Since we are stopped, any breakpoint must
210      have been removed.  */
211   if (!safe_frame_unwind_memory (this_frame, pc, {buf, insns_sz}))
212     {
213       /* Failed to unwind frame.  */
214       return FALSE;
215     }
216 
217   /* Is that code the sigtramp instruction sequence?  */
218   if (memcmp (buf, arc_sigtramp_insns, insns_sz) == 0)
219     return TRUE;
220 
221   /* No - look one instruction earlier in the code...  */
222   if (!safe_frame_unwind_memory (this_frame, pc - 4, {buf, insns_sz}))
223     {
224       /* Failed to unwind frame.  */
225       return FALSE;
226     }
227 
228   return (memcmp (buf, arc_sigtramp_insns, insns_sz) == 0);
229 }
230 
231 /* Get sigcontext structure of sigtramp frame - it contains saved
232    registers of interrupted frame.
233 
234    Stack pointer points to the rt_sigframe structure, and sigcontext can
235    be found as in:
236 
237    struct rt_sigframe {
238      struct siginfo info;
239      struct ucontext uc;
240      ...
241    };
242 
243    struct ucontext {
244      unsigned long uc_flags;
245      struct ucontext *uc_link;
246      stack_t uc_stack;
247      struct sigcontext uc_mcontext;
248      sigset_t uc_sigmask;
249    };
250 
251    sizeof (struct siginfo) == 0x80
252    offsetof (struct ucontext, uc_mcontext) == 0x14
253 
254    GDB cannot include linux headers and use offsetof () because those are
255    target headers and GDB might be built for a different run host.  There
256    doesn't seem to be an established mechanism to figure out those offsets
257    via gdbserver, so the only way is to hardcode values in the GDB,
258    meaning that GDB will be broken if values will change.  That seems to
259    be a very unlikely scenario and other arches (aarch64, alpha, amd64,
260    etc) in GDB hardcode values.  */
261 
262 static CORE_ADDR
arc_linux_sigcontext_addr(const frame_info_ptr & this_frame)263 arc_linux_sigcontext_addr (const frame_info_ptr &this_frame)
264 {
265   const int ucontext_offset = 0x80;
266   const int sigcontext_offset = 0x14;
267   return get_frame_sp (this_frame) + ucontext_offset + sigcontext_offset;
268 }
269 
270 /* Implement the "cannot_fetch_register" gdbarch method.  */
271 
272 static int
arc_linux_cannot_fetch_register(struct gdbarch * gdbarch,int regnum)273 arc_linux_cannot_fetch_register (struct gdbarch *gdbarch, int regnum)
274 {
275   /* Assume that register is readable if it is unknown.  */
276   switch (regnum)
277     {
278     case ARC_ILINK_REGNUM:
279     case ARC_RESERVED_REGNUM:
280     case ARC_LIMM_REGNUM:
281       return true;
282     case ARC_R30_REGNUM:
283     case ARC_R58_REGNUM:
284     case ARC_R59_REGNUM:
285       return !arc_mach_is_arcv2 (gdbarch);
286     }
287   return (regnum > ARC_BLINK_REGNUM) && (regnum < ARC_LP_COUNT_REGNUM);
288 }
289 
290 /* Implement the "cannot_store_register" gdbarch method.  */
291 
292 static int
arc_linux_cannot_store_register(struct gdbarch * gdbarch,int regnum)293 arc_linux_cannot_store_register (struct gdbarch *gdbarch, int regnum)
294 {
295   /* Assume that register is writable if it is unknown.  */
296   switch (regnum)
297     {
298     case ARC_ILINK_REGNUM:
299     case ARC_RESERVED_REGNUM:
300     case ARC_LIMM_REGNUM:
301     case ARC_PCL_REGNUM:
302       return true;
303     case ARC_R30_REGNUM:
304     case ARC_R58_REGNUM:
305     case ARC_R59_REGNUM:
306       return !arc_mach_is_arcv2 (gdbarch);
307     }
308   return (regnum > ARC_BLINK_REGNUM) && (regnum < ARC_LP_COUNT_REGNUM);
309 }
310 
311 /* For ARC Linux, breakpoints use the 16-bit TRAP_S 1 instruction, which
312    is 0x3e78 (little endian) or 0x783e (big endian).  */
313 
314 static const gdb_byte arc_linux_trap_s_be[] = { 0x78, 0x3e };
315 static const gdb_byte arc_linux_trap_s_le[] = { 0x3e, 0x78 };
316 static const int trap_size = 2;   /* Number of bytes to insert "trap".  */
317 
318 /* Implement the "breakpoint_kind_from_pc" gdbarch method.  */
319 
320 static int
arc_linux_breakpoint_kind_from_pc(struct gdbarch * gdbarch,CORE_ADDR * pcptr)321 arc_linux_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
322 {
323   return trap_size;
324 }
325 
326 /* Implement the "sw_breakpoint_from_kind" gdbarch method.  */
327 
328 static const gdb_byte *
arc_linux_sw_breakpoint_from_kind(struct gdbarch * gdbarch,int kind,int * size)329 arc_linux_sw_breakpoint_from_kind (struct gdbarch *gdbarch,
330                                            int kind, int *size)
331 {
332   gdb_assert (kind == trap_size);
333   *size = kind;
334   return ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
335             ? arc_linux_trap_s_be
336             : arc_linux_trap_s_le);
337 }
338 
339 /* Check for an atomic sequence of instructions beginning with an
340    LLOCK instruction and ending with a SCOND instruction.
341 
342    These patterns are hand coded in libc's (glibc and uclibc). Take
343    a look at [1] for instance:
344 
345    main+14: llock   r2,[r0]
346    main+18: brne.nt r2,0,main+30
347    main+22: scond   r3,[r0]
348    main+26: bne     main+14
349    main+30: mov_s   r0,0
350 
351    If such a sequence is found, attempt to step over it.
352    A breakpoint is placed at the end of the sequence.
353 
354    This function expects the INSN to be a "llock(d)" instruction.
355 
356    [1]
357    https://cgit.uclibc-ng.org/cgi/cgit/uclibc-ng.git/tree/libc/ \
358      sysdeps/linux/arc/bits/atomic.h#n46
359    */
360 
361 static std::vector<CORE_ADDR>
handle_atomic_sequence(arc_instruction insn,disassemble_info * di)362 handle_atomic_sequence (arc_instruction insn, disassemble_info *di)
363 {
364   const int atomic_seq_len = 24;    /* Instruction sequence length.  */
365   std::vector<CORE_ADDR> next_pcs;
366 
367   /* Sanity check.  */
368   gdb_assert (insn.insn_class == LLOCK);
369 
370   /* Data size we are dealing with: LLOCK vs. LLOCKD  */
371   arc_ldst_data_size llock_data_size_mode = insn.data_size_mode;
372   /* Indicator if any conditional branch is found in the sequence.  */
373   bool found_bc = false;
374   /* Becomes true if "LLOCK(D) .. SCOND(D)" sequence is found.  */
375   bool is_pattern_valid = false;
376 
377   for (int insn_count = 0; insn_count < atomic_seq_len; ++insn_count)
378     {
379       arc_insn_decode (arc_insn_get_linear_next_pc (insn),
380                            di, arc_delayed_print_insn, &insn);
381 
382       if (insn.insn_class == BRCC)
383           {
384             /* If more than one conditional branch is found, this is not
385                the pattern we are interested in.  */
386             if (found_bc)
387               break;
388             found_bc = true;
389             continue;
390           }
391 
392       /* This is almost a happy ending.  */
393       if (insn.insn_class == SCOND)
394           {
395             /* SCOND should match the LLOCK's data size.  */
396             if (insn.data_size_mode == llock_data_size_mode)
397               is_pattern_valid = true;
398             break;
399           }
400     }
401 
402   if (is_pattern_valid)
403     {
404       /* Get next instruction after scond(d).  There is no limm.  */
405       next_pcs.push_back (insn.address + insn.length);
406     }
407 
408   return next_pcs;
409 }
410 
411 /* Implement the "software_single_step" gdbarch method.  */
412 
413 static std::vector<CORE_ADDR>
arc_linux_software_single_step(struct regcache * regcache)414 arc_linux_software_single_step (struct regcache *regcache)
415 {
416   struct gdbarch *gdbarch = regcache->arch ();
417   arc_gdbarch_tdep *tdep = gdbarch_tdep<arc_gdbarch_tdep> (gdbarch);
418   struct gdb_non_printing_memory_disassembler dis (gdbarch);
419 
420   /* Read current instruction.  */
421   struct arc_instruction curr_insn;
422   arc_insn_decode (regcache_read_pc (regcache), dis.disasm_info (),
423                        arc_delayed_print_insn, &curr_insn);
424 
425   if (curr_insn.insn_class == LLOCK)
426     return handle_atomic_sequence (curr_insn, dis.disasm_info ());
427 
428   CORE_ADDR next_pc = arc_insn_get_linear_next_pc (curr_insn);
429   std::vector<CORE_ADDR> next_pcs;
430 
431   /* For instructions with delay slots, the fall thru is not the
432      instruction immediately after the current instruction, but the one
433      after that.  */
434   if (curr_insn.has_delay_slot)
435     {
436       struct arc_instruction next_insn;
437       arc_insn_decode (next_pc, dis.disasm_info (), arc_delayed_print_insn,
438                            &next_insn);
439       next_pcs.push_back (arc_insn_get_linear_next_pc (next_insn));
440     }
441   else
442     next_pcs.push_back (next_pc);
443 
444   ULONGEST status32;
445   regcache_cooked_read_unsigned (regcache, gdbarch_ps_regnum (gdbarch),
446                                          &status32);
447 
448   if (curr_insn.is_control_flow)
449     {
450       CORE_ADDR branch_pc = arc_insn_get_branch_target (curr_insn);
451       if (branch_pc != next_pc)
452           next_pcs.push_back (branch_pc);
453     }
454   /* Is current instruction the last in a loop body?  */
455   else if (tdep->has_hw_loops)
456     {
457       /* If STATUS32.L is 1, then ZD-loops are disabled.  */
458       if ((status32 & ARC_STATUS32_L_MASK) == 0)
459           {
460             ULONGEST lp_end, lp_start, lp_count;
461             regcache_cooked_read_unsigned (regcache, ARC_LP_START_REGNUM,
462                                                    &lp_start);
463             regcache_cooked_read_unsigned (regcache, ARC_LP_END_REGNUM, &lp_end);
464             regcache_cooked_read_unsigned (regcache, ARC_LP_COUNT_REGNUM,
465                                                    &lp_count);
466 
467             arc_linux_debug_printf ("lp_start = %s, lp_end = %s, "
468                                           "lp_count = %s, next_pc = %s",
469                                           paddress (gdbarch, lp_start),
470                                           paddress (gdbarch, lp_end),
471                                           pulongest (lp_count),
472                                           paddress (gdbarch, next_pc));
473 
474             if (next_pc == lp_end && lp_count > 1)
475               {
476                 /* The instruction is in effect a jump back to the start of
477                      the loop.  */
478                 next_pcs.push_back (lp_start);
479               }
480           }
481     }
482 
483   /* Is this a delay slot?  Then next PC is in BTA register.  */
484   if ((status32 & ARC_STATUS32_DE_MASK) != 0)
485     {
486       ULONGEST bta;
487       regcache_cooked_read_unsigned (regcache, ARC_BTA_REGNUM, &bta);
488       next_pcs.push_back (bta);
489     }
490 
491   return next_pcs;
492 }
493 
494 /* Implement the "skip_solib_resolver" gdbarch method.
495 
496    See glibc_skip_solib_resolver for details.  */
497 
498 static CORE_ADDR
arc_linux_skip_solib_resolver(struct gdbarch * gdbarch,CORE_ADDR pc)499 arc_linux_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
500 {
501   /* For uClibc 0.9.26+.
502 
503      An unresolved PLT entry points to "__dl_linux_resolve", which calls
504      "_dl_linux_resolver" to do the resolving and then eventually jumps to
505      the function.
506 
507      So we look for the symbol `_dl_linux_resolver', and if we are there,
508      gdb sets a breakpoint at the return address, and continues.  */
509   struct bound_minimal_symbol resolver
510     = lookup_minimal_symbol ("_dl_linux_resolver", NULL, NULL);
511 
512   if (arc_debug)
513     {
514       if (resolver.minsym != nullptr)
515           {
516             CORE_ADDR res_addr = resolver.value_address ();
517             arc_linux_debug_printf ("pc = %s, resolver at %s",
518                                           print_core_address (gdbarch, pc),
519                                           print_core_address (gdbarch, res_addr));
520           }
521       else
522           arc_linux_debug_printf ("pc = %s, no resolver found",
523                                         print_core_address (gdbarch, pc));
524     }
525 
526   if (resolver.minsym != nullptr && resolver.value_address () == pc)
527     {
528       /* Find the return address.  */
529       return frame_unwind_caller_pc (get_current_frame ());
530     }
531   else
532     {
533       /* No breakpoint required.  */
534       return 0;
535     }
536 }
537 
538 /* Populate REGCACHE with register REGNUM from BUF.  */
539 
540 static void
supply_register(struct regcache * regcache,int regnum,const gdb_byte * buf)541 supply_register (struct regcache *regcache, int regnum, const gdb_byte *buf)
542 {
543   /* Skip non-existing registers.  */
544   if ((arc_linux_core_reg_offsets[regnum] == ARC_OFFSET_NO_REGISTER))
545     return;
546 
547   regcache->raw_supply (regnum, buf + arc_linux_core_reg_offsets[regnum]);
548 }
549 
550 void
arc_linux_supply_gregset(const struct regset * regset,struct regcache * regcache,int regnum,const void * gregs,size_t size)551 arc_linux_supply_gregset (const struct regset *regset,
552                                 struct regcache *regcache,
553                                 int regnum, const void *gregs, size_t size)
554 {
555   static_assert (ARC_LAST_REGNUM
556                          < ARRAY_SIZE (arc_linux_core_reg_offsets));
557 
558   const bfd_byte *buf = (const bfd_byte *) gregs;
559 
560   /* REGNUM == -1 means writing all the registers.  */
561   if (regnum == -1)
562     for (int reg = 0; reg <= ARC_LAST_REGNUM; reg++)
563       supply_register (regcache, reg, buf);
564   else if (regnum <= ARC_LAST_REGNUM)
565     supply_register (regcache, regnum, buf);
566   else
567     gdb_assert_not_reached ("Invalid regnum in arc_linux_supply_gregset.");
568 }
569 
570 void
arc_linux_supply_v2_regset(const struct regset * regset,struct regcache * regcache,int regnum,const void * v2_regs,size_t size)571 arc_linux_supply_v2_regset (const struct regset *regset,
572                                   struct regcache *regcache, int regnum,
573                                   const void *v2_regs, size_t size)
574 {
575   const bfd_byte *buf = (const bfd_byte *) v2_regs;
576 
577   /* user_regs_arcv2 is defined in linux arch/arc/include/uapi/asm/ptrace.h.  */
578   if (regnum == -1 || regnum == ARC_R30_REGNUM)
579     regcache->raw_supply (ARC_R30_REGNUM, buf);
580   if (regnum == -1 || regnum == ARC_R58_REGNUM)
581     regcache->raw_supply (ARC_R58_REGNUM, buf + REGOFF (1));
582   if (regnum == -1 || regnum == ARC_R59_REGNUM)
583     regcache->raw_supply (ARC_R59_REGNUM, buf + REGOFF (2));
584 }
585 
586 /* Populate BUF with register REGNUM from the REGCACHE.  */
587 
588 static void
collect_register(const struct regcache * regcache,struct gdbarch * gdbarch,int regnum,gdb_byte * buf)589 collect_register (const struct regcache *regcache, struct gdbarch *gdbarch,
590                       int regnum, gdb_byte *buf)
591 {
592   int offset;
593 
594   /* Skip non-existing registers.  */
595   if (arc_linux_core_reg_offsets[regnum] == ARC_OFFSET_NO_REGISTER)
596     return;
597 
598   /* The address where the execution has stopped is in pseudo-register
599      STOP_PC.  However, when kernel code is returning from the exception,
600      it uses the value from ERET register.  Since, TRAP_S (the breakpoint
601      instruction) commits, the ERET points to the next instruction.  In
602      other words: ERET != STOP_PC.  To jump back from the kernel code to
603      the correct address, ERET must be overwritten by GDB's STOP_PC.  Else,
604      the program will continue at the address after the current instruction.
605      */
606   if (regnum == gdbarch_pc_regnum (gdbarch))
607     offset = arc_linux_core_reg_offsets[ARC_ERET_REGNUM];
608   else
609     offset = arc_linux_core_reg_offsets[regnum];
610   regcache->raw_collect (regnum, buf + offset);
611 }
612 
613 void
arc_linux_collect_gregset(const struct regset * regset,const struct regcache * regcache,int regnum,void * gregs,size_t size)614 arc_linux_collect_gregset (const struct regset *regset,
615                                  const struct regcache *regcache,
616                                  int regnum, void *gregs, size_t size)
617 {
618   static_assert (ARC_LAST_REGNUM
619                          < ARRAY_SIZE (arc_linux_core_reg_offsets));
620 
621   gdb_byte *buf = (gdb_byte *) gregs;
622   struct gdbarch *gdbarch = regcache->arch ();
623 
624   /* REGNUM == -1 means writing all the registers.  */
625   if (regnum == -1)
626     for (int reg = 0; reg <= ARC_LAST_REGNUM; reg++)
627       collect_register (regcache, gdbarch, reg, buf);
628   else if (regnum <= ARC_LAST_REGNUM)
629     collect_register (regcache, gdbarch, regnum, buf);
630   else
631     gdb_assert_not_reached ("Invalid regnum in arc_linux_collect_gregset.");
632 }
633 
634 void
arc_linux_collect_v2_regset(const struct regset * regset,const struct regcache * regcache,int regnum,void * v2_regs,size_t size)635 arc_linux_collect_v2_regset (const struct regset *regset,
636                                    const struct regcache *regcache, int regnum,
637                                    void *v2_regs, size_t size)
638 {
639   bfd_byte *buf = (bfd_byte *) v2_regs;
640 
641   if (regnum == -1 || regnum == ARC_R30_REGNUM)
642     regcache->raw_collect (ARC_R30_REGNUM, buf);
643   if (regnum == -1 || regnum == ARC_R58_REGNUM)
644     regcache->raw_collect (ARC_R58_REGNUM, buf + REGOFF (1));
645   if (regnum == -1 || regnum == ARC_R59_REGNUM)
646     regcache->raw_collect (ARC_R59_REGNUM, buf + REGOFF (2));
647 }
648 
649 /* Linux regset definitions.  */
650 
651 static const struct regset arc_linux_gregset = {
652   arc_linux_core_reg_offsets,
653   arc_linux_supply_gregset,
654   arc_linux_collect_gregset,
655 };
656 
657 static const struct regset arc_linux_v2_regset = {
658   NULL,
659   arc_linux_supply_v2_regset,
660   arc_linux_collect_v2_regset,
661 };
662 
663 /* Implement the `iterate_over_regset_sections` gdbarch method.  */
664 
665 static void
arc_linux_iterate_over_regset_sections(struct gdbarch * gdbarch,iterate_over_regset_sections_cb * cb,void * cb_data,const struct regcache * regcache)666 arc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
667                                                   iterate_over_regset_sections_cb *cb,
668                                                   void *cb_data,
669                                                   const struct regcache *regcache)
670 {
671   /* There are 40 registers in Linux user_regs_struct, although some of
672      them are now just a mere paddings, kept to maintain binary
673      compatibility with older tools.  */
674   const int sizeof_gregset = 40 * ARC_REGISTER_SIZE;
675 
676   cb (".reg", sizeof_gregset, sizeof_gregset, &arc_linux_gregset, NULL,
677       cb_data);
678   cb (".reg-arc-v2", ARC_LINUX_SIZEOF_V2_REGSET, ARC_LINUX_SIZEOF_V2_REGSET,
679       &arc_linux_v2_regset, NULL, cb_data);
680 }
681 
682 /* Implement the `core_read_description` gdbarch method.  */
683 
684 static const struct target_desc *
arc_linux_core_read_description(struct gdbarch * gdbarch,struct target_ops * target,bfd * abfd)685 arc_linux_core_read_description (struct gdbarch *gdbarch,
686                                          struct target_ops *target,
687                                          bfd *abfd)
688 {
689   arc_arch_features features
690     = arc_arch_features_create (abfd,
691                                         gdbarch_bfd_arch_info (gdbarch)->mach);
692   return arc_lookup_target_description (features);
693 }
694 
695 /* Initialization specific to Linux environment.  */
696 
697 static void
arc_linux_init_osabi(struct gdbarch_info info,struct gdbarch * gdbarch)698 arc_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
699 {
700   arc_gdbarch_tdep *tdep = gdbarch_tdep<arc_gdbarch_tdep> (gdbarch);
701 
702   arc_linux_debug_printf ("GNU/Linux OS/ABI initialization.");
703 
704   /* Fill in target-dependent info in ARC-private structure.  */
705   tdep->is_sigtramp = arc_linux_is_sigtramp;
706   tdep->sigcontext_addr = arc_linux_sigcontext_addr;
707   tdep->sc_reg_offset = arc_linux_sc_reg_offsets;
708   tdep->sc_num_regs = ARRAY_SIZE (arc_linux_sc_reg_offsets);
709 
710   /* If we are using Linux, we have in uClibc
711      (libc/sysdeps/linux/arc/bits/setjmp.h):
712 
713      typedef int __jmp_buf[13+1+1+1];    //r13-r25, fp, sp, blink
714 
715      Where "blink" is a stored PC of a caller function.
716    */
717   tdep->jb_pc = 15;
718 
719   linux_init_abi (info, gdbarch, 0);
720 
721   /* Set up target dependent GDB architecture entries.  */
722   set_gdbarch_cannot_fetch_register (gdbarch, arc_linux_cannot_fetch_register);
723   set_gdbarch_cannot_store_register (gdbarch, arc_linux_cannot_store_register);
724   set_gdbarch_breakpoint_kind_from_pc (gdbarch,
725                                                arc_linux_breakpoint_kind_from_pc);
726   set_gdbarch_sw_breakpoint_from_kind (gdbarch,
727                                                arc_linux_sw_breakpoint_from_kind);
728   set_gdbarch_fetch_tls_load_module_address (gdbarch,
729                                                        svr4_fetch_objfile_link_map);
730   set_gdbarch_software_single_step (gdbarch, arc_linux_software_single_step);
731   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
732   set_gdbarch_skip_solib_resolver (gdbarch, arc_linux_skip_solib_resolver);
733   set_gdbarch_iterate_over_regset_sections
734     (gdbarch, arc_linux_iterate_over_regset_sections);
735   set_gdbarch_core_read_description (gdbarch, arc_linux_core_read_description);
736 
737   /* GNU/Linux uses SVR4-style shared libraries, with 32-bit ints, longs
738      and pointers (ILP32).  */
739   set_solib_svr4_fetch_link_map_offsets (gdbarch,
740                                                    linux_ilp32_fetch_link_map_offsets);
741 }
742 
743 /* Suppress warning from -Wmissing-prototypes.  */
744 extern initialize_file_ftype _initialize_arc_linux_tdep;
745 
746 void
_initialize_arc_linux_tdep()747 _initialize_arc_linux_tdep ()
748 {
749   gdbarch_register_osabi (bfd_arch_arc, 0, GDB_OSABI_LINUX,
750                                 arc_linux_init_osabi);
751 }
752