1 /* Target-dependent code for GNU/Linux UltraSPARC.
3 Copyright (C) 2003-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 #include "extract-store-integer.h"
22 #include "frame-unwind.h"
23 #include "dwarf2/frame.h"
29 #include "solib-svr4.h"
31 #include "trad-frame.h"
32 #include "tramp-frame.h"
33 #include "xml-syscall.h"
34 #include "linux-tdep.h"
35 #include "solib-svr4-linux.h"
37 /* ADI specific si_code */
42 #define SEGV_ADIDERR 4
45 #define SEGV_ADIPERR 5
48 /* The syscall's XML filename for sparc 64-bit. */
49 #define XML_SYSCALL_FILENAME_SPARC64 "syscalls/sparc64-linux.xml"
51 #include "sparc64-tdep.h"
53 /* Signal trampoline support. */
55 static void sparc64_linux_sigframe_init (const struct tramp_frame
*self
,
56 const frame_info_ptr
&this_frame
,
57 struct trad_frame_cache
*this_cache
,
60 /* See sparc-linux-tdep.c for details. Note that 64-bit binaries only
63 static const struct tramp_frame sparc64_linux_rt_sigframe
=
68 { 0x82102065, ULONGEST_MAX
}, /* mov __NR_rt_sigreturn, %g1 */
69 { 0x91d0206d, ULONGEST_MAX
}, /* ta 0x6d */
70 { TRAMP_SENTINEL_INSN
, ULONGEST_MAX
}
72 sparc64_linux_sigframe_init
76 sparc64_linux_sigframe_init (const struct tramp_frame
*self
,
77 const frame_info_ptr
&this_frame
,
78 struct trad_frame_cache
*this_cache
,
81 CORE_ADDR base
, addr
, sp_addr
;
84 base
= get_frame_register_unsigned (this_frame
, SPARC_O1_REGNUM
);
87 /* Offsets from <bits/sigcontext.h>. */
89 /* Since %g0 is always zero, keep the identity encoding. */
91 sp_addr
= base
+ ((SPARC_SP_REGNUM
- SPARC_G0_REGNUM
) * 8);
92 for (regnum
= SPARC_G1_REGNUM
; regnum
<= SPARC_O7_REGNUM
; regnum
++)
94 trad_frame_set_reg_addr (this_cache
, regnum
, addr
);
98 trad_frame_set_reg_addr (this_cache
, SPARC64_STATE_REGNUM
, addr
+ 0);
99 trad_frame_set_reg_addr (this_cache
, SPARC64_PC_REGNUM
, addr
+ 8);
100 trad_frame_set_reg_addr (this_cache
, SPARC64_NPC_REGNUM
, addr
+ 16);
101 trad_frame_set_reg_addr (this_cache
, SPARC64_Y_REGNUM
, addr
+ 24);
102 trad_frame_set_reg_addr (this_cache
, SPARC64_FPRS_REGNUM
, addr
+ 28);
104 base
= get_frame_register_unsigned (this_frame
, SPARC_SP_REGNUM
);
108 addr
= get_frame_memory_unsigned (this_frame
, sp_addr
, 8);
112 for (regnum
= SPARC_L0_REGNUM
; regnum
<= SPARC_I7_REGNUM
; regnum
++)
114 trad_frame_set_reg_addr (this_cache
, regnum
, addr
);
117 trad_frame_set_id (this_cache
, frame_id_build (base
, func
));
120 /* sparc64 GNU/Linux implementation of the report_signal_info
122 Displays information related to ADI memory corruptions. */
125 sparc64_linux_report_signal_info (struct gdbarch
*gdbarch
, struct ui_out
*uiout
,
126 enum gdb_signal siggnal
)
128 if (gdbarch_bfd_arch_info (gdbarch
)->bits_per_word
!= 64
129 || siggnal
!= GDB_SIGNAL_SEGV
)
137 /* Evaluate si_code to see if the segfault is ADI related. */
138 si_code
= parse_and_eval_long ("$_siginfo.si_code\n");
140 if (si_code
>= SEGV_ACCADI
&& si_code
<= SEGV_ADIPERR
)
141 addr
= parse_and_eval_long ("$_siginfo._sifields._sigfault.si_addr");
143 catch (const gdb_exception_error
&exception
)
148 /* Print out ADI event based on sig_code value */
151 case SEGV_ACCADI
: /* adi not enabled */
153 uiout
->field_string ("sigcode-meaning", _("ADI disabled"));
154 uiout
->text (_(" while accessing address "));
155 uiout
->field_core_addr ("bound-access", gdbarch
, addr
);
157 case SEGV_ADIDERR
: /* disrupting mismatch */
159 uiout
->field_string ("sigcode-meaning", _("ADI deferred mismatch"));
160 uiout
->text (_(" while accessing address "));
161 uiout
->field_core_addr ("bound-access", gdbarch
, addr
);
163 case SEGV_ADIPERR
: /* precise mismatch */
165 uiout
->field_string ("sigcode-meaning", _("ADI precise mismatch"));
166 uiout
->text (_(" while accessing address "));
167 uiout
->field_core_addr ("bound-access", gdbarch
, addr
);
176 /* Return the address of a system call's alternative return
180 sparc64_linux_step_trap (const frame_info_ptr
&frame
, unsigned long insn
)
182 /* __NR_rt_sigreturn is 101 */
183 if ((insn
== 0x91d0206d)
184 && (get_frame_register_unsigned (frame
, SPARC_G1_REGNUM
) == 101))
186 struct gdbarch
*gdbarch
= get_frame_arch (frame
);
187 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
189 ULONGEST sp
= get_frame_register_unsigned (frame
, SPARC_SP_REGNUM
);
193 /* The kernel puts the sigreturn registers on the stack,
194 and this is where the signal unwinding state is take from
195 when returning from a signal.
197 A siginfo_t sits 192 bytes from the base of the stack. This
198 siginfo_t is 128 bytes, and is followed by the sigreturn
199 register save area. The saved PC sits at a 136 byte offset
202 return read_memory_unsigned_integer (sp
+ 192 + 128 + 136,
210 const struct sparc_gregmap sparc64_linux_core_gregmap
=
212 32 * 8, /* %tstate */
225 sparc64_linux_supply_core_gregset (const struct regset
*regset
,
226 struct regcache
*regcache
,
227 int regnum
, const void *gregs
, size_t len
)
229 sparc64_supply_gregset (&sparc64_linux_core_gregmap
,
230 regcache
, regnum
, gregs
);
234 sparc64_linux_collect_core_gregset (const struct regset
*regset
,
235 const struct regcache
*regcache
,
236 int regnum
, void *gregs
, size_t len
)
238 sparc64_collect_gregset (&sparc64_linux_core_gregmap
,
239 regcache
, regnum
, gregs
);
243 sparc64_linux_supply_core_fpregset (const struct regset
*regset
,
244 struct regcache
*regcache
,
245 int regnum
, const void *fpregs
, size_t len
)
247 sparc64_supply_fpregset (&sparc64_bsd_fpregmap
, regcache
, regnum
, fpregs
);
251 sparc64_linux_collect_core_fpregset (const struct regset
*regset
,
252 const struct regcache
*regcache
,
253 int regnum
, void *fpregs
, size_t len
)
255 sparc64_collect_fpregset (&sparc64_bsd_fpregmap
, regcache
, regnum
, fpregs
);
258 /* Set the program counter for process PTID to PC. */
260 #define TSTATE_SYSCALL 0x0000000000000020ULL
263 sparc64_linux_write_pc (struct regcache
*regcache
, CORE_ADDR pc
)
265 gdbarch
*arch
= regcache
->arch ();
266 sparc_gdbarch_tdep
*tdep
= gdbarch_tdep
<sparc_gdbarch_tdep
> (arch
);
269 regcache_cooked_write_unsigned (regcache
, tdep
->pc_regnum
, pc
);
270 regcache_cooked_write_unsigned (regcache
, tdep
->npc_regnum
, pc
+ 4);
272 /* Clear the "in syscall" bit to prevent the kernel from
273 messing with the PCs we just installed, if we happen to be
274 within an interrupted system call that the kernel wants to
277 Note that after we return from the dummy call, the TSTATE et al.
278 registers will be automatically restored, and the kernel
279 continues to restart the system call at this point. */
280 regcache_cooked_read_unsigned (regcache
, SPARC64_STATE_REGNUM
, &state
);
281 state
&= ~TSTATE_SYSCALL
;
282 regcache_cooked_write_unsigned (regcache
, SPARC64_STATE_REGNUM
, state
);
286 sparc64_linux_get_syscall_number (struct gdbarch
*gdbarch
,
289 struct regcache
*regcache
= get_thread_regcache (thread
);
290 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
291 /* The content of a register. */
296 /* Getting the system call number from the register.
297 When dealing with the sparc architecture, this information
298 is stored at the %g1 register. */
299 regcache
->cooked_read (SPARC_G1_REGNUM
, buf
);
301 ret
= extract_signed_integer (buf
, 8, byte_order
);
307 /* Implement the "get_longjmp_target" gdbarch method. */
310 sparc64_linux_get_longjmp_target (const frame_info_ptr
&frame
, CORE_ADDR
*pc
)
312 struct gdbarch
*gdbarch
= get_frame_arch (frame
);
316 jb_addr
= get_frame_register_unsigned (frame
, SPARC_O0_REGNUM
);
318 /* setjmp and longjmp in SPARC64 are implemented in glibc using the
319 setcontext and getcontext system calls respectively. These
320 system calls operate on ucontext_t structures, which happen to
321 partially have the same structure than jmp_buf. However the
322 ucontext returned by getcontext, and thus the jmp_buf structure
323 returned by setjmp, contains the context of the trap instruction
324 in the glibc __[sig]setjmp wrapper, not the context of the user
327 %o7 in the jmp_buf structure is stored at offset 18*8 in the
328 mc_gregs array, which is itself located at offset 32 into
329 jmp_buf. See bits/setjmp.h. This register contains the address
330 of the 'call setjmp' instruction in user code.
332 In order to determine the longjmp target address in the
333 initiating frame we need to examine the call instruction itself,
334 in particular whether the annul bit is set. If it is not set
335 then we need to jump over the instruction at the delay slot. */
337 if (target_read_memory (jb_addr
+ 32 + (18 * 8), buf
, 8))
340 *pc
= extract_unsigned_integer (buf
, 8, gdbarch_byte_order (gdbarch
));
342 if (!sparc_is_annulled_branch_insn (*pc
))
343 *pc
+= 4; /* delay slot insn */
344 *pc
+= 4; /* call insn */
351 static const struct regset sparc64_linux_gregset
=
354 sparc64_linux_supply_core_gregset
,
355 sparc64_linux_collect_core_gregset
358 static const struct regset sparc64_linux_fpregset
=
361 sparc64_linux_supply_core_fpregset
,
362 sparc64_linux_collect_core_fpregset
366 sparc64_linux_init_abi (struct gdbarch_info info
, struct gdbarch
*gdbarch
)
368 sparc_gdbarch_tdep
*tdep
= gdbarch_tdep
<sparc_gdbarch_tdep
> (gdbarch
);
370 linux_init_abi (info
, gdbarch
, 0);
372 tdep
->gregset
= &sparc64_linux_gregset
;
373 tdep
->sizeof_gregset
= 288;
375 tdep
->fpregset
= &sparc64_linux_fpregset
;
376 tdep
->sizeof_fpregset
= 280;
378 tramp_frame_prepend_unwinder (gdbarch
, &sparc64_linux_rt_sigframe
);
380 /* Hook in the DWARF CFI frame unwinder. */
381 dwarf2_append_unwinders (gdbarch
);
383 sparc64_init_abi (info
, gdbarch
);
385 /* GNU/Linux has SVR4-style shared libraries... */
386 set_gdbarch_skip_trampoline_code (gdbarch
, find_solib_trampoline_target
);
387 set_solib_svr4_ops (gdbarch
, make_linux_lp64_svr4_solib_ops
);
389 /* ...which means that we need some special handling when doing
390 prologue analysis. */
391 tdep
->plt_entry_size
= 16;
393 /* Enable TLS support. */
394 set_gdbarch_fetch_tls_load_module_address (gdbarch
,
395 svr4_fetch_objfile_link_map
);
397 /* Make sure we can single-step over signal return system calls. */
398 tdep
->step_trap
= sparc64_linux_step_trap
;
400 /* Make sure we can single-step over longjmp calls. */
401 set_gdbarch_get_longjmp_target (gdbarch
, sparc64_linux_get_longjmp_target
);
403 set_gdbarch_write_pc (gdbarch
, sparc64_linux_write_pc
);
405 /* Functions for 'catch syscall'. */
406 set_xml_syscall_file_name (gdbarch
, XML_SYSCALL_FILENAME_SPARC64
);
407 set_gdbarch_get_syscall_number (gdbarch
,
408 sparc64_linux_get_syscall_number
);
409 set_gdbarch_report_signal_info (gdbarch
, sparc64_linux_report_signal_info
);
412 INIT_GDB_FILE (sparc64_linux_tdep
)
414 gdbarch_register_osabi (bfd_arch_sparc
, bfd_mach_sparc_v9
,
415 GDB_OSABI_LINUX
, sparc64_linux_init_abi
);