1 /* Target-dependent code for the Matsushita MN10300 for GDB, the GNU debugger.
2 Copyright 2003, 2004, 2005
3 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
24 #include "gdb_string.h"
26 #include "mn10300-tdep.h"
27 #include "gdb_assert.h"
32 #include "solib-svr4.h"
36 /* Transliterated from <asm-mn10300/elf.h>... */
37 #define MN10300_ELF_NGREG 28
38 #define MN10300_ELF_NFPREG 32
40 typedef gdb_byte mn10300_elf_greg_t[4];
41 typedef mn10300_elf_greg_t mn10300_elf_gregset_t[MN10300_ELF_NGREG];
43 typedef gdb_byte mn10300_elf_fpreg_t[4];
46 mn10300_elf_fpreg_t fpregs[MN10300_ELF_NFPREG];
48 } mn10300_elf_fpregset_t;
50 /* elf_gregset_t register indices stolen from include/asm-mn10300/ptrace.h. */
51 #define MN10300_ELF_GREGSET_T_REG_INDEX_A3 0
52 #define MN10300_ELF_GREGSET_T_REG_INDEX_A2 1
53 #define MN10300_ELF_GREGSET_T_REG_INDEX_D3 2
54 #define MN10300_ELF_GREGSET_T_REG_INDEX_D2 3
55 #define MN10300_ELF_GREGSET_T_REG_INDEX_MCVF 4
56 #define MN10300_ELF_GREGSET_T_REG_INDEX_MCRL 5
57 #define MN10300_ELF_GREGSET_T_REG_INDEX_MCRH 6
58 #define MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ 7
59 #define MN10300_ELF_GREGSET_T_REG_INDEX_E1 8
60 #define MN10300_ELF_GREGSET_T_REG_INDEX_E0 9
61 #define MN10300_ELF_GREGSET_T_REG_INDEX_E7 10
62 #define MN10300_ELF_GREGSET_T_REG_INDEX_E6 11
63 #define MN10300_ELF_GREGSET_T_REG_INDEX_E5 12
64 #define MN10300_ELF_GREGSET_T_REG_INDEX_E4 13
65 #define MN10300_ELF_GREGSET_T_REG_INDEX_E3 14
66 #define MN10300_ELF_GREGSET_T_REG_INDEX_E2 15
67 #define MN10300_ELF_GREGSET_T_REG_INDEX_SP 16
68 #define MN10300_ELF_GREGSET_T_REG_INDEX_LAR 17
69 #define MN10300_ELF_GREGSET_T_REG_INDEX_LIR 18
70 #define MN10300_ELF_GREGSET_T_REG_INDEX_MDR 19
71 #define MN10300_ELF_GREGSET_T_REG_INDEX_A1 20
72 #define MN10300_ELF_GREGSET_T_REG_INDEX_A0 21
73 #define MN10300_ELF_GREGSET_T_REG_INDEX_D1 22
74 #define MN10300_ELF_GREGSET_T_REG_INDEX_D0 23
75 #define MN10300_ELF_GREGSET_T_REG_INDEX_ORIG_D0 24
76 #define MN10300_ELF_GREGSET_T_REG_INDEX_EPSW 25
77 #define MN10300_ELF_GREGSET_T_REG_INDEX_PC 26
79 /* New gdbarch API for corefile registers.
80 Given a section name and size, create a struct reg object
81 with a supply_register and a collect_register method. */
83 /* Copy register value of REGNUM from regset to regcache.
84 If REGNUM is -1, do this for all gp registers in regset. */
87 am33_supply_gregset_method (const struct regset *regset,
88 struct regcache *regcache,
89 int regnum, const void *gregs, size_t len)
91 char zerobuf[MAX_REGISTER_SIZE];
92 const mn10300_elf_greg_t *regp = (const mn10300_elf_greg_t *) gregs;
95 gdb_assert (len == sizeof (mn10300_elf_gregset_t));
99 regcache_raw_supply (regcache, E_D0_REGNUM,
100 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D0));
103 regcache_raw_supply (regcache, E_D1_REGNUM,
104 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D1));
107 regcache_raw_supply (regcache, E_D2_REGNUM,
108 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D2));
111 regcache_raw_supply (regcache, E_D3_REGNUM,
112 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D3));
115 regcache_raw_supply (regcache, E_A0_REGNUM,
116 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A0));
119 regcache_raw_supply (regcache, E_A1_REGNUM,
120 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A1));
123 regcache_raw_supply (regcache, E_A2_REGNUM,
124 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A2));
127 regcache_raw_supply (regcache, E_A3_REGNUM,
128 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A3));
131 regcache_raw_supply (regcache, E_SP_REGNUM,
132 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_SP));
135 regcache_raw_supply (regcache, E_PC_REGNUM,
136 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_PC));
139 regcache_raw_supply (regcache, E_MDR_REGNUM,
140 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDR));
143 regcache_raw_supply (regcache, E_PSW_REGNUM,
144 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_EPSW));
147 regcache_raw_supply (regcache, E_LIR_REGNUM,
148 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LIR));
151 regcache_raw_supply (regcache, E_LAR_REGNUM,
152 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LAR));
155 regcache_raw_supply (regcache, E_MDRQ_REGNUM,
156 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ));
159 regcache_raw_supply (regcache, E_E0_REGNUM,
160 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E0));
163 regcache_raw_supply (regcache, E_E1_REGNUM,
164 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E1));
167 regcache_raw_supply (regcache, E_E2_REGNUM,
168 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E2));
171 regcache_raw_supply (regcache, E_E3_REGNUM,
172 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E3));
175 regcache_raw_supply (regcache, E_E4_REGNUM,
176 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E4));
179 regcache_raw_supply (regcache, E_E5_REGNUM,
180 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E5));
183 regcache_raw_supply (regcache, E_E6_REGNUM,
184 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E6));
187 regcache_raw_supply (regcache, E_E7_REGNUM,
188 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E7));
191 /* ssp, msp, and usp are inaccessible. */
193 memset (zerobuf, 0, MAX_REGISTER_SIZE);
194 regcache_raw_supply (regcache, E_E8_REGNUM, zerobuf);
197 memset (zerobuf, 0, MAX_REGISTER_SIZE);
198 regcache_raw_supply (regcache, E_E9_REGNUM, zerobuf);
201 memset (zerobuf, 0, MAX_REGISTER_SIZE);
202 regcache_raw_supply (regcache, E_E10_REGNUM, zerobuf);
206 regcache_raw_supply (regcache, E_MCRH_REGNUM,
207 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRH));
210 regcache_raw_supply (regcache, E_MCRL_REGNUM,
211 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRL));
214 regcache_raw_supply (regcache, E_MCVF_REGNUM,
215 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCVF));
218 /* FPCR is numbered among the GP regs, but handled as an FP reg.
221 case E_FPCR_REGNUM + 1:
222 /* The two unused registers beyond fpcr are inaccessible. */
223 memset (zerobuf, 0, MAX_REGISTER_SIZE);
224 regcache_raw_supply (regcache, E_FPCR_REGNUM + 1, zerobuf);
226 case E_FPCR_REGNUM + 2:
227 memset (zerobuf, 0, MAX_REGISTER_SIZE);
228 regcache_raw_supply (regcache, E_FPCR_REGNUM + 2, zerobuf);
230 default: /* An error, obviously, but should we error out? */
233 for (i = 0; i < MN10300_ELF_NGREG; i++)
234 am33_supply_gregset_method (regset, regcache, i, gregs, len);
240 /* Copy fp register value of REGNUM from regset to regcache.
241 If REGNUM is -1, do this for all fp registers in regset. */
244 am33_supply_fpregset_method (const struct regset *regset,
245 struct regcache *regcache,
246 int regnum, const void *fpregs, size_t len)
248 const mn10300_elf_fpregset_t *fpregset = fpregs;
250 gdb_assert (len == sizeof (mn10300_elf_fpregset_t));
256 for (i = 0; i < MN10300_ELF_NFPREG; i++)
257 am33_supply_fpregset_method (regset, regcache,
258 E_FS0_REGNUM + i, fpregs, len);
259 am33_supply_fpregset_method (regset, regcache,
260 E_FPCR_REGNUM, fpregs, len);
262 else if (regnum == E_FPCR_REGNUM)
263 regcache_raw_supply (current_regcache, E_FPCR_REGNUM,
265 else if (E_FS0_REGNUM <= regnum && regnum < E_FS0_REGNUM + MN10300_ELF_NFPREG)
266 regcache_raw_supply (current_regcache, regnum,
267 &fpregset->fpregs[regnum - E_FS0_REGNUM]);
272 /* Copy register values from regcache to regset. */
275 am33_collect_gregset_method (const struct regset *regset,
276 const struct regcache *regcache,
277 int regnum, void *gregs, size_t len)
279 mn10300_elf_gregset_t *regp = gregs;
282 gdb_assert (len == sizeof (mn10300_elf_gregset_t));
286 regcache_raw_collect (regcache, E_D0_REGNUM,
287 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D0));
290 regcache_raw_collect (regcache, E_D1_REGNUM,
291 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D1));
294 regcache_raw_collect (regcache, E_D2_REGNUM,
295 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D2));
298 regcache_raw_collect (regcache, E_D3_REGNUM,
299 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D3));
302 regcache_raw_collect (regcache, E_A0_REGNUM,
303 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A0));
306 regcache_raw_collect (regcache, E_A1_REGNUM,
307 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A1));
310 regcache_raw_collect (regcache, E_A2_REGNUM,
311 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A2));
314 regcache_raw_collect (regcache, E_A3_REGNUM,
315 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A3));
318 regcache_raw_collect (regcache, E_SP_REGNUM,
319 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_SP));
322 regcache_raw_collect (regcache, E_PC_REGNUM,
323 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_PC));
326 regcache_raw_collect (regcache, E_MDR_REGNUM,
327 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDR));
330 regcache_raw_collect (regcache, E_PSW_REGNUM,
331 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_EPSW));
334 regcache_raw_collect (regcache, E_LIR_REGNUM,
335 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LIR));
338 regcache_raw_collect (regcache, E_LAR_REGNUM,
339 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LAR));
342 regcache_raw_collect (regcache, E_MDRQ_REGNUM,
343 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ));
346 regcache_raw_collect (regcache, E_E0_REGNUM,
347 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E0));
350 regcache_raw_collect (regcache, E_E1_REGNUM,
351 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E1));
354 regcache_raw_collect (regcache, E_E2_REGNUM,
355 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E2));
358 regcache_raw_collect (regcache, E_E3_REGNUM,
359 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E3));
362 regcache_raw_collect (regcache, E_E4_REGNUM,
363 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E4));
366 regcache_raw_collect (regcache, E_E5_REGNUM,
367 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E5));
370 regcache_raw_collect (regcache, E_E6_REGNUM,
371 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E6));
374 regcache_raw_collect (regcache, E_E7_REGNUM,
375 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E7));
378 /* ssp, msp, and usp are inaccessible. */
380 /* The gregset struct has noplace to put this: do nothing. */
383 /* The gregset struct has noplace to put this: do nothing. */
386 /* The gregset struct has noplace to put this: do nothing. */
389 regcache_raw_collect (regcache, E_MCRH_REGNUM,
390 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRH));
393 regcache_raw_collect (regcache, E_MCRL_REGNUM,
394 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRL));
397 regcache_raw_collect (regcache, E_MCVF_REGNUM,
398 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCVF));
401 /* FPCR is numbered among the GP regs, but handled as an FP reg.
404 case E_FPCR_REGNUM + 1:
405 /* The gregset struct has noplace to put this: do nothing. */
407 case E_FPCR_REGNUM + 2:
408 /* The gregset struct has noplace to put this: do nothing. */
410 default: /* An error, obviously, but should we error out? */
413 for (i = 0; i < MN10300_ELF_NGREG; i++)
414 am33_collect_gregset_method (regset, regcache, i, gregs, len);
420 /* Copy fp register values from regcache to regset. */
423 am33_collect_fpregset_method (const struct regset *regset,
424 const struct regcache *regcache,
425 int regnum, void *fpregs, size_t len)
427 mn10300_elf_fpregset_t *fpregset = fpregs;
429 gdb_assert (len == sizeof (mn10300_elf_fpregset_t));
434 for (i = 0; i < MN10300_ELF_NFPREG; i++)
435 am33_collect_fpregset_method (regset, regcache, E_FS0_REGNUM + i,
437 am33_collect_fpregset_method (regset, regcache,
438 E_FPCR_REGNUM, fpregs, len);
440 else if (regnum == E_FPCR_REGNUM)
441 regcache_raw_collect (current_regcache, E_FPCR_REGNUM,
443 else if (E_FS0_REGNUM <= regnum
444 && regnum < E_FS0_REGNUM + MN10300_ELF_NFPREG)
445 regcache_raw_collect (current_regcache, regnum,
446 &fpregset->fpregs[regnum - E_FS0_REGNUM]);
451 /* Create a struct regset from a corefile register section. */
453 static const struct regset *
454 am33_regset_from_core_section (struct gdbarch *gdbarch,
455 const char *sect_name,
458 /* We will call regset_alloc, and pass the names of the supply and
461 if (sect_size == sizeof (mn10300_elf_fpregset_t))
462 return regset_alloc (gdbarch,
463 am33_supply_fpregset_method,
464 am33_collect_fpregset_method);
466 return regset_alloc (gdbarch,
467 am33_supply_gregset_method,
468 am33_collect_gregset_method);
471 /* Fetch, and possibly build, an appropriate link_map_offsets structure
472 for mn10300 linux targets using the struct offsets defined in <link.h>.
473 Note, however, that link.h is not actually referred to in this file.
474 Instead, the relevant structs offsets were obtained from examining
475 link.h. (We can't refer to link.h from this file because the host
476 system won't necessarily have it, or if it does, the structs which
477 it defines will refer to the host system, not the target.) */
479 struct link_map_offsets *
480 mn10300_linux_svr4_fetch_link_map_offsets (void)
482 static struct link_map_offsets lmo;
483 static struct link_map_offsets *lmp = 0;
489 lmo.r_debug_size = 8; /* Actual size is 20, but this is all we
492 lmo.r_map_offset = 4;
495 lmo.link_map_size = 20; /* Might be larger, but this is all we
498 lmo.l_addr_offset = 0;
501 lmo.l_name_offset = 4;
504 lmo.l_next_offset = 12;
507 lmo.l_prev_offset = 16;
514 /* AM33 Linux osabi has been recognized.
515 Now's our chance to register our corefile handling. */
518 am33_linux_init_osabi (struct gdbarch_info gdbinfo, struct gdbarch *gdbarch)
520 set_gdbarch_regset_from_core_section (gdbarch,
521 am33_regset_from_core_section);
522 set_solib_svr4_fetch_link_map_offsets
523 (gdbarch, mn10300_linux_svr4_fetch_link_map_offsets);
527 _initialize_mn10300_linux_tdep (void)
529 gdbarch_register_osabi (bfd_arch_mn10300, 0,
530 GDB_OSABI_LINUX, am33_linux_init_osabi);