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 | |
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 | { |
861fb77c | 70 | const gdb_byte *regs = gregs; |
20cb8cda | 71 | int i; |
13a38d45 | 72 | |
861fb77c | 73 | gdb_assert (len >= SHNBSD_SIZEOF_GREGS); |
20cb8cda | 74 | |
3e8c568d UW |
75 | if (regnum == gdbarch_pc_regnum (current_gdbarch) || regnum == -1) |
76 | regcache_raw_supply (regcache, | |
77 | gdbarch_pc_regnum (current_gdbarch), | |
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 | { |
861fb77c | 109 | gdb_byte *regs = gregs; |
20cb8cda | 110 | int i; |
13a38d45 | 111 | |
861fb77c | 112 | gdb_assert (len >= SHNBSD_SIZEOF_GREGS); |
20cb8cda | 113 | |
3e8c568d UW |
114 | if (regnum == gdbarch_pc_regnum (current_gdbarch) || regnum == -1) |
115 | regcache_raw_collect (regcache, gdbarch_pc_regnum (current_gdbarch), | |
116 | regs + (0 * 4)); | |
20cb8cda | 117 | |
861fb77c MK |
118 | if (regnum == SR_REGNUM || regnum == -1) |
119 | regcache_raw_collect (regcache, SR_REGNUM, regs + (1 * 4)); | |
20cb8cda | 120 | |
861fb77c MK |
121 | if (regnum == PR_REGNUM || regnum == -1) |
122 | regcache_raw_collect (regcache, PR_REGNUM, regs + (2 * 4)); | |
20cb8cda | 123 | |
861fb77c MK |
124 | if (regnum == MACH_REGNUM || regnum == -1) |
125 | regcache_raw_collect (regcache, MACH_REGNUM, regs + (3 * 4)); | |
20cb8cda | 126 | |
861fb77c MK |
127 | if (regnum == MACL_REGNUM || regnum == -1) |
128 | regcache_raw_collect (regcache, MACL_REGNUM, regs + (4 * 4)); | |
129 | ||
130 | for (i = R0_REGNUM; i <= (R0_REGNUM + 15); i++) | |
20cb8cda | 131 | { |
861fb77c MK |
132 | if (regnum == i || regnum == -1) |
133 | regcache_raw_collect (regcache, i, regs + regmap[i - R0_REGNUM]); | |
20cb8cda | 134 | } |
13a38d45 JT |
135 | } |
136 | ||
861fb77c | 137 | /* SH register sets. */ |
13a38d45 | 138 | |
861fb77c MK |
139 | static struct regset shnbsd_gregset = |
140 | { | |
141 | NULL, | |
142 | shnbsd_supply_gregset, | |
143 | shnbsd_collect_gregset | |
144 | }; | |
13a38d45 | 145 | |
861fb77c MK |
146 | /* Return the appropriate register set for the core section identified |
147 | by SECT_NAME and SECT_SIZE. */ | |
13a38d45 | 148 | |
861fb77c MK |
149 | const struct regset * |
150 | shnbsd_regset_from_core_section (struct gdbarch *gdbarch, | |
151 | const char *sect_name, size_t sect_size) | |
13a38d45 | 152 | { |
861fb77c MK |
153 | if (strcmp (sect_name, ".reg") == 0 && sect_size >= SHNBSD_SIZEOF_GREGS) |
154 | return &shnbsd_gregset; | |
155 | ||
156 | return NULL; | |
13a38d45 JT |
157 | } |
158 | ||
861fb77c | 159 | void |
4e3269e3 | 160 | shnbsd_supply_reg (struct regcache *regcache, const char *regs, int regnum) |
13a38d45 | 161 | { |
4e3269e3 | 162 | shnbsd_supply_gregset (&shnbsd_gregset, regcache, regnum, |
861fb77c MK |
163 | regs, SHNBSD_SIZEOF_GREGS); |
164 | } | |
13a38d45 | 165 | |
861fb77c | 166 | void |
4e3269e3 | 167 | shnbsd_fill_reg (const struct regcache *regcache, char *regs, int regnum) |
13a38d45 | 168 | { |
4e3269e3 | 169 | shnbsd_collect_gregset (&shnbsd_gregset, regcache, regnum, |
861fb77c MK |
170 | regs, SHNBSD_SIZEOF_GREGS); |
171 | } | |
172 | \f | |
13a38d45 JT |
173 | |
174 | static void | |
20cb8cda | 175 | shnbsd_init_abi (struct gdbarch_info info, |
13a38d45 JT |
176 | struct gdbarch *gdbarch) |
177 | { | |
861fb77c MK |
178 | set_gdbarch_regset_from_core_section |
179 | (gdbarch, shnbsd_regset_from_core_section); | |
180 | ||
181 | set_solib_svr4_fetch_link_map_offsets | |
182 | (gdbarch, svr4_ilp32_fetch_link_map_offsets); | |
183 | } | |
184 | \f | |
185 | ||
186 | /* OpenBSD uses uses the traditional NetBSD core file format, even for | |
187 | ports that use ELF. */ | |
188 | #define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF | |
189 | ||
190 | static enum gdb_osabi | |
191 | shnbsd_core_osabi_sniffer (bfd *abfd) | |
192 | { | |
193 | if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0) | |
194 | return GDB_OSABI_NETBSD_CORE; | |
195 | ||
196 | return GDB_OSABI_UNKNOWN; | |
13a38d45 JT |
197 | } |
198 | ||
199 | void | |
20cb8cda | 200 | _initialize_shnbsd_tdep (void) |
13a38d45 | 201 | { |
861fb77c MK |
202 | /* BFD doesn't set a flavour for NetBSD style a.out core files. */ |
203 | gdbarch_register_osabi_sniffer (bfd_arch_sh, bfd_target_unknown_flavour, | |
204 | shnbsd_core_osabi_sniffer); | |
13a38d45 | 205 | |
05816f70 MK |
206 | gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_NETBSD_ELF, |
207 | shnbsd_init_abi); | |
54fe9172 MK |
208 | gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_OPENBSD_ELF, |
209 | shnbsd_init_abi); | |
13a38d45 | 210 | } |