gdb
[deliverable/binutils-gdb.git] / gdb / arm-linux-tdep.c
index 2f3109c15e78ca7c418544a3a4981b49302bbd15..b7ff5ecdb4629207199a99e6cc83d866d40d51c2 100644 (file)
@@ -669,18 +669,24 @@ arm_linux_regset_from_core_section (struct gdbarch *gdbarch,
 }
 
 /* Copy the value of next pc of sigreturn and rt_sigrturn into PC,
-   and return 1.  Return 0 if it is not a rt_sigreturn/sigreturn
-   syscall.  */
+   return 1.  In addition, set IS_THUMB depending on whether we
+   will return to ARM or Thumb code.  Return 0 if it is not a
+   rt_sigreturn/sigreturn syscall.  */
 static int
 arm_linux_sigreturn_return_addr (struct frame_info *frame,
                                 unsigned long svc_number,
-                                CORE_ADDR *pc)
+                                CORE_ADDR *pc, int *is_thumb)
 {
   /* Is this a sigreturn or rt_sigreturn syscall?  */
   if (svc_number == 119 || svc_number == 173)
     {
       if (get_frame_type (frame) == SIGTRAMP_FRAME)
        {
+         ULONGEST t_bit = arm_psr_thumb_bit (frame_unwind_arch (frame));
+         CORE_ADDR cpsr
+           = frame_unwind_register_unsigned (frame, ARM_PS_REGNUM);
+
+         *is_thumb = (cpsr & t_bit) != 0;
          *pc = frame_unwind_caller_pc (frame);
          return 1;
        }
@@ -698,11 +704,11 @@ arm_linux_syscall_next_pc (struct frame_info *frame)
   CORE_ADDR return_addr = 0;
   int is_thumb = arm_frame_is_thumb (frame);
   ULONGEST svc_number = 0;
-  int is_sigreturn = 0;
 
   if (is_thumb)
     {
       svc_number = get_frame_register_unsigned (frame, 7);
+      return_addr = pc + 2;
     }
   else
     {
@@ -721,24 +727,15 @@ arm_linux_syscall_next_pc (struct frame_info *frame)
        {
          svc_number = get_frame_register_unsigned (frame, 7);
        }
+
+      return_addr = pc + 4;
     }
 
-  is_sigreturn = arm_linux_sigreturn_return_addr (frame, svc_number, 
-                                                 &return_addr);
+  arm_linux_sigreturn_return_addr (frame, svc_number, &return_addr, &is_thumb);
 
-  if (is_sigreturn)
-    return return_addr;
-  
+  /* Addresses for calling Thumb functions have the bit 0 set.  */
   if (is_thumb)
-    {
-      return_addr = pc + 2;
-      /* Addresses for calling Thumb functions have the bit 0 set.  */
-      return_addr |= 1;
-    }
-  else
-    {
-      return_addr = pc + 4;
-    }
+    return_addr |= 1;
 
   return return_addr;
 }
@@ -761,7 +758,7 @@ arm_linux_software_single_step (struct frame_info *frame)
   if (next_pc > 0xffff0000)
     next_pc = get_frame_register_unsigned (frame, ARM_LR_REGNUM);
 
-  insert_single_step_breakpoint (gdbarch, aspace, next_pc);
+  arm_insert_single_step_breakpoint (gdbarch, aspace, next_pc);
 
   return 1;
 }
@@ -798,23 +795,20 @@ arm_linux_cleanup_svc (struct gdbarch *gdbarch,
 }
 
 static int
-arm_linux_copy_svc (struct gdbarch *gdbarch, uint32_t insn, CORE_ADDR to,
-                   struct regcache *regs, struct displaced_step_closure *dsc)
+arm_linux_copy_svc (struct gdbarch *gdbarch, struct regcache *regs,
+                   struct displaced_step_closure *dsc)
 {
   CORE_ADDR return_to = 0;
 
   struct frame_info *frame;
   unsigned int svc_number = displaced_read_reg (regs, dsc, 7);
   int is_sigreturn = 0;
-
-  if (debug_displaced)
-    fprintf_unfiltered (gdb_stdlog, "displaced: copying Linux svc insn %.8lx\n",
-                       (unsigned long) insn);
+  int is_thumb;
 
   frame = get_current_frame ();
 
   is_sigreturn = arm_linux_sigreturn_return_addr(frame, svc_number,
-                                                &return_to);
+                                                &return_to, &is_thumb);
   if (is_sigreturn)
     {
          struct symtab_and_line sal;
@@ -864,7 +858,6 @@ arm_linux_copy_svc (struct gdbarch *gdbarch, uint32_t insn, CORE_ADDR to,
      Cleanup: if pc lands in scratch space, pc <- insn_addr + 4
               else leave pc alone.  */
 
-  dsc->modinsn[0] = insn;
 
   dsc->cleanup = &arm_linux_cleanup_svc;
   /* Pretend we wrote to the PC, so cleanup doesn't set PC to the next
This page took 0.025278 seconds and 4 git commands to generate.