1 1.1 christos /* Target-dependent code for OpenBSD/alpha. 2 1.1 christos 3 1.1.1.5 christos Copyright (C) 2006-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos This file is part of GDB. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 1.1 christos 20 1.1 christos #include "frame.h" 21 1.1 christos #include "gdbcore.h" 22 1.1 christos #include "osabi.h" 23 1.1 christos 24 1.1 christos #include "obsd-tdep.h" 25 1.1 christos #include "alpha-tdep.h" 26 1.1 christos #include "alpha-bsd-tdep.h" 27 1.1 christos #include "solib-svr4.h" 28 1.1 christos 29 1.1 christos /* Signal trampolines. */ 30 1.1 christos 31 1.1 christos /* The OpenBSD kernel maps the signal trampoline at some random 32 1.1 christos location in user space, which means that the traditional BSD way of 33 1.1 christos detecting it won't work. 34 1.1 christos 35 1.1 christos The signal trampoline will be mapped at an address that is page 36 1.1 christos aligned. We recognize the signal trampoline by looking for the 37 1.1 christos sigreturn system call. */ 38 1.1 christos 39 1.1 christos static const int alphaobsd_page_size = 8192; 40 1.1 christos 41 1.1 christos static LONGEST 42 1.1 christos alphaobsd_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc) 43 1.1 christos { 44 1.1 christos return (pc & (alphaobsd_page_size - 1)); 45 1.1 christos } 46 1.1 christos 47 1.1 christos static int 48 1.1 christos alphaobsd_pc_in_sigtramp (struct gdbarch *gdbarch, 49 1.1 christos CORE_ADDR pc, const char *name) 50 1.1 christos { 51 1.1 christos CORE_ADDR start_pc = (pc & ~(alphaobsd_page_size - 1)); 52 1.1 christos unsigned insn; 53 1.1 christos 54 1.1 christos if (name) 55 1.1 christos return 0; 56 1.1 christos 57 1.1 christos /* Check for "". */ 58 1.1 christos insn = alpha_read_insn (gdbarch, start_pc + 5 * ALPHA_INSN_SIZE); 59 1.1 christos if (insn != 0x201f0067) 60 1.1 christos return 0; 61 1.1 christos 62 1.1 christos /* Check for "". */ 63 1.1 christos insn = alpha_read_insn (gdbarch, start_pc + 6 * ALPHA_INSN_SIZE); 64 1.1 christos if (insn != 0x00000083) 65 1.1 christos return 0; 66 1.1 christos 67 1.1 christos return 1; 68 1.1 christos } 69 1.1 christos 70 1.1 christos static CORE_ADDR 71 1.1.1.5 christos alphaobsd_sigcontext_addr (const frame_info_ptr &this_frame) 72 1.1 christos { 73 1.1 christos struct gdbarch *gdbarch = get_frame_arch (this_frame); 74 1.1 christos CORE_ADDR pc = get_frame_pc (this_frame); 75 1.1 christos 76 1.1 christos if (alphaobsd_sigtramp_offset (gdbarch, pc) < 3 * ALPHA_INSN_SIZE) 77 1.1 christos { 78 1.1 christos /* On entry, a pointer the `struct sigcontext' is passed in %a2. */ 79 1.1 christos return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM + 2); 80 1.1 christos } 81 1.1 christos else if (alphaobsd_sigtramp_offset (gdbarch, pc) < 4 * ALPHA_INSN_SIZE) 82 1.1 christos { 83 1.1 christos /* It is stored on the stack Before calling the signal handler. */ 84 1.1 christos CORE_ADDR sp; 85 1.1 christos sp = get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM); 86 1.1 christos return get_frame_memory_unsigned (this_frame, sp, 8); 87 1.1 christos } 88 1.1 christos else 89 1.1 christos { 90 1.1 christos /* It is reloaded into %a0 for the sigreturn(2) call. */ 91 1.1 christos return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM); 92 1.1 christos } 93 1.1 christos } 94 1.1 christos 95 1.1 christos 97 1.1 christos static void 98 1.1 christos alphaobsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) 99 1.1.1.4 christos { 100 1.1 christos alpha_gdbarch_tdep *tdep = gdbarch_tdep<alpha_gdbarch_tdep> (gdbarch); 101 1.1 christos 102 1.1 christos /* Hook into the DWARF CFI frame unwinder. */ 103 1.1 christos alpha_dwarf2_init_abi (info, gdbarch); 104 1.1 christos 105 1.1 christos /* Hook into the MDEBUG frame unwinder. */ 106 1.1 christos alpha_mdebug_init_abi (info, gdbarch); 107 1.1 christos 108 1.1 christos /* OpenBSD/alpha 3.0 and earlier does not provide single step 109 1.1 christos support via ptrace(2); use software single-stepping for now. */ 110 1.1 christos set_gdbarch_software_single_step (gdbarch, alpha_software_single_step); 111 1.1 christos 112 1.1 christos /* OpenBSD/alpha has SVR4-style shared libraries. */ 113 1.1 christos set_solib_svr4_fetch_link_map_offsets 114 1.1 christos (gdbarch, svr4_lp64_fetch_link_map_offsets); 115 1.1 christos set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver); 116 1.1 christos 117 1.1 christos tdep->dynamic_sigtramp_offset = alphaobsd_sigtramp_offset; 118 1.1 christos tdep->pc_in_sigtramp = alphaobsd_pc_in_sigtramp; 119 1.1 christos tdep->sigcontext_addr = alphaobsd_sigcontext_addr; 120 1.1 christos 121 1.1 christos tdep->jb_pc = 2; 122 1.1 christos tdep->jb_elt_size = 8; 123 1.1 christos 124 1.1 christos set_gdbarch_iterate_over_regset_sections 125 1.1 christos (gdbarch, alphanbsd_iterate_over_regset_sections); 126 1.1 christos } 127 1.1 christos 128 1.1.1.3 christos 130 1.1.1.3 christos void _initialize_alphaobsd_tdep (); 131 1.1 christos void 132 1.1 christos _initialize_alphaobsd_tdep () 133 1.1.1.4 christos { 134 1.1 christos gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_OPENBSD, 135 alphaobsd_init_abi); 136 } 137