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