]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/arc-linux-tdep.c
arc: Add support for Linux coredump files
[thirdparty/binutils-gdb.git] / gdb / arc-linux-tdep.c
CommitLineData
8d7f0635
AK
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"
460fd13b 30#include "arc-linux-tdep.h"
8d7f0635 31#include "arc-tdep.h"
460fd13b
AK
32#include "arch/arc.h"
33
34#define REGOFF(offset) (offset * ARC_REGISTER_SIZE)
35
36/* arc_linux_core_reg_offsets[i] is the offset in the .reg section of GDB
37 regnum i. Array index is an internal GDB register number, as defined in
38 arc-tdep.h:arc_regnum.
39
40 From include/uapi/asm/ptrace.h in the ARC Linux sources. */
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. */
45static const int arc_linux_core_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 REGOFF (37), REGOFF (36), REGOFF (35), REGOFF (34),
54 REGOFF (33), REGOFF (32), REGOFF (31), REGOFF (30),
55 REGOFF (29), REGOFF (28), REGOFF (27), REGOFF (26),
56 REGOFF (25),
57
58 REGOFF (9), /* R26 (GP) */
59 REGOFF (8), /* FP */
60 REGOFF (23), /* SP */
61 ARC_OFFSET_NO_REGISTER, /* ILINK */
62 ARC_OFFSET_NO_REGISTER, /* R30 */
63 REGOFF (7), /* BLINK */
64
65 /* R32 - R59. */
66 ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER, ARC_OFFSET_NO_REGISTER,
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,
76
77 REGOFF (4), /* LP_COUNT */
78 ARC_OFFSET_NO_REGISTER, /* RESERVED */
79 ARC_OFFSET_NO_REGISTER, /* LIMM */
80 ARC_OFFSET_NO_REGISTER, /* PCL */
81
82 REGOFF (39), /* PC */
83 REGOFF (5), /* STATUS32 */
84 REGOFF (2), /* LP_START */
85 REGOFF (3), /* LP_END */
86 REGOFF (1), /* BTA */
87 REGOFF (6) /* ERET */
88};
8d7f0635
AK
89
90/* Implement the "cannot_fetch_register" gdbarch method. */
91
92static int
93arc_linux_cannot_fetch_register (struct gdbarch *gdbarch, int regnum)
94{
95 /* Assume that register is readable if it is unknown. */
96 switch (regnum)
97 {
98 case ARC_ILINK_REGNUM:
99 case ARC_RESERVED_REGNUM:
100 case ARC_LIMM_REGNUM:
101 return true;
102 case ARC_R30_REGNUM:
103 case ARC_R58_REGNUM:
104 case ARC_R59_REGNUM:
105 return !arc_mach_is_arcv2 (gdbarch);
106 }
107 return (regnum > ARC_BLINK_REGNUM) && (regnum < ARC_LP_COUNT_REGNUM);
108}
109
110/* Implement the "cannot_store_register" gdbarch method. */
111
112static int
113arc_linux_cannot_store_register (struct gdbarch *gdbarch, int regnum)
114{
115 /* Assume that register is writable if it is unknown. */
116 switch (regnum)
117 {
118 case ARC_ILINK_REGNUM:
119 case ARC_RESERVED_REGNUM:
120 case ARC_LIMM_REGNUM:
121 case ARC_PCL_REGNUM:
122 return true;
123 case ARC_R30_REGNUM:
124 case ARC_R58_REGNUM:
125 case ARC_R59_REGNUM:
126 return !arc_mach_is_arcv2 (gdbarch);
127 }
128 return (regnum > ARC_BLINK_REGNUM) && (regnum < ARC_LP_COUNT_REGNUM);
129}
130
131/* For ARC Linux, breakpoints use the 16-bit TRAP_S 1 instruction, which
132 is 0x3e78 (little endian) or 0x783e (big endian). */
133
134static const gdb_byte arc_linux_trap_s_be[] = { 0x78, 0x3e };
135static const gdb_byte arc_linux_trap_s_le[] = { 0x3e, 0x78 };
136static const int trap_size = 2; /* Number of bytes to insert "trap". */
137
138/* Implement the "breakpoint_kind_from_pc" gdbarch method. */
139
140static int
141arc_linux_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
142{
143 return trap_size;
144}
145
146/* Implement the "sw_breakpoint_from_kind" gdbarch method. */
147
148static const gdb_byte *
149arc_linux_sw_breakpoint_from_kind (struct gdbarch *gdbarch,
150 int kind, int *size)
151{
152 *size = kind;
153 return ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
154 ? arc_linux_trap_s_be
155 : arc_linux_trap_s_le);
156}
157
158/* Implement the "software_single_step" gdbarch method. */
159
160static std::vector<CORE_ADDR>
161arc_linux_software_single_step (struct regcache *regcache)
162{
163 struct gdbarch *gdbarch = regcache->arch ();
164 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
165 struct disassemble_info di = arc_disassemble_info (gdbarch);
166
167 /* Read current instruction. */
168 struct arc_instruction curr_insn;
169 arc_insn_decode (regcache_read_pc (regcache), &di, arc_delayed_print_insn,
170 &curr_insn);
171 CORE_ADDR next_pc = arc_insn_get_linear_next_pc (curr_insn);
172
173 std::vector<CORE_ADDR> next_pcs;
174
175 /* For instructions with delay slots, the fall thru is not the
176 instruction immediately after the current instruction, but the one
177 after that. */
178 if (curr_insn.has_delay_slot)
179 {
180 struct arc_instruction next_insn;
181 arc_insn_decode (next_pc, &di, arc_delayed_print_insn, &next_insn);
182 next_pcs.push_back (arc_insn_get_linear_next_pc (next_insn));
183 }
184 else
185 next_pcs.push_back (next_pc);
186
187 ULONGEST status32;
188 regcache_cooked_read_unsigned (regcache, gdbarch_ps_regnum (gdbarch),
189 &status32);
190
191 if (curr_insn.is_control_flow)
192 {
193 CORE_ADDR branch_pc = arc_insn_get_branch_target (curr_insn);
194 if (branch_pc != next_pc)
195 next_pcs.push_back (branch_pc);
196 }
197 /* Is current instruction the last in a loop body? */
198 else if (tdep->has_hw_loops)
199 {
200 /* If STATUS32.L is 1, then ZD-loops are disabled. */
201 if ((status32 & ARC_STATUS32_L_MASK) == 0)
202 {
203 ULONGEST lp_end, lp_start, lp_count;
204 regcache_cooked_read_unsigned (regcache, ARC_LP_START_REGNUM,
205 &lp_start);
206 regcache_cooked_read_unsigned (regcache, ARC_LP_END_REGNUM, &lp_end);
207 regcache_cooked_read_unsigned (regcache, ARC_LP_COUNT_REGNUM,
208 &lp_count);
209
210 if (arc_debug)
211 {
212 debug_printf ("arc-linux: lp_start = %s, lp_end = %s, "
213 "lp_count = %s, next_pc = %s\n",
214 paddress (gdbarch, lp_start),
215 paddress (gdbarch, lp_end),
216 pulongest (lp_count),
217 paddress (gdbarch, next_pc));
218 }
219
220 if (next_pc == lp_end && lp_count > 1)
221 {
222 /* The instruction is in effect a jump back to the start of
223 the loop. */
224 next_pcs.push_back (lp_start);
225 }
226 }
227 }
228
229 /* Is this a delay slot? Then next PC is in BTA register. */
230 if ((status32 & ARC_STATUS32_DE_MASK) != 0)
231 {
232 ULONGEST bta;
233 regcache_cooked_read_unsigned (regcache, ARC_BTA_REGNUM, &bta);
234 next_pcs.push_back (bta);
235 }
236
237 return next_pcs;
238}
239
240/* Implement the "skip_solib_resolver" gdbarch method.
241
242 See glibc_skip_solib_resolver for details. */
243
244static CORE_ADDR
245arc_linux_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
246{
247 /* For uClibc 0.9.26+.
248
249 An unresolved PLT entry points to "__dl_linux_resolve", which calls
250 "_dl_linux_resolver" to do the resolving and then eventually jumps to
251 the function.
252
253 So we look for the symbol `_dl_linux_resolver', and if we are there,
254 gdb sets a breakpoint at the return address, and continues. */
255 struct bound_minimal_symbol resolver
256 = lookup_minimal_symbol ("_dl_linux_resolver", NULL, NULL);
257
258 if (arc_debug)
259 {
260 if (resolver.minsym != nullptr)
261 {
262 CORE_ADDR res_addr = BMSYMBOL_VALUE_ADDRESS (resolver);
263 debug_printf ("arc-linux: skip_solib_resolver (): "
264 "pc = %s, resolver at %s\n",
265 print_core_address (gdbarch, pc),
266 print_core_address (gdbarch, res_addr));
267 }
268 else
269 {
270 debug_printf ("arc-linux: skip_solib_resolver (): "
271 "pc = %s, no resolver found\n",
272 print_core_address (gdbarch, pc));
273 }
274 }
275
276 if (resolver.minsym != nullptr && BMSYMBOL_VALUE_ADDRESS (resolver) == pc)
277 {
278 /* Find the return address. */
279 return frame_unwind_caller_pc (get_current_frame ());
280 }
281 else
282 {
283 /* No breakpoint required. */
284 return 0;
285 }
286}
287
460fd13b
AK
288void
289arc_linux_supply_gregset (const struct regset *regset,
290 struct regcache *regcache,
291 int regnum, const void *gregs, size_t size)
292{
293 gdb_static_assert (ARC_LAST_REGNUM
294 < ARRAY_SIZE (arc_linux_core_reg_offsets));
295
296 const bfd_byte *buf = (const bfd_byte *) gregs;
297
298 for (int reg = 0; reg <= ARC_LAST_REGNUM; reg++)
299 if (arc_linux_core_reg_offsets[reg] != ARC_OFFSET_NO_REGISTER)
300 regcache->raw_supply (reg, buf + arc_linux_core_reg_offsets[reg]);
301}
302
303void
304arc_linux_supply_v2_regset (const struct regset *regset,
305 struct regcache *regcache, int regnum,
306 const void *v2_regs, size_t size)
307{
308 const bfd_byte *buf = (const bfd_byte *) v2_regs;
309
310 /* user_regs_arcv2 is defined in linux arch/arc/include/uapi/asm/ptrace.h. */
311 regcache->raw_supply (ARC_R30_REGNUM, buf);
312 regcache->raw_supply (ARC_R58_REGNUM, buf + REGOFF (1));
313 regcache->raw_supply (ARC_R59_REGNUM, buf + REGOFF (2));
314}
315
316/* Populate BUF with register REGNUM from the REGCACHE. */
317
318static void
319collect_register (const struct regcache *regcache, struct gdbarch *gdbarch,
320 int regnum, gdb_byte *buf)
321{
322 /* Skip non-existing registers. */
323 if ((arc_linux_core_reg_offsets[regnum] == ARC_OFFSET_NO_REGISTER))
324 return;
325
326 /* The address where the execution has stopped is in pseudo-register
327 STOP_PC. However, when kernel code is returning from the exception,
328 it uses the value from ERET register. Since, TRAP_S (the breakpoint
329 instruction) commits, the ERET points to the next instruction. In
330 other words: ERET != STOP_PC. To jump back from the kernel code to
331 the correct address, ERET must be overwritten by GDB's STOP_PC. Else,
332 the program will continue at the address after the current instruction.
333 */
334 if (regnum == gdbarch_pc_regnum (gdbarch))
335 regnum = ARC_ERET_REGNUM;
336 regcache->raw_collect (regnum, buf + arc_linux_core_reg_offsets[regnum]);
337}
338
339void
340arc_linux_collect_gregset (const struct regset *regset,
341 const struct regcache *regcache,
342 int regnum, void *gregs, size_t size)
343{
344 gdb_static_assert (ARC_LAST_REGNUM
345 < ARRAY_SIZE (arc_linux_core_reg_offsets));
346
347 gdb_byte *buf = (gdb_byte *) gregs;
348 struct gdbarch *gdbarch = regcache->arch ();
349
350 /* regnum == -1 means writing all the registers. */
351 if (regnum == -1)
352 for (int reg = 0; reg <= ARC_LAST_REGNUM; reg++)
353 collect_register (regcache, gdbarch, reg, buf);
354 else if (regnum <= ARC_LAST_REGNUM)
355 collect_register (regcache, gdbarch, regnum, buf);
356 else
357 gdb_assert_not_reached ("Invalid regnum in arc_linux_collect_gregset.");
358}
359
360void
361arc_linux_collect_v2_regset (const struct regset *regset,
362 const struct regcache *regcache, int regnum,
363 void *v2_regs, size_t size)
364{
365 bfd_byte *buf = (bfd_byte *) v2_regs;
366
367 regcache->raw_collect (ARC_R30_REGNUM, buf);
368 regcache->raw_collect (ARC_R58_REGNUM, buf + REGOFF (1));
369 regcache->raw_collect (ARC_R59_REGNUM, buf + REGOFF (2));
370}
371
372/* Linux regset definitions. */
373
374static const struct regset arc_linux_gregset = {
375 arc_linux_core_reg_offsets,
376 arc_linux_supply_gregset,
377 arc_linux_collect_gregset,
378};
379
380static const struct regset arc_linux_v2_regset = {
381 NULL,
382 arc_linux_supply_v2_regset,
383 arc_linux_collect_v2_regset,
384};
385
386/* Implement the `iterate_over_regset_sections` gdbarch method. */
387
388static void
389arc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
390 iterate_over_regset_sections_cb *cb,
391 void *cb_data,
392 const struct regcache *regcache)
393{
394 /* There are 40 registers in Linux user_regs_struct, although some of
395 them are now just a mere paddings, kept to maintain binary
396 compatibility with older tools. */
397 const int sizeof_gregset = 40 * ARC_REGISTER_SIZE;
398
399 cb (".reg", sizeof_gregset, sizeof_gregset, &arc_linux_gregset, NULL,
400 cb_data);
401 cb (".reg-arc-v2", ARC_LINUX_SIZEOF_V2_REGSET, ARC_LINUX_SIZEOF_V2_REGSET,
402 &arc_linux_v2_regset, NULL, cb_data);
403}
404
405/* Implement the `core_read_description` gdbarch method. */
406
407static const struct target_desc *
408arc_linux_core_read_description (struct gdbarch *gdbarch,
409 struct target_ops *target,
410 bfd *abfd)
411{
412 arc_arch_features features
413 = arc_arch_features_create (abfd,
414 gdbarch_bfd_arch_info (gdbarch)->mach);
415 return arc_lookup_target_description (features);
416}
417
8d7f0635
AK
418/* Initialization specific to Linux environment. */
419
420static void
421arc_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
422{
423 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
424
425 if (arc_debug)
426 debug_printf ("arc-linux: GNU/Linux OS/ABI initialization.\n");
427
428 /* If we are using Linux, we have in uClibc
429 (libc/sysdeps/linux/arc/bits/setjmp.h):
430
431 typedef int __jmp_buf[13+1+1+1]; //r13-r25, fp, sp, blink
432
433 Where "blink" is a stored PC of a caller function.
434 */
435 tdep->jb_pc = 15;
436
437 linux_init_abi (info, gdbarch);
438
439 /* Set up target dependent GDB architecture entries. */
440 set_gdbarch_cannot_fetch_register (gdbarch, arc_linux_cannot_fetch_register);
441 set_gdbarch_cannot_store_register (gdbarch, arc_linux_cannot_store_register);
442 set_gdbarch_breakpoint_kind_from_pc (gdbarch,
443 arc_linux_breakpoint_kind_from_pc);
444 set_gdbarch_sw_breakpoint_from_kind (gdbarch,
445 arc_linux_sw_breakpoint_from_kind);
446 set_gdbarch_fetch_tls_load_module_address (gdbarch,
447 svr4_fetch_objfile_link_map);
448 set_gdbarch_software_single_step (gdbarch, arc_linux_software_single_step);
449 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
450 set_gdbarch_skip_solib_resolver (gdbarch, arc_linux_skip_solib_resolver);
460fd13b
AK
451 set_gdbarch_iterate_over_regset_sections
452 (gdbarch, arc_linux_iterate_over_regset_sections);
453 set_gdbarch_core_read_description (gdbarch, arc_linux_core_read_description);
8d7f0635
AK
454
455 /* GNU/Linux uses SVR4-style shared libraries, with 32-bit ints, longs
456 and pointers (ILP32). */
457 set_solib_svr4_fetch_link_map_offsets (gdbarch,
458 svr4_ilp32_fetch_link_map_offsets);
459}
460
461/* Suppress warning from -Wmissing-prototypes. */
462extern initialize_file_ftype _initialize_arc_linux_tdep;
463
464void
465_initialize_arc_linux_tdep ()
466{
467 gdbarch_register_osabi (bfd_arch_arc, 0, GDB_OSABI_LINUX,
468 arc_linux_init_osabi);
469}