Merge branch 'master' into merge-job
[deliverable/binutils-gdb.git] / gdb / aarch64-tdep.c
index 2c8c6a1bdc32bb01894cc66efc0d8374d1245726..da41e22130768ac19f306f47b6f6e6e96e4911da 100644 (file)
@@ -1,6 +1,6 @@
 /* Common target dependent code for GDB on AArch64 systems.
 
-   Copyright (C) 2009-2019 Free Software Foundation, Inc.
+   Copyright (C) 2009-2020 Free Software Foundation, Inc.
    Contributed by ARM Ltd.
 
    This file is part of GDB.
@@ -21,7 +21,6 @@
 #include "defs.h"
 
 #include "frame.h"
-#include "inferior.h"
 #include "gdbcmd.h"
 #include "gdbcore.h"
 #include "dis-asm.h"
 #include "prologue-value.h"
 #include "target-descriptions.h"
 #include "user-regs.h"
-#include "language.h"
-#include "infcall.h"
-#include "ax.h"
 #include "ax-gdb.h"
-#include "common/selftest.h"
+#include "gdbsupport/selftest.h"
 
 #include "aarch64-tdep.h"
 #include "aarch64-ravenscar-thread.h"
 
-#include "elf-bfd.h"
-#include "elf/aarch64.h"
-
-#include "common/vec.h"
-
 #include "record.h"
 #include "record-full.h"
 #include "arch/aarch64-insn.h"
+#include "gdbarch.h"
 
 #include "opcode/aarch64.h"
 #include <algorithm>
@@ -249,13 +241,13 @@ class instruction_reader : public abstract_instruction_reader
 
 } // namespace
 
-/* If address signing is enabled, mask off the signature bits from ADDR, using
-   the register values in THIS_FRAME.  */
+/* If address signing is enabled, mask off the signature bits from the link
+   register, which is passed by value in ADDR, using the register values in
+   THIS_FRAME.  */
 
 static CORE_ADDR
