Commit | Line | Data |
---|---|---|
54fe9172 MK |
1 | /* Target-dependent code for NetBSD/sh. |
2 | ||
9b254dd1 | 3 | Copyright (C) 2002, 2003, 2006, 2007, 2008 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 | |
a9762ec7 | 11 | the Free Software Foundation; either version 3 of the License, or |
13a38d45 JT |
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 | |
a9762ec7 | 20 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
13a38d45 JT |
21 | |
22 | #include "defs.h" | |
23 | #include "gdbcore.h" | |
24 | #include "regcache.h" | |
861fb77c | 25 | #include "regset.h" |
13a38d45 | 26 | #include "value.h" |
4be87837 | 27 | #include "osabi.h" |
13a38d45 | 28 | |
861fb77c MK |
29 | #include "gdb_assert.h" |
30 | #include "gdb_string.h" | |
9964235a | 31 | |
ab3b8126 | 32 | #include "sh-tdep.h" |
4015edd1 | 33 | #include "shnbsd-tdep.h" |
861fb77c | 34 | #include "solib-svr4.h" |
13a38d45 JT |
35 | |
36 | /* Convert an r0-r15 register number into an offset into a ptrace | |
37 | register structure. */ | |
38 | static const int regmap[] = | |
39 | { | |
40 | (20 * 4), /* r0 */ | |
41 | (19 * 4), /* r1 */ | |
42 | (18 * 4), /* r2 */ | |
43 | (17 * 4), /* r3 */ | |
44 | (16 * 4), /* r4 */ | |
45 | (15 * 4), /* r5 */ | |
46 | (14 * 4), /* r6 */ | |
47 | (13 * 4), /* r7 */ | |
48 | (12 * 4), /* r8 */ | |
49 | (11 * 4), /* r9 */ | |
50 | (10 * 4), /* r10 */ | |
51 | ( 9 * 4), /* r11 */ | |
52 | ( 8 * 4), /* r12 */ | |
53 | ( 7 * 4), /* r13 */ | |
54 | ( 6 * 4), /* r14 */ | |
55 | ( 5 * 4), /* r15 */ | |
56 | }; | |
57 | ||
861fb77c MK |
58 | /* Sizeof `struct reg' in <machine/reg.h>. */ |
59 | #define SHNBSD_SIZEOF_GREGS (21 * 4) | |
13a38d45 | 60 | |
861fb77c MK |
61 | /* Supply register REGNUM from the buffer specified by GREGS and LEN |
62 | in the general-purpose register set REGSET to register cache | |
63 | REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ | |
64 | ||
65 | static void | |
66 | shnbsd_supply_gregset (const struct regset *regset, | |
67 | struct regcache *regcache, | |
68 | int regnum, const void *gregs, size_t len) | |
13a38d45 | 69 | { |
9970f04b | 70 | struct gdbarch *gdbarch = get_regcache_arch (regcache); |
861fb77c | 71 | const gdb_byte *regs = gregs; |
20cb8cda | 72 | int i; |
13a38d45 | 73 | |
861fb77c | 74 | gdb_assert (len >= SHNBSD_SIZEOF_GREGS); |
20cb8cda | 75 | |
9970f04b MD |
76 | if (regnum == gdbarch_pc_regnum (gdbarch) || regnum == -1) |
77 | regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch), | |
3e8c568d | 78 | 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 | { |
9970f04b | 109 | struct gdbarch *gdbarch = get_regcache_arch (regcache); |
861fb77c | 110 | gdb_byte *regs = gregs; |
20cb8cda | 111 | int i; |
13a38d45 | 112 | |
861fb77c | 113 | gdb_assert (len >= SHNBSD_SIZEOF_GREGS); |
20cb8cda | 114 | |
9970f04b MD |
115 | if (regnum == gdbarch_pc_regnum (gdbarch) || regnum == -1) |
116 | regcache_raw_collect (regcache, gdbarch_pc_regnum (gdbarch), | |
3e8c568d | 117 | regs + (0 * 4)); |
20cb8cda | 118 | |
861fb77c MK |
119 | if (regnum == SR_REGNUM || regnum == -1) |
120 | regcache_raw_collect (regcache, SR_REGNUM, regs + (1 * 4)); | |
20cb8cda | 121 | |
861fb77c MK |
122 | if (regnum == PR_REGNUM || regnum == -1) |
123 | regcache_raw_collect (regcache, PR_REGNUM, regs + (2 * 4)); | |
20cb8cda | 124 | |
861fb77c MK |
125 | if (regnum == MACH_REGNUM || regnum == -1) |
126 | regcache_raw_collect (regcache, MACH_REGNUM, regs + (3 * 4)); | |
20cb8cda | 127 | |
861fb77c MK |
128 | if (regnum == MACL_REGNUM || regnum == -1) |
129 | regcache_raw_collect (regcache, MACL_REGNUM, regs + (4 * 4)); | |
130 | ||
131 | for (i = R0_REGNUM; i <= (R0_REGNUM + 15); i++) | |
20cb8cda | 132 | { |
861fb77c MK |
133 | if (regnum == i || regnum == -1) |
134 | regcache_raw_collect (regcache, i, regs + regmap[i - R0_REGNUM]); | |
20cb8cda | 135 | } |
13a38d45 JT |
136 | } |
137 | ||
861fb77c | 138 | /* SH register sets. */ |
13a38d45 | 139 | |
861fb77c MK |
140 | static struct regset shnbsd_gregset = |
141 | { | |
142 | NULL, | |
143 | shnbsd_supply_gregset, | |
144 | shnbsd_collect_gregset | |
145 | }; | |
13a38d45 | 146 | |
861fb77c MK |
147 | /* Return the appropriate register set for the core section identified |
148 | by SECT_NAME and SECT_SIZE. */ | |
13a38d45 | 149 | |
861fb77c MK |
150 | const struct regset * |
151 | shnbsd_regset_from_core_section (struct gdbarch *gdbarch, | |
152 | const char *sect_name, size_t sect_size) | |
13a38d45 | 153 | { |
861fb77c MK |
154 | if (strcmp (sect_name, ".reg") == 0 && sect_size >= SHNBSD_SIZEOF_GREGS) |
155 | return &shnbsd_gregset; | |
156 | ||
157 | return NULL; | |
13a38d45 JT |
158 | } |
159 | ||
861fb77c | 160 | void |
4e3269e3 | 161 | shnbsd_supply_reg (struct regcache *regcache, const char *regs, int regnum) |
13a38d45 | 162 | { |
4e3269e3 | 163 | shnbsd_supply_gregset (&shnbsd_gregset, regcache, regnum, |
861fb77c MK |
164 | regs, SHNBSD_SIZEOF_GREGS); |
165 | } | |
13a38d45 | 166 | |
861fb77c | 167 | void |
4e3269e3 | 168 | shnbsd_fill_reg (const struct regcache *regcache, char *regs, int regnum) |
13a38d45 | 169 | { |
4e3269e3 | 170 | shnbsd_collect_gregset (&shnbsd_gregset, regcache, regnum, |
861fb77c MK |
171 | regs, SHNBSD_SIZEOF_GREGS); |
172 | } | |
173 | \f | |
13a38d45 JT |
174 | |
175 | static void | |
20cb8cda | 176 | shnbsd_init_abi (struct gdbarch_info info, |
13a38d45 JT |
177 | struct gdbarch *gdbarch) |
178 | { | |
861fb77c MK |
179 | set_gdbarch_regset_from_core_section |
180 | (gdbarch, shnbsd_regset_from_core_section); | |
181 | ||
182 | set_solib_svr4_fetch_link_map_offsets | |
183 | (gdbarch, svr4_ilp32_fetch_link_map_offsets); | |
184 | } | |
185 | \f | |
186 | ||
187 | /* OpenBSD uses uses the traditional NetBSD core file format, even for | |
188 | ports that use ELF. */ | |
189 | #define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF | |
190 | ||
191 | static enum gdb_osabi | |
192 | shnbsd_core_osabi_sniffer (bfd *abfd) | |
193 | { | |
194 | if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0) | |
195 | return GDB_OSABI_NETBSD_CORE; | |
196 | ||
197 | return GDB_OSABI_UNKNOWN; | |
13a38d45 JT |
198 | } |
199 | ||
200 | void | |
20cb8cda | 201 | _initialize_shnbsd_tdep (void) |
13a38d45 | 202 | { |
861fb77c MK |
203 | /* BFD doesn't set a flavour for NetBSD style a.out core files. */ |
204 | gdbarch_register_osabi_sniffer (bfd_arch_sh, bfd_target_unknown_flavour, | |
205 | shnbsd_core_osabi_sniffer); | |
13a38d45 | 206 | |
05816f70 MK |
207 | gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_NETBSD_ELF, |
208 | shnbsd_init_abi); | |
54fe9172 MK |
209 | gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_OPENBSD_ELF, |
210 | shnbsd_init_abi); | |
13a38d45 | 211 | } |