]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[Morello] Fix displaced stepping LSB adjustment and add debugging output
authorLuis Machado <luis.machado@arm.com>
Mon, 28 Sep 2020 14:06:30 +0000 (11:06 -0300)
committerLuis Machado <luis.machado@linaro.org>
Tue, 20 Oct 2020 18:06:10 +0000 (15:06 -0300)
This patch fixes cases where the LSB of a pure cap function isn't cleared when
we use it for address arithmetic. Also adds debugging output.

gdb/ChangeLog:

2020-10-20  Luis Machado  <luis.machado@arm.com>

* aarch64-tdep.c (aarch64_displaced_step_data) <gdbarch>: New field.
(aarch64_displaced_step_b): Add debugging output.
(aarch64_displaced_step_copy_insn): Initialize the gdbarch member.
(aarch64_pointer_to_address, aarch64_address_to_pointer)
(aarch64_integer_to_address): Add debugging output.
* arch/aarch64-insn.c (aarch64_decode_b, aarch64_decode_bcond)
(aarch64_decode_cb, aarch64_decode_tb)
(aarch64_decode_ldr_literal): Refactor and add debugging output.
* infrun.c (displaced_step_prepare_throw): Clear LSB bits.

gdb/ChangeLog
gdb/aarch64-tdep.c
gdb/arch/aarch64-insn.c
gdb/infrun.c

index d87129edd7fd6221e6fef0001e38e188bdba6f0a..850bb825e2be1f01b506bee6fd5facb7eb28b9c5 100644 (file)
@@ -1,3 +1,15 @@
+2020-10-20  Luis Machado  <luis.machado@arm.com>
+
+       * aarch64-tdep.c (aarch64_displaced_step_data) <gdbarch>: New field.
+       (aarch64_displaced_step_b): Add debugging output.
+       (aarch64_displaced_step_copy_insn): Initialize the gdbarch member.
+       (aarch64_pointer_to_address, aarch64_address_to_pointer)
+       (aarch64_integer_to_address): Add debugging output.
+       * arch/aarch64-insn.c (aarch64_decode_b, aarch64_decode_bcond)
+       (aarch64_decode_cb, aarch64_decode_tb)
+       (aarch64_decode_ldr_literal): Refactor and add debugging output.
+       * infrun.c (displaced_step_prepare_throw): Clear LSB bits.
+
 2020-10-20  Luis Machado  <luis.machado@arm.com>
 
        * aarch64-linux-tdep.c: Include arch/aarch64-insn.h.
index 220c519d4e8069e067c27cbfbb679900556c6aaf..e490fb051168b41dac9f20f3aab84750d67f0bfc 100644 (file)
@@ -3019,6 +3019,8 @@ struct aarch64_displaced_step_data
   unsigned insn_count;
   /* Registers when doing displaced stepping.  */
   struct regcache *regs;
+  /* The gdbarch.  */
+  struct gdbarch *gdbarch;
 
   aarch64_displaced_step_closure *dsc;
 };
