]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/arm-tdep.c
gdb/configure.ac: add --enable-source-highlight
[thirdparty/binutils-gdb.git] / gdb / arm-tdep.c
index f64df4c57416d8cda7ad92aec3d7939de94b343d..599f785b3494929cd53343f60fcf3f80e5762dbf 100644 (file)
@@ -1,6 +1,6 @@
 /* Common target dependent code for GDB on ARM systems.
 
-   Copyright (C) 1988-2018 Free Software Foundation, Inc.
+   Copyright (C) 1988-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -55,7 +55,7 @@
 #include "coff/internal.h"
 #include "elf/arm.h"
 
-#include "vec.h"
+#include "common/vec.h"
 
 #include "record.h"
 #include "record-full.h"
@@ -70,7 +70,7 @@
 #include "features/arm/arm-with-neon.c"
 
 #if GDB_SELF_TEST
-#include "selftest.h"
+#include "common/selftest.h"
 #endif
 
 static int arm_debug;
@@ -1801,6 +1801,10 @@ arm_scan_prologue (struct frame_info *this_frame,
       CORE_ADDR frame_loc;
       ULONGEST return_value;
 
+      /* AAPCS does not use a frame register, so we can abort here.  */
+      if (gdbarch_tdep (gdbarch)->arm_abi == ARM_ABI_AAPCS)
+        return;
+
       frame_loc = get_frame_register_unsigned (this_frame, ARM_FP_REGNUM);
       if (!safe_read_memory_unsigned_integer (frame_loc, 4, byte_order,
                                              &return_value))
@@ -3055,38 +3059,6 @@ struct frame_base arm_normal_base = {
   arm_normal_frame_base
 };
 
-/* Assuming THIS_FRAME is a dummy, return the frame ID of that
-   dummy frame.  The frame ID's base needs to match the TOS value
-   saved by save_dummy_frame_tos() and returned from
-   arm_push_dummy_call, and the PC needs to match the dummy frame's
-   breakpoint.  */
-
-static struct frame_id
-arm_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
-  return frame_id_build (get_frame_register_unsigned (this_frame,
-                                                     ARM_SP_REGNUM),
-                        get_frame_pc (this_frame));
-}
-
-/* Given THIS_FRAME, find the previous frame's resume PC (which will
-   be used to construct the previous frame's ID, after looking up the
-   containing function).  */
-
-static CORE_ADDR
-arm_unwind_pc (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
-  CORE_ADDR pc;
-  pc = frame_unwind_register_unsigned (this_frame, ARM_PC_REGNUM);
-  return arm_addr_bits_remove (gdbarch, pc);
-}
-
-static CORE_ADDR
-arm_unwind_sp (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
-  return frame_unwind_register_unsigned (this_frame, ARM_SP_REGNUM);
-}
-
 static struct value *
 arm_dwarf2_prev_register (struct frame_info *this_frame, void **this_cache,
                          int regnum)
@@ -3679,7 +3651,8 @@ arm_vfp_abi_for_function (struct gdbarch *gdbarch, struct type *func_type)
 static CORE_ADDR
 arm_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                     struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
-                    struct value **args, CORE_ADDR sp, int struct_return,
+                    struct value **args, CORE_ADDR sp,
+                    function_call_return_method return_method,
                     CORE_ADDR struct_addr)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -3714,7 +3687,7 @@ arm_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
   /* The struct_return pointer occupies the first parameter
      passing register.  */
-  if (struct_return)
+  if (return_method == return_method_struct)
     {
       if (arm_debug)
        fprintf_unfiltered (gdb_stdlog, "struct return in %s = %s\n",
@@ -3804,8 +3777,7 @@ arm_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                                 reg_char, reg_scaled + i);
                      regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
                                                            strlen (name_buf));
-                     regcache_cooked_write (regcache, regnum,
-                                            val + i * unit_length);
+                     regcache->cooked_write (regnum, val + i * unit_length);
                    }
                }
              continue;
