1 /* Target dependent code for GNU/Linux ARC.
3 Copyright 2020 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"
28 /* ARC header files. */
29 #include "opcodes/arc-dis.h"
32 /* Implement the "cannot_fetch_register" gdbarch method. */
35 arc_linux_cannot_fetch_register (struct gdbarch
*gdbarch
, int regnum
)
37 /* Assume that register is readable if it is unknown. */
40 case ARC_ILINK_REGNUM
:
41 case ARC_RESERVED_REGNUM
:
47 return !arc_mach_is_arcv2 (gdbarch
);
49 return (regnum
> ARC_BLINK_REGNUM
) && (regnum
< ARC_LP_COUNT_REGNUM
);
52 /* Implement the "cannot_store_register" gdbarch method. */
55 arc_linux_cannot_store_register (struct gdbarch
*gdbarch
, int regnum
)
57 /* Assume that register is writable if it is unknown. */
60 case ARC_ILINK_REGNUM
:
61 case ARC_RESERVED_REGNUM
:
68 return !arc_mach_is_arcv2 (gdbarch
);
70 return (regnum
> ARC_BLINK_REGNUM
) && (regnum
< ARC_LP_COUNT_REGNUM
);
73 /* For ARC Linux, breakpoints use the 16-bit TRAP_S 1 instruction, which
74 is 0x3e78 (little endian) or 0x783e (big endian). */
76 static const gdb_byte arc_linux_trap_s_be
[] = { 0x78, 0x3e };
77 static const gdb_byte arc_linux_trap_s_le
[] = { 0x3e, 0x78 };
78 static const int trap_size
= 2; /* Number of bytes to insert "trap". */
80 /* Implement the "breakpoint_kind_from_pc" gdbarch method. */
83 arc_linux_breakpoint_kind_from_pc (struct gdbarch
*gdbarch
, CORE_ADDR
*pcptr
)
88 /* Implement the "sw_breakpoint_from_kind" gdbarch method. */
90 static const gdb_byte
*
91 arc_linux_sw_breakpoint_from_kind (struct gdbarch
*gdbarch
,
95 return ((gdbarch_byte_order (gdbarch
) == BFD_ENDIAN_BIG
)
97 : arc_linux_trap_s_le
);
100 /* Implement the "software_single_step" gdbarch method. */
102 static std::vector
<CORE_ADDR
>
103 arc_linux_software_single_step (struct regcache
*regcache
)
105 struct gdbarch
*gdbarch
= regcache
->arch ();
106 struct gdbarch_tdep
*tdep
= gdbarch_tdep (gdbarch
);
107 struct disassemble_info di
= arc_disassemble_info (gdbarch
);
109 /* Read current instruction. */
110 struct arc_instruction curr_insn
;
111 arc_insn_decode (regcache_read_pc (regcache
), &di
, arc_delayed_print_insn
,
113 CORE_ADDR next_pc
= arc_insn_get_linear_next_pc (curr_insn
);
115 std::vector
<CORE_ADDR
> next_pcs
;
117 /* For instructions with delay slots, the fall thru is not the
118 instruction immediately after the current instruction, but the one
120 if (curr_insn
.has_delay_slot
)
122 struct arc_instruction next_insn
;
123 arc_insn_decode (next_pc
, &di
, arc_delayed_print_insn
, &next_insn
);
124 next_pcs
.push_back (arc_insn_get_linear_next_pc (next_insn
));
127 next_pcs
.push_back (next_pc
);
130 regcache_cooked_read_unsigned (regcache
, gdbarch_ps_regnum (gdbarch
),
133 if (curr_insn
.is_control_flow
)
135 CORE_ADDR branch_pc
= arc_insn_get_branch_target (curr_insn
);
136 if (branch_pc
!= next_pc
)
137 next_pcs
.push_back (branch_pc
);
139 /* Is current instruction the last in a loop body? */
140 else if (tdep
->has_hw_loops
)
142 /* If STATUS32.L is 1, then ZD-loops are disabled. */
143 if ((status32
& ARC_STATUS32_L_MASK
) == 0)
145 ULONGEST lp_end
, lp_start
, lp_count
;
146 regcache_cooked_read_unsigned (regcache
, ARC_LP_START_REGNUM
,
148 regcache_cooked_read_unsigned (regcache
, ARC_LP_END_REGNUM
, &lp_end
);
149 regcache_cooked_read_unsigned (regcache
, ARC_LP_COUNT_REGNUM
,
154 debug_printf ("arc-linux: lp_start = %s, lp_end = %s, "
155 "lp_count = %s, next_pc = %s\n",
156 paddress (gdbarch
, lp_start
),
157 paddress (gdbarch
, lp_end
),
158 pulongest (lp_count
),
159 paddress (gdbarch
, next_pc
));
162 if (next_pc
== lp_end
&& lp_count
> 1)
164 /* The instruction is in effect a jump back to the start of
166 next_pcs
.push_back (lp_start
);
171 /* Is this a delay slot? Then next PC is in BTA register. */
172 if ((status32
& ARC_STATUS32_DE_MASK
) != 0)
175 regcache_cooked_read_unsigned (regcache
, ARC_BTA_REGNUM
, &bta
);
176 next_pcs
.push_back (bta
);
182 /* Implement the "skip_solib_resolver" gdbarch method.
184 See glibc_skip_solib_resolver for details. */
187 arc_linux_skip_solib_resolver (struct gdbarch
*gdbarch
, CORE_ADDR pc
)
189 /* For uClibc 0.9.26+.
191 An unresolved PLT entry points to "__dl_linux_resolve", which calls
192 "_dl_linux_resolver" to do the resolving and then eventually jumps to
195 So we look for the symbol `_dl_linux_resolver', and if we are there,
196 gdb sets a breakpoint at the return address, and continues. */
197 struct bound_minimal_symbol resolver
198 = lookup_minimal_symbol ("_dl_linux_resolver", NULL
, NULL
);
202 if (resolver
.minsym
!= nullptr)
204 CORE_ADDR res_addr
= BMSYMBOL_VALUE_ADDRESS (resolver
);
205 debug_printf ("arc-linux: skip_solib_resolver (): "
206 "pc = %s, resolver at %s\n",
207 print_core_address (gdbarch
, pc
),
208 print_core_address (gdbarch
, res_addr
));
212 debug_printf ("arc-linux: skip_solib_resolver (): "
213 "pc = %s, no resolver found\n",
214 print_core_address (gdbarch
, pc
));
218 if (resolver
.minsym
!= nullptr && BMSYMBOL_VALUE_ADDRESS (resolver
) == pc
)
220 /* Find the return address. */
221 return frame_unwind_caller_pc (get_current_frame ());
225 /* No breakpoint required. */
230 /* Initialization specific to Linux environment. */
233 arc_linux_init_osabi (struct gdbarch_info info
, struct gdbarch
*gdbarch
)
235 struct gdbarch_tdep
*tdep
= gdbarch_tdep (gdbarch
);
238 debug_printf ("arc-linux: GNU/Linux OS/ABI initialization.\n");
240 /* If we are using Linux, we have in uClibc
241 (libc/sysdeps/linux/arc/bits/setjmp.h):
243 typedef int __jmp_buf[13+1+1+1]; //r13-r25, fp, sp, blink
245 Where "blink" is a stored PC of a caller function.
249 linux_init_abi (info
, gdbarch
);
251 /* Set up target dependent GDB architecture entries. */
252 set_gdbarch_cannot_fetch_register (gdbarch
, arc_linux_cannot_fetch_register
);
253 set_gdbarch_cannot_store_register (gdbarch
, arc_linux_cannot_store_register
);
254 set_gdbarch_breakpoint_kind_from_pc (gdbarch
,
255 arc_linux_breakpoint_kind_from_pc
);
256 set_gdbarch_sw_breakpoint_from_kind (gdbarch
,
257 arc_linux_sw_breakpoint_from_kind
);
258 set_gdbarch_fetch_tls_load_module_address (gdbarch
,
259 svr4_fetch_objfile_link_map
);
260 set_gdbarch_software_single_step (gdbarch
, arc_linux_software_single_step
);
261 set_gdbarch_skip_trampoline_code (gdbarch
, find_solib_trampoline_target
);
262 set_gdbarch_skip_solib_resolver (gdbarch
, arc_linux_skip_solib_resolver
);
264 /* GNU/Linux uses SVR4-style shared libraries, with 32-bit ints, longs
265 and pointers (ILP32). */
266 set_solib_svr4_fetch_link_map_offsets (gdbarch
,
267 svr4_ilp32_fetch_link_map_offsets
);
270 /* Suppress warning from -Wmissing-prototypes. */
271 extern initialize_file_ftype _initialize_arc_linux_tdep
;
274 _initialize_arc_linux_tdep ()
276 gdbarch_register_osabi (bfd_arch_arc
, 0, GDB_OSABI_LINUX
,
277 arc_linux_init_osabi
);