@@ -3032,6 +3034,15 @@ aarch64_displaced_step_b (const int is_bl, const int32_t offset,
   struct aarch64_displaced_step_data *dsd
     = (struct aarch64_displaced_step_data *) data;
   int64_t new_offset = data->insn_addr - dsd->new_addr + offset;
+  struct gdbarch *gdbarch = dsd->gdbarch;
+
+  if (aarch64_debug)
+    debug_printf ("aarch64_displaced_step_b: Insn address %s, offset %s\n"
+                 "new_offset: %s, new_addr: %s",
+                 paddress (gdbarch, data->insn_addr),
+                 paddress (gdbarch, offset),
+                 paddress (gdbarch, new_offset),
+                 paddress (gdbarch, dsd->new_addr));
 
   if (can_encode_int32 (new_offset, 28))
     {
@@ -3254,6 +3265,7 @@ aarch64_displaced_step_copy_insn (struct gdbarch *gdbarch,
   dsd.base.insn_addr = from;
   dsd.new_addr = to;
   dsd.regs = regs;
+  dsd.gdbarch = gdbarch;
   dsd.dsc = dsc.get ();
   dsd.insn_count = 0;
   aarch64_relocate_instruction (insn, &visitor,
@@ -3502,6 +3514,9 @@ aarch64_pointer_to_address (struct gdbarch *gdbarch, struct type *type,
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 
+  if (aarch64_debug)
+    debug_printf ("aarch64: Entering %s\n", __func__);
+
   if (type->length <= 8)
     return signed_pointer_to_address (gdbarch, type, buf);
   else
@@ -3510,6 +3525,9 @@ aarch64_pointer_to_address (struct gdbarch *gdbarch, struct type *type,
         the extra information.  */
       return extract_unsigned_integer (buf, 8, byte_order);
     }
+
+  if (aarch64_debug)
+    debug_printf ("aarch64: Exiting %s\n", __func__);
 }
 
 /* Implements the gdbarch_address_to_pointer hook.  */
@@ -3520,6 +3538,9 @@ aarch64_address_to_pointer (struct gdbarch *gdbarch, struct type *type,
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 
+  if (aarch64_debug)
+    debug_printf ("aarch64: Entering %s\n", __func__);
+
   if (type->length <= 8)
     address_to_signed_pointer (gdbarch, type, buf, addr);
   else
@@ -3528,6 +3549,9 @@ aarch64_address_to_pointer (struct gdbarch *gdbarch, struct type *type,
       memset (buf, 0, type->length);
       store_unsigned_integer (buf, 8, byte_order, addr);
     }
+
+  if (aarch64_debug)
+    debug_printf ("aarch64: Exiting %s\n", __func__);
 }
 
 /* Implements the gdbarch_integer_to_address hook.  */
@@ -3536,7 +3560,13 @@ static CORE_ADDR
 aarch64_integer_to_address (struct gdbarch *gdbarch,
                            struct type *type, const gdb_byte *buf)
 {
+  if (aarch64_debug)
+    debug_printf ("aarch64: Entering %s\n", __func__);
+
   return aarch64_pointer_to_address (gdbarch, type, buf);
+
+  if (aarch64_debug)
+    debug_printf ("aarch64: Exiting %s\n", __func__);
 }
 
 /* Remove useless bits from addresses in a running program.  This is
index 711500aaf4fec2106f7fd99e10685b23cca5eb12..5a2ea18da663e7357685649646682b4c7c05b846 100644 (file)
@@ -113,6 +113,11 @@ int
 aarch64_decode_b (CORE_ADDR addr, uint32_t insn, int *is_bl,
                  int32_t *offset)
 {
+  if (aarch64_debug)
+    debug_printf ("aarch64: Entering %s\n", __func__);
+
+  int retval = 0;
+
   /* b  0001 01ii iiii iiii iiii iiii iiii iiii */
   /* bl 1001 01ii iiii iiii iiii iiii iiii iiii */
   if (decode_masked_match (insn, 0x7c000000, 0x14000000))
@@ -128,9 +133,13 @@ aarch64_decode_b (CORE_ADDR addr, uint32_t insn, int *is_bl,
                        core_addr_to_string_nz (addr + *offset));
        }
 
-      return 1;
+      retval = 1;
     }
-  return 0;
+
+  if (aarch64_debug)
+    debug_printf ("aarch64: Exiting %s\n", __func__);
+
+  return retval;
 }
 
 /* Decode an opcode if it represents a conditional branch instruction.
@@ -147,6 +156,11 @@ int
 aarch64_decode_bcond (CORE_ADDR addr, uint32_t insn, unsigned *cond,
                      int32_t *offset)
 {
+  if (aarch64_debug)
+    debug_printf ("aarch64: Entering %s\n", __func__);
+
+  int retval = 0;
+
   /* b.cond  0101 0100 iiii iiii iiii iiii iii0 cccc */
   if (decode_masked_match (insn, 0xff000010, 0x54000000))
     {
@@ -159,9 +173,13 @@ aarch64_decode_bcond (CORE_ADDR addr, uint32_t insn, unsigned *cond,
                        core_addr_to_string_nz (addr), insn, *cond,
                        core_addr_to_string_nz (addr + *offset));
        }
-      return 1;
+      retval = 1;
     }
