m68k-bsd-tdep.c revision 1.1.1.4 1 1.1 christos /* Target-dependent code for Motorola 68000 BSD's.
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 "arch-utils.h"
22 1.1 christos #include "frame.h"
23 1.1 christos #include "osabi.h"
24 1.1 christos #include "regcache.h"
25 1.1 christos #include "regset.h"
26 1.1 christos #include "trad-frame.h"
27 1.1 christos #include "tramp-frame.h"
28 1.1 christos #include "gdbtypes.h"
29 1.1 christos
30 1.1 christos #include "m68k-tdep.h"
31 1.1.1.4 christos #include "netbsd-tdep.h"
32 1.1 christos #include "solib-svr4.h"
33 1.1 christos
34 1.1 christos /* Core file support. */
35 1.1 christos
36 1.1 christos /* Sizeof `struct reg' in <machine/reg.h>. */
37 1.1 christos #define M68KBSD_SIZEOF_GREGS (18 * 4)
38 1.1 christos
39 1.1 christos /* Sizeof `struct fpreg' in <machine/reg.h. */
40 1.1 christos #define M68KBSD_SIZEOF_FPREGS (((8 * 3) + 3) * 4)
41 1.1 christos
42 1.1 christos int
43 1.1 christos m68kbsd_fpreg_offset (struct gdbarch *gdbarch, int regnum)
44 1.1 christos {
45 1.1.1.4 christos int fp_len = gdbarch_register_type (gdbarch, regnum)->length ();
46 1.1 christos
47 1.1 christos if (regnum >= M68K_FPC_REGNUM)
48 1.1 christos return 8 * fp_len + (regnum - M68K_FPC_REGNUM) * 4;
49 1.1 christos
50 1.1 christos return (regnum - M68K_FP0_REGNUM) * fp_len;
51 1.1 christos }
52 1.1 christos
53 1.1 christos /* Supply register REGNUM from the buffer specified by FPREGS and LEN
54 1.1 christos in the floating-point register set REGSET to register cache
55 1.1 christos REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
56 1.1 christos
57 1.1 christos static void
58 1.1 christos m68kbsd_supply_fpregset (const struct regset *regset,
59 1.1 christos struct regcache *regcache,
60 1.1 christos int regnum, const void *fpregs, size_t len)
61 1.1 christos {
62 1.1.1.2 christos struct gdbarch *gdbarch = regcache->arch ();
63 1.1 christos const gdb_byte *regs = (const gdb_byte *) fpregs;
64 1.1 christos int i;
65 1.1 christos
66 1.1 christos gdb_assert (len >= M68KBSD_SIZEOF_FPREGS);
67 1.1 christos
68 1.1 christos for (i = M68K_FP0_REGNUM; i <= M68K_PC_REGNUM; i++)
69 1.1 christos {
70 1.1 christos if (regnum == i || regnum == -1)
71 1.1.1.2 christos regcache->raw_supply (i, regs + m68kbsd_fpreg_offset (gdbarch, i));
72 1.1 christos }
73 1.1 christos }
74 1.1 christos
75 1.1 christos /* Supply register REGNUM from the buffer specified by GREGS and LEN
76 1.1 christos in the general-purpose register set REGSET to register cache
77 1.1 christos REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
78 1.1 christos
79 1.1 christos static void
80 1.1 christos m68kbsd_supply_gregset (const struct regset *regset,
81 1.1 christos struct regcache *regcache,
82 1.1 christos int regnum, const void *gregs, size_t len)
83 1.1 christos {
84 1.1 christos const gdb_byte *regs = (const gdb_byte *) gregs;
85 1.1 christos int i;
86 1.1 christos
87 1.1 christos gdb_assert (len >= M68KBSD_SIZEOF_GREGS);
88 1.1 christos
89 1.1 christos for (i = M68K_D0_REGNUM; i <= M68K_PC_REGNUM; i++)
90 1.1 christos {
91 1.1 christos if (regnum == i || regnum == -1)
92 1.1.1.2 christos regcache->raw_supply (i, regs + i * 4);
93 1.1 christos }
94 1.1 christos
95 1.1 christos if (len >= M68KBSD_SIZEOF_GREGS + M68KBSD_SIZEOF_FPREGS)
96 1.1 christos {
97 1.1 christos regs += M68KBSD_SIZEOF_GREGS;
98 1.1 christos len -= M68KBSD_SIZEOF_GREGS;
99 1.1 christos m68kbsd_supply_fpregset (regset, regcache, regnum, regs, len);
100 1.1 christos }
101 1.1 christos }
102 1.1 christos
103 1.1 christos /* Motorola 68000 register sets. */
104 1.1 christos
105 1.1 christos static const struct regset m68kbsd_gregset =
106 1.1 christos {
107 1.1 christos NULL,
108 1.1 christos m68kbsd_supply_gregset,
109 1.1 christos NULL,
110 1.1 christos REGSET_VARIABLE_SIZE
111 1.1 christos };
112 1.1 christos
113 1.1 christos static const struct regset m68kbsd_fpregset =
114 1.1 christos {
115 1.1 christos NULL,
116 1.1 christos m68kbsd_supply_fpregset
117 1.1 christos };
118 1.1 christos
119 1.1 christos /* Iterate over core file register note sections. */
120 1.1 christos
121 1.1 christos static void
122 1.1 christos m68kbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
123 1.1 christos iterate_over_regset_sections_cb *cb,
124 1.1 christos void *cb_data,
125 1.1 christos const struct regcache *regcache)
126 1.1 christos {
127 1.1.1.2 christos cb (".reg", M68KBSD_SIZEOF_GREGS, M68KBSD_SIZEOF_GREGS, &m68kbsd_gregset,
128 1.1.1.2 christos NULL, cb_data);
129 1.1.1.2 christos cb (".reg2", M68KBSD_SIZEOF_FPREGS, M68KBSD_SIZEOF_FPREGS, &m68kbsd_fpregset,
130 1.1.1.2 christos NULL, cb_data);
131 1.1 christos }
132 1.1 christos
133 1.1 christos
135 1.1 christos static void
136 1.1 christos m68kbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
137 1.1.1.4 christos {
138 1.1.1.4 christos m68k_gdbarch_tdep *tdep = gdbarch_tdep<m68k_gdbarch_tdep> (gdbarch);
139 1.1.1.4 christos
140 1.1 christos nbsd_init_abi (info, gdbarch);
141 1.1 christos
142 1.1 christos tdep->jb_pc = 5;
143 1.1 christos tdep->jb_elt_size = 4;
144 1.1 christos
145 1.1 christos set_gdbarch_decr_pc_after_break (gdbarch, 2);
146 1.1 christos
147 1.1 christos set_gdbarch_iterate_over_regset_sections
148 1.1 christos (gdbarch, m68kbsd_iterate_over_regset_sections);
149 1.1 christos
150 1.1 christos /* NetBSD ELF uses the SVR4 ABI. */
151 1.1 christos m68k_svr4_init_abi (info, gdbarch);
152 1.1 christos tdep->struct_return = pcc_struct_return;
153 1.1 christos
154 1.1 christos /* NetBSD ELF uses SVR4-style shared libraries. */
155 1.1 christos set_solib_svr4_fetch_link_map_offsets
156 1.1 christos (gdbarch, svr4_ilp32_fetch_link_map_offsets);
157 1.1 christos }
158 1.1.1.3 christos
159 1.1 christos void _initialize_m68kbsd_tdep ();
160 1.1.1.3 christos void
161 1.1 christos _initialize_m68kbsd_tdep ()
162 1.1 christos {
163 1.1 christos gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_NETBSD,
164 1.1 christos m68kbsd_init_abi);
165 }
166