mips64-obsd-tdep.c revision 1.1.1.5 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