* arm-linux-tdep.c (ARM_OABI_SYSCALL_RESTART_SYSCALL): New macro.
authorMaciej W. Rozycki <macro@linux-mips.org>
Sat, 19 Dec 2009 00:40:15 +0000 (00:40 +0000)
committerMaciej W. Rozycki <macro@linux-mips.org>
Sat, 19 Dec 2009 00:40:15 +0000 (00:40 +0000)
(ARM_LDR_PC_SP_12): Likewise.
(arm_linux_restart_syscall_init): New function.
(arm_linux_restart_syscall_tramp_frame): New variable.
(arm_linux_init_abi): Install the
arm_linux_restart_syscall_tramp_frame unwinder.

gdb/ChangeLog
gdb/arm-linux-tdep.c

index 16d3f66a04b615461ebcc471c5d177b36da76789..9868c7af83056f57c72d3f154c57298e10cede7e 100644 (file)
@@ -1,3 +1,12 @@
+2009-12-19  Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * arm-linux-tdep.c (ARM_OABI_SYSCALL_RESTART_SYSCALL): New macro.
+       (ARM_LDR_PC_SP_12): Likewise.
+       (arm_linux_restart_syscall_init): New function.
+       (arm_linux_restart_syscall_tramp_frame): New variable.
+       (arm_linux_init_abi): Install the
+       arm_linux_restart_syscall_tramp_frame unwinder.
+
 2009-12-18  Doug Evans  <dje@google.com>
 
        * gdb_proc_service.h (psaddr_t): Fix type.
index 7bd74a090a40f054ede59ea835b0688042092e8d..6d3eb266cebeafd987e233499afc2b0183fe6122 100644 (file)
@@ -216,6 +216,11 @@ static const char arm_linux_thumb_le_breakpoint[] = {0x01, 0xde};
 #define ARM_SET_R7_RT_SIGRETURN                0xe3a070ad
 #define ARM_EABI_SYSCALL               0xef000000
 
+/* OABI syscall restart trampoline, used for EABI executables too
+   whenever OABI support has been enabled in the kernel.  */
+#define ARM_OABI_SYSCALL_RESTART_SYSCALL 0xef900000
+#define ARM_LDR_PC_SP_12               0xe49df00c
+
 static void
 arm_linux_sigtramp_cache (struct frame_info *this_frame,
                          struct trad_frame_cache *this_cache,
@@ -325,6 +330,21 @@ arm_linux_rt_sigreturn_init (const struct tramp_frame *self,
                              + ARM_SIGCONTEXT_R0);
 }
 
+static void
+arm_linux_restart_syscall_init (const struct tramp_frame *self,
+                               struct frame_info *this_frame,
+                               struct trad_frame_cache *this_cache,
+                               CORE_ADDR func)
+{
+  CORE_ADDR sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM);
+
+  trad_frame_set_reg_addr (this_cache, ARM_PC_REGNUM, sp);
+  trad_frame_set_reg_value (this_cache, ARM_SP_REGNUM, sp + 12);
+
+  /* Save a frame ID.  */
+  trad_frame_set_id (this_cache, frame_id_build (sp, func));
+}
+
 static struct tramp_frame arm_linux_sigreturn_tramp_frame = {
   SIGTRAMP_FRAME,
   4,
@@ -367,6 +387,17 @@ static struct tramp_frame arm_eabi_linux_rt_sigreturn_tramp_frame = {
   arm_linux_rt_sigreturn_init
 };
 
+static struct tramp_frame arm_linux_restart_syscall_tramp_frame = {
+  NORMAL_FRAME,
+  4,
+  {
+    { ARM_OABI_SYSCALL_RESTART_SYSCALL, -1 },
+    { ARM_LDR_PC_SP_12, -1 },
+    { TRAMP_SENTINEL_INSN }
+  },
+  arm_linux_restart_syscall_init
+};
+
 /* Core file and register set support.  */
 
 #define ARM_LINUX_SIZEOF_GREGSET (18 * INT_REGISTER_SIZE)
@@ -860,6 +891,8 @@ arm_linux_init_abi (struct gdbarch_info info,
                                &arm_eabi_linux_sigreturn_tramp_frame);
   tramp_frame_prepend_unwinder (gdbarch,
                                &arm_eabi_linux_rt_sigreturn_tramp_frame);
+  tramp_frame_prepend_unwinder (gdbarch,
+                               &arm_linux_restart_syscall_tramp_frame);
 
   /* Core file support.  */
   set_gdbarch_regset_from_core_section (gdbarch,