windows-nat: Don't change current_event.dwThreadId in handle_output_debug_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,
f962539a
AA
108 m68kbsd_supply_gregset,
109 NULL,
110 REGSET_VARIABLE_SIZE
8f2d3ea0
MK
111};
112
3ca7dae4 113static const struct regset m68kbsd_fpregset =
8f2d3ea0
MK
114{
115 NULL,
116 m68kbsd_supply_fpregset
117};
118
022c98ab 119/* Iterate over core file register note sections. */
8f2d3ea0 120
022c98ab
AA
121static void
122m68kbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
123 iterate_over_regset_sections_cb *cb,
124 void *cb_data,
125 const struct regcache *regcache)
8f2d3ea0 126{
022c98ab
AA
127 cb (".reg", M68KBSD_SIZEOF_GREGS, &m68kbsd_gregset, NULL, cb_data);
128 cb (".reg2", M68KBSD_SIZEOF_FPREGS, &m68kbsd_fpregset, NULL, cb_data);
8f2d3ea0 129}
059cb7d2
MK
130\f
131
132/* Signal trampolines. */
133
134static void
135m68kobsd_sigtramp_cache_init (const struct tramp_frame *self,
5366653e 136 struct frame_info *this_frame,
059cb7d2
MK
137 struct trad_frame_cache *this_cache,
138 CORE_ADDR func)
139{
140 CORE_ADDR addr, base, pc;
141 int regnum;
142
5366653e 143 base = get_frame_register_unsigned (this_frame, M68K_SP_REGNUM);
059cb7d2
MK
144
145 /* The 'addql #4,%sp' instruction at offset 8 adjusts the stack
146 pointer. Adjust the frame base accordingly. */
5366653e 147 pc = get_frame_register_unsigned (this_frame, M68K_PC_REGNUM);
059cb7d2
MK
148 if ((pc - func) > 8)
149 base -= 4;
150
151 /* Get frame pointer, stack pointer, program counter and processor
152 state from `struct sigcontext'. */
5366653e 153 addr = get_frame_memory_unsigned (this_frame, base + 8, 4);
059cb7d2
MK
154 trad_frame_set_reg_addr (this_cache, M68K_FP_REGNUM, addr + 8);
155 trad_frame_set_reg_addr (this_cache, M68K_SP_REGNUM, addr + 12);
156 trad_frame_set_reg_addr (this_cache, M68K_PC_REGNUM, addr + 20);
157 trad_frame_set_reg_addr (this_cache, M68K_PS_REGNUM, addr + 24);
158
159 /* The sc_ap member of `struct sigcontext' points to additional
160 hardware state. Here we find the missing registers. */
5366653e 161 addr = get_frame_memory_unsigned (this_frame, addr + 16, 4) + 4;
059cb7d2
MK
162 for (regnum = M68K_D0_REGNUM; regnum < M68K_FP_REGNUM; regnum++, addr += 4)
163 trad_frame_set_reg_addr (this_cache, regnum, addr);
164
165 /* Construct the frame ID using the function start. */
166 trad_frame_set_id (this_cache, frame_id_build (base, func));
167}
168
169static const struct tramp_frame m68kobsd_sigtramp = {
170 SIGTRAMP_FRAME,
171 2,
172 {
173 { 0x206f, -1 }, { 0x000c, -1}, /* moveal %sp@(12),%a0 */
174 { 0x4e90, -1 }, /* jsr %a0@ */
175 { 0x588f, -1 }, /* addql #4,%sp */
176 { 0x4e41, -1 }, /* trap #1 */
177 { 0x2f40, -1 }, { 0x0004, -1 }, /* moveal %d0,%sp@(4) */
178 { 0x7001, -1 }, /* moveq #SYS_exit,%d0 */
179 { 0x4e40, -1 }, /* trap #0 */
180 { TRAMP_SENTINEL_INSN, -1 }
181 },
182 m68kobsd_sigtramp_cache_init
183};
184\f
8f2d3ea0
MK
185
186static void
187m68kbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
188{
189 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
190
191 tdep->jb_pc = 5;
192 tdep->jb_elt_size = 4;
193
9418f048
UW
194 set_gdbarch_decr_pc_after_break (gdbarch, 2);
195
022c98ab
AA
196 set_gdbarch_iterate_over_regset_sections
197 (gdbarch, m68kbsd_iterate_over_regset_sections);
8f2d3ea0
MK
198}
199
200/* OpenBSD and NetBSD a.out. */
201
202static void
203m68kbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
204{
205 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
206
207 m68kbsd_init_abi (info, gdbarch);
208
209 tdep->struct_return = reg_struct_return;
059cb7d2
MK
210
211 tramp_frame_prepend_unwinder (gdbarch, &m68kobsd_sigtramp);
8f2d3ea0
MK
212}
213
214/* NetBSD ELF. */
215
216static void
217m68kbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
218{
219 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
220
221 m68kbsd_init_abi (info, gdbarch);
222
5ab5aa0f
MK
223 /* NetBSD ELF uses the SVR4 ABI. */
224 m68k_svr4_init_abi (info, gdbarch);
8f2d3ea0
MK
225 tdep->struct_return = pcc_struct_return;
226
227 /* NetBSD ELF uses SVR4-style shared libraries. */
8f2d3ea0
MK
228 set_solib_svr4_fetch_link_map_offsets
229 (gdbarch, svr4_ilp32_fetch_link_map_offsets);
230}
231\f
232
233static enum gdb_osabi
234m68kbsd_aout_osabi_sniffer (bfd *abfd)
235{
236 if (strcmp (bfd_get_target (abfd), "a.out-m68k-netbsd") == 0
237 || strcmp (bfd_get_target (abfd), "a.out-m68k4k-netbsd") == 0)
238 return GDB_OSABI_NETBSD_AOUT;
239
240 return GDB_OSABI_UNKNOWN;
241}
242
243static enum gdb_osabi
244m68kbsd_core_osabi_sniffer (bfd *abfd)
245{
246 if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
247 return GDB_OSABI_NETBSD_AOUT;
248
249 return GDB_OSABI_UNKNOWN;
250}
251\f
252
253/* Provide a prototype to silence -Wmissing-prototypes. */
254void _initialize_m68kbsd_tdep (void);
255
256void
257_initialize_m68kbsd_tdep (void)
258{
259 gdbarch_register_osabi_sniffer (bfd_arch_m68k, bfd_target_aout_flavour,
260 m68kbsd_aout_osabi_sniffer);
261
262 /* BFD doesn't set a flavour for NetBSD style a.out core files. */
263 gdbarch_register_osabi_sniffer (bfd_arch_m68k, bfd_target_unknown_flavour,
264 m68kbsd_core_osabi_sniffer);
265
266 gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_NETBSD_AOUT,
267 m68kbsd_aout_init_abi);
268 gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_NETBSD_ELF,
269 m68kbsd_elf_init_abi);
270}
This page took 0.979435 seconds and 4 git commands to generate.