Free results of varobj_get_type and type_to_string
[deliverable/binutils-gdb.git] / gdb / m68kbsd-tdep.c
CommitLineData
8f2d3ea0
MK
1/* Target-dependent code for Motorola 68000 BSD's.
2
32d0add0 3 Copyright (C) 2004-2015 Free Software Foundation, Inc.
8f2d3ea0
MK
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
8f2d3ea0
MK
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
8f2d3ea0
MK
19
20#include "defs.h"
21#include "arch-utils.h"
059cb7d2 22#include "frame.h"
8f2d3ea0
MK
23#include "osabi.h"
24#include "regcache.h"
25#include "regset.h"
059cb7d2
MK
26#include "trad-frame.h"
27#include "tramp-frame.h"
ec20a626 28#include "gdbtypes.h"
8f2d3ea0 29
8f2d3ea0
MK
30#include "m68k-tdep.h"
31#include "solib-svr4.h"
32
33/* Core file support. */
34
35/* Sizeof `struct reg' in <machine/reg.h>. */
36#define M68KBSD_SIZEOF_GREGS (18 * 4)
37
38/* Sizeof `struct fpreg' in <machine/reg.h. */
39#define M68KBSD_SIZEOF_FPREGS (((8 * 3) + 3) * 4)
40
41int
6ba38425 42m68kbsd_fpreg_offset (struct gdbarch *gdbarch, int regnum)
8f2d3ea0 43{
6ba38425 44 int fp_len = TYPE_LENGTH (gdbarch_register_type (gdbarch, regnum));
8ed86d01 45
8f2d3ea0 46 if (regnum >= M68K_FPC_REGNUM)
8ed86d01 47 return 8 * fp_len + (regnum - M68K_FPC_REGNUM) * 4;
8f2d3ea0 48
8ed86d01 49 return (regnum - M68K_FP0_REGNUM) * fp_len;
8f2d3ea0
MK
50}
51
52/* Supply register REGNUM from the buffer specified by FPREGS and LEN
53 in the floating-point register set REGSET to register cache
54 REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
55
56static void
57m68kbsd_supply_fpregset (const struct regset *regset,
58 struct regcache *regcache,
59 int regnum, const void *fpregs, size_t len)
60{
6ba38425 61 struct gdbarch *gdbarch = get_regcache_arch (regcache);
f5cf7aa1 62 const gdb_byte *regs = fpregs;
8f2d3ea0
MK
63 int i;
64
65 gdb_assert (len >= M68KBSD_SIZEOF_FPREGS);
66
67 for (i = M68K_FP0_REGNUM; i <= M68K_PC_REGNUM; i++)
68 {
69 if (regnum == i || regnum == -1)
6ba38425
UW
70 regcache_raw_supply (regcache, i,
71 regs + m68kbsd_fpreg_offset (gdbarch, i));
8f2d3ea0
MK
72 }
73}
74
75/* Supply register REGNUM from the buffer specified by GREGS and LEN
76 in the general-purpose register set REGSET to register cache
77 REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
78
79static void
80m68kbsd_supply_gregset (const struct regset *regset,
81 struct regcache *regcache,
82 int regnum, const void *gregs, size_t len)
83{
f5cf7aa1 84 const gdb_byte *regs = gregs;
8f2d3ea0
MK
85 int i;
86
87 gdb_assert (len >= M68KBSD_SIZEOF_GREGS);
88
89 for (i = M68K_D0_REGNUM; i <= M68K_PC_REGNUM; i++)
90 {
91 if (regnum == i || regnum == -1)
92 regcache_raw_supply (regcache, i, regs + i * 4);
93 }
94
95 if (len >= M68KBSD_SIZEOF_GREGS + M68KBSD_SIZEOF_FPREGS)
96 {
97 regs += M68KBSD_SIZEOF_GREGS;
98 len -= M68KBSD_SIZEOF_GREGS;
99 m68kbsd_supply_fpregset (regset, regcache, regnum, regs, len);
100 }
101}
102
103/* Motorola 68000 register sets. */
104
3ca7dae4 105static const struct regset m68kbsd_gregset =
8f2d3ea0
MK
106{
107 NULL,
108 m68kbsd_supply_gregset
109};
110
3ca7dae4 111static const struct regset m68kbsd_fpregset =
8f2d3ea0
MK
112{
113 NULL,
114 m68kbsd_supply_fpregset
115};
116
022c98ab 117/* Iterate over core file register note sections. */
8f2d3ea0 118
022c98ab
AA
119static void
120m68kbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
121 iterate_over_regset_sections_cb *cb,
122 void *cb_data,
123 const struct regcache *regcache)
8f2d3ea0 124{
022c98ab
AA
125 cb (".reg", M68KBSD_SIZEOF_GREGS, &m68kbsd_gregset, NULL, cb_data);
126 cb (".reg2", M68KBSD_SIZEOF_FPREGS, &m68kbsd_fpregset, NULL, cb_data);
8f2d3ea0 127}
059cb7d2
MK
128\f
129
130/* Signal trampolines. */
131
132static void
133m68kobsd_sigtramp_cache_init (const struct tramp_frame *self,
5366653e 134 struct frame_info *this_frame,
059cb7d2
MK
135 struct trad_frame_cache *this_cache,
136 CORE_ADDR func)
137{
138 CORE_ADDR addr, base, pc;
139 int regnum;
140
5366653e 141 base = get_frame_register_unsigned (this_frame, M68K_SP_REGNUM);
059cb7d2
MK
142
143 /* The 'addql #4,%sp' instruction at offset 8 adjusts the stack
144 pointer. Adjust the frame base accordingly. */
5366653e 145 pc = get_frame_register_unsigned (this_frame, M68K_PC_REGNUM);
059cb7d2
MK
146 if ((pc - func) > 8)
147 base -= 4;
148
149 /* Get frame pointer, stack pointer, program counter and processor
150 state from `struct sigcontext'. */
5366653e 151 addr = get_frame_memory_unsigned (this_frame, base + 8, 4);
059cb7d2
MK
152 trad_frame_set_reg_addr (this_cache, M68K_FP_REGNUM, addr + 8);
153 trad_frame_set_reg_addr (this_cache, M68K_SP_REGNUM, addr + 12);
154 trad_frame_set_reg_addr (this_cache, M68K_PC_REGNUM, addr + 20);
155 trad_frame_set_reg_addr (this_cache, M68K_PS_REGNUM, addr + 24);
156
157 /* The sc_ap member of `struct sigcontext' points to additional
158 hardware state. Here we find the missing registers. */
5366653e 159 addr = get_frame_memory_unsigned (this_frame, addr + 16, 4) + 4;
059cb7d2
MK
160 for (regnum = M68K_D0_REGNUM; regnum < M68K_FP_REGNUM; regnum++, addr += 4)
161 trad_frame_set_reg_addr (this_cache, regnum, addr);
162
163 /* Construct the frame ID using the function start. */
164 trad_frame_set_id (this_cache, frame_id_build (base, func));
165}
166
167static const struct tramp_frame m68kobsd_sigtramp = {
168 SIGTRAMP_FRAME,
169 2,
170 {
171 { 0x206f, -1 }, { 0x000c, -1}, /* moveal %sp@(12),%a0 */
172 { 0x4e90, -1 }, /* jsr %a0@ */
173 { 0x588f, -1 }, /* addql #4,%sp */
174 { 0x4e41, -1 }, /* trap #1 */
175 { 0x2f40, -1 }, { 0x0004, -1 }, /* moveal %d0,%sp@(4) */
176 { 0x7001, -1 }, /* moveq #SYS_exit,%d0 */
177 { 0x4e40, -1 }, /* trap #0 */
178 { TRAMP_SENTINEL_INSN, -1 }
179 },
180 m68kobsd_sigtramp_cache_init
181};
182\f
8f2d3ea0
MK
183
184static void
185m68kbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
186{
187 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
188
189 tdep->jb_pc = 5;
190 tdep->jb_elt_size = 4;
191
9418f048
UW
192 set_gdbarch_decr_pc_after_break (gdbarch, 2);
193
022c98ab
AA
194 set_gdbarch_iterate_over_regset_sections
195 (gdbarch, m68kbsd_iterate_over_regset_sections);
8f2d3ea0
MK
196}
197
198/* OpenBSD and NetBSD a.out. */
199
200static void
201m68kbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
202{
203 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
204
205 m68kbsd_init_abi (info, gdbarch);
206
207 tdep->struct_return = reg_struct_return;
059cb7d2
MK
208
209 tramp_frame_prepend_unwinder (gdbarch, &m68kobsd_sigtramp);
8f2d3ea0
MK
210}
211
212/* NetBSD ELF. */
213
214static void
215m68kbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
216{
217 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
218
219 m68kbsd_init_abi (info, gdbarch);
220
5ab5aa0f
MK
221 /* NetBSD ELF uses the SVR4 ABI. */
222 m68k_svr4_init_abi (info, gdbarch);
8f2d3ea0
MK
223 tdep->struct_return = pcc_struct_return;
224
225 /* NetBSD ELF uses SVR4-style shared libraries. */
8f2d3ea0
MK
226 set_solib_svr4_fetch_link_map_offsets
227 (gdbarch, svr4_ilp32_fetch_link_map_offsets);
228}
229\f
230
231static enum gdb_osabi
232m68kbsd_aout_osabi_sniffer (bfd *abfd)
233{
234 if (strcmp (bfd_get_target (abfd), "a.out-m68k-netbsd") == 0
235 || strcmp (bfd_get_target (abfd), "a.out-m68k4k-netbsd") == 0)
236 return GDB_OSABI_NETBSD_AOUT;
237
238 return GDB_OSABI_UNKNOWN;
239}
240
241static enum gdb_osabi
242m68kbsd_core_osabi_sniffer (bfd *abfd)
243{
244 if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
245 return GDB_OSABI_NETBSD_AOUT;
246
247 return GDB_OSABI_UNKNOWN;
248}
249\f
250
251/* Provide a prototype to silence -Wmissing-prototypes. */
252void _initialize_m68kbsd_tdep (void);
253
254void
255_initialize_m68kbsd_tdep (void)
256{
257 gdbarch_register_osabi_sniffer (bfd_arch_m68k, bfd_target_aout_flavour,
258 m68kbsd_aout_osabi_sniffer);
259
260 /* BFD doesn't set a flavour for NetBSD style a.out core files. */
261 gdbarch_register_osabi_sniffer (bfd_arch_m68k, bfd_target_unknown_flavour,
262 m68kbsd_core_osabi_sniffer);
263
264 gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_NETBSD_AOUT,
265 m68kbsd_aout_init_abi);
266 gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_NETBSD_ELF,
267 m68kbsd_elf_init_abi);
268}
This page took 0.95017 seconds and 4 git commands to generate.