2009-07-01 Paul Brook <paul@codesourcery.com>
[deliverable/binutils-gdb.git] / gdb / shnbsd-tdep.c
CommitLineData
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. */
39static 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
66static void
67shnbsd_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
105static void
106shnbsd_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
141static 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 151static const struct regset *
861fb77c
MK
152shnbsd_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 161void
4e3269e3 162shnbsd_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 168void
4e3269e3 169shnbsd_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
176static void
20cb8cda 177shnbsd_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
192static enum gdb_osabi
193shnbsd_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. */
202extern initialize_file_ftype _initialize_shnbsd_tdep;
203
13a38d45 204void
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}
This page took 0.675966 seconds and 4 git commands to generate.