Commit | Line | Data |
---|---|---|
54fe9172 MK |
1 | /* Target-dependent code for NetBSD/sh. |
2 | ||
6aba47ca | 3 | Copyright (C) 2002, 2003, 2006, 2007 Free Software Foundation, Inc. |
54fe9172 | 4 | |
13a38d45 JT |
5 | Contributed by Wasabi Systems, Inc. |
6 | ||
7 | This file is part of GDB. | |
8 | ||
9 | This program is free software; you can redistribute it and/or modify | |
10 | it under the terms of the GNU General Public License as published by | |
11 | the Free Software Foundation; either version 2 of the License, or | |
12 | (at your option) any later version. | |
13 | ||
14 | This program is distributed in the hope that it will be useful, | |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | GNU General Public License for more details. | |
18 | ||
19 | You should have received a copy of the GNU General Public License | |
20 | along with this program; if not, write to the Free Software | |
197e01b6 EZ |
21 | Foundation, Inc., 51 Franklin Street, Fifth Floor, |
22 | Boston, MA 02110-1301, USA. */ | |
13a38d45 JT |
23 | |
24 | #include "defs.h" | |
25 | #include "gdbcore.h" | |
26 | #include "regcache.h" | |
861fb77c | 27 | #include "regset.h" |
13a38d45 | 28 | #include "value.h" |
4be87837 | 29 | #include "osabi.h" |
13a38d45 | 30 | |
861fb77c MK |
31 | #include "gdb_assert.h" |
32 | #include "gdb_string.h" | |
9964235a | 33 | |
ab3b8126 | 34 | #include "sh-tdep.h" |
4015edd1 | 35 | #include "shnbsd-tdep.h" |
861fb77c | 36 | #include "solib-svr4.h" |
13a38d45 JT |
37 | |
38 | /* Convert an r0-r15 register number into an offset into a ptrace | |
39 | register structure. */ | |
40 | static const int regmap[] = | |
41 | { | |
42 | (20 * 4), /* r0 */ | |
43 | (19 * 4), /* r1 */ | |
44 | (18 * 4), /* r2 */ | |
45 | (17 * 4), /* r3 */ | |
46 | (16 * 4), /* r4 */ | |
47 | (15 * 4), /* r5 */ | |
48 | (14 * 4), /* r6 */ | |
49 | (13 * 4), /* r7 */ | |
50 | (12 * 4), /* r8 */ | |
51 | (11 * 4), /* r9 */ | |
52 | (10 * 4), /* r10 */ | |
53 | ( 9 * 4), /* r11 */ | |
54 | ( 8 * 4), /* r12 */ | |
55 | ( 7 * 4), /* r13 */ | |
56 | ( 6 * 4), /* r14 */ | |
57 | ( 5 * 4), /* r15 */ | |
58 | }; | |
59 | ||
861fb77c MK |
60 | /* Sizeof `struct reg' in <machine/reg.h>. */ |
61 | #define SHNBSD_SIZEOF_GREGS (21 * 4) | |
13a38d45 | 62 | |
861fb77c MK |
63 | /* Supply register REGNUM from the buffer specified by GREGS and LEN |
64 | in the general-purpose register set REGSET to register cache | |
65 | REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ | |
66 | ||
67 | static void | |
68 | shnbsd_supply_gregset (const struct regset *regset, | |
69 | struct regcache *regcache, | |
70 | int regnum, const void *gregs, size_t len) | |
13a38d45 | 71 | { |
861fb77c | 72 | const gdb_byte *regs = gregs; |
20cb8cda | 73 | int i; |
13a38d45 | 74 | |
861fb77c | 75 | gdb_assert (len >= SHNBSD_SIZEOF_GREGS); |
20cb8cda | 76 | |
861fb77c MK |
77 | if (regnum == PC_REGNUM || regnum == -1) |
78 | regcache_raw_supply (regcache, PC_REGNUM, regs + (0 * 4)); | |
20cb8cda | 79 | |
861fb77c MK |
80 | if (regnum == SR_REGNUM || regnum == -1) |
81 | regcache_raw_supply (regcache, SR_REGNUM, regs + (1 * 4)); | |
13a38d45 | 82 | |
861fb77c MK |
83 | if (regnum == PR_REGNUM || regnum == -1) |
84 | regcache_raw_supply (regcache, PR_REGNUM, regs + (2 * 4)); | |
13a38d45 | 85 | |
861fb77c MK |
86 | if (regnum == MACH_REGNUM || regnum == -1) |
87 | regcache_raw_supply (regcache, MACH_REGNUM, regs + (3 * 4)); | |
13a38d45 | 88 | |
861fb77c MK |
89 | if (regnum == MACL_REGNUM || regnum == -1) |
90 | regcache_raw_supply (regcache, MACL_REGNUM, regs + (4 * 4)); | |
91 | ||
92 | for (i = R0_REGNUM; i <= (R0_REGNUM + 15); i++) | |
20cb8cda | 93 | { |
861fb77c MK |
94 | if (regnum == i || regnum == -1) |
95 | regcache_raw_supply (regcache, i, regs + regmap[i - R0_REGNUM]); | |
20cb8cda | 96 | } |
13a38d45 JT |
97 | } |
98 | ||
861fb77c MK |
99 | /* Collect register REGNUM in the general-purpose register set |
100 | REGSET. from register cache REGCACHE into the buffer specified by | |
101 | GREGS and LEN. If REGNUM is -1, do this for all registers in | |
102 | REGSET. */ | |
103 | ||
104 | static void | |
105 | shnbsd_collect_gregset (const struct regset *regset, | |
106 | const struct regcache *regcache, | |
107 | int regnum, void *gregs, size_t len) | |
13a38d45 | 108 | { |
861fb77c | 109 | gdb_byte *regs = gregs; |
20cb8cda | 110 | int i; |
13a38d45 | 111 | |
861fb77c | 112 | gdb_assert (len >= SHNBSD_SIZEOF_GREGS); |
20cb8cda | 113 | |
861fb77c MK |
114 | if (regnum == PC_REGNUM || regnum == -1) |
115 | regcache_raw_collect (regcache, PC_REGNUM, regs + (0 * 4)); | |
20cb8cda | 116 | |
861fb77c MK |
117 | if (regnum == SR_REGNUM || regnum == -1) |
118 | regcache_raw_collect (regcache, SR_REGNUM, regs + (1 * 4)); | |
20cb8cda | 119 | |
861fb77c MK |
120 | if (regnum == PR_REGNUM || regnum == -1) |
121 | regcache_raw_collect (regcache, PR_REGNUM, regs + (2 * 4)); | |
20cb8cda | 122 | |
861fb77c MK |
123 | if (regnum == MACH_REGNUM || regnum == -1) |
124 | regcache_raw_collect (regcache, MACH_REGNUM, regs + (3 * 4)); | |
20cb8cda | 125 | |
861fb77c MK |
126 | if (regnum == MACL_REGNUM || regnum == -1) |
127 | regcache_raw_collect (regcache, MACL_REGNUM, regs + (4 * 4)); | |
128 | ||
129 | for (i = R0_REGNUM; i <= (R0_REGNUM + 15); i++) | |
20cb8cda | 130 | { |
861fb77c MK |
131 | if (regnum == i || regnum == -1) |
132 | regcache_raw_collect (regcache, i, regs + regmap[i - R0_REGNUM]); | |
20cb8cda | 133 | } |
13a38d45 JT |
134 | } |
135 | ||
861fb77c | 136 | /* SH register sets. */ |
13a38d45 | 137 | |
861fb77c MK |
138 | static struct regset shnbsd_gregset = |
139 | { | |
140 | NULL, | |
141 | shnbsd_supply_gregset, | |
142 | shnbsd_collect_gregset | |
143 | }; | |
13a38d45 | 144 | |
861fb77c MK |
145 | /* Return the appropriate register set for the core section identified |
146 | by SECT_NAME and SECT_SIZE. */ | |
13a38d45 | 147 | |
861fb77c MK |
148 | const struct regset * |
149 | shnbsd_regset_from_core_section (struct gdbarch *gdbarch, | |
150 | const char *sect_name, size_t sect_size) | |
13a38d45 | 151 | { |
861fb77c MK |
152 | if (strcmp (sect_name, ".reg") == 0 && sect_size >= SHNBSD_SIZEOF_GREGS) |
153 | return &shnbsd_gregset; | |
154 | ||
155 | return NULL; | |
13a38d45 JT |
156 | } |
157 | ||
861fb77c | 158 | void |
4e3269e3 | 159 | shnbsd_supply_reg (struct regcache *regcache, const char *regs, int regnum) |
13a38d45 | 160 | { |
4e3269e3 | 161 | shnbsd_supply_gregset (&shnbsd_gregset, regcache, regnum, |
861fb77c MK |
162 | regs, SHNBSD_SIZEOF_GREGS); |
163 | } | |
13a38d45 | 164 | |
861fb77c | 165 | void |
4e3269e3 | 166 | shnbsd_fill_reg (const struct regcache *regcache, char *regs, int regnum) |
13a38d45 | 167 | { |
4e3269e3 | 168 | shnbsd_collect_gregset (&shnbsd_gregset, regcache, regnum, |
861fb77c MK |
169 | regs, SHNBSD_SIZEOF_GREGS); |
170 | } | |
171 | \f | |
13a38d45 JT |
172 | |
173 | static void | |
20cb8cda | 174 | shnbsd_init_abi (struct gdbarch_info info, |
13a38d45 JT |
175 | struct gdbarch *gdbarch) |
176 | { | |
861fb77c MK |
177 | set_gdbarch_regset_from_core_section |
178 | (gdbarch, shnbsd_regset_from_core_section); | |
179 | ||
180 | set_solib_svr4_fetch_link_map_offsets | |
181 | (gdbarch, svr4_ilp32_fetch_link_map_offsets); | |
182 | } | |
183 | \f | |
184 | ||
185 | /* OpenBSD uses uses the traditional NetBSD core file format, even for | |
186 | ports that use ELF. */ | |
187 | #define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF | |
188 | ||
189 | static enum gdb_osabi | |
190 | shnbsd_core_osabi_sniffer (bfd *abfd) | |
191 | { | |
192 | if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0) | |
193 | return GDB_OSABI_NETBSD_CORE; | |
194 | ||
195 | return GDB_OSABI_UNKNOWN; | |
13a38d45 JT |
196 | } |
197 | ||
198 | void | |
20cb8cda | 199 | _initialize_shnbsd_tdep (void) |
13a38d45 | 200 | { |
861fb77c MK |
201 | /* BFD doesn't set a flavour for NetBSD style a.out core files. */ |
202 | gdbarch_register_osabi_sniffer (bfd_arch_sh, bfd_target_unknown_flavour, | |
203 | shnbsd_core_osabi_sniffer); | |
13a38d45 | 204 | |
05816f70 MK |
205 | gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_NETBSD_ELF, |
206 | shnbsd_init_abi); | |
54fe9172 MK |
207 | gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_OPENBSD_ELF, |
208 | shnbsd_init_abi); | |
13a38d45 | 209 | } |