gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / arm-linux-tdep.c
index bc921771ac67fc211f75cbae952e2229c5e2f221..9b69f8ad3d73805d8ee6b65ed4616c22539a889b 100644 (file)
@@ -1,6 +1,6 @@
 /* GNU/Linux on ARM target support.
 
-   Copyright (C) 1999-2016 Free Software Foundation, Inc.
+   Copyright (C) 1999-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "target.h"
 #include "value.h"
 #include "gdbtypes.h"
-#include "floatformat.h"
 #include "gdbcore.h"
 #include "frame.h"
 #include "regcache.h"
-#include "doublest.h"
 #include "solib-svr4.h"
 #include "osabi.h"
 #include "regset.h"
@@ -35,6 +33,7 @@
 #include "auxv.h"
 #include "xml-syscall.h"
 
+#include "aarch32-tdep.h"
 #include "arch/arm.h"
 #include "arch/arm-get-next-pcs.h"
 #include "arch/arm-linux.h"
@@ -57,7 +56,6 @@
 #include "user-regs.h"
 #include <ctype.h>
 #include "elf/common.h"
-extern int arm_apcs_32;
 
 /* Under ARM GNU/Linux the traditional way of performing a breakpoint
    is to execute a particular software interrupt, rather than use a
@@ -105,7 +103,7 @@ static const gdb_byte arm_linux_thumb2_le_breakpoint[] = { 0xf0, 0xf7, 0x00, 0xa
    SoftVFP or VFP (which implies EABI) then the PC is at offset 9 in the 
    buffer.  This is also true for the SoftFPA model.  However, for the FPA 
    model the PC is at offset 21 in the buffer.  */
-#define ARM_LINUX_JB_ELEMENT_SIZE      INT_REGISTER_SIZE
+#define ARM_LINUX_JB_ELEMENT_SIZE      ARM_INT_REGISTER_SIZE
 #define ARM_LINUX_JB_PC_FPA            21
 #define ARM_LINUX_JB_PC_EABI           9
 
@@ -387,7 +385,7 @@ static struct tramp_frame arm_linux_sigreturn_tramp_frame = {
   SIGTRAMP_FRAME,
   4,
   {
-    { ARM_LINUX_SIGRETURN_INSTR, -1 },
+    { ARM_LINUX_SIGRETURN_INSTR, ULONGEST_MAX },
     { TRAMP_SENTINEL_INSN }
   },
   arm_linux_sigreturn_init
@@ -397,7 +395,7 @@ static struct tramp_frame arm_linux_rt_sigreturn_tramp_frame = {
   SIGTRAMP_FRAME,
   4,
   {
-    { ARM_LINUX_RT_SIGRETURN_INSTR, -1 },
+    { ARM_LINUX_RT_SIGRETURN_INSTR, ULONGEST_MAX },
     { TRAMP_SENTINEL_INSN }
   },
   arm_linux_rt_sigreturn_init
@@ -407,8 +405,8 @@ static struct tramp_frame arm_eabi_linux_sigreturn_tramp_frame = {
   SIGTRAMP_FRAME,
   4,
   {
-    { ARM_SET_R7_SIGRETURN, -1 },
-    { ARM_EABI_SYSCALL, -1 },
+    { ARM_SET_R7_SIGRETURN, ULONGEST_MAX },
+    { ARM_EABI_SYSCALL, ULONGEST_MAX },
     { TRAMP_SENTINEL_INSN }
   },
   arm_linux_sigreturn_init
@@ -418,8 +416,8 @@ static struct tramp_frame arm_eabi_linux_rt_sigreturn_tramp_frame = {
   SIGTRAMP_FRAME,
   4,
   {
-    { ARM_SET_R7_RT_SIGRETURN, -1 },
-    { ARM_EABI_SYSCALL, -1 },
+    { ARM_SET_R7_RT_SIGRETURN, ULONGEST_MAX },
+    { ARM_EABI_SYSCALL, ULONGEST_MAX },
     { TRAMP_SENTINEL_INSN }
   },
   arm_linux_rt_sigreturn_init
@@ -429,9 +427,9 @@ 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 },
+    { THUMB2_SET_R7_SIGRETURN1, ULONGEST_MAX },
+    { THUMB2_SET_R7_SIGRETURN2, ULONGEST_MAX },
+    { THUMB2_EABI_SYSCALL, ULONGEST_MAX },
     { TRAMP_SENTINEL_INSN }
   },
   arm_linux_sigreturn_init
@@ -441,9 +439,9 @@ 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 },
+    { THUMB2_SET_R7_RT_SIGRETURN1, ULONGEST_MAX },
+    { THUMB2_SET_R7_RT_SIGRETURN2, ULONGEST_MAX },
+    { THUMB2_EABI_SYSCALL, ULONGEST_MAX },
     { TRAMP_SENTINEL_INSN }
   },
   arm_linux_rt_sigreturn_init
