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