Add am33 linux signal frame support.
authorKevin Buettner <kevinb@redhat.com>
Tue, 28 Feb 2006 22:38:04 +0000 (22:38 +0000)
committerKevin Buettner <kevinb@redhat.com>
Tue, 28 Feb 2006 22:38:04 +0000 (22:38 +0000)
gdb/ChangeLog
gdb/Makefile.in
gdb/mn10300-linux-tdep.c

index de59ea5..e3784ac 100644 (file)
@@ -1,5 +1,25 @@
 2006-02-28  Kevin Buettner  <kevinb@redhat.com>
 
+       * Makefile.in (mn10300-linux-tdep.o): Update dependencies.
+       * mn10300-linux-tdep.c (frame.h, trad-frame.h, tramp-frame.h):
+       Include.
+       (am33_linux_sigframe_cache_init): New function.
+       (am33_linux_sigframe, am33_linux_rt_sigframe): New signal frame
+       descriptions.
+       (AM33_SIGCONTEXT_D0, AM33_SIGCONTEXT_D1, AM33_SIGCONTEXT_D2)
+       (AM33_SIGCONTEXT_D3, AM33_SIGCONTEXT_A0, AM33_SIGCONTEXT_A1)
+       (AM33_SIGCONTEXT_A2, AM33_SIGCONTEXT_A3, AM33_SIGCONTEXT_E0)
+       (AM33_SIGCONTEXT_E1, AM33_SIGCONTEXT_E2, AM33_SIGCONTEXT_E3)
+       (AM33_SIGCONTEXT_E4, AM33_SIGCONTEXT_E5, AM33_SIGCONTEXT_E6)
+       (AM33_SIGCONTEXT_E7, AM33_SIGCONTEXT_LAR, AM33_SIGCONTEXT_LIR)
+       (AM33_SIGCONTEXT_MDR, AM33_SIGCONTEXT_MCVF, AM33_SIGCONTEXT_MCRL)
+       (AM33_SIGCONTEXT_MCRH, AM33_SIGCONTEXT_MDRQ, AM33_SIGCONTEXT_SP)
+       (AM33_SIGCONTEXT_EPSW, AM33_SIGCONTEXT_PC, AM33_SIGCONTEXT_FPUCONTEXT):
+       New constants.
+       (am33_linux_init_osabi): Register signal frame unwinders.
+
+2006-02-28  Kevin Buettner  <kevinb@redhat.com>
+
        * mn10300-tdep.c (mn10300_analyze_prologue):  Implement backtrack
        out of pattern match by saving relevant state.  Fix stack size
        adjustment bug.
index 92bc0c4..d5abb4f 100644 (file)
@@ -2326,7 +2326,8 @@ mipsv4-nat.o: mipsv4-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) $(target_h) \
        $(regcache_h) $(gregset_h)
 mn10300-linux-tdep.o: mn10300-linux-tdep.c $(defs_h) $(gdbcore_h) \
        $(gdb_string_h) $(regcache_h) $(mn10300_tdep_h) $(gdb_assert_h) \
-       $(bfd_h) $(elf_bfd_h) $(osabi_h) $(regset_h) $(solib_svr4_h)
+       $(bfd_h) $(elf_bfd_h) $(osabi_h) $(regset_h) $(solib_svr4_h) \
+       $(frame_h) $(trad_frame_h) $(tramp_frame_h)
 mn10300-tdep.o: mn10300-tdep.c $(defs_h) $(arch_utils_h) $(dis_asm_h) \
        $(gdbtypes_h) $(regcache_h) $(gdb_string_h) $(gdb_assert_h) \
        $(frame_h) $(frame_unwind_h) $(frame_base_h) $(trad_frame_h) \
index a659d85..a2d6f01 100644 (file)
@@ -30,6 +30,9 @@
 #include "osabi.h"
 #include "regset.h"
 #include "solib-svr4.h"
+#include "frame.h"
+#include "trad-frame.h"
+#include "tramp-frame.h"
 
 #include <stdlib.h>
 
@@ -467,7 +470,240 @@ 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 *next_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 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
+
+
+static void
+am33_linux_sigframe_cache_init (const struct tramp_frame *self,
+                                struct frame_info *next_frame,
+                               struct trad_frame_cache *this_cache,
+                               CORE_ADDR func)
+{
+  CORE_ADDR sc_base, fpubase;
+  int i;
 
+  sc_base = frame_unwind_register_unsigned (next_frame, E_SP_REGNUM);
+  if (self == &am33_linux_sigframe)
+    {
+      sc_base += 8;
+    }
+  else
+    {
+      sc_base += 12;
+      sc_base = get_frame_memory_unsigned (next_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 (next_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));
+}
+\f
 /* AM33 Linux osabi has been recognized.
    Now's our chance to register our corefile handling.  */
 
@@ -478,6 +714,9 @@ am33_linux_init_osabi (struct gdbarch_info gdbinfo, struct gdbarch *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);
 }
 
 void