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