1 /* Target dependent code for GNU/Linux ARC.
3 Copyright 2020-2025 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. */
21 #include "linux-tdep.h"
22 #include "solib-svr4-linux.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 (const frame_info_ptr
&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 constexpr size_t max_insn_sz
= std::max (sizeof (insns_be_hs
),
179 sizeof (insns_be_700
));
181 gdb_byte arc_sigtramp_insns
[sizeof (insns_be_700
)];
183 if (arc_mach_is_arcv2 (gdbarch
))
185 insns_sz
= sizeof (insns_be_hs
);
186 memcpy (arc_sigtramp_insns
, insns_be_hs
, insns_sz
);
190 insns_sz
= sizeof (insns_be_700
);
191 memcpy (arc_sigtramp_insns
, insns_be_700
, insns_sz
);
193 if (gdbarch_byte_order (gdbarch
) == BFD_ENDIAN_LITTLE
)
195 /* On little endian targets, ARC code section is in what is called
196 "middle endian", where half-words are in the big-endian order,
197 only bytes inside the halfwords are in the little endian order.
198 As a result it is very easy to convert big endian instruction to
199 little endian, since it is needed to swap bytes in the halfwords,
200 so there is no need to have information on whether that is a
201 4-byte instruction or 2-byte. */
202 gdb_assert ((insns_sz
% 2) == 0);
203 for (int i
= 0; i
< insns_sz
; i
+= 2)
204 std::swap (arc_sigtramp_insns
[i
], arc_sigtramp_insns
[i
+1]);
207 gdb_assert (insns_sz
<= max_insn_sz
);
208 gdb_byte buf
[max_insn_sz
];
210 /* Read the memory at the PC. Since we are stopped, any breakpoint must
211 have been removed. */
212 if (!safe_frame_unwind_memory (this_frame
, pc
, {buf
, insns_sz
}))
214 /* Failed to unwind frame. */
218 /* Is that code the sigtramp instruction sequence? */
219 if (memcmp (buf
, arc_sigtramp_insns
, insns_sz
) == 0)
222 /* No - look one instruction earlier in the code... */
223 if (!safe_frame_unwind_memory (this_frame
, pc
- 4, {buf
, insns_sz
}))
225 /* Failed to unwind frame. */
229 return (memcmp (buf
, arc_sigtramp_insns
, insns_sz
) == 0);
232 /* Get sigcontext structure of sigtramp frame - it contains saved
233 registers of interrupted frame.
235 Stack pointer points to the rt_sigframe structure, and sigcontext can
245 unsigned long uc_flags;
246 struct ucontext *uc_link;
248 struct sigcontext uc_mcontext;
252 sizeof (struct siginfo) == 0x80
253 offsetof (struct ucontext, uc_mcontext) == 0x14
255 GDB cannot include linux headers and use offsetof () because those are
256 target headers and GDB might be built for a different run host. There
257 doesn't seem to be an established mechanism to figure out those offsets
258 via gdbserver, so the only way is to hardcode values in the GDB,
259 meaning that GDB will be broken if values will change. That seems to
260 be a very unlikely scenario and other arches (aarch64, alpha, amd64,
261 etc) in GDB hardcode values. */
264 arc_linux_sigcontext_addr (const frame_info_ptr
&this_frame
)
266 const int ucontext_offset
= 0x80;
267 const int sigcontext_offset
= 0x14;
268 return get_frame_sp (this_frame
) + ucontext_offset
+ sigcontext_offset
;
271 /* Implement the "cannot_fetch_register" gdbarch method. */
274 arc_linux_cannot_fetch_register (struct gdbarch
*gdbarch
, int regnum
)
276 /* Assume that register is readable if it is unknown. */
279 case ARC_ILINK_REGNUM
:
280 case ARC_RESERVED_REGNUM
:
281 case ARC_LIMM_REGNUM
:
286 return !arc_mach_is_arcv2 (gdbarch
);
288 return (regnum
> ARC_BLINK_REGNUM
) && (regnum
< ARC_LP_COUNT_REGNUM
);
291 /* Implement the "cannot_store_register" gdbarch method. */
294 arc_linux_cannot_store_register (struct gdbarch
*gdbarch
, int regnum
)
296 /* Assume that register is writable if it is unknown. */
299 case ARC_ILINK_REGNUM
:
300 case ARC_RESERVED_REGNUM
:
301 case ARC_LIMM_REGNUM
:
307 return !arc_mach_is_arcv2 (gdbarch
);
309 return (regnum
> ARC_BLINK_REGNUM
) && (regnum
< ARC_LP_COUNT_REGNUM
);
312 /* For ARC Linux, breakpoints use the 16-bit TRAP_S 1 instruction, which
313 is 0x3e78 (little endian) or 0x783e (big endian). */
315 static const gdb_byte arc_linux_trap_s_be
[] = { 0x78, 0x3e };
316 static const gdb_byte arc_linux_trap_s_le
[] = { 0x3e, 0x78 };
317 static const int trap_size
= 2; /* Number of bytes to insert "trap". */
319 /* Implement the "breakpoint_kind_from_pc" gdbarch method. */
322 arc_linux_breakpoint_kind_from_pc (struct gdbarch
*gdbarch
, CORE_ADDR
*pcptr
)
327 /* Implement the "sw_breakpoint_from_kind" gdbarch method. */
329 static const gdb_byte
*
330 arc_linux_sw_breakpoint_from_kind (struct gdbarch
*gdbarch
,
333 gdb_assert (kind
== trap_size
);
335 return ((gdbarch_byte_order (gdbarch
) == BFD_ENDIAN_BIG
)
336 ? arc_linux_trap_s_be
337 : arc_linux_trap_s_le
);
340 /* Check for an atomic sequence of instructions beginning with an
341 LLOCK instruction and ending with a SCOND instruction.
343 These patterns are hand coded in libc's (glibc and uclibc). Take
344 a look at [1] for instance:
346 main+14: llock r2,[r0]
347 main+18: brne.nt r2,0,main+30
348 main+22: scond r3,[r0]
352 If such a sequence is found, attempt to step over it.
353 A breakpoint is placed at the end of the sequence.
355 This function expects the INSN to be a "llock(d)" instruction.
358 https://cgit.uclibc-ng.org/cgi/cgit/uclibc-ng.git/tree/libc/ \
359 sysdeps/linux/arc/bits/atomic.h#n46
362 static std::vector
<CORE_ADDR
>
363 handle_atomic_sequence (arc_instruction insn
, disassemble_info
*di
)
365 const int atomic_seq_len
= 24; /* Instruction sequence length. */
366 std::vector
<CORE_ADDR
> next_pcs
;
369 gdb_assert (insn
.insn_class
== LLOCK
);
371 /* Data size we are dealing with: LLOCK vs. LLOCKD */
372 arc_ldst_data_size llock_data_size_mode
= insn
.data_size_mode
;
373 /* Indicator if any conditional branch is found in the sequence. */
374 bool found_bc
= false;
375 /* Becomes true if "LLOCK(D) .. SCOND(D)" sequence is found. */
376 bool is_pattern_valid
= false;
378 for (int insn_count
= 0; insn_count
< atomic_seq_len
; ++insn_count
)
380 arc_insn_decode (arc_insn_get_linear_next_pc (insn
),
381 di
, arc_delayed_print_insn
, &insn
);
383 if (insn
.insn_class
== BRCC
)
385 /* If more than one conditional branch is found, this is not
386 the pattern we are interested in. */
393 /* This is almost a happy ending. */
394 if (insn
.insn_class
== SCOND
)
396 /* SCOND should match the LLOCK's data size. */
397 if (insn
.data_size_mode
== llock_data_size_mode
)
398 is_pattern_valid
= true;
403 if (is_pattern_valid
)
405 /* Get next instruction after scond(d). There is no limm. */
406 next_pcs
.push_back (insn
.address
+ insn
.length
);
412 /* Implement the "software_single_step" gdbarch method. */
414 static std::vector
<CORE_ADDR
>
415 arc_linux_software_single_step (struct regcache
*regcache
)
417 struct gdbarch
*gdbarch
= regcache
->arch ();
418 arc_gdbarch_tdep
*tdep
= gdbarch_tdep
<arc_gdbarch_tdep
> (gdbarch
);
419 struct gdb_non_printing_memory_disassembler
dis (gdbarch
);
421 /* Read current instruction. */
422 struct arc_instruction curr_insn
;
423 arc_insn_decode (regcache_read_pc (regcache
), dis
.disasm_info (),
424 arc_delayed_print_insn
, &curr_insn
);
426 if (curr_insn
.insn_class
== LLOCK
)
427 return handle_atomic_sequence (curr_insn
, dis
.disasm_info ());
429 CORE_ADDR next_pc
= arc_insn_get_linear_next_pc (curr_insn
);
430 std::vector
<CORE_ADDR
> next_pcs
;
432 /* For instructions with delay slots, the fall through is not the
433 instruction immediately after the current instruction, but the one
435 if (curr_insn
.has_delay_slot
)
437 struct arc_instruction next_insn
;
438 arc_insn_decode (next_pc
, dis
.disasm_info (), arc_delayed_print_insn
,
440 next_pcs
.push_back (arc_insn_get_linear_next_pc (next_insn
));
443 next_pcs
.push_back (next_pc
);
446 regcache_cooked_read_unsigned (regcache
, gdbarch_ps_regnum (gdbarch
),
449 if (curr_insn
.is_control_flow
)
451 CORE_ADDR branch_pc
= arc_insn_get_branch_target (curr_insn
);
452 if (branch_pc
!= next_pc
)
453 next_pcs
.push_back (branch_pc
);
455 /* Is current instruction the last in a loop body? */
456 else if (tdep
->has_hw_loops
)
458 /* If STATUS32.L is 1, then ZD-loops are disabled. */
459 if ((status32
& ARC_STATUS32_L_MASK
) == 0)
461 ULONGEST lp_end
, lp_start
, lp_count
;
462 regcache_cooked_read_unsigned (regcache
, ARC_LP_START_REGNUM
,
464 regcache_cooked_read_unsigned (regcache
, ARC_LP_END_REGNUM
, &lp_end
);
465 regcache_cooked_read_unsigned (regcache
, ARC_LP_COUNT_REGNUM
,
468 arc_linux_debug_printf ("lp_start = %s, lp_end = %s, "
469 "lp_count = %s, next_pc = %s",
470 paddress (gdbarch
, lp_start
),
471 paddress (gdbarch
, lp_end
),
472 pulongest (lp_count
),
473 paddress (gdbarch
, next_pc
));
475 if (next_pc
== lp_end
&& lp_count
> 1)
477 /* The instruction is in effect a jump back to the start of
479 next_pcs
.push_back (lp_start
);
484 /* Is this a delay slot? Then next PC is in BTA register. */
485 if ((status32
& ARC_STATUS32_DE_MASK
) != 0)
488 regcache_cooked_read_unsigned (regcache
, ARC_BTA_REGNUM
, &bta
);
489 next_pcs
.push_back (bta
);
495 /* Implement the "skip_solib_resolver" gdbarch method.
497 See glibc_skip_solib_resolver for details. */
500 arc_linux_skip_solib_resolver (struct gdbarch
*gdbarch
, CORE_ADDR pc
)
502 /* For uClibc 0.9.26+.
504 An unresolved PLT entry points to "__dl_linux_resolve", which calls
505 "_dl_linux_resolver" to do the resolving and then eventually jumps to
508 So we look for the symbol `_dl_linux_resolver', and if we are there,
509 gdb sets a breakpoint at the return address, and continues. */
510 bound_minimal_symbol resolver
511 = lookup_minimal_symbol (current_program_space
, "_dl_linux_resolver");
515 if (resolver
.minsym
!= nullptr)
517 CORE_ADDR res_addr
= resolver
.value_address ();
518 arc_linux_debug_printf ("pc = %s, resolver at %s",
519 print_core_address (gdbarch
, pc
),
520 print_core_address (gdbarch
, res_addr
));
523 arc_linux_debug_printf ("pc = %s, no resolver found",
524 print_core_address (gdbarch
, pc
));
527 if (resolver
.minsym
!= nullptr && resolver
.value_address () == pc
)
529 /* Find the return address. */
530 return frame_unwind_caller_pc (get_current_frame ());
534 /* No breakpoint required. */
539 /* Populate REGCACHE with register REGNUM from BUF. */
542 supply_register (struct regcache
*regcache
, int regnum
, const gdb_byte
*buf
)
544 /* Skip non-existing registers. */
545 if ((arc_linux_core_reg_offsets
[regnum
] == ARC_OFFSET_NO_REGISTER
))
548 regcache
->raw_supply (regnum
, buf
+ arc_linux_core_reg_offsets
[regnum
]);
552 arc_linux_supply_gregset (const struct regset
*regset
,
553 struct regcache
*regcache
,
554 int regnum
, const void *gregs
, size_t size
)
556 static_assert (ARC_LAST_REGNUM
557 < ARRAY_SIZE (arc_linux_core_reg_offsets
));
559 const bfd_byte
*buf
= (const bfd_byte
*) gregs
;
561 /* REGNUM == -1 means writing all the registers. */
563 for (int reg
= 0; reg
<= ARC_LAST_REGNUM
; reg
++)
564 supply_register (regcache
, reg
, buf
);
565 else if (regnum
<= ARC_LAST_REGNUM
)
566 supply_register (regcache
, regnum
, buf
);
568 gdb_assert_not_reached ("Invalid regnum in arc_linux_supply_gregset.");
572 arc_linux_supply_v2_regset (const struct regset
*regset
,
573 struct regcache
*regcache
, int regnum
,
574 const void *v2_regs
, size_t size
)
576 const bfd_byte
*buf
= (const bfd_byte
*) v2_regs
;
578 /* user_regs_arcv2 is defined in linux arch/arc/include/uapi/asm/ptrace.h. */
579 if (regnum
== -1 || regnum
== ARC_R30_REGNUM
)
580 regcache
->raw_supply (ARC_R30_REGNUM
, buf
);
581 if (regnum
== -1 || regnum
== ARC_R58_REGNUM
)
582 regcache
->raw_supply (ARC_R58_REGNUM
, buf
+ REGOFF (1));
583 if (regnum
== -1 || regnum
== ARC_R59_REGNUM
)
584 regcache
->raw_supply (ARC_R59_REGNUM
, buf
+ REGOFF (2));
587 /* Populate BUF with register REGNUM from the REGCACHE. */
590 collect_register (const struct regcache
*regcache
, struct gdbarch
*gdbarch
,
591 int regnum
, gdb_byte
*buf
)
595 /* Skip non-existing registers. */
596 if (arc_linux_core_reg_offsets
[regnum
] == ARC_OFFSET_NO_REGISTER
)
599 /* The address where the execution has stopped is in pseudo-register
600 STOP_PC. However, when kernel code is returning from the exception,
601 it uses the value from ERET register. Since, TRAP_S (the breakpoint
602 instruction) commits, the ERET points to the next instruction. In
603 other words: ERET != STOP_PC. To jump back from the kernel code to
604 the correct address, ERET must be overwritten by GDB's STOP_PC. Else,
605 the program will continue at the address after the current instruction.
607 if (regnum
== gdbarch_pc_regnum (gdbarch
))
608 offset
= arc_linux_core_reg_offsets
[ARC_ERET_REGNUM
];
610 offset
= arc_linux_core_reg_offsets
[regnum
];
611 regcache
->raw_collect (regnum
, buf
+ offset
);
615 arc_linux_collect_gregset (const struct regset
*regset
,
616 const struct regcache
*regcache
,
617 int regnum
, void *gregs
, size_t size
)
619 static_assert (ARC_LAST_REGNUM
620 < ARRAY_SIZE (arc_linux_core_reg_offsets
));
622 gdb_byte
*buf
= (gdb_byte
*) gregs
;
623 struct gdbarch
*gdbarch
= regcache
->arch ();
625 /* REGNUM == -1 means writing all the registers. */
627 for (int reg
= 0; reg
<= ARC_LAST_REGNUM
; reg
++)
628 collect_register (regcache
, gdbarch
, reg
, buf
);
629 else if (regnum
<= ARC_LAST_REGNUM
)
630 collect_register (regcache
, gdbarch
, regnum
, buf
);
632 gdb_assert_not_reached ("Invalid regnum in arc_linux_collect_gregset.");
636 arc_linux_collect_v2_regset (const struct regset
*regset
,
637 const struct regcache
*regcache
, int regnum
,
638 void *v2_regs
, size_t size
)
640 bfd_byte
*buf
= (bfd_byte
*) v2_regs
;
642 if (regnum
== -1 || regnum
== ARC_R30_REGNUM
)
643 regcache
->raw_collect (ARC_R30_REGNUM
, buf
);
644 if (regnum
== -1 || regnum
== ARC_R58_REGNUM
)
645 regcache
->raw_collect (ARC_R58_REGNUM
, buf
+ REGOFF (1));
646 if (regnum
== -1 || regnum
== ARC_R59_REGNUM
)
647 regcache
->raw_collect (ARC_R59_REGNUM
, buf
+ REGOFF (2));
650 /* Linux regset definitions. */
652 static const struct regset arc_linux_gregset
= {
653 arc_linux_core_reg_offsets
,
654 arc_linux_supply_gregset
,
655 arc_linux_collect_gregset
,
658 static const struct regset arc_linux_v2_regset
= {
660 arc_linux_supply_v2_regset
,
661 arc_linux_collect_v2_regset
,
664 /* Implement the `iterate_over_regset_sections` gdbarch method. */
667 arc_linux_iterate_over_regset_sections (struct gdbarch
*gdbarch
,
668 iterate_over_regset_sections_cb
*cb
,
670 const struct regcache
*regcache
)
672 /* There are 40 registers in Linux user_regs_struct, although some of
673 them are now just a mere paddings, kept to maintain binary
674 compatibility with older tools. */
675 const int sizeof_gregset
= 40 * ARC_REGISTER_SIZE
;
677 cb (".reg", sizeof_gregset
, sizeof_gregset
, &arc_linux_gregset
, NULL
,
679 cb (".reg-arc-v2", ARC_LINUX_SIZEOF_V2_REGSET
, ARC_LINUX_SIZEOF_V2_REGSET
,
680 &arc_linux_v2_regset
, NULL
, cb_data
);
683 /* Implement the `core_read_description` gdbarch method. */
685 static const struct target_desc
*
686 arc_linux_core_read_description (struct gdbarch
*gdbarch
,
687 struct target_ops
*target
,
690 arc_arch_features features
691 = arc_arch_features_create (abfd
,
692 gdbarch_bfd_arch_info (gdbarch
)->mach
);
693 return arc_lookup_target_description (features
);
696 /* Initialization specific to Linux environment. */
699 arc_linux_init_osabi (struct gdbarch_info info
, struct gdbarch
*gdbarch
)
701 arc_gdbarch_tdep
*tdep
= gdbarch_tdep
<arc_gdbarch_tdep
> (gdbarch
);
703 arc_linux_debug_printf ("GNU/Linux OS/ABI initialization.");
705 /* Fill in target-dependent info in ARC-private structure. */
706 tdep
->is_sigtramp
= arc_linux_is_sigtramp
;
707 tdep
->sigcontext_addr
= arc_linux_sigcontext_addr
;
708 tdep
->sc_reg_offset
= arc_linux_sc_reg_offsets
;
709 tdep
->sc_num_regs
= ARRAY_SIZE (arc_linux_sc_reg_offsets
);
711 /* If we are using Linux, we have in uClibc
712 (libc/sysdeps/linux/arc/bits/setjmp.h):
714 typedef int __jmp_buf[13+1+1+1]; //r13-r25, fp, sp, blink
716 Where "blink" is a stored PC of a caller function.
720 linux_init_abi (info
, gdbarch
, 0);
722 /* Set up target dependent GDB architecture entries. */
723 set_gdbarch_cannot_fetch_register (gdbarch
, arc_linux_cannot_fetch_register
);
724 set_gdbarch_cannot_store_register (gdbarch
, arc_linux_cannot_store_register
);
725 set_gdbarch_breakpoint_kind_from_pc (gdbarch
,
726 arc_linux_breakpoint_kind_from_pc
);
727 set_gdbarch_sw_breakpoint_from_kind (gdbarch
,
728 arc_linux_sw_breakpoint_from_kind
);
729 set_gdbarch_fetch_tls_load_module_address (gdbarch
,
730 svr4_fetch_objfile_link_map
);
731 set_gdbarch_software_single_step (gdbarch
, arc_linux_software_single_step
);
732 set_gdbarch_skip_trampoline_code (gdbarch
, find_solib_trampoline_target
);
733 set_gdbarch_skip_solib_resolver (gdbarch
, arc_linux_skip_solib_resolver
);
734 set_gdbarch_iterate_over_regset_sections
735 (gdbarch
, arc_linux_iterate_over_regset_sections
);
736 set_gdbarch_core_read_description (gdbarch
, arc_linux_core_read_description
);
738 /* GNU/Linux uses SVR4-style shared libraries, with 32-bit ints, longs
739 and pointers (ILP32). */
740 set_solib_svr4_ops (gdbarch
, make_linux_ilp32_svr4_solib_ops
);
743 INIT_GDB_FILE (arc_linux_tdep
)
745 gdbarch_register_osabi (bfd_arch_arc
, 0, GDB_OSABI_LINUX
,
746 arc_linux_init_osabi
);