packaging: support aarch64 build
[platform/upstream/binutils.git] / gdb / arm-linux-tdep.c
index a96ea3f..e3587f3 100644 (file)
@@ -54,8 +54,6 @@
 #include "user-regs.h"
 #include <ctype.h>
 #include "elf/common.h"
-#include <string.h>
-
 extern int arm_apcs_32;
 
 /* Under ARM GNU/Linux the traditional way of performing a breakpoint
@@ -246,6 +244,13 @@ static const gdb_byte arm_linux_thumb2_le_breakpoint[] = { 0xf0, 0xf7, 0x00, 0xa
 #define ARM_SET_R7_RT_SIGRETURN                0xe3a070ad
 #define ARM_EABI_SYSCALL               0xef000000
 
+/* Equivalent patterns for Thumb2.  */
+#define THUMB2_SET_R7_SIGRETURN1       0xf04f
+#define THUMB2_SET_R7_SIGRETURN2       0x0777
+#define THUMB2_SET_R7_RT_SIGRETURN1    0xf04f
+#define THUMB2_SET_R7_RT_SIGRETURN2    0x07ad
+#define THUMB2_EABI_SYSCALL            0xdf00
+
 /* 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
@@ -444,6 +449,30 @@ static struct tramp_frame arm_eabi_linux_rt_sigreturn_tramp_frame = {
   arm_linux_rt_sigreturn_init
 };
 
+static struct tramp_frame thumb2_eabi_linux_sigreturn_tramp_frame = {
+  SIGTRAMP_FRAME,
+  2,
+  {
+    { THUMB2_SET_R7_SIGRETURN1, -1 },
+    { THUMB2_SET_R7_SIGRETURN2, -1 },
+    { THUMB2_EABI_SYSCALL, -1 },
+    { TRAMP_SENTINEL_INSN }
+  },
+  arm_linux_sigreturn_init
+};
+
+static struct tramp_frame thumb2_eabi_linux_rt_sigreturn_tramp_frame = {
+  SIGTRAMP_FRAME,
+  2,
+  {
+    { THUMB2_SET_R7_RT_SIGRETURN1, -1 },
+    { THUMB2_SET_R7_RT_SIGRETURN2, -1 },
+    { THUMB2_EABI_SYSCALL, -1 },
+    { TRAMP_SENTINEL_INSN }
+  },
+  arm_linux_rt_sigreturn_init
+};
+
 static struct tramp_frame arm_linux_restart_syscall_tramp_frame = {
   NORMAL_FRAME,
   4,
@@ -702,44 +731,26 @@ static const struct regset arm_linux_vfpregset =
     NULL, arm_linux_supply_vfp, arm_linux_collect_vfp
   };
 
-/* Return the appropriate register set for the core section identified
-   by SECT_NAME and SECT_SIZE.  */
+/* Iterate over core file register note sections.  */
 
-static const struct regset *
-arm_linux_regset_from_core_section (struct gdbarch *gdbarch,
-                                   const char *sect_name, size_t sect_size)
+static void
+arm_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
+                                       iterate_over_regset_sections_cb *cb,
+                                       void *cb_data,
+                                       const struct regcache *regcache)
 {
-  if (strcmp (sect_name, ".reg") == 0
-      && sect_size == ARM_LINUX_SIZEOF_GREGSET)
-    return &arm_linux_gregset;
-
-  if (strcmp (sect_name, ".reg2") == 0
-      && sect_size == ARM_LINUX_SIZEOF_NWFPE)
-    return &arm_linux_fpregset;
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  if (strcmp (sect_name, ".reg-arm-vfp") == 0
-      && sect_size == ARM_LINUX_SIZEOF_VFP)
-    return &arm_linux_vfpregset;
+  cb (".reg", ARM_LINUX_SIZEOF_GREGSET, &arm_linux_gregset, NULL, cb_data);
 
-  return NULL;
+  if (tdep->have_vfp_registers)
+    cb (".reg-arm-vfp", ARM_LINUX_SIZEOF_VFP, &arm_linux_vfpregset,
+       "VFP floating-point", cb_data);
+  else if (tdep->have_fpa_registers)
+    cb (".reg2", ARM_LINUX_SIZEOF_NWFPE, &arm_linux_fpregset,
+       "FPA floating-point", cb_data);
 }
 
-/* Core file register set sections.  */
-
-static struct core_regset_section arm_linux_fpa_regset_sections[] =
-{
-  { ".reg", ARM_LINUX_SIZEOF_GREGSET, "general-purpose" },
-  { ".reg2", ARM_LINUX_SIZEOF_NWFPE, "FPA floating-point" },
-  { NULL, 0}
-};
-
-static struct core_regset_section arm_linux_vfp_regset_sections[] =
-{
-  { ".reg", ARM_LINUX_SIZEOF_GREGSET, "general-purpose" },
-  { ".reg-arm-vfp", ARM_LINUX_SIZEOF_VFP, "VFP floating-point" },
-  { NULL, 0}
-};
-
 /* Determine target description from core file.  */
 
 static const struct target_desc *
@@ -1416,20 +1427,19 @@ arm_linux_init_abi (struct gdbarch_info info,
   tramp_frame_prepend_unwinder (gdbarch,
                                &arm_eabi_linux_rt_sigreturn_tramp_frame);
   tramp_frame_prepend_unwinder (gdbarch,
+                               &thumb2_eabi_linux_sigreturn_tramp_frame);
+  tramp_frame_prepend_unwinder (gdbarch,
+                               &thumb2_eabi_linux_rt_sigreturn_tramp_frame);
+  tramp_frame_prepend_unwinder (gdbarch,
                                &arm_linux_restart_syscall_tramp_frame);
   tramp_frame_prepend_unwinder (gdbarch,
                                &arm_kernel_linux_restart_syscall_tramp_frame);
 
   /* Core file support.  */
-  set_gdbarch_regset_from_core_section (gdbarch,
-                                       arm_linux_regset_from_core_section);
+  set_gdbarch_iterate_over_regset_sections
+    (gdbarch, arm_linux_iterate_over_regset_sections);
   set_gdbarch_core_read_description (gdbarch, arm_linux_core_read_description);
 
-  if (tdep->have_vfp_registers)
-    set_gdbarch_core_regset_sections (gdbarch, arm_linux_vfp_regset_sections);
-  else if (tdep->have_fpa_registers)
-    set_gdbarch_core_regset_sections (gdbarch, arm_linux_fpa_regset_sections);
-
   set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type);
 
   /* Displaced stepping.  */