@@ -453,8 +451,8 @@ 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 },
+    { ARM_OABI_SYSCALL_RESTART_SYSCALL, ULONGEST_MAX },
+    { ARM_LDR_PC_SP_12, ULONGEST_MAX },
     { TRAMP_SENTINEL_INSN }
   },
   arm_linux_restart_syscall_init
@@ -464,8 +462,8 @@ static struct tramp_frame arm_kernel_linux_restart_syscall_tramp_frame = {
   NORMAL_FRAME,
   4,
   {
-    { ARM_OABI_SYSCALL_RESTART_SYSCALL, -1 },
-    { ARM_LDR_PC_SP_4, -1 },
+    { ARM_OABI_SYSCALL_RESTART_SYSCALL, ULONGEST_MAX },
+    { ARM_LDR_PC_SP_4, ULONGEST_MAX },
     { TRAMP_SENTINEL_INSN }
   },
   arm_linux_restart_syscall_init
@@ -473,43 +471,43 @@ static struct tramp_frame arm_kernel_linux_restart_syscall_tramp_frame = {
 
 /* Core file and register set support.  */
 
-#define ARM_LINUX_SIZEOF_GREGSET (18 * INT_REGISTER_SIZE)
+#define ARM_LINUX_SIZEOF_GREGSET (18 * ARM_INT_REGISTER_SIZE)
 
 void
 arm_linux_supply_gregset (const struct regset *regset,
                          struct regcache *regcache,
                          int regnum, const void *gregs_buf, size_t len)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   const gdb_byte *gregs = (const gdb_byte *) gregs_buf;
   int regno;
   CORE_ADDR reg_pc;
-  gdb_byte pc_buf[INT_REGISTER_SIZE];
+  gdb_byte pc_buf[ARM_INT_REGISTER_SIZE];
 
   for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
     if (regnum == -1 || regnum == regno)
-      regcache_raw_supply (regcache, regno,
-                          gregs + INT_REGISTER_SIZE * regno);
+      regcache->raw_supply (regno, gregs + ARM_INT_REGISTER_SIZE * regno);
 
   if (regnum == ARM_PS_REGNUM || regnum == -1)
     {
       if (arm_apcs_32)
-       regcache_raw_supply (regcache, ARM_PS_REGNUM,
-                            gregs + INT_REGISTER_SIZE * ARM_CPSR_GREGNUM);
+       regcache->raw_supply (ARM_PS_REGNUM,
+                             gregs + ARM_INT_REGISTER_SIZE * ARM_CPSR_GREGNUM);
       else
-       regcache_raw_supply (regcache, ARM_PS_REGNUM,
-                            gregs + INT_REGISTER_SIZE * ARM_PC_REGNUM);
+       regcache->raw_supply (ARM_PS_REGNUM,
+                            gregs + ARM_INT_REGISTER_SIZE * ARM_PC_REGNUM);
     }
 
   if (regnum == ARM_PC_REGNUM || regnum == -1)
     {
-      reg_pc = extract_unsigned_integer (gregs
-                                        + INT_REGISTER_SIZE * ARM_PC_REGNUM,
-                                        INT_REGISTER_SIZE, byte_order);
+      reg_pc = extract_unsigned_integer (
+                gregs + ARM_INT_REGISTER_SIZE * ARM_PC_REGNUM,
+                ARM_INT_REGISTER_SIZE, byte_order);
       reg_pc = gdbarch_addr_bits_remove (gdbarch, reg_pc);
-      store_unsigned_integer (pc_buf, INT_REGISTER_SIZE, byte_order, reg_pc);
-      regcache_raw_supply (regcache, ARM_PC_REGNUM, pc_buf);
+      store_unsigned_integer (pc_buf, ARM_INT_REGISTER_SIZE, byte_order,
+                             reg_pc);
+      regcache->raw_supply (ARM_PC_REGNUM, pc_buf);
     }
 }
 
@@ -523,22 +521,22 @@ arm_linux_collect_gregset (const struct regset *regset,
 
   for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
     if (regnum == -1 || regnum == regno)
-      regcache_raw_collect (regcache, regno,
-                           gregs + INT_REGISTER_SIZE * regno);
+      regcache->raw_collect (regno,
+                           gregs + ARM_INT_REGISTER_SIZE * regno);
 
   if (regnum == ARM_PS_REGNUM || regnum == -1)
     {
       if (arm_apcs_32)
-       regcache_raw_collect (regcache, ARM_PS_REGNUM,
-                             gregs + INT_REGISTER_SIZE * ARM_CPSR_GREGNUM);
+       regcache->raw_collect (ARM_PS_REGNUM,
+                             gregs + ARM_INT_REGISTER_SIZE * ARM_CPSR_GREGNUM);
       else
-       regcache_raw_collect (regcache, ARM_PS_REGNUM,
-                             gregs + INT_REGISTER_SIZE * ARM_PC_REGNUM);
+       regcache->raw_collect (ARM_PS_REGNUM,
+                             gregs + ARM_INT_REGISTER_SIZE * ARM_PC_REGNUM);
     }
 
   if (regnum == ARM_PC_REGNUM || regnum == -1)
-    regcache_raw_collect (regcache, ARM_PC_REGNUM,
-                         gregs + INT_REGISTER_SIZE * ARM_PC_REGNUM);
+    regcache->raw_collect (ARM_PC_REGNUM,
+                          gregs + ARM_INT_REGISTER_SIZE * ARM_PC_REGNUM);
 }
 
 /* Support for register format used by the NWFPE FPA emulator.  */
@@ -554,11 +552,11 @@ supply_nwfpe_register (struct regcache *regcache, int regno,
 {
   const gdb_byte *reg_data;
   gdb_byte reg_tag;
-  gdb_byte buf[FP_REGISTER_SIZE];
+  gdb_byte buf[ARM_FP_REGISTER_SIZE];
 
-  reg_data = regs + (regno - ARM_F0_REGNUM) * FP_REGISTER_SIZE;
+  reg_data = regs + (regno - ARM_F0_REGNUM) * ARM_FP_REGISTER_SIZE;
   reg_tag = regs[(regno - ARM_F0_REGNUM) + NWFPE_TAGS_OFFSET];
-  memset (buf, 0, FP_REGISTER_SIZE);
+  memset (buf, 0, ARM_FP_REGISTER_SIZE);
 
   switch (reg_tag)
     {
@@ -580,7 +578,7 @@ supply_nwfpe_register (struct regcache *regcache, int regno,
       break;
     }
 
-  regcache_raw_supply (regcache, regno, buf);
+  regcache->raw_supply (regno, buf);
 }
 
 void
@@ -589,16 +587,16 @@ collect_nwfpe_register (const struct regcache *regcache, int regno,
 {
   gdb_byte *reg_data;
   gdb_byte reg_tag;
-  gdb_byte buf[FP_REGISTER_SIZE];
+  gdb_byte buf[ARM_FP_REGISTER_SIZE];
 
-  regcache_raw_collect (regcache, regno, buf);
+  regcache->raw_collect (regno, buf);
 
   /* NOTE drow/2006-06-07: This code uses the tag already in the
      register buffer.  I've preserved that when moving the code
      from the native file to the target file.  But this doesn't
      always make sense.  */
 
-  reg_data = regs + (regno - ARM_F0_REGNUM) * FP_REGISTER_SIZE;
+  reg_data = regs + (regno - ARM_F0_REGNUM) * ARM_FP_REGISTER_SIZE;
   reg_tag = regs[(regno - ARM_F0_REGNUM) + NWFPE_TAGS_OFFSET];
 
   switch (reg_tag)
@@ -629,7 +627,7 @@ arm_linux_supply_nwfpe (const struct regset *regset,
   int regno;
 
   if (regnum == ARM_FPS_REGNUM || regnum == -1)
-    regcache_raw_supply (regcache, ARM_FPS_REGNUM,
+    regcache->raw_supply (ARM_FPS_REGNUM,
                         regs + NWFPE_FPSR_OFFSET);
 
   for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
@@ -650,8 +648,8 @@ arm_linux_collect_nwfpe (const struct regset *regset,
       collect_nwfpe_register (regcache, regno, regs);
 
   if (regnum == ARM_FPS_REGNUM || regnum == -1)
-    regcache_raw_collect (regcache, ARM_FPS_REGNUM,
-                         regs + INT_REGISTER_SIZE * ARM_FPS_REGNUM);
+    regcache->raw_collect (ARM_FPS_REGNUM,
+                          regs + ARM_INT_REGISTER_SIZE * ARM_FPS_REGNUM);
 }
 
 /* Support VFP register format.  */
@@ -667,12 +665,11 @@ arm_linux_supply_vfp (const struct regset *regset,
   int regno;
 
   if (regnum == ARM_FPSCR_REGNUM || regnum == -1)
-    regcache_raw_supply (regcache, ARM_FPSCR_REGNUM, regs + 32 * 8);
+    regcache->raw_supply (ARM_FPSCR_REGNUM, regs + 32 * 8);
 
   for (regno = ARM_D0_REGNUM; regno <= ARM_D31_REGNUM; regno++)
     if (regnum == -1 || regnum == regno)
-      regcache_raw_supply (regcache, regno,
-                          regs + (regno - ARM_D0_REGNUM) * 8);
+      regcache->raw_supply (regno, regs + (regno - ARM_D0_REGNUM) * 8);
 }
 
 static void
@@ -684,12 +681,11 @@ arm_linux_collect_vfp (const struct regset *regset,
   int regno;
 
   if (regnum == ARM_FPSCR_REGNUM || regnum == -1)
-    regcache_raw_collect (regcache, ARM_FPSCR_REGNUM, regs + 32 * 8);
+    regcache->raw_collect (ARM_FPSCR_REGNUM, regs + 32 * 8);
 
   for (regno = ARM_D0_REGNUM; regno <= ARM_D31_REGNUM; regno++)
     if (regnum == -1 || regnum == regno)
-      regcache_raw_collect (regcache, regno,
-                           regs + (regno - ARM_D0_REGNUM) * 8);
+      regcache->raw_collect (regno, regs + (regno - ARM_D0_REGNUM) * 8);
 }
 
 static const struct regset arm_linux_gregset =
@@ -717,14 +713,15 @@ arm_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  cb (".reg", ARM_LINUX_SIZEOF_GREGSET, &arm_linux_gregset, NULL, cb_data);
+  cb (".reg", ARM_LINUX_SIZEOF_GREGSET, ARM_LINUX_SIZEOF_GREGSET,
+      &arm_linux_gregset, NULL, cb_data);
 
   if (tdep->vfp_register_count > 0)
-    cb (".reg-arm-vfp", ARM_LINUX_SIZEOF_VFP, &arm_linux_vfpregset,
-       "VFP floating-point", cb_data);
+    cb (".reg-arm-vfp", ARM_LINUX_SIZEOF_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);
+    cb (".reg2", ARM_LINUX_SIZEOF_NWFPE, ARM_LINUX_SIZEOF_NWFPE,
+       &arm_linux_fpregset, "FPA floating-point", cb_data);
 }
 
 /* Determine target description from core file.  */
@@ -734,24 +731,21 @@ arm_linux_core_read_description (struct gdbarch *gdbarch,
                                  struct target_ops *target,
                                  bfd *abfd)
 {
-  CORE_ADDR arm_hwcap = 0;
-
-  if (target_auxv_search (target, AT_HWCAP, &arm_hwcap) != 1)
-    return NULL;
+  CORE_ADDR arm_hwcap = linux_get_hwcap (target);
 
   if (arm_hwcap & HWCAP_VFP)
     {
       /* NEON implies VFPv3-D32 or no-VFP unit.  Say that we only support
          Neon with VFPv3-D32.  */
       if (arm_hwcap & HWCAP_NEON)
-       return tdesc_arm_with_neon;
+       return aarch32_read_description ();
       else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3)
-       return tdesc_arm_with_vfpv3;
-      else
-       return tdesc_arm_with_vfpv2;
+       return arm_read_description (ARM_FP_TYPE_VFPV3);
+
+      return arm_read_description (ARM_FP_TYPE_VFPV2);
     }
 
-  return NULL;
+  return nullptr;
 }
 
 
@@ -792,7 +786,7 @@ arm_linux_sigreturn_next_pc (struct regcache *regcache,
   ULONGEST sp;
   unsigned long sp_data;
   CORE_ADDR next_pc = 0;
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int pc_offset = 0;
   int is_sigreturn = 0;
@@ -824,9 +818,9 @@ arm_linux_sigreturn_next_pc (struct regcache *regcache,
 
 static LONGEST
 arm_linux_get_syscall_number (struct gdbarch *gdbarch,
-                             ptid_t ptid)
+                             thread_info *thread)
 {
-  struct regcache *regs = get_thread_regcache (ptid);
+  struct regcache *regs = get_thread_regcache (thread);
 
   ULONGEST pc;
   ULONGEST cpsr;
@@ -884,7 +878,7 @@ arm_linux_get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self)
     }
   else
     {
-      struct gdbarch *gdbarch = get_regcache_arch (self->regcache);
+      struct gdbarch *gdbarch = self->regcache->arch ();
       enum bfd_endian byte_order_for_code = 
        gdbarch_byte_order_for_code (gdbarch);
       unsigned long this_instr = 
@@ -921,24 +915,16 @@ arm_linux_get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self)
 
 /* Insert a single step breakpoint at the next executed instruction.  */
 
-static int
-arm_linux_software_single_step (struct frame_info *frame)
+static std::vector<CORE_ADDR>
+arm_linux_software_single_step (struct regcache *regcache)
 {
-  struct regcache *regcache = get_current_regcache ();
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  struct address_space *aspace = get_regcache_aspace (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct arm_get_next_pcs next_pcs_ctx;
-  CORE_ADDR pc;
-  int i;
-  VEC (CORE_ADDR) *next_pcs = NULL;
-  struct cleanup *old_chain;
 
   /* If the target does have hardware single step, GDB doesn't have
      to bother software single step.  */
   if (target_can_do_single_step () == 1)
-    return 0;
-
-  old_chain = make_cleanup (VEC_cleanup (CORE_ADDR), &next_pcs);
+    return {};
 
   arm_get_next_pcs_ctor (&next_pcs_ctx,
                         &arm_linux_get_next_pcs_ops,
@@ -947,17 +933,12 @@ arm_linux_software_single_step (struct frame_info *frame)
                         1,
                         regcache);
 
-  next_pcs = arm_get_next_pcs (&next_pcs_ctx);
+  std::vector<CORE_ADDR> next_pcs = arm_get_next_pcs (&next_pcs_ctx);
 
-  for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); i++)
-    {
-      pc = gdbarch_addr_bits_remove (gdbarch, pc);
-      insert_single_step_breakpoint (gdbarch, aspace, pc);
-    }
+  for (CORE_ADDR &pc_ref : next_pcs)
+    pc_ref = gdbarch_addr_bits_remove (gdbarch, pc_ref);
 
-  do_cleanups (old_chain);
-
-  return 1;
+  return next_pcs;
 }
 
 /* Support for displaced stepping of Linux SVC instructions.  */
@@ -965,7 +946,7 @@ arm_linux_software_single_step (struct frame_info *frame)
 static void
 arm_linux_cleanup_svc (struct gdbarch *gdbarch,
                       struct regcache *regs,
-                      struct displaced_step_closure *dsc)
+                      arm_displaced_step_copy_insn_closure *dsc)
 {
   ULONGEST apparent_pc;
   int within_scratch;
@@ -974,7 +955,7 @@ arm_linux_cleanup_svc (struct gdbarch *gdbarch,
 
   within_scratch = (apparent_pc >= dsc->scratch_base
                    && apparent_pc < (dsc->scratch_base
-                                     + DISPLACED_MODIFIED_INSNS * 4 + 4));
+                                     + ARM_DISPLACED_MODIFIED_INSNS * 4 + 4));
 
   if (debug_displaced)
     {
@@ -993,7 +974,7 @@ arm_linux_cleanup_svc (struct gdbarch *gdbarch,
 
 static int
 arm_linux_copy_svc (struct gdbarch *gdbarch, struct regcache *regs,
-                   struct displaced_step_closure *dsc)
+                   arm_displaced_step_copy_insn_closure *dsc)
 {
   CORE_ADDR return_to = 0;
 
@@ -1035,7 +1016,7 @@ arm_linux_copy_svc (struct gdbarch *gdbarch, struct regcache *regs,
        {
          inferior_thread ()->control.step_resume_breakpoint
            = set_momentary_breakpoint (gdbarch, sal, get_frame_id (frame),
-                                       bp_step_resume);
+                                       bp_step_resume).release ();
 
          /* set_momentary_breakpoint invalidates FRAME.  */
          frame = NULL;
@@ -1084,7 +1065,7 @@ arm_linux_copy_svc (struct gdbarch *gdbarch, struct regcache *regs,
 static void
 cleanup_kernel_helper_return (struct gdbarch *gdbarch,
                              struct regcache *regs,
-                             struct displaced_step_closure *dsc)
+                             arm_displaced_step_copy_insn_closure *dsc)
 {
   displaced_write_reg (regs, dsc, ARM_LR_REGNUM, dsc->tmp[0], CANNOT_WRITE_PC);
   displaced_write_reg (regs, dsc, ARM_PC_REGNUM, dsc->tmp[0], BRANCH_WRITE_PC);
@@ -1093,7 +1074,7 @@ cleanup_kernel_helper_return (struct gdbarch *gdbarch,
 static void
 arm_catch_kernel_helper_return (struct gdbarch *gdbarch, CORE_ADDR from,
                                CORE_ADDR to, struct regcache *regs,
-                               struct displaced_step_closure *dsc)
+                               arm_displaced_step_copy_insn_closure *dsc)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 
@@ -1122,12 +1103,13 @@ arm_catch_kernel_helper_return (struct gdbarch *gdbarch, CORE_ADDR from,
    the program has stepped into a Linux kernel helper routine (which must be
    handled as a special case).  */
 
-static struct displaced_step_closure *
+static displaced_step_copy_insn_closure_up
 arm_linux_displaced_step_copy_insn (struct gdbarch *gdbarch,
                                    CORE_ADDR from, CORE_ADDR to,
                                    struct regcache *regs)
 {
-  struct displaced_step_closure *dsc = XNEW (struct displaced_step_closure);
+  std::unique_ptr<arm_displaced_step_copy_insn_closure> dsc
+    (new arm_displaced_step_copy_insn_closure);
 
   /* Detect when we enter an (inaccessible by GDB) Linux kernel helper, and
      stop at the return location.  */
@@ -1137,19 +1119,20 @@ arm_linux_displaced_step_copy_insn (struct gdbarch *gdbarch,
         fprintf_unfiltered (gdb_stdlog, "displaced: detected kernel helper "
                            "at %.8lx\n", (unsigned long) from);
 
-      arm_catch_kernel_helper_return (gdbarch, from, to, regs, dsc);
+      arm_catch_kernel_helper_return (gdbarch, from, to, regs, dsc.get ());
     }
   else
     {
       /* Override the default handling of SVC instructions.  */
       dsc->u.svc.copy_svc_os = arm_linux_copy_svc;
 
-      arm_process_displaced_insn (gdbarch, from, to, regs, dsc);
+      arm_process_displaced_insn (gdbarch, from, to, regs, dsc.get ());
     }
 
-  arm_displaced_init_closure (gdbarch, from, to, dsc);
+  arm_displaced_init_closure (gdbarch, from, to, dsc.get ());
 
-  return dsc;
+  /* This is a work around for a problem with g++ 4.8.  */
+  return displaced_step_copy_insn_closure_up (dsc.release ());
 }
 
 /* Implementation of `gdbarch_stap_is_single_operand', as defined in
@@ -1224,7 +1207,7 @@ arm_stap_parse_special_token (struct gdbarch *gdbarch,
               regname, p->saved_arg);
 
       ++tmp;
-      tmp = skip_spaces_const (tmp);
+      tmp = skip_spaces (tmp);
       if (*tmp == '#' || *tmp == '$')
        ++tmp;
 
@@ -1727,6 +1710,15 @@ arm_linux_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
   return find_solib_trampoline_target (frame, pc);
 }
 
+/* Implement the gcc_target_options gdbarch method.  */
+
+static std::string
+arm_linux_gcc_target_options (struct gdbarch *gdbarch)
+{
+  /* GCC doesn't know "-m32".  */
+  return {};
+}
+
 static void
 arm_linux_init_abi (struct gdbarch_info info,
                    struct gdbarch *gdbarch)
@@ -1825,8 +1817,6 @@ arm_linux_init_abi (struct gdbarch_info info,
   set_gdbarch_displaced_step_copy_insn (gdbarch,
                                        arm_linux_displaced_step_copy_insn);
   set_gdbarch_displaced_step_fixup (gdbarch, arm_displaced_step_fixup);
-  set_gdbarch_displaced_step_free_closure (gdbarch,
-                                          simple_displaced_step_free_closure);
   set_gdbarch_displaced_step_location (gdbarch, linux_displaced_step_location);
 
   /* Reversible debugging, process record.  */
@@ -2009,13 +1999,13 @@ arm_linux_init_abi (struct gdbarch_info info,
   arm_linux_record_tdep.arg5 = ARM_A1_REGNUM + 4;
   arm_linux_record_tdep.arg6 = ARM_A1_REGNUM + 5;
   arm_linux_record_tdep.arg7 = ARM_A1_REGNUM + 6;
-}
 
-/* Provide a prototype to silence -Wmissing-prototypes.  */
-extern initialize_file_ftype _initialize_arm_linux_tdep;
+  set_gdbarch_gcc_target_options (gdbarch, arm_linux_gcc_target_options);
+}
 
+void _initialize_arm_linux_tdep ();
 void
-_initialize_arm_linux_tdep (void)
+_initialize_arm_linux_tdep ()
 {
   gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_LINUX,
                          arm_linux_init_abi);
This page took 0.035023 seconds and 4 git commands to generate.