GDB (xrefs)
/tmp/gdb-7.10/gdb/m68kbsd-tdep.c
Go to the documentation of this file.
1 /* Target-dependent code for Motorola 68000 BSD's.
2 
3  Copyright (C) 2004-2015 Free Software Foundation, Inc.
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
9  the Free Software Foundation; either version 3 of the License, or
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
18  along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 
20 #include "defs.h"
21 #include "arch-utils.h"
22 #include "frame.h"
23 #include "osabi.h"
24 #include "regcache.h"
25 #include "regset.h"
26 #include "trad-frame.h"
27 #include "tramp-frame.h"
28 #include "gdbtypes.h"
29 
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 
41 int
43 {
44  int fp_len = TYPE_LENGTH (gdbarch_register_type (gdbarch, regnum));
45 
46  if (regnum >= M68K_FPC_REGNUM)
47  return 8 * fp_len + (regnum - M68K_FPC_REGNUM) * 4;
48 
49  return (regnum - M68K_FP0_REGNUM) * fp_len;
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 
56 static void
58  struct regcache *regcache,
59  int regnum, const void *fpregs, size_t len)
60 {
61  struct gdbarch *gdbarch = get_regcache_arch (regcache);
62  const gdb_byte *regs = fpregs;
63  int i;
64 
66 
67  for (i = M68K_FP0_REGNUM; i <= M68K_PC_REGNUM; i++)
68  {
69  if (regnum == i || regnum == -1)
70  regcache_raw_supply (regcache, i,
71  regs + m68kbsd_fpreg_offset (gdbarch, i));
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 
79 static void
81  struct regcache *regcache,
82  int regnum, const void *gregs, size_t len)
83 {
84  const gdb_byte *regs = gregs;
85  int i;
86 
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 
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 
105 static const struct regset m68kbsd_gregset =
106 {
107  NULL,
109  NULL,
111 };
112 
113 static const struct regset m68kbsd_fpregset =
114 {
115  NULL,
117 };
118 
119 /* Iterate over core file register note sections. */
120 
121 static void
124  void *cb_data,
125  const struct regcache *regcache)
126 {
127  cb (".reg", M68KBSD_SIZEOF_GREGS, &m68kbsd_gregset, NULL, cb_data);
128  cb (".reg2", M68KBSD_SIZEOF_FPREGS, &m68kbsd_fpregset, NULL, cb_data);
129 }
130 
131 
132 /* Signal trampolines. */
133 
134 static void
136  struct frame_info *this_frame,
137  struct trad_frame_cache *this_cache,
138  CORE_ADDR func)
139 {
140  CORE_ADDR addr, base, pc;
141  int regnum;
142 
143  base = get_frame_register_unsigned (this_frame, M68K_SP_REGNUM);
144 
145  /* The 'addql #4,%sp' instruction at offset 8 adjusts the stack
146  pointer. Adjust the frame base accordingly. */
147  pc = get_frame_register_unsigned (this_frame, M68K_PC_REGNUM);
148  if ((pc - func) > 8)
149  base -= 4;
150 
151  /* Get frame pointer, stack pointer, program counter and processor
152  state from `struct sigcontext'. */
153  addr = get_frame_memory_unsigned (this_frame, base + 8, 4);
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. */
161  addr = get_frame_memory_unsigned (this_frame, addr + 16, 4) + 4;
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 
169 static const struct tramp_frame m68kobsd_sigtramp = {
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  },
183 };
184 
185 
186 static void
188 {
189  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
190 
191  tdep->jb_pc = 5;
192  tdep->jb_elt_size = 4;
193 
194  set_gdbarch_decr_pc_after_break (gdbarch, 2);
195 
198 }
199 
200 /* OpenBSD and NetBSD a.out. */
201 
202 static void
204 {
205  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
206 
207  m68kbsd_init_abi (info, gdbarch);
208 
210 
211  tramp_frame_prepend_unwinder (gdbarch, &m68kobsd_sigtramp);
212 }
213 
214 /* NetBSD ELF. */
215 
216 static void
218 {
219  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
220 
221  m68kbsd_init_abi (info, gdbarch);
222 
223  /* NetBSD ELF uses the SVR4 ABI. */
224  m68k_svr4_init_abi (info, gdbarch);
226 
227  /* NetBSD ELF uses SVR4-style shared libraries. */
230 }
231 
232 
233 static enum gdb_osabi
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 
243 static enum gdb_osabi
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 
252 
253 /* Provide a prototype to silence -Wmissing-prototypes. */
254 void _initialize_m68kbsd_tdep (void);
255 
256 void
258 {
259  gdbarch_register_osabi_sniffer (bfd_arch_m68k, bfd_target_aout_flavour,
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,
265 
268  gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_NETBSD_ELF,
270 }
void m68k_svr4_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
Definition: m68k-tdep.c:1065
void trad_frame_set_reg_addr(struct trad_frame_cache *this_trad_cache, int regnum, CORE_ADDR addr)
Definition: trad-frame.c:119
struct frame_id frame_id_build(CORE_ADDR stack_addr, CORE_ADDR code_addr)
Definition: frame.c:554
static void m68kbsd_elf_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
Definition: m68kbsd-tdep.c:217
static enum gdb_osabi m68kbsd_core_osabi_sniffer(bfd *abfd)
Definition: m68kbsd-tdep.c:244
bfd_vma CORE_ADDR
Definition: common-types.h:41
#define TRAMP_SENTINEL_INSN
Definition: tramp-frame.h:44
#define M68KBSD_SIZEOF_FPREGS
Definition: m68kbsd-tdep.c:39
struct gdbarch * get_regcache_arch(const struct regcache *regcache)
Definition: regcache.c:297
void(* func)(char *)
void trad_frame_set_id(struct trad_frame_cache *this_trad_cache, struct frame_id this_id)
Definition: trad-frame.c:164
void gdbarch_register_osabi_sniffer(enum bfd_architecture arch, enum bfd_flavour flavour, enum gdb_osabi(*sniffer_fn)(bfd *))
Definition: osabi.c:225
struct link_map_offsets * svr4_ilp32_fetch_link_map_offsets(void)
Definition: solib-svr4.c:3149
ULONGEST get_frame_memory_unsigned(struct frame_info *this_frame, CORE_ADDR addr, int len)
Definition: frame.c:2515
struct gdbarch_tdep * gdbarch_tdep(struct gdbarch *gdbarch)
Definition: gdbarch.c:1402
static enum gdb_osabi m68kbsd_aout_osabi_sniffer(bfd *abfd)
Definition: m68kbsd-tdep.c:234
Definition: regset.h:34
static void m68kobsd_sigtramp_cache_init(const struct tramp_frame *self, struct frame_info *this_frame, struct trad_frame_cache *this_cache, CORE_ADDR func)
Definition: m68kbsd-tdep.c:135
static void m68kbsd_supply_gregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t len)
Definition: m68kbsd-tdep.c:80
enum struct_return struct_return
Definition: arm-tdep.h:197
void set_gdbarch_decr_pc_after_break(struct gdbarch *gdbarch, CORE_ADDR decr_pc_after_break)
Definition: gdbarch.c:2764
void set_solib_svr4_fetch_link_map_offsets(struct gdbarch *gdbarch, struct link_map_offsets *(*flmo)(void))
Definition: solib-svr4.c:3108
#define REGSET_VARIABLE_SIZE
Definition: regset.h:52
#define gdb_assert(expr)
Definition: gdb_assert.h:33
void _initialize_m68kbsd_tdep(void)
Definition: m68kbsd-tdep.c:257
static void m68kbsd_supply_fpregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *fpregs, size_t len)
Definition: m68kbsd-tdep.c:57
int regnum
Definition: aarch64-tdep.c:69
void( iterate_over_regset_sections_cb)(const char *sect_name, int size, const struct regset *regset, const char *human_name, void *cb_data)
Definition: gdbarch.h:98
ULONGEST get_frame_register_unsigned(struct frame_info *frame, int regnum)
Definition: frame.c:1194
size_t jb_elt_size
Definition: aarch64-tdep.h:83
struct type * gdbarch_register_type(struct gdbarch *gdbarch, int reg_nr)
Definition: gdbarch.c:2141
static void m68kbsd_iterate_over_regset_sections(struct gdbarch *gdbarch, iterate_over_regset_sections_cb *cb, void *cb_data, const struct regcache *regcache)
Definition: m68kbsd-tdep.c:122
bfd_byte gdb_byte
Definition: common-types.h:38
static void m68kbsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
Definition: m68kbsd-tdep.c:187
int m68kbsd_fpreg_offset(struct gdbarch *gdbarch, int regnum)
Definition: m68kbsd-tdep.c:42
void tramp_frame_prepend_unwinder(struct gdbarch *gdbarch, const struct tramp_frame *tramp_frame)
Definition: tramp-frame.c:145
void regcache_raw_supply(struct regcache *regcache, int regnum, const void *buf)
Definition: regcache.c:1041
#define M68KBSD_SIZEOF_GREGS
Definition: m68kbsd-tdep.c:36
#define TYPE_LENGTH(thistype)
Definition: gdbtypes.h:1237
void set_gdbarch_iterate_over_regset_sections(struct gdbarch *gdbarch, gdbarch_iterate_over_regset_sections_ftype iterate_over_regset_sections)
Definition: gdbarch.c:3398
static void m68kbsd_aout_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
Definition: m68kbsd-tdep.c:203
void gdbarch_register_osabi(enum bfd_architecture arch, unsigned long machine, enum gdb_osabi osabi, void(*init_osabi)(struct gdbarch_info, struct gdbarch *))
Definition: osabi.c:148
gdb_osabi
Definition: defs.h:540
const ULONGEST const LONGEST len
Definition: target.h:309