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