]> 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)
committerJohn Baldwin <jhb@FreeBSD.org>
Thu, 1 Sep 2022 22:53:22 +0000 (15:53 -0700)
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/aarch64-tdep.c
gdb/arch/aarch64-insn.c
gdb/linux-tdep.c

index 7c9d238fe2d7334d5521bc85ffb211041e0281a1..01d1e327da3315ce3fc233410f1c171adf2d37e2 100644 (file)
@@ -3070,6 +3070,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_copy_insn_closure *dsc;
 };
@@ -3083,6 +3085,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))
     {
@@ -3312,6 +3323,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,
@@ -3572,6 +3584,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
@@ -3580,6 +3595,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.  */
@@ -3590,6 +3608,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
@@ -3598,6 +3619,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.  */
@@ -3606,7 +3630,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 3a3104f1c6a116deaf953135ffd2a42a535e3c71..2c51b90db1e6c7e838461fb52b4347284e839fda 100644 (file)
@@ -91,6 +91,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))
@@ -106,9 +111,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.
@@ -125,6 +134,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))
     {
@@ -137,9 +151,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.
@@ -157,6 +175,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))
@@ -173,9 +196,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.
@@ -193,6 +220,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))
@@ -209,9 +241,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
@@ -230,6 +266,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)
@@ -253,10 +294,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 528c9beea661b1a9e9f3b52948039f9e7106ea6c..517d3bd884b4baf208a4277744919d15f68d6d7f 100644 (file)
@@ -2556,6 +2556,10 @@ linux_displaced_step_location (struct gdbarch *gdbarch)
     throw_error (NOT_SUPPORTED_ERROR,
                 _("Cannot find AT_ENTRY auxiliary vector entry."));
 
+  /* Some architectures like AArch64 Morello have the LSB set for addresses
+     in the text segment (pure capability ABI).  */
+  addr = gdbarch_addr_bits_remove (gdbarch, addr);
+
   /* Make certain that the address points at real code, and not a
      function descriptor.  */
   addr = gdbarch_convert_from_func_ptr_addr