-aarch64_frame_unmask_address (struct gdbarch_tdep *tdep,
-                             struct frame_info *this_frame,
-                             CORE_ADDR addr)
+aarch64_frame_unmask_lr (struct gdbarch_tdep *tdep,
+                        struct frame_info *this_frame, CORE_ADDR addr)
 {
   if (tdep->has_pauth ()
       && frame_unwind_register_unsigned (this_frame,
@@ -264,11 +256,25 @@ aarch64_frame_unmask_address (struct gdbarch_tdep *tdep,
       int cmask_num = AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base);
       CORE_ADDR cmask = frame_unwind_register_unsigned (this_frame, cmask_num);
       addr = addr & ~cmask;
+
+      /* Record in the frame that the link register required unmasking.  */
+      set_frame_previous_pc_masked (this_frame);
     }
 
   return addr;
 }
 
+/* Implement the "get_pc_address_flags" gdbarch method.  */
+
+static std::string
+aarch64_get_pc_address_flags (frame_info *frame, CORE_ADDR pc)
+{
+  if (pc != 0 && get_frame_pc_masked (frame))
+    return "PAC";
+
+  return "";
+}
+
 /* Analyze a prologue, looking for a recognizable stack frame
    and frame pointer.  Scan until we encounter a store that could
    clobber the stack frame unexpectedly, or an unknown instruction.  */
@@ -383,17 +389,16 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
        {
          unsigned rt = inst.operands[0].reg.regno;
          unsigned rn = inst.operands[1].addr.base_regno;
-         int is64
-           = (aarch64_get_qualifier_esize (inst.operands[0].qualifier) == 8);
+         int size = aarch64_get_qualifier_esize (inst.operands[0].qualifier);
 
          gdb_assert (aarch64_num_of_operands (inst.opcode) == 2);
          gdb_assert (inst.operands[0].type == AARCH64_OPND_Rt);
          gdb_assert (inst.operands[1].type == AARCH64_OPND_ADDR_SIMM9);
          gdb_assert (!inst.operands[1].addr.offset.is_reg);
 
-         stack.store (pv_add_constant (regs[rn],
-                                       inst.operands[1].addr.offset.imm),
-                      is64 ? 8 : 4, regs[rt]);
+         stack.store
+           (pv_add_constant (regs[rn], inst.operands[1].addr.offset.imm),
+            size, regs[rt]);
        }
       else if ((inst.opcode->iclass == ldstpair_off
                || (inst.opcode->iclass == ldstpair_indexed
@@ -405,6 +410,7 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
          unsigned rt2;
          unsigned rn = inst.operands[2].addr.base_regno;
          int32_t imm = inst.operands[2].addr.offset.imm;
+         int size = aarch64_get_qualifier_esize (inst.operands[0].qualifier);
 
          gdb_assert (inst.operands[0].type == AARCH64_OPND_Rt
                      || inst.operands[0].type == AARCH64_OPND_Ft);
@@ -426,17 +432,12 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
          rt2 = inst.operands[1].reg.regno;
          if (inst.operands[0].type == AARCH64_OPND_Ft)
            {
-             /* Only bottom 64-bit of each V register (D register) need
-                to be preserved.  */
-             gdb_assert (inst.operands[0].qualifier == AARCH64_OPND_QLF_S_D);
              rt1 += AARCH64_X_REGISTER_COUNT;
              rt2 += AARCH64_X_REGISTER_COUNT;
            }
 
-         stack.store (pv_add_constant (regs[rn], imm), 8,
-                      regs[rt1]);
-         stack.store (pv_add_constant (regs[rn], imm + 8), 8,
-                      regs[rt2]);
+         stack.store (pv_add_constant (regs[rn], imm), size, regs[rt1]);
+         stack.store (pv_add_constant (regs[rn], imm + size), size, regs[rt2]);
 
          if (inst.operands[2].addr.writeback)
            regs[rn] = pv_add_constant (regs[rn], imm);
@@ -453,21 +454,14 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
          unsigned int rt = inst.operands[0].reg.regno;
          int32_t imm = inst.operands[1].addr.offset.imm;
          unsigned int rn = inst.operands[1].addr.base_regno;
-         bool is64
-           = (aarch64_get_qualifier_esize (inst.operands[0].qualifier) == 8);
+         int size = aarch64_get_qualifier_esize (inst.operands[0].qualifier);
          gdb_assert (inst.operands[0].type == AARCH64_OPND_Rt
                      || inst.operands[0].type == AARCH64_OPND_Ft);
 
          if (inst.operands[0].type == AARCH64_OPND_Ft)
-           {
-             /* Only bottom 64-bit of each V register (D register) need
-                to be preserved.  */
-             gdb_assert (inst.operands[0].qualifier == AARCH64_OPND_QLF_S_D);
-             rt += AARCH64_X_REGISTER_COUNT;
-           }
+           rt += AARCH64_X_REGISTER_COUNT;
 
-         stack.store (pv_add_constant (regs[rn], imm),
-                      is64 ? 8 : 4, regs[rt]);
+         stack.store (pv_add_constant (regs[rn], imm), size, regs[rt]);
          if (inst.operands[1].addr.writeback)
            regs[rn] = pv_add_constant (regs[rn], imm);
        }
@@ -951,7 +945,7 @@ aarch64_prologue_prev_register (struct frame_info *this_frame,
       if (tdep->has_pauth ()
          && trad_frame_value_p (cache->saved_regs,
                                 tdep->pauth_ra_state_regnum))
-       lr = aarch64_frame_unmask_address (tdep, this_frame, lr);
+       lr = aarch64_frame_unmask_lr (tdep, this_frame, lr);
 
       return frame_unwind_got_constant (this_frame, prev_regnum, lr);
     }
@@ -1118,7 +1112,7 @@ aarch64_dwarf2_prev_register (struct frame_info *this_frame,
     {
     case AARCH64_PC_REGNUM:
       lr = frame_unwind_register_unsigned (this_frame, AARCH64_LR_REGNUM);
-      lr = aarch64_frame_unmask_address (tdep, this_frame, lr);
+      lr = aarch64_frame_unmask_lr (tdep, this_frame, lr);
       return frame_unwind_got_constant (this_frame, regnum, lr);
 
     default:
@@ -1180,8 +1174,12 @@ aarch64_execute_dwarf_cfa_vendor_op (struct gdbarch *gdbarch, gdb_byte op,
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   struct dwarf2_frame_state_reg *ra_state;
 
-  if (tdep->has_pauth () && op == DW_CFA_AARCH64_negate_ra_state)
+  if (op == DW_CFA_AARCH64_negate_ra_state)
     {
+      /* On systems without pauth, treat as a nop.  */
+      if (!tdep->has_pauth ())
+       return true;
+
       /* Allocate RA_STATE column if it's not allocated yet.  */
       fs->regs.alloc_regs (AARCH64_DWARF_PAUTH_RA_STATE + 1);
 
@@ -1409,7 +1407,7 @@ struct aarch64_call_info
 };
 
 /* Pass a value in a sequence of consecutive X registers.  The caller
-   is responsbile for ensuring sufficient registers are available.  */
+   is responsible for ensuring sufficient registers are available.  */
 
 static void
 pass_in_x (struct gdbarch *gdbarch, struct regcache *regcache,
@@ -1885,6 +1883,9 @@ aarch64_vnh_type (struct gdbarch *gdbarch)
       t = arch_composite_type (gdbarch, "__gdb_builtin_type_vnh",
                               TYPE_CODE_UNION);
 
+      elem = builtin_type (gdbarch)->builtin_half;
+      append_composite_type_field (t, "f", elem);
+
       elem = builtin_type (gdbarch)->builtin_uint16;
       append_composite_type_field (t, "u", elem);
 
@@ -1963,6 +1964,8 @@ aarch64_vnv_type (struct gdbarch *gdbarch)
 
       sub = arch_composite_type (gdbarch, "__gdb_builtin_type_vnh",
                                 TYPE_CODE_UNION);
+      append_composite_type_field (sub, "f",
+                                  init_vector_type (bt->builtin_half, 8));
       append_composite_type_field (sub, "u",
                                   init_vector_type (bt->builtin_uint16, 8));
       append_composite_type_field (sub, "s",
@@ -2747,7 +2750,7 @@ struct aarch64_displaced_step_data
   /* The address where the instruction will be executed at.  */
   CORE_ADDR new_addr;
   /* Buffer of instructions to be copied to NEW_ADDR to execute.  */
-  uint32_t insn_buf[DISPLACED_MODIFIED_INSNS];
+  uint32_t insn_buf[AARCH64_DISPLACED_MODIFIED_INSNS];
   /* Number of instructions in INSN_BUF.  */
   unsigned insn_count;
   /* Registers when doing displaced stepping.  */
@@ -2991,7 +2994,7 @@ aarch64_displaced_step_copy_insn (struct gdbarch *gdbarch,
   dsd.insn_count = 0;
   aarch64_relocate_instruction (insn, &visitor,
                                (struct aarch64_insn_data *) &dsd);
-  gdb_assert (dsd.insn_count <= DISPLACED_MODIFIED_INSNS);
+  gdb_assert (dsd.insn_count <= AARCH64_DISPLACED_MODIFIED_INSNS);
 
   if (dsd.insn_count != 0)
     {
@@ -3369,6 +3372,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_gen_return_address (gdbarch, aarch64_gen_return_address);
 
+  set_gdbarch_get_pc_address_flags (gdbarch, aarch64_get_pc_address_flags);
+
   tdesc_use_registers (gdbarch, tdesc, tdesc_data);
 
   /* Add standard register aliases.  */
@@ -3421,8 +3426,6 @@ When on, AArch64 specific debugging is enabled."),
                            selftests::aarch64_analyze_prologue_test);
   selftests::register_test ("aarch64-process-record",
                            selftests::aarch64_process_record_test);
-  selftests::record_xml_tdesc ("aarch64.xml",
-                              aarch64_create_target_description (0, false));
 #endif
 }
 
@@ -3540,7 +3543,7 @@ aarch64_record_data_proc_reg (insn_decode_record *aarch64_insn_r)
            }
          else if (insn_bits21_23 == 0x04 || insn_bits21_23 == 0x06)
            {
-             /* CConditional select.  */
+             /* Conditional select.  */
              /* Data-processing (2 source).  */
              /* Data-processing (1 source).  */
              record_buf[0] = reg_rd;
This page took 0.028684 seconds and 4 git commands to generate.