1 1.1 christos /* Target-dependent code for OpenBSD/mips64. 2 1.1 christos 3 1.1.1.5 christos Copyright (C) 2004-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 "gdbtypes.h" 21 1.1 christos #include "osabi.h" 22 1.1 christos #include "regcache.h" 23 1.1 christos #include "regset.h" 24 1.1 christos #include "trad-frame.h" 25 1.1 christos #include "tramp-frame.h" 26 1.1 christos 27 1.1 christos #include "obsd-tdep.h" 28 1.1 christos #include "mips-tdep.h" 29 1.1 christos #include "solib-svr4.h" 30 1.1 christos 31 1.1 christos #define MIPS64OBSD_NUM_REGS 73 32 1.1 christos 33 1.1 christos /* Core file support. */ 34 1.1 christos 35 1.1 christos /* Supply register REGNUM from the buffer specified by GREGS and LEN 36 1.1 christos in the general-purpose register set REGSET to register cache 37 1.1 christos REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ 38 1.1 christos 39 1.1 christos static void 40 1.1 christos mips64obsd_supply_gregset (const struct regset *regset, 41 1.1 christos struct regcache *regcache, int regnum, 42 1.1 christos const void *gregs, size_t len) 43 1.1 christos { 44 1.1 christos const char *regs = (const char *) gregs; 45 1.1 christos int i; 46 1.1 christos 47 1.1 christos for (i = 0; i < MIPS64OBSD_NUM_REGS; i++) 48 1.1 christos { 49 1.1 christos if (regnum == i || regnum == -1) 50 1.1.1.2 christos regcache->raw_supply (i, regs + i * 8); 51 1.1 christos } 52 1.1 christos } 53 1.1 christos 54 1.1 christos /* OpenBSD/mips64 register set. */ 55 1.1 christos 56 1.1 christos static const struct regset mips64obsd_gregset = 57 1.1 christos { 58 1.1 christos NULL, 59 1.1 christos mips64obsd_supply_gregset 60 1.1 christos }; 61 1.1 christos 62 1.1 christos /* Iterate over core file register note sections. */ 63 1.1 christos 64 1.1 christos static void 65 1.1 christos mips64obsd_iterate_over_regset_sections (struct gdbarch *gdbarch, 66 1.1 christos iterate_over_regset_sections_cb *cb, 67 1.1 christos void *cb_data, 68 1.1 christos const struct regcache *regcache) 69 1.1 christos { 70 1.1.1.2 christos cb (".reg", MIPS64OBSD_NUM_REGS * 8, MIPS64OBSD_NUM_REGS * 8, 71 1.1.1.2 christos &mips64obsd_gregset, NULL, cb_data); 72 1.1 christos } 73 1.1 christos 74 1.1 christos 76 1.1 christos /* Signal trampolines. */ 77 1.1 christos 78 1.1 christos static void 79 1.1.1.5 christos mips64obsd_sigframe_init (const struct tramp_frame *self, 80 1.1 christos const frame_info_ptr &this_frame, 81 1.1 christos struct trad_frame_cache *cache, 82 1.1 christos CORE_ADDR func) 83 1.1 christos { 84 1.1 christos struct gdbarch *gdbarch = get_frame_arch (this_frame); 85 1.1 christos CORE_ADDR sp, sigcontext_addr, addr; 86 1.1 christos int regnum; 87 1.1 christos 88 1.1 christos /* We find the appropriate instance of `struct sigcontext' at a 89 1.1 christos fixed offset in the signal frame. */ 90 1.1 christos sp = get_frame_register_signed (this_frame, 91 1.1 christos MIPS_SP_REGNUM + gdbarch_num_regs (gdbarch)); 92 1.1 christos sigcontext_addr = sp + 32; 93 1.1 christos 94 1.1 christos /* PC. */ 95 1.1 christos regnum = mips_regnum (gdbarch)->pc; 96 1.1 christos trad_frame_set_reg_addr (cache, 97 1.1 christos regnum + gdbarch_num_regs (gdbarch), 98 1.1 christos sigcontext_addr + 16); 99 1.1 christos 100 1.1 christos /* GPRs. */ 101 1.1 christos for (regnum = MIPS_AT_REGNUM, addr = sigcontext_addr + 32; 102 1.1 christos regnum <= MIPS_RA_REGNUM; regnum++, addr += 8) 103 1.1 christos trad_frame_set_reg_addr (cache, 104 1.1 christos regnum + gdbarch_num_regs (gdbarch), 105 1.1 christos addr); 106 1.1 christos 107 1.1 christos /* HI and LO. */ 108 1.1 christos regnum = mips_regnum (gdbarch)->lo; 109 1.1 christos trad_frame_set_reg_addr (cache, 110 1.1 christos regnum + gdbarch_num_regs (gdbarch), 111 1.1 christos sigcontext_addr + 280); 112 1.1 christos regnum = mips_regnum (gdbarch)->hi; 113 1.1 christos trad_frame_set_reg_addr (cache, 114 1.1 christos regnum + gdbarch_num_regs (gdbarch), 115 1.1 christos sigcontext_addr + 288); 116 1.1 christos 117 1.1 christos /* TODO: Handle the floating-point registers. */ 118 1.1 christos 119 1.1 christos trad_frame_set_id (cache, frame_id_build (sp, func)); 120 1.1 christos } 121 1.1 christos 122 1.1 christos static const struct tramp_frame mips64obsd_sigframe = 123 1.1 christos { 124 1.1 christos SIGTRAMP_FRAME, 125 1.1 christos MIPS_INSN32_SIZE, 126 1.1.1.2 christos { 127 1.1.1.2 christos { 0x67a40020, ULONGEST_MAX }, /* daddiu a0,sp,32 */ 128 1.1.1.2 christos { 0x24020067, ULONGEST_MAX }, /* li v0,103 */ 129 1.1.1.2 christos { 0x0000000c, ULONGEST_MAX }, /* syscall */ 130 1.1.1.2 christos { 0x0000000d, ULONGEST_MAX }, /* break */ 131 1.1 christos { TRAMP_SENTINEL_INSN, ULONGEST_MAX } 132 1.1 christos }, 133 1.1 christos mips64obsd_sigframe_init 134 1.1 christos }; 135 1.1 christos 136 1.1 christos 137 1.1 christos static void 139 1.1 christos mips64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 140 1.1 christos { 141 1.1 christos /* OpenBSD/mips64 only supports the n64 ABI, but the braindamaged 142 1.1 christos way GDB works, forces us to pretend we can handle them all. */ 143 1.1 christos 144 1.1 christos set_gdbarch_iterate_over_regset_sections 145 1.1 christos (gdbarch, mips64obsd_iterate_over_regset_sections); 146 1.1 christos 147 1.1 christos tramp_frame_prepend_unwinder (gdbarch, &mips64obsd_sigframe); 148 1.1.1.4 christos 149 1.1 christos set_gdbarch_long_double_bit (gdbarch, 128); 150 1.1 christos set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad); 151 1.1 christos 152 1.1 christos obsd_init_abi(info, gdbarch); 153 1.1 christos 154 1.1 christos /* OpenBSD/mips64 has SVR4-style shared libraries. */ 155 1.1 christos set_solib_svr4_fetch_link_map_offsets 156 1.1 christos (gdbarch, svr4_lp64_fetch_link_map_offsets); 157 1.1.1.3 christos } 158 1.1 christos 159 1.1.1.3 christos void _initialize_mips64obsd_tdep (); 160 1.1 christos void 161 1.1 christos _initialize_mips64obsd_tdep () 162 1.1 christos { 163 1.1 christos gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_OPENBSD, 164 mips64obsd_init_abi); 165 } 166