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