1b725ae77Skettenis /* Target-dependent code for SuperH running NetBSD, for GDB.
2b725ae77Skettenis Copyright 2002, 2003 Free Software Foundation, Inc.
3b725ae77Skettenis Contributed by Wasabi Systems, Inc.
4b725ae77Skettenis
5b725ae77Skettenis This file is part of GDB.
6b725ae77Skettenis
7b725ae77Skettenis This program is free software; you can redistribute it and/or modify
8b725ae77Skettenis it under the terms of the GNU General Public License as published by
9b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
10b725ae77Skettenis (at your option) any later version.
11b725ae77Skettenis
12b725ae77Skettenis This program is distributed in the hope that it will be useful,
13b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
14b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15b725ae77Skettenis GNU General Public License for more details.
16b725ae77Skettenis
17b725ae77Skettenis You should have received a copy of the GNU General Public License
18b725ae77Skettenis along with this program; if not, write to the Free Software
19b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
20b725ae77Skettenis Boston, MA 02111-1307, USA. */
21b725ae77Skettenis
22b725ae77Skettenis #include "defs.h"
23b725ae77Skettenis #include "gdbcore.h"
24b725ae77Skettenis #include "regcache.h"
25b725ae77Skettenis #include "value.h"
26b725ae77Skettenis #include "osabi.h"
27b725ae77Skettenis
28b725ae77Skettenis #include "solib-svr4.h"
29b725ae77Skettenis
30b725ae77Skettenis #include "nbsd-tdep.h"
31b725ae77Skettenis #include "sh-tdep.h"
32b725ae77Skettenis #include "shnbsd-tdep.h"
33b725ae77Skettenis
34b725ae77Skettenis /* Convert an r0-r15 register number into an offset into a ptrace
35b725ae77Skettenis register structure. */
36b725ae77Skettenis static const int regmap[] =
37b725ae77Skettenis {
38b725ae77Skettenis (20 * 4), /* r0 */
39b725ae77Skettenis (19 * 4), /* r1 */
40b725ae77Skettenis (18 * 4), /* r2 */
41b725ae77Skettenis (17 * 4), /* r3 */
42b725ae77Skettenis (16 * 4), /* r4 */
43b725ae77Skettenis (15 * 4), /* r5 */
44b725ae77Skettenis (14 * 4), /* r6 */
45b725ae77Skettenis (13 * 4), /* r7 */
46b725ae77Skettenis (12 * 4), /* r8 */
47b725ae77Skettenis (11 * 4), /* r9 */
48b725ae77Skettenis (10 * 4), /* r10 */
49b725ae77Skettenis ( 9 * 4), /* r11 */
50b725ae77Skettenis ( 8 * 4), /* r12 */
51b725ae77Skettenis ( 7 * 4), /* r13 */
52b725ae77Skettenis ( 6 * 4), /* r14 */
53b725ae77Skettenis ( 5 * 4), /* r15 */
54b725ae77Skettenis };
55b725ae77Skettenis
56b725ae77Skettenis #define SIZEOF_STRUCT_REG (21 * 4)
57b725ae77Skettenis
58b725ae77Skettenis void
shnbsd_supply_reg(char * regs,int regno)59b725ae77Skettenis shnbsd_supply_reg (char *regs, int regno)
60b725ae77Skettenis {
61b725ae77Skettenis int i;
62b725ae77Skettenis
63b725ae77Skettenis if (regno == PC_REGNUM || regno == -1)
6411efff7fSkettenis regcache_raw_supply (current_regcache, PC_REGNUM, regs + (0 * 4));
65b725ae77Skettenis
66b725ae77Skettenis if (regno == SR_REGNUM || regno == -1)
6711efff7fSkettenis regcache_raw_supply (current_regcache, SR_REGNUM, regs + (1 * 4));
68b725ae77Skettenis
69b725ae77Skettenis if (regno == PR_REGNUM || regno == -1)
7011efff7fSkettenis regcache_raw_supply (current_regcache, PR_REGNUM, regs + (2 * 4));
71b725ae77Skettenis
72b725ae77Skettenis if (regno == MACH_REGNUM || regno == -1)
7311efff7fSkettenis regcache_raw_supply (current_regcache, MACH_REGNUM, regs + (3 * 4));
74b725ae77Skettenis
75b725ae77Skettenis if (regno == MACL_REGNUM || regno == -1)
7611efff7fSkettenis regcache_raw_supply (current_regcache, MACL_REGNUM, regs + (4 * 4));
77b725ae77Skettenis
78b725ae77Skettenis if ((regno >= R0_REGNUM && regno <= (R0_REGNUM + 15)) || regno == -1)
79b725ae77Skettenis {
80b725ae77Skettenis for (i = R0_REGNUM; i <= (R0_REGNUM + 15); i++)
81b725ae77Skettenis if (regno == i || regno == -1)
8211efff7fSkettenis regcache_raw_supply (current_regcache, i,
8311efff7fSkettenis regs + regmap[i - R0_REGNUM]);
84b725ae77Skettenis }
85b725ae77Skettenis }
86b725ae77Skettenis
87b725ae77Skettenis void
shnbsd_fill_reg(char * regs,int regno)88b725ae77Skettenis shnbsd_fill_reg (char *regs, int regno)
89b725ae77Skettenis {
90b725ae77Skettenis int i;
91b725ae77Skettenis
92b725ae77Skettenis if (regno == PC_REGNUM || regno == -1)
9311efff7fSkettenis regcache_raw_collect (current_regcache, PC_REGNUM, regs + (0 * 4));
94b725ae77Skettenis
95b725ae77Skettenis if (regno == SR_REGNUM || regno == -1)
9611efff7fSkettenis regcache_raw_collect (current_regcache, SR_REGNUM, regs + (1 * 4));
97b725ae77Skettenis
98b725ae77Skettenis if (regno == PR_REGNUM || regno == -1)
9911efff7fSkettenis regcache_raw_collect (current_regcache, PR_REGNUM, regs + (2 * 4));
100b725ae77Skettenis
101b725ae77Skettenis if (regno == MACH_REGNUM || regno == -1)
10211efff7fSkettenis regcache_raw_collect (current_regcache, MACH_REGNUM, regs + (3 * 4));
103b725ae77Skettenis
104b725ae77Skettenis if (regno == MACL_REGNUM || regno == -1)
10511efff7fSkettenis regcache_raw_collect (current_regcache, MACL_REGNUM, regs + (4 * 4));
106b725ae77Skettenis
107b725ae77Skettenis if ((regno >= R0_REGNUM && regno <= (R0_REGNUM + 15)) || regno == -1)
108b725ae77Skettenis {
109b725ae77Skettenis for (i = R0_REGNUM; i <= (R0_REGNUM + 15); i++)
110b725ae77Skettenis if (regno == i || regno == -1)
11111efff7fSkettenis regcache_raw_collect (current_regcache, i,
11211efff7fSkettenis regs + regmap[i - R0_REGNUM]);
113b725ae77Skettenis }
114b725ae77Skettenis }
115b725ae77Skettenis
116b725ae77Skettenis static void
fetch_core_registers(char * core_reg_sect,unsigned core_reg_size,int which,CORE_ADDR ignore)117b725ae77Skettenis fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
118b725ae77Skettenis int which, CORE_ADDR ignore)
119b725ae77Skettenis {
120b725ae77Skettenis /* We get everything from the .reg section. */
121b725ae77Skettenis if (which != 0)
122b725ae77Skettenis return;
123b725ae77Skettenis
124b725ae77Skettenis if (core_reg_size < SIZEOF_STRUCT_REG)
125b725ae77Skettenis {
126b725ae77Skettenis warning ("Wrong size register set in core file.");
127b725ae77Skettenis return;
128b725ae77Skettenis }
129b725ae77Skettenis
130b725ae77Skettenis /* Integer registers. */
131b725ae77Skettenis shnbsd_supply_reg (core_reg_sect, -1);
132b725ae77Skettenis }
133b725ae77Skettenis
134b725ae77Skettenis static void
fetch_elfcore_registers(char * core_reg_sect,unsigned core_reg_size,int which,CORE_ADDR ignore)135b725ae77Skettenis fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size,
136b725ae77Skettenis int which, CORE_ADDR ignore)
137b725ae77Skettenis {
138b725ae77Skettenis switch (which)
139b725ae77Skettenis {
140b725ae77Skettenis case 0: /* Integer registers. */
141b725ae77Skettenis if (core_reg_size != SIZEOF_STRUCT_REG)
142b725ae77Skettenis warning ("Wrong size register set in core file.");
143b725ae77Skettenis else
144b725ae77Skettenis shnbsd_supply_reg (core_reg_sect, -1);
145b725ae77Skettenis break;
146b725ae77Skettenis
147b725ae77Skettenis default:
148b725ae77Skettenis /* Don't know what kind of register request this is; just ignore it. */
149b725ae77Skettenis break;
150b725ae77Skettenis }
151b725ae77Skettenis }
152b725ae77Skettenis
153b725ae77Skettenis static struct core_fns shnbsd_core_fns =
154b725ae77Skettenis {
155b725ae77Skettenis bfd_target_unknown_flavour, /* core_flavour */
156b725ae77Skettenis default_check_format, /* check_format */
157b725ae77Skettenis default_core_sniffer, /* core_sniffer */
158b725ae77Skettenis fetch_core_registers, /* core_read_registers */
159b725ae77Skettenis NULL /* next */
160b725ae77Skettenis };
161b725ae77Skettenis
162b725ae77Skettenis static struct core_fns shnbsd_elfcore_fns =
163b725ae77Skettenis {
164b725ae77Skettenis bfd_target_elf_flavour, /* core_flavour */
165b725ae77Skettenis default_check_format, /* check_format */
166b725ae77Skettenis default_core_sniffer, /* core_sniffer */
167b725ae77Skettenis fetch_elfcore_registers, /* core_read_registers */
168b725ae77Skettenis NULL /* next */
169b725ae77Skettenis };
170b725ae77Skettenis
171b725ae77Skettenis static void
shnbsd_init_abi(struct gdbarch_info info,struct gdbarch * gdbarch)172b725ae77Skettenis shnbsd_init_abi (struct gdbarch_info info,
173b725ae77Skettenis struct gdbarch *gdbarch)
174b725ae77Skettenis {
175b725ae77Skettenis set_solib_svr4_fetch_link_map_offsets (gdbarch,
176b725ae77Skettenis nbsd_ilp32_solib_svr4_fetch_link_map_offsets);
177b725ae77Skettenis }
178b725ae77Skettenis
179b725ae77Skettenis void
_initialize_shnbsd_tdep(void)180b725ae77Skettenis _initialize_shnbsd_tdep (void)
181b725ae77Skettenis {
18211efff7fSkettenis deprecated_add_core_fns (&shnbsd_core_fns);
18311efff7fSkettenis deprecated_add_core_fns (&shnbsd_elfcore_fns);
184b725ae77Skettenis
185b725ae77Skettenis gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_NETBSD_ELF,
186b725ae77Skettenis shnbsd_init_abi);
187*9e8fd9f4Skettenis gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_OPENBSD_ELF,
188*9e8fd9f4Skettenis shnbsd_init_abi);
189b725ae77Skettenis }
190