1 /* Target dependent code for GNU/Linux ARC.
3 Copyright 2020-2022 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
20 /* GDB header files. */
22 #include "linux-tdep.h"
24 #include "opcode/arc.h"
26 #include "solib-svr4.h"
29 /* ARC header files. */
30 #include "opcodes/arc-dis.h"
31 #include "arc-linux-tdep.h"
35 /* Print an "arc-linux" debug statement. */
37 #define arc_linux_debug_printf(fmt, ...) \
38 debug_prefixed_printf_cond (arc_debug, "arc-linux", fmt, ##__VA_ARGS__)
40 #define REGOFF(offset) (offset * ARC_REGISTER_SIZE)
42 /* arc_linux_sc_reg_offsets[i] is the offset of register i in the `struct
43 sigcontext'. Array index is an internal GDB register number, as defined in
44 arc-tdep.h:arc_regnum.
46 From <include/uapi/asm/sigcontext.h> and <include/uapi/asm/ptrace.h>.
48 The layout of this struct is tightly bound to "arc_regnum" enum
49 in arc-tdep.h. Any change of order in there, must be reflected
51 static const int arc_linux_sc_reg_offsets
[] = {
53 REGOFF (22), REGOFF (21), REGOFF (20), REGOFF (19),
54 REGOFF (18), REGOFF (17), REGOFF (16), REGOFF (15),
55 REGOFF (14), REGOFF (13), REGOFF (12), REGOFF (11),
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
, ARC_OFFSET_NO_REGISTER
, ARC_OFFSET_NO_REGISTER
,
63 ARC_OFFSET_NO_REGISTER
,
65 REGOFF (9), /* R26 (GP) */
68 ARC_OFFSET_NO_REGISTER
, /* ILINK */
69 ARC_OFFSET_NO_REGISTER
, /* R30 */
70 REGOFF (7), /* BLINK */
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
, ARC_OFFSET_NO_REGISTER
, ARC_OFFSET_NO_REGISTER
,
82 ARC_OFFSET_NO_REGISTER
,
84 REGOFF (4), /* LP_COUNT */
85 ARC_OFFSET_NO_REGISTER
, /* RESERVED */
86 ARC_OFFSET_NO_REGISTER
, /* LIMM */
87 ARC_OFFSET_NO_REGISTER
, /* PCL */
90 REGOFF (5), /* STATUS32 */
91 REGOFF (2), /* LP_START */
92 REGOFF (3), /* LP_END */
96 /* arc_linux_core_reg_offsets[i] is the offset in the .reg section of GDB
97 regnum i. Array index is an internal GDB register number, as defined in
98 arc-tdep.h:arc_regnum.
100 From include/uapi/asm/ptrace.h in the ARC Linux sources. */
102 /* The layout of this struct is tightly bound to "arc_regnum" enum
103 in arc-tdep.h. Any change of order in there, must be reflected
105 static const int arc_linux_core_reg_offsets
[] = {
107 REGOFF (22), REGOFF (21), REGOFF (20), REGOFF (19),
108 REGOFF (18), REGOFF (17), REGOFF (16), REGOFF (15),
109 REGOFF (14), REGOFF (13), REGOFF (12), REGOFF (11),
113 REGOFF (37), REGOFF (36), REGOFF (35), REGOFF (34),
114 REGOFF (33), REGOFF (32), REGOFF (31), REGOFF (30),
115 REGOFF (29), REGOFF (28), REGOFF (27), REGOFF (26),
118 REGOFF (9), /* R26 (GP) */
120 REGOFF (23), /* SP */
121 ARC_OFFSET_NO_REGISTER
, /* ILINK */
122 ARC_OFFSET_NO_REGISTER
, /* R30 */
123 REGOFF (7), /* BLINK */
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
, ARC_OFFSET_NO_REGISTER
, ARC_OFFSET_NO_REGISTER
,
135 ARC_OFFSET_NO_REGISTER
,
137 REGOFF (4), /* LP_COUNT */
138 ARC_OFFSET_NO_REGISTER
, /* RESERVED */
139 ARC_OFFSET_NO_REGISTER
, /* LIMM */
140 ARC_OFFSET_NO_REGISTER
, /* PCL */
142 REGOFF (39), /* PC */
143 REGOFF (5), /* STATUS32 */
144 REGOFF (2), /* LP_START */
145 REGOFF (3), /* LP_END */
146 REGOFF (1), /* BTA */
147 REGOFF (6) /* ERET */
150 /* Is THIS_FRAME a sigtramp function - the function that returns from
151 signal handler into normal execution flow? This is the case if the PC is
152 either at the start of, or in the middle of the two instructions:
154 mov r8, __NR_rt_sigreturn ; __NR_rt_sigreturn == 139
155 trap_s 0 ; `swi' for ARC700
157 On ARC uClibc Linux this function is called __default_rt_sa_restorer.
159 Returns TRUE if this is a sigtramp frame. */
162 arc_linux_is_sigtramp (struct frame_info
*this_frame
)
164 struct gdbarch
*gdbarch
= get_frame_arch (this_frame
);
165 CORE_ADDR pc
= get_frame_pc (this_frame
);
167 arc_linux_debug_printf ("pc=%s", paddress(gdbarch
, pc
));
169 static const gdb_byte insns_be_hs
[] = {
170 0x20, 0x8a, 0x12, 0xc2, /* mov r8,nr_rt_sigreturn */
171 0x78, 0x1e /* trap_s 0 */
173 static const gdb_byte insns_be_700
[] = {
174 0x20, 0x8a, 0x12, 0xc2, /* mov r8,nr_rt_sigreturn */
175 0x22, 0x6f, 0x00, 0x3f /* swi */
178 gdb_byte arc_sigtramp_insns
[sizeof (insns_be_700
)];
180 if (arc_mach_is_arcv2 (gdbarch
))
182 insns_sz
= sizeof (insns_be_hs
);
183 memcpy (arc_sigtramp_insns
, insns_be_hs
, insns_sz
);
187 insns_sz
= sizeof (insns_be_700
);
188 memcpy (arc_sigtramp_insns
, insns_be_700
, insns_sz
);
190 if (gdbarch_byte_order (gdbarch
) == BFD_ENDIAN_LITTLE
)
192 /* On little endian targets, ARC code section is in what is called
193 "middle endian", where half-words are in the big-endian order,
194 only bytes inside the halfwords are in the little endian order.
195 As a result it is very easy to convert big endian instruction to
196 little endian, since it is needed to swap bytes in the halfwords,
197 so there is no need to have information on whether that is a
198 4-byte instruction or 2-byte. */
199 gdb_assert ((insns_sz
% 2) == 0);
200 for (int i
= 0; i
< insns_sz
; i
+= 2)
201 std::swap (arc_sigtramp_insns
[i
], arc_sigtramp_insns
[i
+1]);
204 gdb_byte buf
[insns_sz
];
206 /* Read the memory at the PC. Since we are stopped, any breakpoint must
207 have been removed. */
208 if (!safe_frame_unwind_memory (this_frame
, pc
, {buf
, insns_sz
}))
210 /* Failed to unwind frame. */
214 /* Is that code the sigtramp instruction sequence? */
215 if (memcmp (buf
, arc_sigtramp_insns
, insns_sz
) == 0)
218 /* No - look one instruction earlier in the code... */
219 if (!safe_frame_unwind_memory (this_frame
, pc
- 4, {buf
, insns_sz
}))
221 /* Failed to unwind frame. */
225 return (memcmp (buf
, arc_sigtramp_insns
, insns_sz
) == 0);
228 /* Get sigcontext structure of sigtramp frame - it contains saved
229 registers of interrupted frame.
231 Stack pointer points to the rt_sigframe structure, and sigcontext can
241 unsigned long uc_flags;
242 struct ucontext *uc_link;
244 struct sigcontext uc_mcontext;
248 sizeof (struct siginfo) == 0x80
249 offsetof (struct ucontext, uc_mcontext) == 0x14
251 GDB cannot include linux headers and use offsetof () because those are
252 target headers and GDB might be built for a different run host. There
253 doesn't seem to be an established mechanism to figure out those offsets
254 via gdbserver, so the only way is to hardcode values in the GDB,
255 meaning that GDB will be broken if values will change. That seems to
256 be a very unlikely scenario and other arches (aarch64, alpha, amd64,
257 etc) in GDB hardcode values. */
260 arc_linux_sigcontext_addr (struct frame_info
*this_frame
)
262 const int ucontext_offset
= 0x80;
263 const int sigcontext_offset
= 0x14;
264 return get_frame_sp (this_frame
) + ucontext_offset
+ sigcontext_offset
;
267 /* Implement the "cannot_fetch_register" gdbarch method. */
270 arc_linux_cannot_fetch_register (struct gdbarch
*gdbarch
, int regnum
)
272 /* Assume that register is readable if it is unknown. */
275 case ARC_ILINK_REGNUM
:
276 case ARC_RESERVED_REGNUM
:
277 case ARC_LIMM_REGNUM
:
282 return !arc_mach_is_arcv2 (gdbarch
);
284 return (regnum
> ARC_BLINK_REGNUM
) && (regnum
< ARC_LP_COUNT_REGNUM
);
287 /* Implement the "cannot_store_register" gdbarch method. */
290 arc_linux_cannot_store_register (struct gdbarch
*gdbarch
, int regnum
)
292 /* Assume that register is writable if it is unknown. */
295 case ARC_ILINK_REGNUM
:
296 case ARC_RESERVED_REGNUM
:
297 case ARC_LIMM_REGNUM
:
303 return !arc_mach_is_arcv2 (gdbarch
);
305 return (regnum
> ARC_BLINK_REGNUM
) && (regnum
< ARC_LP_COUNT_REGNUM
);
308 /* For ARC Linux, breakpoints use the 16-bit TRAP_S 1 instruction, which
309 is 0x3e78 (little endian) or 0x783e (big endian). */
311 static const gdb_byte arc_linux_trap_s_be
[] = { 0x78, 0x3e };
312 static const gdb_byte arc_linux_trap_s_le
[] = { 0x3e, 0x78 };
313 static const int trap_size
= 2; /* Number of bytes to insert "trap". */
315 /* Implement the "breakpoint_kind_from_pc" gdbarch method. */
318 arc_linux_breakpoint_kind_from_pc (struct gdbarch
*gdbarch
, CORE_ADDR
*pcptr
)
323 /* Implement the "sw_breakpoint_from_kind" gdbarch method. */
325 static const gdb_byte
*
326 arc_linux_sw_breakpoint_from_kind (struct gdbarch
*gdbarch
,
329 gdb_assert (kind
== trap_size
);
331 return ((gdbarch_byte_order (gdbarch
) == BFD_ENDIAN_BIG
)
332 ? arc_linux_trap_s_be
333 : arc_linux_trap_s_le
);
336 /* Check for an atomic sequence of instructions beginning with an
337 LLOCK instruction and ending with a SCOND instruction.
339 These patterns are hand coded in libc's (glibc and uclibc). Take
340 a look at [1] for instance:
342 main+14: llock r2,[r0]
343 main+18: brne.nt r2,0,main+30
344 main+22: scond r3,[r0]
348 If such a sequence is found, attempt to step over it.
349 A breakpoint is placed at the end of the sequence.
351 This function expects the INSN to be a "llock(d)" instruction.
354 https://cgit.uclibc-ng.org/cgi/cgit/uclibc-ng.git/tree/libc/ \
355 sysdeps/linux/arc/bits/atomic.h#n46
358 static std::vector
<CORE_ADDR
>
359 handle_atomic_sequence (arc_instruction insn
, disassemble_info
&di
)
361 const int atomic_seq_len
= 24; /* Instruction sequence length. */
362 std::vector
<CORE_ADDR
> next_pcs
;
365 gdb_assert (insn
.insn_class
== LLOCK
);
367 /* Data size we are dealing with: LLOCK vs. LLOCKD */
368 arc_ldst_data_size llock_data_size_mode
= insn
.data_size_mode
;
369 /* Indicator if any conditional branch is found in the sequence. */
370 bool found_bc
= false;
371 /* Becomes true if "LLOCK(D) .. SCOND(D)" sequence is found. */
372 bool is_pattern_valid
= false;
374 for (int insn_count
= 0; insn_count
< atomic_seq_len
; ++insn_count
)
376 arc_insn_decode (arc_insn_get_linear_next_pc (insn
),
377 &di
, arc_delayed_print_insn
, &insn
);
379 if (insn
.insn_class
== BRCC
)
381 /* If more than one conditional branch is found, this is not
382 the pattern we are interested in. */
389 /* This is almost a happy ending. */
390 if (insn
.insn_class
== SCOND
)
392 /* SCOND should match the LLOCK's data size. */
393 if (insn
.data_size_mode
== llock_data_size_mode
)
394 is_pattern_valid
= true;
399 if (is_pattern_valid
)
401 /* Get next instruction after scond(d). There is no limm. */
402 next_pcs
.push_back (insn
.address
+ insn
.length
);
408 /* Implement the "software_single_step" gdbarch method. */
410 static std::vector
<CORE_ADDR
>
411 arc_linux_software_single_step (struct regcache
*regcache
)
413 struct gdbarch
*gdbarch
= regcache
->arch ();
414 arc_gdbarch_tdep
*tdep
= (arc_gdbarch_tdep
*) gdbarch_tdep (gdbarch
);
415 struct disassemble_info di
= arc_disassemble_info (gdbarch
);
417 /* Read current instruction. */
418 struct arc_instruction curr_insn
;
419 arc_insn_decode (regcache_read_pc (regcache
), &di
, arc_delayed_print_insn
,
422 if (curr_insn
.insn_class
== LLOCK
)
423 return handle_atomic_sequence (curr_insn
, di
);
425 CORE_ADDR next_pc
= arc_insn_get_linear_next_pc (curr_insn
);
426 std::vector
<CORE_ADDR
> next_pcs
;
428 /* For instructions with delay slots, the fall thru is not the
429 instruction immediately after the current instruction, but the one
431 if (curr_insn
.has_delay_slot
)
433 struct arc_instruction next_insn
;
434 arc_insn_decode (next_pc
, &di
, arc_delayed_print_insn
, &next_insn
);
435 next_pcs
.push_back (arc_insn_get_linear_next_pc (next_insn
));
438 next_pcs
.push_back (next_pc
);
441 regcache_cooked_read_unsigned (regcache
, gdbarch_ps_regnum (gdbarch
),
444 if (curr_insn
.is_control_flow
)
446 CORE_ADDR branch_pc
= arc_insn_get_branch_target (curr_insn
);
447 if (branch_pc
!= next_pc
)
448 next_pcs
.push_back (branch_pc
);
450 /* Is current instruction the last in a loop body? */
451 else if (tdep
->has_hw_loops
)
453 /* If STATUS32.L is 1, then ZD-loops are disabled. */
454 if ((status32
& ARC_STATUS32_L_MASK
) == 0)
456 ULONGEST lp_end
, lp_start
, lp_count
;
457 regcache_cooked_read_unsigned (regcache
, ARC_LP_START_REGNUM
,
459 regcache_cooked_read_unsigned (regcache
, ARC_LP_END_REGNUM
, &lp_end
);
460 regcache_cooked_read_unsigned (regcache
, ARC_LP_COUNT_REGNUM
,
463 arc_linux_debug_printf ("lp_start = %s, lp_end = %s, "
464 "lp_count = %s, next_pc = %s",
465 paddress (gdbarch
, lp_start
),
466 paddress (gdbarch
, lp_end
),
467 pulongest (lp_count
),
468 paddress (gdbarch
, next_pc
));
470 if (next_pc
== lp_end
&& lp_count
> 1)
472 /* The instruction is in effect a jump back to the start of
474 next_pcs
.push_back (lp_start
);
479 /* Is this a delay slot? Then next PC is in BTA register. */
480 if ((status32
& ARC_STATUS32_DE_MASK
) != 0)
483 regcache_cooked_read_unsigned (regcache
, ARC_BTA_REGNUM
, &bta
);
484 next_pcs
.push_back (bta
);
490 /* Implement the "skip_solib_resolver" gdbarch method.
492 See glibc_skip_solib_resolver for details. */
495 arc_linux_skip_solib_resolver (struct gdbarch
*gdbarch
, CORE_ADDR pc
)
497 /* For uClibc 0.9.26+.
499 An unresolved PLT entry points to "__dl_linux_resolve", which calls
500 "_dl_linux_resolver" to do the resolving and then eventually jumps to
503 So we look for the symbol `_dl_linux_resolver', and if we are there,
504 gdb sets a breakpoint at the return address, and continues. */
505 struct bound_minimal_symbol resolver
506 = lookup_minimal_symbol ("_dl_linux_resolver", NULL
, NULL
);
510 if (resolver
.minsym
!= nullptr)
512 CORE_ADDR res_addr
= resolver
.value_address ();
513 arc_linux_debug_printf ("pc = %s, resolver at %s",
514 print_core_address (gdbarch
, pc
),
515 print_core_address (gdbarch
, res_addr
));
518 arc_linux_debug_printf ("pc = %s, no resolver found",
519 print_core_address (gdbarch
, pc
));
522 if (resolver
.minsym
!= nullptr && resolver
.value_address () == pc
)
524 /* Find the return address. */
525 return frame_unwind_caller_pc (get_current_frame ());
529 /* No breakpoint required. */
534 /* Populate REGCACHE with register REGNUM from BUF. */
537 supply_register (struct regcache
*regcache
, int regnum
, const gdb_byte
*buf
)
539 /* Skip non-existing registers. */
540 if ((arc_linux_core_reg_offsets
[regnum
] == ARC_OFFSET_NO_REGISTER
))
543 regcache
->raw_supply (regnum
, buf
+ arc_linux_core_reg_offsets
[regnum
]);
547 arc_linux_supply_gregset (const struct regset
*regset
,
548 struct regcache
*regcache
,
549 int regnum
, const void *gregs
, size_t size
)
551 gdb_static_assert (ARC_LAST_REGNUM
552 < ARRAY_SIZE (arc_linux_core_reg_offsets
));
554 const bfd_byte
*buf
= (const bfd_byte
*) gregs
;
556 /* REGNUM == -1 means writing all the registers. */
558 for (int reg
= 0; reg
<= ARC_LAST_REGNUM
; reg
++)
559 supply_register (regcache
, reg
, buf
);
560 else if (regnum
<= ARC_LAST_REGNUM
)
561 supply_register (regcache
, regnum
, buf
);
563 gdb_assert_not_reached ("Invalid regnum in arc_linux_supply_gregset.");
567 arc_linux_supply_v2_regset (const struct regset
*regset
,
568 struct regcache
*regcache
, int regnum
,
569 const void *v2_regs
, size_t size
)
571 const bfd_byte
*buf
= (const bfd_byte
*) v2_regs
;
573 /* user_regs_arcv2 is defined in linux arch/arc/include/uapi/asm/ptrace.h. */
574 if (regnum
== -1 || regnum
== ARC_R30_REGNUM
)
575 regcache
->raw_supply (ARC_R30_REGNUM
, buf
);
576 if (regnum
== -1 || regnum
== ARC_R58_REGNUM
)
577 regcache
->raw_supply (ARC_R58_REGNUM
, buf
+ REGOFF (1));
578 if (regnum
== -1 || regnum
== ARC_R59_REGNUM
)
579 regcache
->raw_supply (ARC_R59_REGNUM
, buf
+ REGOFF (2));
582 /* Populate BUF with register REGNUM from the REGCACHE. */
585 collect_register (const struct regcache
*regcache
, struct gdbarch
*gdbarch
,
586 int regnum
, gdb_byte
*buf
)
590 /* Skip non-existing registers. */
591 if (arc_linux_core_reg_offsets
[regnum
] == ARC_OFFSET_NO_REGISTER
)
594 /* The address where the execution has stopped is in pseudo-register
595 STOP_PC. However, when kernel code is returning from the exception,
596 it uses the value from ERET register. Since, TRAP_S (the breakpoint
597 instruction) commits, the ERET points to the next instruction. In
598 other words: ERET != STOP_PC. To jump back from the kernel code to
599 the correct address, ERET must be overwritten by GDB's STOP_PC. Else,
600 the program will continue at the address after the current instruction.
602 if (regnum
== gdbarch_pc_regnum (gdbarch
))
603 offset
= arc_linux_core_reg_offsets
[ARC_ERET_REGNUM
];
605 offset
= arc_linux_core_reg_offsets
[regnum
];
606 regcache
->raw_collect (regnum
, buf
+ offset
);
610 arc_linux_collect_gregset (const struct regset
*regset
,
611 const struct regcache
*regcache
,
612 int regnum
, void *gregs
, size_t size
)
614 gdb_static_assert (ARC_LAST_REGNUM
615 < ARRAY_SIZE (arc_linux_core_reg_offsets
));
617 gdb_byte
*buf
= (gdb_byte
*) gregs
;
618 struct gdbarch
*gdbarch
= regcache
->arch ();
620 /* REGNUM == -1 means writing all the registers. */
622 for (int reg
= 0; reg
<= ARC_LAST_REGNUM
; reg
++)
623 collect_register (regcache
, gdbarch
, reg
, buf
);
624 else if (regnum
<= ARC_LAST_REGNUM
)
625 collect_register (regcache
, gdbarch
, regnum
, buf
);
627 gdb_assert_not_reached ("Invalid regnum in arc_linux_collect_gregset.");
631 arc_linux_collect_v2_regset (const struct regset
*regset
,
632 const struct regcache
*regcache
, int regnum
,
633 void *v2_regs
, size_t size
)
635 bfd_byte
*buf
= (bfd_byte
*) v2_regs
;
637 if (regnum
== -1 || regnum
== ARC_R30_REGNUM
)
638 regcache
->raw_collect (ARC_R30_REGNUM
, buf
);
639 if (regnum
== -1 || regnum
== ARC_R58_REGNUM
)
640 regcache
->raw_collect (ARC_R58_REGNUM
, buf
+ REGOFF (1));
641 if (regnum
== -1 || regnum
== ARC_R59_REGNUM
)
642 regcache
->raw_collect (ARC_R59_REGNUM
, buf
+ REGOFF (2));
645 /* Linux regset definitions. */
647 static const struct regset arc_linux_gregset
= {
648 arc_linux_core_reg_offsets
,
649 arc_linux_supply_gregset
,
650 arc_linux_collect_gregset
,
653 static const struct regset arc_linux_v2_regset
= {
655 arc_linux_supply_v2_regset
,
656 arc_linux_collect_v2_regset
,
659 /* Implement the `iterate_over_regset_sections` gdbarch method. */
662 arc_linux_iterate_over_regset_sections (struct gdbarch
*gdbarch
,
663 iterate_over_regset_sections_cb
*cb
,
665 const struct regcache
*regcache
)
667 /* There are 40 registers in Linux user_regs_struct, although some of
668 them are now just a mere paddings, kept to maintain binary
669 compatibility with older tools. */
670 const int sizeof_gregset
= 40 * ARC_REGISTER_SIZE
;
672 cb (".reg", sizeof_gregset
, sizeof_gregset
, &arc_linux_gregset
, NULL
,
674 cb (".reg-arc-v2", ARC_LINUX_SIZEOF_V2_REGSET
, ARC_LINUX_SIZEOF_V2_REGSET
,
675 &arc_linux_v2_regset
, NULL
, cb_data
);
678 /* Implement the `core_read_description` gdbarch method. */
680 static const struct target_desc
*
681 arc_linux_core_read_description (struct gdbarch
*gdbarch
,
682 struct target_ops
*target
,
685 arc_arch_features features
686 = arc_arch_features_create (abfd
,
687 gdbarch_bfd_arch_info (gdbarch
)->mach
);
688 return arc_lookup_target_description (features
);
691 /* Initialization specific to Linux environment. */
694 arc_linux_init_osabi (struct gdbarch_info info
, struct gdbarch
*gdbarch
)
696 arc_gdbarch_tdep
*tdep
= (arc_gdbarch_tdep
*) gdbarch_tdep (gdbarch
);
698 arc_linux_debug_printf ("GNU/Linux OS/ABI initialization.");
700 /* Fill in target-dependent info in ARC-private structure. */
701 tdep
->is_sigtramp
= arc_linux_is_sigtramp
;
702 tdep
->sigcontext_addr
= arc_linux_sigcontext_addr
;
703 tdep
->sc_reg_offset
= arc_linux_sc_reg_offsets
;
704 tdep
->sc_num_regs
= ARRAY_SIZE (arc_linux_sc_reg_offsets
);
706 /* If we are using Linux, we have in uClibc
707 (libc/sysdeps/linux/arc/bits/setjmp.h):
709 typedef int __jmp_buf[13+1+1+1]; //r13-r25, fp, sp, blink
711 Where "blink" is a stored PC of a caller function.
715 linux_init_abi (info
, gdbarch
, 0);
717 /* Set up target dependent GDB architecture entries. */
718 set_gdbarch_cannot_fetch_register (gdbarch
, arc_linux_cannot_fetch_register
);
719 set_gdbarch_cannot_store_register (gdbarch
, arc_linux_cannot_store_register
);
720 set_gdbarch_breakpoint_kind_from_pc (gdbarch
,
721 arc_linux_breakpoint_kind_from_pc
);
722 set_gdbarch_sw_breakpoint_from_kind (gdbarch
,
723 arc_linux_sw_breakpoint_from_kind
);
724 set_gdbarch_fetch_tls_load_module_address (gdbarch
,
725 svr4_fetch_objfile_link_map
);
726 set_gdbarch_software_single_step (gdbarch
, arc_linux_software_single_step
);
727 set_gdbarch_skip_trampoline_code (gdbarch
, find_solib_trampoline_target
);
728 set_gdbarch_skip_solib_resolver (gdbarch
, arc_linux_skip_solib_resolver
);
729 set_gdbarch_iterate_over_regset_sections
730 (gdbarch
, arc_linux_iterate_over_regset_sections
);
731 set_gdbarch_core_read_description (gdbarch
, arc_linux_core_read_description
);
733 /* GNU/Linux uses SVR4-style shared libraries, with 32-bit ints, longs
734 and pointers (ILP32). */
735 set_solib_svr4_fetch_link_map_offsets (gdbarch
,
736 linux_ilp32_fetch_link_map_offsets
);
739 /* Suppress warning from -Wmissing-prototypes. */
740 extern initialize_file_ftype _initialize_arc_linux_tdep
;
743 _initialize_arc_linux_tdep ()
745 gdbarch_register_osabi (bfd_arch_arc
, 0, GDB_OSABI_LINUX
,
746 arc_linux_init_osabi
);