+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.
unsigned insn_count;
/* Registers when doing displaced stepping. */
struct regcache *regs;
+ /* The gdbarch. */
+ struct gdbarch *gdbarch;
aarch64_displaced_step_closure *dsc;
};
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))
{
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,
{
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
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. */
{
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
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. */
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
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))
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.
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))
{
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.
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))
*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.
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))
*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
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)
*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.
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))