]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/arc-linux-tdep.c
x86: ld: sframe: Remove SFrame NULL FRE template
[thirdparty/binutils-gdb.git] / gdb / arc-linux-tdep.c
CommitLineData
8d7f0635
AK
1/* Target dependent code for GNU/Linux ARC.
2
d01e8234 3 Copyright 2020-2025 Free Software Foundation, Inc.
8d7f0635
AK
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. */
8d7f0635 21#include "linux-tdep.h"
a2e3cce3 22#include "solib-svr4-linux.h"
8d7f0635
AK
23#include "objfiles.h"
24#include "opcode/arc.h"
25#include "osabi.h"
26#include "solib-svr4.h"
c8154ce0 27#include "disasm.h"
8d7f0635
AK
28
29/* ARC header files. */
30#include "opcodes/arc-dis.h"
cc463201 31#include "arc-linux-tdep.h"
8d7f0635 32#include "arc-tdep.h"
cc463201
AK
33#include "arch/arc.h"
34
d8d1feb4
SM
35/* Print an "arc-linux" debug statement. */
36
37#define arc_linux_debug_printf(fmt, ...) \
38 debug_prefixed_printf_cond (arc_debug, "arc-linux", fmt, ##__VA_ARGS__)
39
cc463201
AK
40#define REGOFF(offset) (offset * ARC_REGISTER_SIZE)
41
d4af7272
AK
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.
45
46 From <include/uapi/asm/sigcontext.h> and <include/uapi/asm/ptrace.h>.
47
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
50 here as well. */
51static const int arc_linux_sc_reg_offsets[] = {
52 /* R0 - R12. */
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),
56 REGOFF (10),
57
58 /* R13 - R25. */
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,
64
65 REGOFF (9), /* R26 (GP) */
66 REGOFF (8), /* FP */
67 REGOFF (23), /* SP */
68 ARC_OFFSET_NO_REGISTER, /* ILINK */
69 ARC_OFFSET_NO_REGISTER, /* R30 */
70 REGOFF (7), /* BLINK */
71
72 /* R32 - R59. */
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,
83
84 REGOFF (4), /* LP_COUNT */
85 ARC_OFFSET_NO_REGISTER, /* RESERVED */
86 ARC_OFFSET_NO_REGISTER, /* LIMM */
87 ARC_OFFSET_NO_REGISTER, /* PCL */
88
89 REGOFF (6), /* PC */
90 REGOFF (5), /* STATUS32 */
91 REGOFF (2), /* LP_START */
92 REGOFF (3), /* LP_END */
93 REGOFF (1), /* BTA */
94};
95
cc463201
AK
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.
99
100 From include/uapi/asm/ptrace.h in the ARC Linux sources. */
101
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
104 here as well. */
105static const int arc_linux_core_reg_offsets[] = {
106 /* R0 - R12. */
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),
110 REGOFF (10),
111
112 /* R13 - R25. */
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),
116 REGOFF (25),
117
118 REGOFF (9), /* R26 (GP) */
119 REGOFF (8), /* FP */
120 REGOFF (23), /* SP */
121 ARC_OFFSET_NO_REGISTER, /* ILINK */
122 ARC_OFFSET_NO_REGISTER, /* R30 */
123 REGOFF (7), /* BLINK */
124
125 /* R32 - R59. */
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,
136
137 REGOFF (4), /* LP_COUNT */
138 ARC_OFFSET_NO_REGISTER, /* RESERVED */
139 ARC_OFFSET_NO_REGISTER, /* LIMM */
140 ARC_OFFSET_NO_REGISTER, /* PCL */
141
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 */
148};
8d7f0635 149
d4af7272
AK
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:
153
154 mov r8, __NR_rt_sigreturn ; __NR_rt_sigreturn == 139
155 trap_s 0 ; `swi' for ARC700
156
157 On ARC uClibc Linux this function is called __default_rt_sa_restorer.
158
159 Returns TRUE if this is a sigtramp frame. */
160
161static bool
8480a37e 162arc_linux_is_sigtramp (const frame_info_ptr &this_frame)
d4af7272
AK
163{
164 struct gdbarch *gdbarch = get_frame_arch (this_frame);
165 CORE_ADDR pc = get_frame_pc (this_frame);
166
d8d1feb4 167 arc_linux_debug_printf ("pc=%s", paddress(gdbarch, pc));
d4af7272
AK
168
169 static const gdb_byte insns_be_hs[] = {
170 0x20, 0x8a, 0x12, 0xc2, /* mov r8,nr_rt_sigreturn */
171 0x78, 0x1e /* trap_s 0 */
172 };
173 static const gdb_byte insns_be_700[] = {
174 0x20, 0x8a, 0x12, 0xc2, /* mov r8,nr_rt_sigreturn */
175 0x22, 0x6f, 0x00, 0x3f /* swi */
176 };
177
6e4be957
TT
178 constexpr size_t max_insn_sz = std::max (sizeof (insns_be_hs),
179 sizeof (insns_be_700));
180
d4af7272
AK
181 gdb_byte arc_sigtramp_insns[sizeof (insns_be_700)];
182 size_t insns_sz;
183 if (arc_mach_is_arcv2 (gdbarch))
184 {
185 insns_sz = sizeof (insns_be_hs);
186 memcpy (arc_sigtramp_insns, insns_be_hs, insns_sz);
187 }
188 else
189 {
190 insns_sz = sizeof (insns_be_700);
191 memcpy (arc_sigtramp_insns, insns_be_700, insns_sz);
192 }
193 if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
194 {
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]);
205 }
206
6e4be957
TT
207 gdb_assert (insns_sz <= max_insn_sz);
208 gdb_byte buf[max_insn_sz];
d4af7272
AK
209
210 /* Read the memory at the PC. Since we are stopped, any breakpoint must
211 have been removed. */
bdec2917 212 if (!safe_frame_unwind_memory (this_frame, pc, {buf, insns_sz}))
d4af7272
AK
213 {
214 /* Failed to unwind frame. */
215 return FALSE;
216 }
217
218 /* Is that code the sigtramp instruction sequence? */
219 if (memcmp (buf, arc_sigtramp_insns, insns_sz) == 0)
220 return TRUE;
221
222 /* No - look one instruction earlier in the code... */
bdec2917 223 if (!safe_frame_unwind_memory (this_frame, pc - 4, {buf, insns_sz}))
d4af7272
AK
224 {
225 /* Failed to unwind frame. */
226 return FALSE;
227 }
228
229 return (memcmp (buf, arc_sigtramp_insns, insns_sz) == 0);
230}
231
232/* Get sigcontext structure of sigtramp frame - it contains saved
233 registers of interrupted frame.
234
235 Stack pointer points to the rt_sigframe structure, and sigcontext can
236 be found as in:
237
238 struct rt_sigframe {
239 struct siginfo info;
240 struct ucontext uc;
241 ...
242 };
243
244 struct ucontext {
245 unsigned long uc_flags;
246 struct ucontext *uc_link;
247 stack_t uc_stack;
248 struct sigcontext uc_mcontext;
249 sigset_t uc_sigmask;
250 };
251
252 sizeof (struct siginfo) == 0x80
253 offsetof (struct ucontext, uc_mcontext) == 0x14
254
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. */
262
263static CORE_ADDR
8480a37e 264arc_linux_sigcontext_addr (const frame_info_ptr &this_frame)
d4af7272
AK
265{
266 const int ucontext_offset = 0x80;
267 const int sigcontext_offset = 0x14;
268 return get_frame_sp (this_frame) + ucontext_offset + sigcontext_offset;
269}
270
8d7f0635
AK
271/* Implement the "cannot_fetch_register" gdbarch method. */
272
273static int
274arc_linux_cannot_fetch_register (struct gdbarch *gdbarch, int regnum)
275{
276 /* Assume that register is readable if it is unknown. */
277 switch (regnum)
278 {
279 case ARC_ILINK_REGNUM:
280 case ARC_RESERVED_REGNUM:
281 case ARC_LIMM_REGNUM:
282 return true;
283 case ARC_R30_REGNUM:
284 case ARC_R58_REGNUM:
285 case ARC_R59_REGNUM:
286 return !arc_mach_is_arcv2 (gdbarch);
287 }
288 return (regnum > ARC_BLINK_REGNUM) && (regnum < ARC_LP_COUNT_REGNUM);
289}
290
291/* Implement the "cannot_store_register" gdbarch method. */
292
293static int
294arc_linux_cannot_store_register (struct gdbarch *gdbarch, int regnum)
295{
296 /* Assume that register is writable if it is unknown. */
297 switch (regnum)
298 {
299 case ARC_ILINK_REGNUM:
300 case ARC_RESERVED_REGNUM:
301 case ARC_LIMM_REGNUM:
302 case ARC_PCL_REGNUM:
303 return true;
304 case ARC_R30_REGNUM:
305 case ARC_R58_REGNUM:
306 case ARC_R59_REGNUM:
307 return !arc_mach_is_arcv2 (gdbarch);
308 }
309 return (regnum > ARC_BLINK_REGNUM) && (regnum < ARC_LP_COUNT_REGNUM);
310}
311
312/* For ARC Linux, breakpoints use the 16-bit TRAP_S 1 instruction, which
313 is 0x3e78 (little endian) or 0x783e (big endian). */
314
315static const gdb_byte arc_linux_trap_s_be[] = { 0x78, 0x3e };
316static const gdb_byte arc_linux_trap_s_le[] = { 0x3e, 0x78 };
317static const int trap_size = 2; /* Number of bytes to insert "trap". */
318
319/* Implement the "breakpoint_kind_from_pc" gdbarch method. */
320
321static int
322arc_linux_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
323{
324 return trap_size;
325}
326
327/* Implement the "sw_breakpoint_from_kind" gdbarch method. */
328
329static const gdb_byte *
330arc_linux_sw_breakpoint_from_kind (struct gdbarch *gdbarch,
331 int kind, int *size)
332{
6f2643db 333 gdb_assert (kind == trap_size);
8d7f0635
AK
334 *size = kind;
335 return ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
336 ? arc_linux_trap_s_be
337 : arc_linux_trap_s_le);
338}
339
9b3e4b5d
SV
340/* Check for an atomic sequence of instructions beginning with an
341 LLOCK instruction and ending with a SCOND instruction.
342
343 These patterns are hand coded in libc's (glibc and uclibc). Take
344 a look at [1] for instance:
345
346 main+14: llock r2,[r0]
347 main+18: brne.nt r2,0,main+30
348 main+22: scond r3,[r0]
349 main+26: bne main+14
350 main+30: mov_s r0,0
351
352 If such a sequence is found, attempt to step over it.
353 A breakpoint is placed at the end of the sequence.
354
355 This function expects the INSN to be a "llock(d)" instruction.
356
357 [1]
358 https://cgit.uclibc-ng.org/cgi/cgit/uclibc-ng.git/tree/libc/ \
359 sysdeps/linux/arc/bits/atomic.h#n46
360 */
361
362static std::vector<CORE_ADDR>
8b39b1e7 363handle_atomic_sequence (arc_instruction insn, disassemble_info *di)
9b3e4b5d
SV
364{
365 const int atomic_seq_len = 24; /* Instruction sequence length. */
366 std::vector<CORE_ADDR> next_pcs;
367
368 /* Sanity check. */
369 gdb_assert (insn.insn_class == LLOCK);
370
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;
377
378 for (int insn_count = 0; insn_count < atomic_seq_len; ++insn_count)
379 {
380 arc_insn_decode (arc_insn_get_linear_next_pc (insn),
8b39b1e7 381 di, arc_delayed_print_insn, &insn);
9b3e4b5d
SV
382
383 if (insn.insn_class == BRCC)
287de656
SM
384 {
385 /* If more than one conditional branch is found, this is not
386 the pattern we are interested in. */
387 if (found_bc)
9b3e4b5d
SV
388 break;
389 found_bc = true;
390 continue;
287de656 391 }
9b3e4b5d
SV
392
393 /* This is almost a happy ending. */
394 if (insn.insn_class == SCOND)
287de656 395 {
9b3e4b5d
SV
396 /* SCOND should match the LLOCK's data size. */
397 if (insn.data_size_mode == llock_data_size_mode)
398 is_pattern_valid = true;
399 break;
287de656 400 }
9b3e4b5d
SV
401 }
402
403 if (is_pattern_valid)
404 {
405 /* Get next instruction after scond(d). There is no limm. */
406 next_pcs.push_back (insn.address + insn.length);
407 }
408
409 return next_pcs;
410}
411
8d7f0635
AK
412/* Implement the "software_single_step" gdbarch method. */
413
414static std::vector<CORE_ADDR>
415arc_linux_software_single_step (struct regcache *regcache)
416{
417 struct gdbarch *gdbarch = regcache->arch ();
08106042 418 arc_gdbarch_tdep *tdep = gdbarch_tdep<arc_gdbarch_tdep> (gdbarch);
8b39b1e7 419 struct gdb_non_printing_memory_disassembler dis (gdbarch);
8d7f0635
AK
420
421 /* Read current instruction. */
422 struct arc_instruction curr_insn;
8b39b1e7
AB
423 arc_insn_decode (regcache_read_pc (regcache), dis.disasm_info (),
424 arc_delayed_print_insn, &curr_insn);
8d7f0635 425
9b3e4b5d 426 if (curr_insn.insn_class == LLOCK)
8b39b1e7 427 return handle_atomic_sequence (curr_insn, dis.disasm_info ());
9b3e4b5d
SV
428
429 CORE_ADDR next_pc = arc_insn_get_linear_next_pc (curr_insn);
8d7f0635
AK
430 std::vector<CORE_ADDR> next_pcs;
431
8f6606b6 432 /* For instructions with delay slots, the fall through is not the
8d7f0635
AK
433 instruction immediately after the current instruction, but the one
434 after that. */
435 if (curr_insn.has_delay_slot)
436 {
437 struct arc_instruction next_insn;
8b39b1e7
AB
438 arc_insn_decode (next_pc, dis.disasm_info (), arc_delayed_print_insn,
439 &next_insn);
8d7f0635
AK
440 next_pcs.push_back (arc_insn_get_linear_next_pc (next_insn));
441 }
442 else
443 next_pcs.push_back (next_pc);
444
445 ULONGEST status32;
446 regcache_cooked_read_unsigned (regcache, gdbarch_ps_regnum (gdbarch),
447 &status32);
448
449 if (curr_insn.is_control_flow)
450 {
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);
454 }
455 /* Is current instruction the last in a loop body? */
456 else if (tdep->has_hw_loops)
457 {
458 /* If STATUS32.L is 1, then ZD-loops are disabled. */
459 if ((status32 & ARC_STATUS32_L_MASK) == 0)
460 {
461 ULONGEST lp_end, lp_start, lp_count;
462 regcache_cooked_read_unsigned (regcache, ARC_LP_START_REGNUM,
463 &lp_start);
464 regcache_cooked_read_unsigned (regcache, ARC_LP_END_REGNUM, &lp_end);
465 regcache_cooked_read_unsigned (regcache, ARC_LP_COUNT_REGNUM,
466 &lp_count);
467
d8d1feb4
SM
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));
8d7f0635
AK
474
475 if (next_pc == lp_end && lp_count > 1)
476 {
477 /* The instruction is in effect a jump back to the start of
478 the loop. */
479 next_pcs.push_back (lp_start);
480 }
481 }
482 }
483
484 /* Is this a delay slot? Then next PC is in BTA register. */
485 if ((status32 & ARC_STATUS32_DE_MASK) != 0)
486 {
487 ULONGEST bta;
488 regcache_cooked_read_unsigned (regcache, ARC_BTA_REGNUM, &bta);
489 next_pcs.push_back (bta);
490 }
491
492 return next_pcs;
493}
494
495/* Implement the "skip_solib_resolver" gdbarch method.
496
497 See glibc_skip_solib_resolver for details. */
498
499static CORE_ADDR
500arc_linux_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
501{
502 /* For uClibc 0.9.26+.
503
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
506 the function.
507
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. */
4144d36a
SM
510 bound_minimal_symbol resolver
511 = lookup_minimal_symbol (current_program_space, "_dl_linux_resolver");
8d7f0635
AK
512
513 if (arc_debug)
514 {
515 if (resolver.minsym != nullptr)
516 {
4aeddc50 517 CORE_ADDR res_addr = resolver.value_address ();
d8d1feb4
SM
518 arc_linux_debug_printf ("pc = %s, resolver at %s",
519 print_core_address (gdbarch, pc),
520 print_core_address (gdbarch, res_addr));
8d7f0635
AK
521 }
522 else
d8d1feb4
SM
523 arc_linux_debug_printf ("pc = %s, no resolver found",
524 print_core_address (gdbarch, pc));
8d7f0635
AK
525 }
526
4aeddc50 527 if (resolver.minsym != nullptr && resolver.value_address () == pc)
8d7f0635
AK
528 {
529 /* Find the return address. */
530 return frame_unwind_caller_pc (get_current_frame ());
531 }
532 else
533 {
534 /* No breakpoint required. */
535 return 0;
536 }
537}
538
46023bbe
SV
539/* Populate REGCACHE with register REGNUM from BUF. */
540
541static void
542supply_register (struct regcache *regcache, int regnum, const gdb_byte *buf)
543{
544 /* Skip non-existing registers. */
545 if ((arc_linux_core_reg_offsets[regnum] == ARC_OFFSET_NO_REGISTER))
546 return;
547
548 regcache->raw_supply (regnum, buf + arc_linux_core_reg_offsets[regnum]);
549}
550
cc463201
AK
551void
552arc_linux_supply_gregset (const struct regset *regset,
553 struct regcache *regcache,
554 int regnum, const void *gregs, size_t size)
555{
69f6730d 556 static_assert (ARC_LAST_REGNUM
cc463201
AK
557 < ARRAY_SIZE (arc_linux_core_reg_offsets));
558
559 const bfd_byte *buf = (const bfd_byte *) gregs;
560
acf10cac 561 /* REGNUM == -1 means writing all the registers. */
46023bbe
SV
562 if (regnum == -1)
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);
567 else
568 gdb_assert_not_reached ("Invalid regnum in arc_linux_supply_gregset.");
cc463201
AK
569}
570
571void
572arc_linux_supply_v2_regset (const struct regset *regset,
573 struct regcache *regcache, int regnum,
574 const void *v2_regs, size_t size)
575{
576 const bfd_byte *buf = (const bfd_byte *) v2_regs;
577
578 /* user_regs_arcv2 is defined in linux arch/arc/include/uapi/asm/ptrace.h. */
46023bbe
SV
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));
cc463201
AK
585}
586
587/* Populate BUF with register REGNUM from the REGCACHE. */
588
589static void
590collect_register (const struct regcache *regcache, struct gdbarch *gdbarch,
591 int regnum, gdb_byte *buf)
592{
10c19fad
SV
593 int offset;
594
cc463201 595 /* Skip non-existing registers. */
10c19fad 596 if (arc_linux_core_reg_offsets[regnum] == ARC_OFFSET_NO_REGISTER)
cc463201
AK
597 return;
598
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.
606 */
607 if (regnum == gdbarch_pc_regnum (gdbarch))
10c19fad
SV
608 offset = arc_linux_core_reg_offsets[ARC_ERET_REGNUM];
609 else
610 offset = arc_linux_core_reg_offsets[regnum];
611 regcache->raw_collect (regnum, buf + offset);
cc463201
AK
612}
613
614void
615arc_linux_collect_gregset (const struct regset *regset,
616 const struct regcache *regcache,
617 int regnum, void *gregs, size_t size)
618{
69f6730d 619 static_assert (ARC_LAST_REGNUM
cc463201
AK
620 < ARRAY_SIZE (arc_linux_core_reg_offsets));
621
622 gdb_byte *buf = (gdb_byte *) gregs;
623 struct gdbarch *gdbarch = regcache->arch ();
624
acf10cac 625 /* REGNUM == -1 means writing all the registers. */
cc463201
AK
626 if (regnum == -1)
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);
631 else
632 gdb_assert_not_reached ("Invalid regnum in arc_linux_collect_gregset.");
633}
634
635void
636arc_linux_collect_v2_regset (const struct regset *regset,
637 const struct regcache *regcache, int regnum,
638 void *v2_regs, size_t size)
639{
640 bfd_byte *buf = (bfd_byte *) v2_regs;
641
46023bbe
SV
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));
cc463201
AK
648}
649
650/* Linux regset definitions. */
651
652static const struct regset arc_linux_gregset = {
653 arc_linux_core_reg_offsets,
654 arc_linux_supply_gregset,
655 arc_linux_collect_gregset,
656};
657
658static const struct regset arc_linux_v2_regset = {
659 NULL,
660 arc_linux_supply_v2_regset,
661 arc_linux_collect_v2_regset,
662};
663
664/* Implement the `iterate_over_regset_sections` gdbarch method. */
665
666static void
667arc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
668 iterate_over_regset_sections_cb *cb,
669 void *cb_data,
670 const struct regcache *regcache)
671{
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;
676
677 cb (".reg", sizeof_gregset, sizeof_gregset, &arc_linux_gregset, NULL,
678 cb_data);
679 cb (".reg-arc-v2", ARC_LINUX_SIZEOF_V2_REGSET, ARC_LINUX_SIZEOF_V2_REGSET,
680 &arc_linux_v2_regset, NULL, cb_data);
681}
682
683/* Implement the `core_read_description` gdbarch method. */
684
685static const struct target_desc *
686arc_linux_core_read_description (struct gdbarch *gdbarch,
687 struct target_ops *target,
688 bfd *abfd)
689{
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);
694}
695
8d7f0635
AK
696/* Initialization specific to Linux environment. */
697
698static void
699arc_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
700{
08106042 701 arc_gdbarch_tdep *tdep = gdbarch_tdep<arc_gdbarch_tdep> (gdbarch);
8d7f0635 702
d8d1feb4 703 arc_linux_debug_printf ("GNU/Linux OS/ABI initialization.");
8d7f0635 704
d4af7272
AK
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);
710
8d7f0635
AK
711 /* If we are using Linux, we have in uClibc
712 (libc/sysdeps/linux/arc/bits/setjmp.h):
713
714 typedef int __jmp_buf[13+1+1+1]; //r13-r25, fp, sp, blink
715
716 Where "blink" is a stored PC of a caller function.
717 */
718 tdep->jb_pc = 15;
719
480af54c 720 linux_init_abi (info, gdbarch, 0);
8d7f0635
AK
721
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);
cc463201
AK
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);
8d7f0635
AK
737
738 /* GNU/Linux uses SVR4-style shared libraries, with 32-bit ints, longs
739 and pointers (ILP32). */
a2e3cce3 740 set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
8d7f0635
AK
741}
742
5fe70629 743INIT_GDB_FILE (arc_linux_tdep)
8d7f0635
AK
744{
745 gdbarch_register_osabi (bfd_arch_arc, 0, GDB_OSABI_LINUX,
746 arc_linux_init_osabi);
747}