-  return 0;
+
+  if (aarch64_debug)
+    debug_printf ("aarch64: Exiting %s\n", __func__);
+
+  return retval;
 }
 
 /* Decode an opcode if it represents a CBZ or CBNZ instruction.
@@ -179,6 +197,11 @@ int
 aarch64_decode_cb (CORE_ADDR addr, uint32_t insn, int *is64, int *is_cbnz,
                   unsigned *rn, int32_t *offset)
 {
+  if (aarch64_debug)
+    debug_printf ("aarch64: Entering %s\n", __func__);
+
+  int retval = 0;
+
   /* cbz  T011 010o iiii iiii iiii iiii iiir rrrr */
   /* cbnz T011 010o iiii iiii iiii iiii iiir rrrr */
   if (decode_masked_match (insn, 0x7e000000, 0x34000000))
@@ -195,9 +218,13 @@ aarch64_decode_cb (CORE_ADDR addr, uint32_t insn, int *is64, int *is_cbnz,
                        *is_cbnz ? "cbnz" : "cbz",
                        core_addr_to_string_nz (addr + *offset));
        }
-      return 1;
+      retval = 1;
     }
-  return 0;
+
+  if (aarch64_debug)
+    debug_printf ("aarch64: Exiting %s\n", __func__);
+
+  return retval;
 }
 
 /* Decode an opcode if it represents a TBZ or TBNZ instruction.
@@ -215,6 +242,11 @@ int
 aarch64_decode_tb (CORE_ADDR addr, uint32_t insn, int *is_tbnz,
                   unsigned *bit, unsigned *rt, int32_t *imm)
 {
+  if (aarch64_debug)
+    debug_printf ("aarch64: Entering %s\n", __func__);
+
+  int retval = 0;
+
   /* tbz  b011 0110 bbbb biii iiii iiii iiir rrrr */
   /* tbnz B011 0111 bbbb biii iiii iiii iiir rrrr */
   if (decode_masked_match (insn, 0x7e000000, 0x36000000))
@@ -231,9 +263,13 @@ aarch64_decode_tb (CORE_ADDR addr, uint32_t insn, int *is_tbnz,
                        *is_tbnz ? "tbnz" : "tbz", *rt, *bit,
                        core_addr_to_string_nz (addr + *imm));
        }
-      return 1;
+      retval = 1;
     }
-  return 0;
+
+  if (aarch64_debug)
+    debug_printf ("aarch64: Exiting %s\n", __func__);
+
+  return retval;
 }
 
 /* Decode an opcode if it represents an LDR or LDRSW instruction taking a
@@ -252,6 +288,11 @@ int
 aarch64_decode_ldr_literal (CORE_ADDR addr, uint32_t insn, int *is_w,
                            int *is64, unsigned *rt, int32_t *offset)
 {
+  if (aarch64_debug)
+    debug_printf ("aarch64: Entering %s\n", __func__);
+
+  int retval = 0;
+
   /* LDR    0T01 1000 iiii iiii iiii iiii iiir rrrr */
   /* LDRSW  1001 1000 iiii iiii iiii iiii iiir rrrr */
   if ((insn & 0x3f000000) == 0x18000000)
@@ -275,10 +316,13 @@ aarch64_decode_ldr_literal (CORE_ADDR addr, uint32_t insn, int *is_w,
                      *is_w ? "ldrsw" : "ldr",
                      *is64 ? "x" : "w", *rt);
 
-      return 1;
+      retval = 1;
     }
 
-  return 0;
+  if (aarch64_debug)
+    debug_printf ("aarch64: Exiting %s\n", __func__);
+
+  return retval;
 }
 
 /* Visit an instruction INSN by VISITOR with all needed information in DATA.
index 8ae39a2877b3152b10c65437833884fb631c4248..9d36a5e4f15600ce32ed641f1e141759c42d2731 100644 (file)
@@ -1718,6 +1718,9 @@ displaced_step_prepare_throw (thread_info *tp)
   original = regcache_read_pc (regcache);
 
   copy = gdbarch_displaced_step_location (gdbarch);
+  /* Some architectures like AArch64 Morello have the LSB set for addresses
+     in the text segment (pure capability ABI).  */
+  copy = gdbarch_addr_bits_remove (gdbarch, copy);
   len = gdbarch_max_insn_length (gdbarch);
 
   if (breakpoint_in_range_p (aspace, copy, len))