From: Luis Machado Date: Mon, 28 Sep 2020 14:06:30 +0000 (-0300) Subject: [Morello] Fix displaced stepping LSB adjustment and add debugging output X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a02532506a969622b53de4e6f81f52725ce63b98;p=thirdparty%2Fbinutils-gdb.git [Morello] Fix displaced stepping LSB adjustment and add debugging output 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 * aarch64-tdep.c (aarch64_displaced_step_data) : 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d87129edd7f..850bb825e2b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2020-10-20 Luis Machado + + * aarch64-tdep.c (aarch64_displaced_step_data) : 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 * aarch64-linux-tdep.c: Include arch/aarch64-insn.h. diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 220c519d4e8..e490fb05116 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -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 diff --git a/gdb/arch/aarch64-insn.c b/gdb/arch/aarch64-insn.c index 711500aaf4f..5a2ea18da66 100644 --- a/gdb/arch/aarch64-insn.c +++ b/gdb/arch/aarch64-insn.c @@ -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. diff --git a/gdb/infrun.c b/gdb/infrun.c index 8ae39a2877b..9d36a5e4f15 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -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))