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