X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fmn10300-linux-tdep.c;h=6acae56dbb1b34679bbfcbdcd69391e97e244da2;hb=322f9c2100806387b8ace4df7a2b940b03b3d703;hp=a659d855307fba37e155e8561345d7166c53e187;hpb=197e01b6dcd118b70ed3621b62b2ff3fa929d50f;p=deliverable%2Fbinutils-gdb.git
diff --git a/gdb/mn10300-linux-tdep.c b/gdb/mn10300-linux-tdep.c
index a659d85530..6acae56dbb 100644
--- a/gdb/mn10300-linux-tdep.c
+++ b/gdb/mn10300-linux-tdep.c
@@ -1,12 +1,12 @@
/* Target-dependent code for the Matsushita MN10300 for GDB, the GNU debugger.
- Copyright (C) 2003, 2004, 2005
- Free Software Foundation, Inc.
+
+ Copyright (C) 2003-2014 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@@ -15,13 +15,11 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see . */
#include "defs.h"
#include "gdbcore.h"
-#include "gdb_string.h"
+#include
#include "regcache.h"
#include "mn10300-tdep.h"
#include "gdb_assert.h"
@@ -30,6 +28,10 @@
#include "osabi.h"
#include "regset.h"
#include "solib-svr4.h"
+#include "frame.h"
+#include "trad-frame.h"
+#include "tramp-frame.h"
+#include "linux-tdep.h"
#include
@@ -80,7 +82,7 @@ typedef struct
Given a section name and size, create a struct reg object
with a supply_register and a collect_register method. */
-/* Copy register value of REGNUM from regset to regcache.
+/* Copy register value of REGNUM from regset to regcache.
If REGNUM is -1, do this for all gp registers in regset. */
static void
@@ -237,8 +239,8 @@ am33_supply_gregset_method (const struct regset *regset,
return;
}
-/* Copy fp register value of REGNUM from regset to regcache.
- If REGNUM is -1, do this for all fp registers in regset. */
+/* Copy fp register value of REGNUM from regset to regcache.
+ If REGNUM is -1, do this for all fp registers in regset. */
static void
am33_supply_fpregset_method (const struct regset *regset,
@@ -260,10 +262,11 @@ am33_supply_fpregset_method (const struct regset *regset,
E_FPCR_REGNUM, fpregs, len);
}
else if (regnum == E_FPCR_REGNUM)
- regcache_raw_supply (current_regcache, E_FPCR_REGNUM,
+ regcache_raw_supply (regcache, E_FPCR_REGNUM,
&fpregset->fpcr);
- else if (E_FS0_REGNUM <= regnum && regnum < E_FS0_REGNUM + MN10300_ELF_NFPREG)
- regcache_raw_supply (current_regcache, regnum,
+ else if (E_FS0_REGNUM <= regnum
+ && regnum < E_FS0_REGNUM + MN10300_ELF_NFPREG)
+ regcache_raw_supply (regcache, regnum,
&fpregset->fpregs[regnum - E_FS0_REGNUM]);
return;
@@ -438,11 +441,11 @@ am33_collect_fpregset_method (const struct regset *regset,
E_FPCR_REGNUM, fpregs, len);
}
else if (regnum == E_FPCR_REGNUM)
- regcache_raw_collect (current_regcache, E_FPCR_REGNUM,
+ regcache_raw_collect (regcache, E_FPCR_REGNUM,
&fpregset->fpcr);
else if (E_FS0_REGNUM <= regnum
&& regnum < E_FS0_REGNUM + MN10300_ELF_NFPREG)
- regcache_raw_collect (current_regcache, regnum,
+ regcache_raw_collect (regcache, regnum,
&fpregset->fpregs[regnum - E_FS0_REGNUM]);
return;
@@ -467,19 +470,263 @@ am33_regset_from_core_section (struct gdbarch *gdbarch,
am33_supply_gregset_method,
am33_collect_gregset_method);
}
+
+static void
+am33_linux_sigframe_cache_init (const struct tramp_frame *self,
+ struct frame_info *this_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func);
+
+static const struct tramp_frame am33_linux_sigframe = {
+ SIGTRAMP_FRAME,
+ 1,
+ {
+ /* mov 119,d0 */
+ { 0x2c, -1 },
+ { 0x77, -1 },
+ { 0x00, -1 },
+ /* syscall 0 */
+ { 0xf0, -1 },
+ { 0xe0, -1 },
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ am33_linux_sigframe_cache_init
+};
+
+static const struct tramp_frame am33_linux_rt_sigframe = {
+ SIGTRAMP_FRAME,
+ 1,
+ {
+ /* mov 173,d0 */
+ { 0x2c, -1 },
+ { 0xad, -1 },
+ { 0x00, -1 },
+ /* syscall 0 */
+ { 0xf0, -1 },
+ { 0xe0, -1 },
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ am33_linux_sigframe_cache_init
+};
+
+/* Relevant struct definitions for signal handling...
+
+From arch/mn10300/kernel/sigframe.h:
+
+struct sigframe
+{
+ void (*pretcode)(void);
+ int sig;
+ struct sigcontext *psc;
+ struct sigcontext sc;
+ struct fpucontext fpuctx;
+ unsigned long extramask[_NSIG_WORDS-1];
+ char retcode[8];
+};
+
+struct rt_sigframe
+{
+ void (*pretcode)(void);
+ int sig;
+ struct siginfo *pinfo;
+ void *puc;
+ struct siginfo info;
+ struct ucontext uc;
+ struct fpucontext fpuctx;
+ char retcode[8];
+};
+
+From include/asm-mn10300/ucontext.h:
+
+struct ucontext {
+ unsigned long uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ struct sigcontext uc_mcontext;
+ sigset_t uc_sigmask;
+};
+
+From include/asm-mn10300/sigcontext.h:
+
+struct fpucontext {
+ unsigned long fs[32];
+ unsigned long fpcr;
+};
+
+struct sigcontext {
+ unsigned long d0;
+ unsigned long d1;
+ unsigned long d2;
+ unsigned long d3;
+ unsigned long a0;
+ unsigned long a1;
+ unsigned long a2;
+ unsigned long a3;
+ unsigned long e0;
+ unsigned long e1;
+ unsigned long e2;
+ unsigned long e3;
+ unsigned long e4;
+ unsigned long e5;
+ unsigned long e6;
+ unsigned long e7;
+ unsigned long lar;
+ unsigned long lir;
+ unsigned long mdr;
+ unsigned long mcvf;
+ unsigned long mcrl;
+ unsigned long mcrh;
+ unsigned long mdrq;
+ unsigned long sp;
+ unsigned long epsw;
+ unsigned long pc;
+ struct fpucontext *fpucontext;
+ unsigned long oldmask;
+}; */
+
+
+#define AM33_SIGCONTEXT_D0 0
+#define AM33_SIGCONTEXT_D1 4
+#define AM33_SIGCONTEXT_D2 8
+#define AM33_SIGCONTEXT_D3 12
+#define AM33_SIGCONTEXT_A0 16
+#define AM33_SIGCONTEXT_A1 20
+#define AM33_SIGCONTEXT_A2 24
+#define AM33_SIGCONTEXT_A3 28
+#define AM33_SIGCONTEXT_E0 32
+#define AM33_SIGCONTEXT_E1 36
+#define AM33_SIGCONTEXT_E2 40
+#define AM33_SIGCONTEXT_E3 44
+#define AM33_SIGCONTEXT_E4 48
+#define AM33_SIGCONTEXT_E5 52
+#define AM33_SIGCONTEXT_E6 56
+#define AM33_SIGCONTEXT_E7 60
+#define AM33_SIGCONTEXT_LAR 64
+#define AM33_SIGCONTEXT_LIR 68
+#define AM33_SIGCONTEXT_MDR 72
+#define AM33_SIGCONTEXT_MCVF 76
+#define AM33_SIGCONTEXT_MCRL 80
+#define AM33_SIGCONTEXT_MCRH 84
+#define AM33_SIGCONTEXT_MDRQ 88
+#define AM33_SIGCONTEXT_SP 92
+#define AM33_SIGCONTEXT_EPSW 96
+#define AM33_SIGCONTEXT_PC 100
+#define AM33_SIGCONTEXT_FPUCONTEXT 104
+
-/* AM33 Linux osabi has been recognized.
+static void
+am33_linux_sigframe_cache_init (const struct tramp_frame *self,
+ struct frame_info *this_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func)
+{
+ CORE_ADDR sc_base, fpubase;
+ int i;
+
+ sc_base = get_frame_register_unsigned (this_frame, E_SP_REGNUM);
+ if (self == &am33_linux_sigframe)
+ {
+ sc_base += 8;
+ sc_base = get_frame_memory_unsigned (this_frame, sc_base, 4);
+ }
+ else
+ {
+ sc_base += 12;
+ sc_base = get_frame_memory_unsigned (this_frame, sc_base, 4);
+ sc_base += 20;
+ }
+
+ trad_frame_set_reg_addr (this_cache, E_D0_REGNUM,
+ sc_base + AM33_SIGCONTEXT_D0);
+ trad_frame_set_reg_addr (this_cache, E_D1_REGNUM,
+ sc_base + AM33_SIGCONTEXT_D1);
+ trad_frame_set_reg_addr (this_cache, E_D2_REGNUM,
+ sc_base + AM33_SIGCONTEXT_D2);
+ trad_frame_set_reg_addr (this_cache, E_D3_REGNUM,
+ sc_base + AM33_SIGCONTEXT_D3);
+
+ trad_frame_set_reg_addr (this_cache, E_A0_REGNUM,
+ sc_base + AM33_SIGCONTEXT_A0);
+ trad_frame_set_reg_addr (this_cache, E_A1_REGNUM,
+ sc_base + AM33_SIGCONTEXT_A1);
+ trad_frame_set_reg_addr (this_cache, E_A2_REGNUM,
+ sc_base + AM33_SIGCONTEXT_A2);
+ trad_frame_set_reg_addr (this_cache, E_A3_REGNUM,
+ sc_base + AM33_SIGCONTEXT_A3);
+
+ trad_frame_set_reg_addr (this_cache, E_E0_REGNUM,
+ sc_base + AM33_SIGCONTEXT_E0);
+ trad_frame_set_reg_addr (this_cache, E_E1_REGNUM,
+ sc_base + AM33_SIGCONTEXT_E1);
+ trad_frame_set_reg_addr (this_cache, E_E2_REGNUM,
+ sc_base + AM33_SIGCONTEXT_E2);
+ trad_frame_set_reg_addr (this_cache, E_E3_REGNUM,
+ sc_base + AM33_SIGCONTEXT_E3);
+ trad_frame_set_reg_addr (this_cache, E_E4_REGNUM,
+ sc_base + AM33_SIGCONTEXT_E4);
+ trad_frame_set_reg_addr (this_cache, E_E5_REGNUM,
+ sc_base + AM33_SIGCONTEXT_E5);
+ trad_frame_set_reg_addr (this_cache, E_E6_REGNUM,
+ sc_base + AM33_SIGCONTEXT_E6);
+ trad_frame_set_reg_addr (this_cache, E_E7_REGNUM,
+ sc_base + AM33_SIGCONTEXT_E7);
+
+ trad_frame_set_reg_addr (this_cache, E_LAR_REGNUM,
+ sc_base + AM33_SIGCONTEXT_LAR);
+ trad_frame_set_reg_addr (this_cache, E_LIR_REGNUM,
+ sc_base + AM33_SIGCONTEXT_LIR);
+ trad_frame_set_reg_addr (this_cache, E_MDR_REGNUM,
+ sc_base + AM33_SIGCONTEXT_MDR);
+ trad_frame_set_reg_addr (this_cache, E_MCVF_REGNUM,
+ sc_base + AM33_SIGCONTEXT_MCVF);
+ trad_frame_set_reg_addr (this_cache, E_MCRL_REGNUM,
+ sc_base + AM33_SIGCONTEXT_MCRL);
+ trad_frame_set_reg_addr (this_cache, E_MDRQ_REGNUM,
+ sc_base + AM33_SIGCONTEXT_MDRQ);
+
+ trad_frame_set_reg_addr (this_cache, E_SP_REGNUM,
+ sc_base + AM33_SIGCONTEXT_SP);
+ trad_frame_set_reg_addr (this_cache, E_PSW_REGNUM,
+ sc_base + AM33_SIGCONTEXT_EPSW);
+ trad_frame_set_reg_addr (this_cache, E_PC_REGNUM,
+ sc_base + AM33_SIGCONTEXT_PC);
+
+ fpubase = get_frame_memory_unsigned (this_frame,
+ sc_base + AM33_SIGCONTEXT_FPUCONTEXT,
+ 4);
+ if (fpubase)
+ {
+ for (i = 0; i < 32; i++)
+ {
+ trad_frame_set_reg_addr (this_cache, E_FS0_REGNUM + i,
+ fpubase + 4 * i);
+ }
+ trad_frame_set_reg_addr (this_cache, E_FPCR_REGNUM, fpubase + 4 * 32);
+ }
+
+ trad_frame_set_id (this_cache, frame_id_build (sc_base, func));
+}
+
+/* AM33 GNU/Linux osabi has been recognized.
Now's our chance to register our corefile handling. */
static void
-am33_linux_init_osabi (struct gdbarch_info gdbinfo, struct gdbarch *gdbarch)
+am33_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
+ linux_init_abi (info, gdbarch);
+
set_gdbarch_regset_from_core_section (gdbarch,
am33_regset_from_core_section);
set_solib_svr4_fetch_link_map_offsets
(gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+ tramp_frame_prepend_unwinder (gdbarch, &am33_linux_sigframe);
+ tramp_frame_prepend_unwinder (gdbarch, &am33_linux_rt_sigframe);
}
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_mn10300_linux_tdep;
+
void
_initialize_mn10300_linux_tdep (void)
{