* rs6000-tdep.c (BL_MASK, BL_INSTRUCTION, BL_DISPLACEMENT_MASK):
[deliverable/binutils-gdb.git] / gdb / mips-linux-tdep.c
index 34a5b83d875c285855fd370fb4cd73f6079de505..8f30aef45ff6b978009a25f6e81400e305239b9f 100644 (file)
@@ -712,12 +712,12 @@ mips_linux_skip_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
    efficient way, but simplest.  First, declare all the unwinders.  */
 
 static void mips_linux_o32_sigframe_init (const struct tramp_frame *self,
-                                         struct frame_info *next_frame,
+                                         struct frame_info *this_frame,
                                          struct trad_frame_cache *this_cache,
                                          CORE_ADDR func);
 
 static void mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
-                                            struct frame_info *next_frame,
+                                            struct frame_info *this_frame,
                                             struct trad_frame_cache *this_cache,
                                             CORE_ADDR func);
 
@@ -853,11 +853,11 @@ static const struct tramp_frame mips_linux_n64_rt_sigframe = {
 
 static void
 mips_linux_o32_sigframe_init (const struct tramp_frame *self,
-                             struct frame_info *next_frame,
+                             struct frame_info *this_frame,
                              struct trad_frame_cache *this_cache,
                              CORE_ADDR func)
 {
-  struct gdbarch *gdbarch = get_frame_arch (next_frame);
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   int ireg, reg_position;
   CORE_ADDR sigcontext_base = func - SIGFRAME_CODE_OFFSET;
   const struct mips_regnum *regs = mips_regnum (gdbarch);
@@ -958,7 +958,7 @@ mips_linux_o32_sigframe_init (const struct tramp_frame *self,
     sigset_t            uc_sigmask;   [ mask last for extensibility ]
   };
 
-  struct rt_sigframe_n32 {
+  struct rt_sigframe {
     u32 rs_ass[4];                  [ argument save space for o32 ]
     u32 rs_code[2];                 [ signal trampoline ]
     struct siginfo rs_info;
@@ -979,15 +979,23 @@ mips_linux_o32_sigframe_init (const struct tramp_frame *self,
     unsigned long long sc_regs[32];
     unsigned long long sc_fpregs[32];
     unsigned long long sc_mdhi;
+    unsigned long long sc_hi1;
+    unsigned long long sc_hi2;
+    unsigned long long sc_hi3;
     unsigned long long sc_mdlo;
+    unsigned long long sc_lo1;
+    unsigned long long sc_lo2;
+    unsigned long long sc_lo3;
     unsigned long long sc_pc;
-    unsigned int       sc_status;
     unsigned int       sc_fpc_csr;
-    unsigned int       sc_fpc_eir;
     unsigned int       sc_used_math;
-    unsigned int       sc_cause;
-    unsigned int       sc_badvaddr;
-  };  */
+    unsigned int       sc_dsp;
+    unsigned int       sc_reserved;
+  };
+
+  That is the post-2.6.12 definition of the 64-bit sigcontext; before
+  then, there were no hi1-hi3 or lo1-lo3.  Cause and badvaddr were
+  included too.  */
 /* *INDENT-ON* */
 
 #define N32_STACK_T_SIZE               STACK_T_SIZE
@@ -1004,22 +1012,19 @@ mips_linux_o32_sigframe_init (const struct tramp_frame *self,
 #define N64_SIGCONTEXT_REGS     (0 * 8)
 #define N64_SIGCONTEXT_FPREGS   (32 * 8)
 #define N64_SIGCONTEXT_HI       (64 * 8)
-#define N64_SIGCONTEXT_LO       (65 * 8)
-#define N64_SIGCONTEXT_PC       (66 * 8)
-#define N64_SIGCONTEXT_FPCSR    (67 * 8 + 1 * 4)
-#define N64_SIGCONTEXT_FIR      (67 * 8 + 2 * 4)
-#define N64_SIGCONTEXT_CAUSE    (67 * 8 + 4 * 4)
-#define N64_SIGCONTEXT_BADVADDR (67 * 8 + 5 * 4)
+#define N64_SIGCONTEXT_LO       (68 * 8)
+#define N64_SIGCONTEXT_PC       (72 * 8)
+#define N64_SIGCONTEXT_FPCSR    (73 * 8)
 
 #define N64_SIGCONTEXT_REG_SIZE 8
 
 static void
 mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
-                                struct frame_info *next_frame,
+                                struct frame_info *this_frame,
                                 struct trad_frame_cache *this_cache,
                                 CORE_ADDR func)
 {
-  struct gdbarch *gdbarch = get_frame_arch (next_frame);
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   int ireg, reg_position;
   CORE_ADDR sigcontext_base = func - SIGFRAME_CODE_OFFSET;
   const struct mips_regnum *regs = mips_regnum (gdbarch);
@@ -1063,12 +1068,6 @@ mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
   trad_frame_set_reg_addr (this_cache,
                           regs->lo + gdbarch_num_regs (gdbarch),
                           sigcontext_base + N64_SIGCONTEXT_LO);
-  trad_frame_set_reg_addr (this_cache,
-                          regs->cause + gdbarch_num_regs (gdbarch),
-                          sigcontext_base + N64_SIGCONTEXT_CAUSE);
-  trad_frame_set_reg_addr (this_cache,
-                          regs->badvaddr + gdbarch_num_regs (gdbarch),
-                          sigcontext_base + N64_SIGCONTEXT_BADVADDR);
 
   /* Choice of the bottom of the sigframe is somewhat arbitrary.  */
   trad_frame_set_id (this_cache,
@@ -1102,6 +1101,26 @@ mips_linux_restart_reg_p (struct gdbarch *gdbarch)
   return register_size (gdbarch, MIPS_RESTART_REGNUM) > 0;
 }
 
+/* When FRAME is at a syscall instruction, return the PC of the next
+   instruction to be executed.  */
+
+CORE_ADDR
+mips_linux_syscall_next_pc (struct frame_info *frame)
+{
+  CORE_ADDR pc = get_frame_pc (frame);
+  ULONGEST v0 = get_frame_register_unsigned (frame, MIPS_V0_REGNUM);
+
+  /* If we are about to make a sigreturn syscall, use the unwinder to
+     decode the signal frame.  */
+  if (v0 == MIPS_NR_sigreturn
+      || v0 == MIPS_NR_rt_sigreturn
+      || v0 == MIPS_NR_N64_rt_sigreturn
+      || v0 == MIPS_NR_N32_rt_sigreturn)
+    return frame_pc_unwind (get_current_frame ());
+
+  return pc + 4;
+}
+
 /* Initialize one of the GNU/Linux OS ABIs.  */
 
 static void
@@ -1149,7 +1168,6 @@ mips_linux_init_abi (struct gdbarch_info info,
        tramp_frame_prepend_unwinder (gdbarch, &mips_linux_n64_rt_sigframe);
        break;
       default:
-       internal_error (__FILE__, __LINE__, _("can't handle ABI"));
        break;
     }
 
@@ -1177,6 +1195,8 @@ mips_linux_init_abi (struct gdbarch_info info,
   set_gdbarch_core_read_description (gdbarch,
                                     mips_linux_core_read_description);
 
+  tdep->syscall_next_pc = mips_linux_syscall_next_pc;
+
   if (tdesc_data)
     {
       const struct tdesc_feature *feature;
This page took 0.024976 seconds and 4 git commands to generate.