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