mn10300-linux-tdep.c revision 1.7
1/* Target-dependent code for the Matsushita MN10300 for GDB, the GNU debugger.
2
3   Copyright (C) 2003-2017 Free Software Foundation, Inc.
4
5   This file is part of GDB.
6
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 3 of the License, or
10   (at your option) any later version.
11
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.
16
17   You should have received a copy of the GNU General Public License
18   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20#include "defs.h"
21#include "gdbcore.h"
22#include "regcache.h"
23#include "mn10300-tdep.h"
24#include "bfd.h"
25#include "elf-bfd.h"
26#include "osabi.h"
27#include "regset.h"
28#include "solib-svr4.h"
29#include "frame.h"
30#include "trad-frame.h"
31#include "tramp-frame.h"
32#include "linux-tdep.h"
33
34/* Transliterated from <asm-mn10300/elf.h>...  */
35#define MN10300_ELF_NGREG 28
36#define MN10300_ELF_NFPREG 32
37
38typedef gdb_byte   mn10300_elf_greg_t[4];
39typedef mn10300_elf_greg_t mn10300_elf_gregset_t[MN10300_ELF_NGREG];
40
41typedef gdb_byte   mn10300_elf_fpreg_t[4];
42typedef struct
43{
44  mn10300_elf_fpreg_t fpregs[MN10300_ELF_NFPREG];
45  gdb_byte    fpcr[4];
46} mn10300_elf_fpregset_t;
47
48/* elf_gregset_t register indices stolen from include/asm-mn10300/ptrace.h.  */
49#define MN10300_ELF_GREGSET_T_REG_INDEX_A3	0
50#define MN10300_ELF_GREGSET_T_REG_INDEX_A2	1
51#define MN10300_ELF_GREGSET_T_REG_INDEX_D3	2
52#define	MN10300_ELF_GREGSET_T_REG_INDEX_D2	3
53#define MN10300_ELF_GREGSET_T_REG_INDEX_MCVF	4
54#define	MN10300_ELF_GREGSET_T_REG_INDEX_MCRL	5
55#define MN10300_ELF_GREGSET_T_REG_INDEX_MCRH	6
56#define	MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ	7
57#define	MN10300_ELF_GREGSET_T_REG_INDEX_E1	8
58#define	MN10300_ELF_GREGSET_T_REG_INDEX_E0	9
59#define	MN10300_ELF_GREGSET_T_REG_INDEX_E7	10
60#define	MN10300_ELF_GREGSET_T_REG_INDEX_E6	11
61#define	MN10300_ELF_GREGSET_T_REG_INDEX_E5	12
62#define	MN10300_ELF_GREGSET_T_REG_INDEX_E4	13
63#define	MN10300_ELF_GREGSET_T_REG_INDEX_E3	14
64#define	MN10300_ELF_GREGSET_T_REG_INDEX_E2	15
65#define	MN10300_ELF_GREGSET_T_REG_INDEX_SP	16
66#define	MN10300_ELF_GREGSET_T_REG_INDEX_LAR	17
67#define	MN10300_ELF_GREGSET_T_REG_INDEX_LIR	18
68#define	MN10300_ELF_GREGSET_T_REG_INDEX_MDR	19
69#define	MN10300_ELF_GREGSET_T_REG_INDEX_A1	20
70#define	MN10300_ELF_GREGSET_T_REG_INDEX_A0	21
71#define	MN10300_ELF_GREGSET_T_REG_INDEX_D1	22
72#define	MN10300_ELF_GREGSET_T_REG_INDEX_D0	23
73#define MN10300_ELF_GREGSET_T_REG_INDEX_ORIG_D0	24
74#define	MN10300_ELF_GREGSET_T_REG_INDEX_EPSW	25
75#define	MN10300_ELF_GREGSET_T_REG_INDEX_PC	26
76
77/* New gdbarch API for corefile registers.
78   Given a section name and size, create a struct reg object
79   with a supply_register and a collect_register method.  */
80
81/* Copy register value of REGNUM from regset to regcache.
82   If REGNUM is -1, do this for all gp registers in regset.  */
83
84static void
85am33_supply_gregset_method (const struct regset *regset,
86			    struct regcache *regcache,
87			    int regnum, const void *gregs, size_t len)
88{
89  char zerobuf[MAX_REGISTER_SIZE];
90  const mn10300_elf_greg_t *regp = (const mn10300_elf_greg_t *) gregs;
91  int i;
92
93  gdb_assert (len >= sizeof (mn10300_elf_gregset_t));
94
95  switch (regnum) {
96  case E_D0_REGNUM:
97    regcache_raw_supply (regcache, E_D0_REGNUM,
98			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D0));
99    break;
100  case E_D1_REGNUM:
101    regcache_raw_supply (regcache, E_D1_REGNUM,
102			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D1));
103    break;
104  case E_D2_REGNUM:
105    regcache_raw_supply (regcache, E_D2_REGNUM,
106			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D2));
107    break;
108  case E_D3_REGNUM:
109    regcache_raw_supply (regcache, E_D3_REGNUM,
110			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D3));
111    break;
112  case E_A0_REGNUM:
113    regcache_raw_supply (regcache, E_A0_REGNUM,
114			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A0));
115    break;
116  case E_A1_REGNUM:
117    regcache_raw_supply (regcache, E_A1_REGNUM,
118			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A1));
119    break;
120  case E_A2_REGNUM:
121    regcache_raw_supply (regcache, E_A2_REGNUM,
122			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A2));
123    break;
124  case E_A3_REGNUM:
125    regcache_raw_supply (regcache, E_A3_REGNUM,
126			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A3));
127    break;
128  case E_SP_REGNUM:
129    regcache_raw_supply (regcache, E_SP_REGNUM,
130			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_SP));
131    break;
132  case E_PC_REGNUM:
133    regcache_raw_supply (regcache, E_PC_REGNUM,
134			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_PC));
135    break;
136  case E_MDR_REGNUM:
137    regcache_raw_supply (regcache, E_MDR_REGNUM,
138			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDR));
139    break;
140  case E_PSW_REGNUM:
141    regcache_raw_supply (regcache, E_PSW_REGNUM,
142			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_EPSW));
143    break;
144  case E_LIR_REGNUM:
145    regcache_raw_supply (regcache, E_LIR_REGNUM,
146			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LIR));
147    break;
148  case E_LAR_REGNUM:
149    regcache_raw_supply (regcache, E_LAR_REGNUM,
150			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LAR));
151    break;
152  case E_MDRQ_REGNUM:
153    regcache_raw_supply (regcache, E_MDRQ_REGNUM,
154			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ));
155    break;
156  case E_E0_REGNUM:
157    regcache_raw_supply (regcache, E_E0_REGNUM,
158			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E0));
159    break;
160  case E_E1_REGNUM:
161    regcache_raw_supply (regcache, E_E1_REGNUM,
162			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E1));
163    break;
164  case E_E2_REGNUM:
165    regcache_raw_supply (regcache, E_E2_REGNUM,
166			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E2));
167    break;
168  case E_E3_REGNUM:
169    regcache_raw_supply (regcache, E_E3_REGNUM,
170			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E3));
171    break;
172  case E_E4_REGNUM:
173    regcache_raw_supply (regcache, E_E4_REGNUM,
174			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E4));
175    break;
176  case E_E5_REGNUM:
177    regcache_raw_supply (regcache, E_E5_REGNUM,
178			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E5));
179    break;
180  case E_E6_REGNUM:
181    regcache_raw_supply (regcache, E_E6_REGNUM,
182			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E6));
183    break;
184  case E_E7_REGNUM:
185    regcache_raw_supply (regcache, E_E7_REGNUM,
186			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E7));
187    break;
188
189    /* ssp, msp, and usp are inaccessible.  */
190  case E_E8_REGNUM:
191    memset (zerobuf, 0, MAX_REGISTER_SIZE);
192    regcache_raw_supply (regcache, E_E8_REGNUM, zerobuf);
193    break;
194  case E_E9_REGNUM:
195    memset (zerobuf, 0, MAX_REGISTER_SIZE);
196    regcache_raw_supply (regcache, E_E9_REGNUM, zerobuf);
197    break;
198  case E_E10_REGNUM:
199    memset (zerobuf, 0, MAX_REGISTER_SIZE);
200    regcache_raw_supply (regcache, E_E10_REGNUM, zerobuf);
201
202    break;
203  case E_MCRH_REGNUM:
204    regcache_raw_supply (regcache, E_MCRH_REGNUM,
205			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRH));
206    break;
207  case E_MCRL_REGNUM:
208    regcache_raw_supply (regcache, E_MCRL_REGNUM,
209			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRL));
210    break;
211  case E_MCVF_REGNUM:
212    regcache_raw_supply (regcache, E_MCVF_REGNUM,
213			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCVF));
214    break;
215  case E_FPCR_REGNUM:
216    /* FPCR is numbered among the GP regs, but handled as an FP reg.
217       Do nothing.  */
218    break;
219  case E_FPCR_REGNUM + 1:
220    /* The two unused registers beyond fpcr are inaccessible.  */
221    memset (zerobuf, 0, MAX_REGISTER_SIZE);
222    regcache_raw_supply (regcache, E_FPCR_REGNUM + 1, zerobuf);
223    break;
224  case E_FPCR_REGNUM + 2:
225    memset (zerobuf, 0, MAX_REGISTER_SIZE);
226    regcache_raw_supply (regcache, E_FPCR_REGNUM + 2, zerobuf);
227    break;
228  default:	/* An error, obviously, but should we error out?  */
229    break;
230  case -1:
231    for (i = 0; i < MN10300_ELF_NGREG; i++)
232      am33_supply_gregset_method (regset, regcache, i, gregs, len);
233    break;
234  }
235  return;
236}
237
238/* Copy fp register value of REGNUM from regset to regcache.
239   If REGNUM is -1, do this for all fp registers in regset.  */
240
241static void
242am33_supply_fpregset_method (const struct regset *regset,
243			     struct regcache *regcache,
244			     int regnum, const void *fpregs, size_t len)
245{
246  const mn10300_elf_fpregset_t *fpregset
247    = (const mn10300_elf_fpregset_t *) fpregs;
248
249  gdb_assert (len >= sizeof (mn10300_elf_fpregset_t));
250
251  if (regnum == -1)
252    {
253      int i;
254
255      for (i = 0; i < MN10300_ELF_NFPREG; i++)
256	am33_supply_fpregset_method (regset, regcache,
257	                             E_FS0_REGNUM + i, fpregs, len);
258      am33_supply_fpregset_method (regset, regcache,
259				   E_FPCR_REGNUM, fpregs, len);
260    }
261  else if (regnum == E_FPCR_REGNUM)
262    regcache_raw_supply (regcache, E_FPCR_REGNUM,
263			 &fpregset->fpcr);
264  else if (E_FS0_REGNUM <= regnum
265	   && regnum < E_FS0_REGNUM + MN10300_ELF_NFPREG)
266    regcache_raw_supply (regcache, regnum,
267			 &fpregset->fpregs[regnum - E_FS0_REGNUM]);
268
269  return;
270}
271
272/* Copy register values from regcache to regset.  */
273
274static void
275am33_collect_gregset_method (const struct regset *regset,
276			     const struct regcache *regcache,
277			     int regnum, void *gregs, size_t len)
278{
279  mn10300_elf_gregset_t *regp = (gdb_byte (*)[28][4]) gregs;
280  int i;
281
282  gdb_assert (len >= sizeof (mn10300_elf_gregset_t));
283
284  switch (regnum) {
285  case E_D0_REGNUM:
286    regcache_raw_collect (regcache, E_D0_REGNUM,
287			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D0));
288    break;
289  case E_D1_REGNUM:
290    regcache_raw_collect (regcache, E_D1_REGNUM,
291			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D1));
292    break;
293  case E_D2_REGNUM:
294    regcache_raw_collect (regcache, E_D2_REGNUM,
295			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D2));
296    break;
297  case E_D3_REGNUM:
298    regcache_raw_collect (regcache, E_D3_REGNUM,
299			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D3));
300    break;
301  case E_A0_REGNUM:
302    regcache_raw_collect (regcache, E_A0_REGNUM,
303			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A0));
304    break;
305  case E_A1_REGNUM:
306    regcache_raw_collect (regcache, E_A1_REGNUM,
307			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A1));
308    break;
309  case E_A2_REGNUM:
310    regcache_raw_collect (regcache, E_A2_REGNUM,
311			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A2));
312    break;
313  case E_A3_REGNUM:
314    regcache_raw_collect (regcache, E_A3_REGNUM,
315			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A3));
316    break;
317  case E_SP_REGNUM:
318    regcache_raw_collect (regcache, E_SP_REGNUM,
319			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_SP));
320    break;
321  case E_PC_REGNUM:
322    regcache_raw_collect (regcache, E_PC_REGNUM,
323			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_PC));
324    break;
325  case E_MDR_REGNUM:
326    regcache_raw_collect (regcache, E_MDR_REGNUM,
327			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDR));
328    break;
329  case E_PSW_REGNUM:
330    regcache_raw_collect (regcache, E_PSW_REGNUM,
331			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_EPSW));
332    break;
333  case E_LIR_REGNUM:
334    regcache_raw_collect (regcache, E_LIR_REGNUM,
335			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LIR));
336    break;
337  case E_LAR_REGNUM:
338    regcache_raw_collect (regcache, E_LAR_REGNUM,
339			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LAR));
340    break;
341  case E_MDRQ_REGNUM:
342    regcache_raw_collect (regcache, E_MDRQ_REGNUM,
343			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ));
344    break;
345  case E_E0_REGNUM:
346    regcache_raw_collect (regcache, E_E0_REGNUM,
347			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E0));
348    break;
349  case E_E1_REGNUM:
350    regcache_raw_collect (regcache, E_E1_REGNUM,
351			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E1));
352    break;
353  case E_E2_REGNUM:
354    regcache_raw_collect (regcache, E_E2_REGNUM,
355			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E2));
356    break;
357  case E_E3_REGNUM:
358    regcache_raw_collect (regcache, E_E3_REGNUM,
359			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E3));
360    break;
361  case E_E4_REGNUM:
362    regcache_raw_collect (regcache, E_E4_REGNUM,
363			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E4));
364    break;
365  case E_E5_REGNUM:
366    regcache_raw_collect (regcache, E_E5_REGNUM,
367			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E5));
368    break;
369  case E_E6_REGNUM:
370    regcache_raw_collect (regcache, E_E6_REGNUM,
371			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E6));
372    break;
373  case E_E7_REGNUM:
374    regcache_raw_collect (regcache, E_E7_REGNUM,
375			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E7));
376    break;
377
378    /* ssp, msp, and usp are inaccessible.  */
379  case E_E8_REGNUM:
380    /* The gregset struct has noplace to put this: do nothing.  */
381    break;
382  case E_E9_REGNUM:
383    /* The gregset struct has noplace to put this: do nothing.  */
384    break;
385  case E_E10_REGNUM:
386    /* The gregset struct has noplace to put this: do nothing.  */
387    break;
388  case E_MCRH_REGNUM:
389    regcache_raw_collect (regcache, E_MCRH_REGNUM,
390			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRH));
391    break;
392  case E_MCRL_REGNUM:
393    regcache_raw_collect (regcache, E_MCRL_REGNUM,
394			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRL));
395    break;
396  case E_MCVF_REGNUM:
397    regcache_raw_collect (regcache, E_MCVF_REGNUM,
398			 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCVF));
399    break;
400  case E_FPCR_REGNUM:
401    /* FPCR is numbered among the GP regs, but handled as an FP reg.
402       Do nothing.  */
403    break;
404  case E_FPCR_REGNUM + 1:
405    /* The gregset struct has noplace to put this: do nothing.  */
406    break;
407  case E_FPCR_REGNUM + 2:
408    /* The gregset struct has noplace to put this: do nothing.  */
409    break;
410  default:	/* An error, obviously, but should we error out?  */
411    break;
412  case -1:
413    for (i = 0; i < MN10300_ELF_NGREG; i++)
414      am33_collect_gregset_method (regset, regcache, i, gregs, len);
415    break;
416  }
417  return;
418}
419
420/* Copy fp register values from regcache to regset.  */
421
422static void
423am33_collect_fpregset_method (const struct regset *regset,
424			      const struct regcache *regcache,
425			      int regnum, void *fpregs, size_t len)
426{
427  mn10300_elf_fpregset_t *fpregset = (mn10300_elf_fpregset_t *) fpregs;
428
429  gdb_assert (len >= sizeof (mn10300_elf_fpregset_t));
430
431  if (regnum == -1)
432    {
433      int i;
434      for (i = 0; i < MN10300_ELF_NFPREG; i++)
435	am33_collect_fpregset_method (regset, regcache, E_FS0_REGNUM + i,
436	                              fpregs, len);
437      am33_collect_fpregset_method (regset, regcache,
438				    E_FPCR_REGNUM, fpregs, len);
439    }
440  else if (regnum == E_FPCR_REGNUM)
441    regcache_raw_collect (regcache, E_FPCR_REGNUM,
442			  &fpregset->fpcr);
443  else if (E_FS0_REGNUM <= regnum
444           && regnum < E_FS0_REGNUM + MN10300_ELF_NFPREG)
445    regcache_raw_collect (regcache, regnum,
446			  &fpregset->fpregs[regnum - E_FS0_REGNUM]);
447
448  return;
449}
450
451static const struct regset am33_gregset =
452  {
453    NULL, am33_supply_gregset_method, am33_collect_gregset_method
454  };
455
456static const struct regset am33_fpregset =
457  {
458    NULL, am33_supply_fpregset_method, am33_collect_fpregset_method
459  };
460
461/* Iterate over core file register note sections.  */
462
463static void
464am33_iterate_over_regset_sections (struct gdbarch *gdbarch,
465				   iterate_over_regset_sections_cb *cb,
466				   void *cb_data,
467				   const struct regcache *regcache)
468{
469  cb (".reg", sizeof (mn10300_elf_gregset_t), &am33_gregset,
470      NULL, cb_data);
471  cb (".reg2", sizeof(mn10300_elf_fpregset_t), &am33_fpregset,
472      NULL, cb_data);
473}
474
475static void
476am33_linux_sigframe_cache_init (const struct tramp_frame *self,
477                                struct frame_info *this_frame,
478			        struct trad_frame_cache *this_cache,
479			        CORE_ADDR func);
480
481static const struct tramp_frame am33_linux_sigframe = {
482  SIGTRAMP_FRAME,
483  1,
484  {
485    /* mov     119,d0 */
486    { 0x2c, -1 },
487    { 0x77, -1 },
488    { 0x00, -1 },
489    /* syscall 0 */
490    { 0xf0, -1 },
491    { 0xe0, -1 },
492    { TRAMP_SENTINEL_INSN, -1 }
493  },
494  am33_linux_sigframe_cache_init
495};
496
497static const struct tramp_frame am33_linux_rt_sigframe = {
498  SIGTRAMP_FRAME,
499  1,
500  {
501    /* mov     173,d0 */
502    { 0x2c, -1 },
503    { 0xad, -1 },
504    { 0x00, -1 },
505    /* syscall 0 */
506    { 0xf0, -1 },
507    { 0xe0, -1 },
508    { TRAMP_SENTINEL_INSN, -1 }
509  },
510  am33_linux_sigframe_cache_init
511};
512
513/* Relevant struct definitions for signal handling...
514
515From arch/mn10300/kernel/sigframe.h:
516
517struct sigframe
518{
519	void (*pretcode)(void);
520	int sig;
521	struct sigcontext *psc;
522	struct sigcontext sc;
523	struct fpucontext fpuctx;
524	unsigned long extramask[_NSIG_WORDS-1];
525	char retcode[8];
526};
527
528struct rt_sigframe
529{
530	void (*pretcode)(void);
531	int sig;
532	struct siginfo *pinfo;
533	void *puc;
534	struct siginfo info;
535	struct ucontext uc;
536	struct fpucontext fpuctx;
537	char retcode[8];
538};
539
540From include/asm-mn10300/ucontext.h:
541
542struct ucontext {
543	unsigned long	  uc_flags;
544	struct ucontext  *uc_link;
545	stack_t		  uc_stack;
546	struct sigcontext uc_mcontext;
547	sigset_t	  uc_sigmask;
548};
549
550From include/asm-mn10300/sigcontext.h:
551
552struct fpucontext {
553	unsigned long	fs[32];
554	unsigned long	fpcr;
555};
556
557struct sigcontext {
558	unsigned long	d0;
559	unsigned long	d1;
560	unsigned long	d2;
561	unsigned long	d3;
562	unsigned long	a0;
563	unsigned long	a1;
564	unsigned long	a2;
565	unsigned long	a3;
566	unsigned long	e0;
567	unsigned long	e1;
568	unsigned long	e2;
569	unsigned long	e3;
570	unsigned long	e4;
571	unsigned long	e5;
572	unsigned long	e6;
573	unsigned long	e7;
574	unsigned long	lar;
575	unsigned long	lir;
576	unsigned long	mdr;
577	unsigned long	mcvf;
578	unsigned long	mcrl;
579	unsigned long	mcrh;
580	unsigned long	mdrq;
581	unsigned long	sp;
582	unsigned long	epsw;
583	unsigned long	pc;
584	struct fpucontext *fpucontext;
585	unsigned long	oldmask;
586}; */
587
588
589#define AM33_SIGCONTEXT_D0 0
590#define AM33_SIGCONTEXT_D1 4
591#define AM33_SIGCONTEXT_D2 8
592#define AM33_SIGCONTEXT_D3 12
593#define AM33_SIGCONTEXT_A0 16
594#define AM33_SIGCONTEXT_A1 20
595#define AM33_SIGCONTEXT_A2 24
596#define AM33_SIGCONTEXT_A3 28
597#define AM33_SIGCONTEXT_E0 32
598#define AM33_SIGCONTEXT_E1 36
599#define AM33_SIGCONTEXT_E2 40
600#define AM33_SIGCONTEXT_E3 44
601#define AM33_SIGCONTEXT_E4 48
602#define AM33_SIGCONTEXT_E5 52
603#define AM33_SIGCONTEXT_E6 56
604#define AM33_SIGCONTEXT_E7 60
605#define AM33_SIGCONTEXT_LAR 64
606#define AM33_SIGCONTEXT_LIR 68
607#define AM33_SIGCONTEXT_MDR 72
608#define AM33_SIGCONTEXT_MCVF 76
609#define AM33_SIGCONTEXT_MCRL 80
610#define AM33_SIGCONTEXT_MCRH 84
611#define AM33_SIGCONTEXT_MDRQ 88
612#define AM33_SIGCONTEXT_SP 92
613#define AM33_SIGCONTEXT_EPSW 96
614#define AM33_SIGCONTEXT_PC 100
615#define AM33_SIGCONTEXT_FPUCONTEXT 104
616
617
618static void
619am33_linux_sigframe_cache_init (const struct tramp_frame *self,
620                                struct frame_info *this_frame,
621			        struct trad_frame_cache *this_cache,
622			        CORE_ADDR func)
623{
624  CORE_ADDR sc_base, fpubase;
625  int i;
626
627  sc_base = get_frame_register_unsigned (this_frame, E_SP_REGNUM);
628  if (self == &am33_linux_sigframe)
629    {
630      sc_base += 8;
631      sc_base = get_frame_memory_unsigned (this_frame, sc_base, 4);
632    }
633  else
634    {
635      sc_base += 12;
636      sc_base = get_frame_memory_unsigned (this_frame, sc_base, 4);
637      sc_base += 20;
638    }
639
640  trad_frame_set_reg_addr (this_cache, E_D0_REGNUM,
641                           sc_base + AM33_SIGCONTEXT_D0);
642  trad_frame_set_reg_addr (this_cache, E_D1_REGNUM,
643                           sc_base + AM33_SIGCONTEXT_D1);
644  trad_frame_set_reg_addr (this_cache, E_D2_REGNUM,
645                           sc_base + AM33_SIGCONTEXT_D2);
646  trad_frame_set_reg_addr (this_cache, E_D3_REGNUM,
647                           sc_base + AM33_SIGCONTEXT_D3);
648
649  trad_frame_set_reg_addr (this_cache, E_A0_REGNUM,
650                           sc_base + AM33_SIGCONTEXT_A0);
651  trad_frame_set_reg_addr (this_cache, E_A1_REGNUM,
652                           sc_base + AM33_SIGCONTEXT_A1);
653  trad_frame_set_reg_addr (this_cache, E_A2_REGNUM,
654                           sc_base + AM33_SIGCONTEXT_A2);
655  trad_frame_set_reg_addr (this_cache, E_A3_REGNUM,
656                           sc_base + AM33_SIGCONTEXT_A3);
657
658  trad_frame_set_reg_addr (this_cache, E_E0_REGNUM,
659                           sc_base + AM33_SIGCONTEXT_E0);
660  trad_frame_set_reg_addr (this_cache, E_E1_REGNUM,
661                           sc_base + AM33_SIGCONTEXT_E1);
662  trad_frame_set_reg_addr (this_cache, E_E2_REGNUM,
663                           sc_base + AM33_SIGCONTEXT_E2);
664  trad_frame_set_reg_addr (this_cache, E_E3_REGNUM,
665                           sc_base + AM33_SIGCONTEXT_E3);
666  trad_frame_set_reg_addr (this_cache, E_E4_REGNUM,
667                           sc_base + AM33_SIGCONTEXT_E4);
668  trad_frame_set_reg_addr (this_cache, E_E5_REGNUM,
669                           sc_base + AM33_SIGCONTEXT_E5);
670  trad_frame_set_reg_addr (this_cache, E_E6_REGNUM,
671                           sc_base + AM33_SIGCONTEXT_E6);
672  trad_frame_set_reg_addr (this_cache, E_E7_REGNUM,
673                           sc_base + AM33_SIGCONTEXT_E7);
674
675  trad_frame_set_reg_addr (this_cache, E_LAR_REGNUM,
676                           sc_base + AM33_SIGCONTEXT_LAR);
677  trad_frame_set_reg_addr (this_cache, E_LIR_REGNUM,
678                           sc_base + AM33_SIGCONTEXT_LIR);
679  trad_frame_set_reg_addr (this_cache, E_MDR_REGNUM,
680                           sc_base + AM33_SIGCONTEXT_MDR);
681  trad_frame_set_reg_addr (this_cache, E_MCVF_REGNUM,
682                           sc_base + AM33_SIGCONTEXT_MCVF);
683  trad_frame_set_reg_addr (this_cache, E_MCRL_REGNUM,
684                           sc_base + AM33_SIGCONTEXT_MCRL);
685  trad_frame_set_reg_addr (this_cache, E_MDRQ_REGNUM,
686                           sc_base + AM33_SIGCONTEXT_MDRQ);
687
688  trad_frame_set_reg_addr (this_cache, E_SP_REGNUM,
689                           sc_base + AM33_SIGCONTEXT_SP);
690  trad_frame_set_reg_addr (this_cache, E_PSW_REGNUM,
691                           sc_base + AM33_SIGCONTEXT_EPSW);
692  trad_frame_set_reg_addr (this_cache, E_PC_REGNUM,
693                           sc_base + AM33_SIGCONTEXT_PC);
694
695  fpubase = get_frame_memory_unsigned (this_frame,
696                                       sc_base + AM33_SIGCONTEXT_FPUCONTEXT,
697				       4);
698  if (fpubase)
699    {
700      for (i = 0; i < 32; i++)
701	{
702	  trad_frame_set_reg_addr (this_cache, E_FS0_REGNUM + i,
703	                           fpubase + 4 * i);
704	}
705      trad_frame_set_reg_addr (this_cache, E_FPCR_REGNUM, fpubase + 4 * 32);
706    }
707
708  trad_frame_set_id (this_cache, frame_id_build (sc_base, func));
709}
710
711/* AM33 GNU/Linux osabi has been recognized.
712   Now's our chance to register our corefile handling.  */
713
714static void
715am33_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
716{
717  linux_init_abi (info, gdbarch);
718
719  set_gdbarch_iterate_over_regset_sections
720    (gdbarch, am33_iterate_over_regset_sections);
721  set_solib_svr4_fetch_link_map_offsets
722    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
723
724  tramp_frame_prepend_unwinder (gdbarch, &am33_linux_sigframe);
725  tramp_frame_prepend_unwinder (gdbarch, &am33_linux_rt_sigframe);
726}
727
728/* Provide a prototype to silence -Wmissing-prototypes.  */
729extern initialize_file_ftype _initialize_mn10300_linux_tdep;
730
731void
732_initialize_mn10300_linux_tdep (void)
733{
734  gdbarch_register_osabi (bfd_arch_mn10300, 0,
735			  GDB_OSABI_LINUX, am33_linux_init_osabi);
736}
737
738