@@ -6568,6 +6540,7 @@ arm_decode_miscellaneous (struct gdbarch *gdbarch, uint32_t insn,
       else if (op == 0x3)
         /* Not really supported.  */
        return arm_copy_unmodified (gdbarch, insn, "smc", dsc);
+      /* Fall through.  */
 
     default:
       return arm_copy_undef (gdbarch, insn, dsc);
@@ -7460,9 +7433,9 @@ thumb_process_displaced_32bit_insn (struct gdbarch *gdbarch, uint16_t insn1,
        {
          if (bit (insn1, 9)) /* Data processing (plain binary imm).  */
            {
-             int op = bits (insn1, 4, 8);
+             int dp_op = bits (insn1, 4, 8);
              int rn = bits (insn1, 0, 3);
-             if ((op == 0 || op == 0xa) && rn == 0xf)
+             if ((dp_op == 0 || dp_op == 0xa) && rn == 0xf)
                err = thumb_copy_pc_relative_32bit (gdbarch, insn1, insn2,
                                                    regs, dsc);
              else
@@ -7892,7 +7865,7 @@ arm_extract_return_value (struct type *type, struct regcache *regs,
               internal type.  */
            bfd_byte tmpbuf[FP_REGISTER_SIZE];
 
-           regcache_cooked_read (regs, ARM_F0_REGNUM, tmpbuf);
+           regs->cooked_read (ARM_F0_REGNUM, tmpbuf);
            target_float_convert (tmpbuf, arm_ext_type (gdbarch),
                                  valbuf, type);
          }
@@ -7903,10 +7876,9 @@ arm_extract_return_value (struct type *type, struct regcache *regs,
          /* ARM_FLOAT_VFP can arise if this is a variadic function so
             not using the VFP ABI code.  */
        case ARM_FLOAT_VFP:
-         regcache_cooked_read (regs, ARM_A1_REGNUM, valbuf);
+         regs->cooked_read (ARM_A1_REGNUM, valbuf);
          if (TYPE_LENGTH (type) > 4)
-           regcache_cooked_read (regs, ARM_A1_REGNUM + 1,
-                                 valbuf + INT_REGISTER_SIZE);
+           regs->cooked_read (ARM_A1_REGNUM + 1, valbuf + INT_REGISTER_SIZE);
          break;
 
        default:
@@ -7954,7 +7926,7 @@ arm_extract_return_value (struct type *type, struct regcache *regs,
 
       while (len > 0)
        {
-         regcache_cooked_read (regs, regno++, tmpbuf);
+         regs->cooked_read (regno++, tmpbuf);
          memcpy (valbuf, tmpbuf,
                  len > INT_REGISTER_SIZE ? INT_REGISTER_SIZE : len);
          len -= INT_REGISTER_SIZE;
@@ -8099,7 +8071,7 @@ arm_store_return_value (struct type *type, struct regcache *regs,
        case ARM_FLOAT_FPA:
 
          target_float_convert (valbuf, type, buf, arm_ext_type (gdbarch));
-         regcache_cooked_write (regs, ARM_F0_REGNUM, buf);
+         regs->cooked_write (ARM_F0_REGNUM, buf);
          break;
 
        case ARM_FLOAT_SOFT_FPA:
@@ -8107,10 +8079,9 @@ arm_store_return_value (struct type *type, struct regcache *regs,
          /* ARM_FLOAT_VFP can arise if this is a variadic function so
             not using the VFP ABI code.  */
        case ARM_FLOAT_VFP:
-         regcache_cooked_write (regs, ARM_A1_REGNUM, valbuf);
+         regs->cooked_write (ARM_A1_REGNUM, valbuf);
          if (TYPE_LENGTH (type) > 4)
-           regcache_cooked_write (regs, ARM_A1_REGNUM + 1, 
-                                  valbuf + INT_REGISTER_SIZE);
+           regs->cooked_write (ARM_A1_REGNUM + 1, valbuf + INT_REGISTER_SIZE);
          break;
 
        default:
@@ -8135,7 +8106,7 @@ arm_store_return_value (struct type *type, struct regcache *regs,
          LONGEST val = unpack_long (type, valbuf);
 
          store_signed_integer (tmpbuf, INT_REGISTER_SIZE, byte_order, val);
-         regcache_cooked_write (regs, ARM_A1_REGNUM, tmpbuf);
+         regs->cooked_write (ARM_A1_REGNUM, tmpbuf);
        }
       else
        {
@@ -8147,7 +8118,7 @@ arm_store_return_value (struct type *type, struct regcache *regs,
 
          while (len > 0)
            {
-             regcache_cooked_write (regs, regno++, valbuf);
+             regs->cooked_write (regno++, valbuf);
              len -= INT_REGISTER_SIZE;
              valbuf += INT_REGISTER_SIZE;
            }
@@ -8166,7 +8137,7 @@ arm_store_return_value (struct type *type, struct regcache *regs,
        {
          memcpy (tmpbuf, valbuf,
                  len > INT_REGISTER_SIZE ? INT_REGISTER_SIZE : len);
-         regcache_cooked_write (regs, regno++, tmpbuf);
+         regs->cooked_write (regno++, tmpbuf);
          len -= INT_REGISTER_SIZE;
          valbuf += INT_REGISTER_SIZE;
        }
@@ -8213,11 +8184,9 @@ arm_return_value (struct gdbarch *gdbarch, struct value *function,
              regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
                                                    strlen (name_buf));
              if (writebuf)
-               regcache_cooked_write (regcache, regnum,
-                                      writebuf + i * unit_length);
+               regcache->cooked_write (regnum, writebuf + i * unit_length);
              if (readbuf)
-               regcache_cooked_read (regcache, regnum,
-                                     readbuf + i * unit_length);
+               regcache->cooked_read (regnum, readbuf + i * unit_length);
            }
        }
       return RETURN_VALUE_REGISTER_CONVENTION;
@@ -8764,9 +8733,9 @@ arm_neon_quad_write (struct gdbarch *gdbarch, struct regcache *regcache,
   else
     offset = 0;
 
-  regcache_raw_write (regcache, double_regnum, buf + offset);
+  regcache->raw_write (double_regnum, buf + offset);
   offset = 8 - offset;
-  regcache_raw_write (regcache, double_regnum + 1, buf + offset);
+  regcache->raw_write (double_regnum + 1, buf + offset);
 }
 
 static void
@@ -8799,9 +8768,9 @@ arm_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
       double_regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
                                                   strlen (name_buf));
 
-      regcache_raw_read (regcache, double_regnum, reg_buf);
+      regcache->raw_read (double_regnum, reg_buf);
       memcpy (reg_buf + offset, buf, 4);
-      regcache_raw_write (regcache, double_regnum, reg_buf);
+      regcache->raw_write (double_regnum, reg_buf);
     }
 }
 
@@ -8959,7 +8928,6 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
          else if (ei_osabi == ELFOSABI_NONE || ei_osabi == ELFOSABI_GNU)
            {
              int eabi_ver = EF_ARM_EABI_VERSION (e_flags);
-             int attr_arch, attr_profile;
 
              switch (eabi_ver)
                {
@@ -9030,11 +8998,13 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
                 executable file includes build attributes; GCC does
                 copy them to the executable, but e.g. RealView does
                 not.  */
-             attr_arch = bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_PROC,
-                                                   Tag_CPU_arch);
-             attr_profile = bfd_elf_get_obj_attr_int (info.abfd,
-                                                      OBJ_ATTR_PROC,
-                                                      Tag_CPU_arch_profile);
+             int attr_arch
+               = bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_PROC,
+                                           Tag_CPU_arch);
+             int attr_profile
+               = bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_PROC,
+                                           Tag_CPU_arch_profile);
+
              /* GCC specifies the profile for v6-M; RealView only
                 specifies the profile for architectures starting with
                 V7 (as opposed to architectures with a tag
@@ -9049,8 +9019,6 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
          if (fp_model == ARM_FLOAT_AUTO)
            {
-             int e_flags = elf_elfheader (info.abfd)->e_flags;
-
              switch (e_flags & (EF_ARM_SOFT_FLOAT | EF_ARM_VFP_FLOAT))
                {
                case 0:
@@ -9362,11 +9330,6 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_write_pc (gdbarch, arm_write_pc);
 
-  /* Frame handling.  */
-  set_gdbarch_dummy_id (gdbarch, arm_dummy_id);
-  set_gdbarch_unwind_pc (gdbarch, arm_unwind_pc);
-  set_gdbarch_unwind_sp (gdbarch, arm_unwind_sp);
-
   frame_base_set_default (gdbarch, &arm_normal_base);
 
   /* Address manipulation.  */
@@ -9576,7 +9539,8 @@ _initialize_arm_tdep (void)
 
 
   arm_disassembler_options = xstrdup ("reg-names-std");
-  const disasm_options_t *disasm_options = disassembler_options_arm ();
+  const disasm_options_t *disasm_options
+    = &disassembler_options_arm ()->options;
   int num_disassembly_styles = 0;
   for (i = 0; disasm_options->name[i] != NULL; i++)
     if (CONST_STRNEQ (disasm_options->name[i], "reg-names-"))
@@ -10222,7 +10186,7 @@ arm_record_data_proc_misc_ld_str (insn_decode_record *arm_insn_r)
   uint32_t record_buf[8], record_buf_mem[8];
   ULONGEST u_regval[2] = {0};
 
-  uint32_t reg_src1 = 0, reg_dest = 0;
+  uint32_t reg_src1 = 0;
   uint32_t opcode1 = 0;
 
   arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 21, 24);
@@ -11420,7 +11384,8 @@ arm_record_vfp_data_proc_insn (insn_decode_record *arm_insn_r)
   opc3 = bits (arm_insn_r->arm_insn, 6, 7);
   dp_op_sz = bit (arm_insn_r->arm_insn, 8);
   bit_d = bit (arm_insn_r->arm_insn, 22);
-  opc1 = opc1 & 0x04;
+  /* Mask off the "D" bit.  */
+  opc1 = opc1 & ~0x04;
 
   /* Handle VMLA, VMLS.  */
   if (opc1 == 0x00)
@@ -11485,7 +11450,7 @@ arm_record_vfp_data_proc_insn (insn_decode_record *arm_insn_r)
         }
     }
   /* Handle VDIV.  */
-  else if (opc1 == 0x0b)
+  else if (opc1 == 0x08)
     {
       if (dp_op_sz)
         curr_insn_type = INSN_T1;
@@ -13061,7 +13026,7 @@ public:
 class instruction_reader : public abstract_memory_reader
 {
  public:
-  bool read (CORE_ADDR memaddr, gdb_byte *buf, const size_t len)
+  bool read (CORE_ADDR memaddr, gdb_byte *buf, const size_t len) override
   {
     if (target_read_memory (memaddr, buf, len))
       return false;
@@ -13214,7 +13179,7 @@ public:
     : m_endian (endian), m_insns (insns), m_insns_size (SIZE)
   {}
 
-  bool read (CORE_ADDR memaddr, gdb_byte *buf, const size_t len)
+  bool read (CORE_ADDR memaddr, gdb_byte *buf, const size_t len) override
   {
     SELF_CHECK (len == 4 || len == 2);
     SELF_CHECK (memaddr % 2 == 0);