New commands "mt set per-command {space,time,symtab} {on,off}".
[deliverable/binutils-gdb.git] / gdb / mn10300-linux-tdep.c
index bba2643e35c4defa17934b8d9bc09a2b4e2fe9f7..881af2bfa1938458840a25d148c549d5de25b23b 100644 (file)
@@ -1,12 +1,12 @@
 /* Target-dependent code for the Matsushita MN10300 for GDB, the GNU debugger.
-   Copyright 2003, 2004, 2005
-   Free Software Foundation, Inc.
+
+   Copyright (C) 2003-2013 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,9 +15,7 @@
    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., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "gdbcore.h"
 #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 <stdlib.h>
 
@@ -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,62 +470,263 @@ am33_regset_from_core_section (struct gdbarch *gdbarch,
                         am33_supply_gregset_method,
                         am33_collect_gregset_method);
 }
+\f
+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
 
-/* Fetch, and possibly build, an appropriate link_map_offsets structure
-   for mn10300 linux targets using the struct offsets defined in <link.h>.
-   Note, however, that link.h is not actually referred to in this file.
-   Instead, the relevant structs offsets were obtained from examining
-   link.h.  (We can't refer to link.h from this file because the host
-   system won't necessarily have it, or if it does, the structs which
-   it defines will refer to the host system, not the target.)  */
 
-struct link_map_offsets *
-mn10300_linux_svr4_fetch_link_map_offsets (void)
+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 struct link_map_offsets lmo;
-  static struct link_map_offsets *lmp = 0;
+  CORE_ADDR sc_base, fpubase;
+  int i;
 
-  if (lmp == 0)
+  sc_base = get_frame_register_unsigned (this_frame, E_SP_REGNUM);
+  if (self == &am33_linux_sigframe)
     {
-      lmp = &lmo;
-
-      lmo.r_debug_size = 8;    /* Actual size is 20, but this is all we
-                                   need. */
-
-      lmo.r_map_offset = 4;
-      lmo.r_map_size   = 4;
-
-      lmo.link_map_size = 20;  /* Might be larger, but this is all we
-                                   need. */
-
-      lmo.l_addr_offset = 0;
-      lmo.l_addr_size   = 4;
-
-      lmo.l_name_offset = 4;
-      lmo.l_name_size   = 4;
-
-      lmo.l_next_offset = 12;
-      lmo.l_next_size   = 4;
+      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;
+    }
 
-      lmo.l_prev_offset = 16;
-      lmo.l_prev_size   = 4;
+  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);
     }
 
-    return lmp;
+  trad_frame_set_id (this_cache, frame_id_build (sc_base, func));
 }
-
-/* AM33 Linux osabi has been recognized.
+\f
+/* 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, mn10300_linux_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)
 {
This page took 0.033313 seconds and 4 git commands to generate.