Create a displaced_step_closure class hierarchy

displaced_step_closure is a type defined in multiple -tdep.c files.
Trying to xfree it from the common code (infrun.c) is a problem when we
try to poison xfree for non-POD types.  Because there can be multiple of
these types in the same build, this patch makes a hierarchy of classes
with a virtual destructor.  When the common code deletes the object
through a displaced_step_closure pointer, it will invoke the right
destructor.

The amd64 used a last-member array with a variable size.  That doesn't
work with new, so I changed it for an std::vector.  Other architectures
which used a simple byte buffer as a closure now use a shared
buf_displaced_step_closure, a closure type that only contains a
gdb::byte_vector.

Reg-tested on the buildbot.

gdb/ChangeLog:

	* infrun.h: Include common/byte-vector.h.
	(struct displaced_step_closure): New struct.
	(struct buf_displaced_step_closure): New struct.
	* infrun.c (displaced_step_closure::~displaced_step_closure):
	Provide default implementation.
	(displaced_step_clear): Deallocate step closure with delete.
	* aarch64-tdep.c (displaced_step_closure): Rename to ...
	(aarch64_displaced_step_closure): ... this, extend
	displaced_step_closure.
	(aarch64_displaced_step_data) <dsc>: Change type to
	aarch64_displaced_step_closure.
	(aarch64_displaced_step_copy_insn): Adjust to type change, use
	unique_ptr.
	(aarch64_displaced_step_fixup): Add cast for displaced step
	closure.
	* amd64-tdep.c (displaced_step_closure): Rename to ...
	(amd64_displaced_step_closure): ... this, extend
	displaced_step_closure.
	<insn_buf>: Change type to std::vector<gdb_byte>.
	<max_len>: Remove.
	(fixup_riprel): Change type of DSC parameter, adjust to type
	change of insn_buf.
	(fixup_displaced_copy): Change type of DSC parameter.
	(amd64_displaced_step_copy_insn): Instantiate
	amd64_displaced_step_closure.
	(amd64_displaced_step_fixup): Add cast for closure type, adjust
	to type change of insn_buf.
	* arm-linux-tdep.c (arm_linux_cleanup_svc): Change type of
	parameter DSC.
	(arm_linux_copy_svc): Likewise.
	(cleanup_kernel_helper_return): Likewise.
	(arm_catch_kernel_helper_return): Likewise.
	(arm_linux_displaced_step_copy_insn): Instantiate
	arm_displaced_step_closure.
	* arm-tdep.c (arm_pc_is_thumb): Add cast for closure.
	(displaced_read_reg): Change type of parameter DSC.
	(branch_write_pc): Likewise.
	(load_write_pc): Likewise.
	(alu_write_pc): Likewise.
	(displaced_write_reg): Likewise.
	(arm_copy_unmodified): Likewise.
	(thumb_copy_unmodified_32bit): Likewise.
	(thumb_copy_unmodified_16bit): Likewise.
	(cleanup_preload): Likewise.
	(install_preload): Likewise.
	(arm_copy_preload): Likewise.
	(thumb2_copy_preload): Likewise.
	(install_preload_reg): Likewise.
	(arm_copy_preload_reg): Likewise.
	(cleanup_copro_load_store): Likewise.
	(install_copro_load_store): Likewise.
	(arm_copy_copro_load_store) Likewise.
	(thumb2_copy_copro_load_store): Likewise.
	(cleanup_branch): Likewise.
	(install_b_bl_blx): Likewise.
	(arm_copy_b_bl_blx): Likewise.
	(thumb2_copy_b_bl_blx): Likewise.
	(thumb_copy_b): Likewise.
	(install_bx_blx_reg): Likewise.
	(arm_copy_bx_blx_reg): Likewise.
	(thumb_copy_bx_blx_reg): Likewise.
	(cleanup_alu_imm): Likewise.
	(arm_copy_alu_imm): Likewise.
	(thumb2_copy_alu_imm): Likewise.
	(cleanup_alu_reg): Likewise.
	(install_alu_reg): Likewise.
	(arm_copy_alu_reg): Likewise.
	(thumb_copy_alu_reg): Likewise.
	(cleanup_alu_shifted_reg): Likewise.
	(install_alu_shifted_reg): Likewise.
	(arm_copy_alu_shifted_reg): Likewise.
	(cleanup_load): Likewise.
	(cleanup_store): Likewise.
	(arm_copy_extra_ld_st): Likewise.
	(install_load_store): Likewise.
	(thumb2_copy_load_literal): Likewise.
	(thumb2_copy_load_reg_imm): Likewise.
	(arm_copy_ldr_str_ldrb_strb): Likewise.
	(cleanup_block_load_all): Likewise.
	(cleanup_block_store_pc): Likewise.
	(cleanup_block_load_pc): Likewise.
	(arm_copy_block_xfer): Likewise.
	(thumb2_copy_block_xfer): Likewise.
	(cleanup_svc): Likewise.
	(install_svc): Likewise.
	(arm_copy_svc): Likewise.
	(thumb_copy_svc): Likewise.
	(arm_copy_undef): Likewise.
	(thumb_32bit_copy_undef): Likewise.
	(arm_copy_unpred): Likewise.
	(arm_decode_misc_memhint_neon): Likewise.
	(arm_decode_unconditional): Likewise.
	(arm_decode_miscellaneous): Likewise.
	(arm_decode_dp_misc): Likewise.
	(arm_decode_ld_st_word_ubyte): Likewise.
	(arm_decode_media): Likewise.
	(arm_decode_b_bl_ldmstm): Likewise.
	(arm_decode_ext_reg_ld_st): Likewise.
	(thumb2_decode_dp_shift_reg): Likewise.
	(thumb2_decode_ext_reg_ld_st): Likewise.
	(arm_decode_svc_copro): Likewise.
	(thumb2_decode_svc_copro): Likewise.
	(install_pc_relative): Likewise.
	(thumb_copy_pc_relative_16bit): Likewise.
	(thumb_decode_pc_relative_16bit): Likewise.
	(thumb_copy_pc_relative_32bit): Likewise.
	(thumb_copy_16bit_ldr_literal): Likewise.
	(thumb_copy_cbnz_cbz): Likewise.
	(thumb2_copy_table_branch): Likewise.
	(cleanup_pop_pc_16bit_all): Likewise.
	(thumb_copy_pop_pc_16bit): Likewise.
	(thumb_process_displaced_16bit_insn): Likewise.
	(decode_thumb_32bit_ld_mem_hints): Likewise.
	(thumb_process_displaced_32bit_insn): Likewise.
	(thumb_process_displaced_insn): Likewise.
	(arm_process_displaced_insn): Likewise.
	(arm_displaced_init_closure): Likewise.
	(arm_displaced_step_fixup): Add cast for closure.
	* arm-tdep.h: Include infrun.h.
	(displaced_step_closure): Rename to ...
	(arm_displaced_step_closure): ... this, extend
	displaced_step_closure.
	<u::svc::copy_svc_os>: Change type of parameter DSC.
	<cleanup>: Likewise.
	(arm_process_displaced_insn): Likewise.
	(arm_displaced_init_closure): Likewise.
	(displaced_read_reg): Likewise.
	(displaced_write_reg): Likewise.
	* i386-linux-tdep.c (i386_linux_displaced_step_copy_insn):
	Adjust.
	* i386-tdep.h: Include infrun.h.
	(i386_displaced_step_closure): New typedef.
	* i386-tdep.c (i386_displaced_step_copy_insn): Use
	i386_displaced_step_closure.
	(i386_displaced_step_fixup): Adjust.
	* rs6000-tdep.c (ppc_displaced_step_closure): New typedef.
	(ppc_displaced_step_copy_insn): Use ppc_displaced_step_closure
	and unique_ptr.
	(ppc_displaced_step_fixup): Adjust.
	* s390-linux-tdep.c (s390_displaced_step_closure): New typedef.
	(s390_displaced_step_copy_insn): Use s390_displaced_step_closure
	and unique_ptr.
	(s390_displaced_step_fixup): Adjust.
This commit is contained in:
Simon Marchi 2017-10-21 11:27:52 -04:00
parent b392b304b9
commit cfba98720f
13 changed files with 340 additions and 157 deletions

View File

@ -1,3 +1,149 @@
2017-10-21 Simon Marchi <simon.marchi@polymtl.ca>
* infrun.h: Include common/byte-vector.h.
(struct displaced_step_closure): New struct.
(struct buf_displaced_step_closure): New struct.
* infrun.c (displaced_step_closure::~displaced_step_closure):
Provide default implementation.
(displaced_step_clear): Deallocate step closure with delete.
* aarch64-tdep.c (displaced_step_closure): Rename to ...
(aarch64_displaced_step_closure): ... this, extend
displaced_step_closure.
(aarch64_displaced_step_data) <dsc>: Change type to
aarch64_displaced_step_closure.
(aarch64_displaced_step_copy_insn): Adjust to type change, use
unique_ptr.
(aarch64_displaced_step_fixup): Add cast for displaced step
closure.
* amd64-tdep.c (displaced_step_closure): Rename to ...
(amd64_displaced_step_closure): ... this, extend
displaced_step_closure.
<insn_buf>: Change type to std::vector<gdb_byte>.
<max_len>: Remove.
(fixup_riprel): Change type of DSC parameter, adjust to type
change of insn_buf.
(fixup_displaced_copy): Change type of DSC parameter.
(amd64_displaced_step_copy_insn): Instantiate
amd64_displaced_step_closure.
(amd64_displaced_step_fixup): Add cast for closure type, adjust
to type change of insn_buf.
* arm-linux-tdep.c (arm_linux_cleanup_svc): Change type of
parameter DSC.
(arm_linux_copy_svc): Likewise.
(cleanup_kernel_helper_return): Likewise.
(arm_catch_kernel_helper_return): Likewise.
(arm_linux_displaced_step_copy_insn): Instantiate
arm_displaced_step_closure.
* arm-tdep.c (arm_pc_is_thumb): Add cast for closure.
(displaced_read_reg): Change type of parameter DSC.
(branch_write_pc): Likewise.
(load_write_pc): Likewise.
(alu_write_pc): Likewise.
(displaced_write_reg): Likewise.
(arm_copy_unmodified): Likewise.
(thumb_copy_unmodified_32bit): Likewise.
(thumb_copy_unmodified_16bit): Likewise.
(cleanup_preload): Likewise.
(install_preload): Likewise.
(arm_copy_preload): Likewise.
(thumb2_copy_preload): Likewise.
(install_preload_reg): Likewise.
(arm_copy_preload_reg): Likewise.
(cleanup_copro_load_store): Likewise.
(install_copro_load_store): Likewise.
(arm_copy_copro_load_store) Likewise.
(thumb2_copy_copro_load_store): Likewise.
(cleanup_branch): Likewise.
(install_b_bl_blx): Likewise.
(arm_copy_b_bl_blx): Likewise.
(thumb2_copy_b_bl_blx): Likewise.
(thumb_copy_b): Likewise.
(install_bx_blx_reg): Likewise.
(arm_copy_bx_blx_reg): Likewise.
(thumb_copy_bx_blx_reg): Likewise.
(cleanup_alu_imm): Likewise.
(arm_copy_alu_imm): Likewise.
(thumb2_copy_alu_imm): Likewise.
(cleanup_alu_reg): Likewise.
(install_alu_reg): Likewise.
(arm_copy_alu_reg): Likewise.
(thumb_copy_alu_reg): Likewise.
(cleanup_alu_shifted_reg): Likewise.
(install_alu_shifted_reg): Likewise.
(arm_copy_alu_shifted_reg): Likewise.
(cleanup_load): Likewise.
(cleanup_store): Likewise.
(arm_copy_extra_ld_st): Likewise.
(install_load_store): Likewise.
(thumb2_copy_load_literal): Likewise.
(thumb2_copy_load_reg_imm): Likewise.
(arm_copy_ldr_str_ldrb_strb): Likewise.
(cleanup_block_load_all): Likewise.
(cleanup_block_store_pc): Likewise.
(cleanup_block_load_pc): Likewise.
(arm_copy_block_xfer): Likewise.
(thumb2_copy_block_xfer): Likewise.
(cleanup_svc): Likewise.
(install_svc): Likewise.
(arm_copy_svc): Likewise.
(thumb_copy_svc): Likewise.
(arm_copy_undef): Likewise.
(thumb_32bit_copy_undef): Likewise.
(arm_copy_unpred): Likewise.
(arm_decode_misc_memhint_neon): Likewise.
(arm_decode_unconditional): Likewise.
(arm_decode_miscellaneous): Likewise.
(arm_decode_dp_misc): Likewise.
(arm_decode_ld_st_word_ubyte): Likewise.
(arm_decode_media): Likewise.
(arm_decode_b_bl_ldmstm): Likewise.
(arm_decode_ext_reg_ld_st): Likewise.
(thumb2_decode_dp_shift_reg): Likewise.
(thumb2_decode_ext_reg_ld_st): Likewise.
(arm_decode_svc_copro): Likewise.
(thumb2_decode_svc_copro): Likewise.
(install_pc_relative): Likewise.
(thumb_copy_pc_relative_16bit): Likewise.
(thumb_decode_pc_relative_16bit): Likewise.
(thumb_copy_pc_relative_32bit): Likewise.
(thumb_copy_16bit_ldr_literal): Likewise.
(thumb_copy_cbnz_cbz): Likewise.
(thumb2_copy_table_branch): Likewise.
(cleanup_pop_pc_16bit_all): Likewise.
(thumb_copy_pop_pc_16bit): Likewise.
(thumb_process_displaced_16bit_insn): Likewise.
(decode_thumb_32bit_ld_mem_hints): Likewise.
(thumb_process_displaced_32bit_insn): Likewise.
(thumb_process_displaced_insn): Likewise.
(arm_process_displaced_insn): Likewise.
(arm_displaced_init_closure): Likewise.
(arm_displaced_step_fixup): Add cast for closure.
* arm-tdep.h: Include infrun.h.
(displaced_step_closure): Rename to ...
(arm_displaced_step_closure): ... this, extend
displaced_step_closure.
<u::svc::copy_svc_os>: Change type of parameter DSC.
<cleanup>: Likewise.
(arm_process_displaced_insn): Likewise.
(arm_displaced_init_closure): Likewise.
(displaced_read_reg): Likewise.
(displaced_write_reg): Likewise.
* i386-linux-tdep.c (i386_linux_displaced_step_copy_insn):
Adjust.
* i386-tdep.h: Include infrun.h.
(i386_displaced_step_closure): New typedef.
* i386-tdep.c (i386_displaced_step_copy_insn): Use
i386_displaced_step_closure.
(i386_displaced_step_fixup): Adjust.
* rs6000-tdep.c (ppc_displaced_step_closure): New typedef.
(ppc_displaced_step_copy_insn): Use ppc_displaced_step_closure
and unique_ptr.
(ppc_displaced_step_fixup): Adjust.
* s390-linux-tdep.c (s390_displaced_step_closure): New typedef.
(s390_displaced_step_copy_insn): Use s390_displaced_step_closure
and unique_ptr.
(s390_displaced_step_fixup): Adjust.
2017-10-21 Simon Marchi <simon.marchi@polymtl.ca> 2017-10-21 Simon Marchi <simon.marchi@polymtl.ca>
* interps.h (interp_resume, interp_suspend, interp_set_temp): * interps.h (interp_resume, interp_suspend, interp_set_temp):

View File

@ -2488,14 +2488,14 @@ aarch64_software_single_step (struct regcache *regcache)
return next_pcs; return next_pcs;
} }
struct displaced_step_closure struct aarch64_displaced_step_closure : public displaced_step_closure
{ {
/* It is true when condition instruction, such as B.CON, TBZ, etc, /* It is true when condition instruction, such as B.CON, TBZ, etc,
is being displaced stepping. */ is being displaced stepping. */
int cond; int cond = 0;
/* PC adjustment offset after displaced stepping. */ /* PC adjustment offset after displaced stepping. */
int32_t pc_adjust; int32_t pc_adjust = 0;
}; };
/* Data when visiting instructions for displaced stepping. */ /* Data when visiting instructions for displaced stepping. */
@ -2513,7 +2513,7 @@ struct aarch64_displaced_step_data
/* Registers when doing displaced stepping. */ /* Registers when doing displaced stepping. */
struct regcache *regs; struct regcache *regs;
struct displaced_step_closure *dsc; aarch64_displaced_step_closure *dsc;
}; };
/* Implementation of aarch64_insn_visitor method "b". */ /* Implementation of aarch64_insn_visitor method "b". */
@ -2727,7 +2727,6 @@ aarch64_displaced_step_copy_insn (struct gdbarch *gdbarch,
CORE_ADDR from, CORE_ADDR to, CORE_ADDR from, CORE_ADDR to,
struct regcache *regs) struct regcache *regs)
{ {
struct displaced_step_closure *dsc = NULL;
enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
uint32_t insn = read_memory_unsigned_integer (from, 4, byte_order_for_code); uint32_t insn = read_memory_unsigned_integer (from, 4, byte_order_for_code);
struct aarch64_displaced_step_data dsd; struct aarch64_displaced_step_data dsd;
@ -2743,11 +2742,12 @@ aarch64_displaced_step_copy_insn (struct gdbarch *gdbarch,
return NULL; return NULL;
} }
dsc = XCNEW (struct displaced_step_closure); std::unique_ptr<aarch64_displaced_step_closure> dsc
(new aarch64_displaced_step_closure);
dsd.base.insn_addr = from; dsd.base.insn_addr = from;
dsd.new_addr = to; dsd.new_addr = to;
dsd.regs = regs; dsd.regs = regs;
dsd.dsc = dsc; dsd.dsc = dsc.get ();
dsd.insn_count = 0; dsd.insn_count = 0;
aarch64_relocate_instruction (insn, &visitor, aarch64_relocate_instruction (insn, &visitor,
(struct aarch64_insn_data *) &dsd); (struct aarch64_insn_data *) &dsd);
@ -2773,21 +2773,22 @@ aarch64_displaced_step_copy_insn (struct gdbarch *gdbarch,
} }
else else
{ {
xfree (dsc);
dsc = NULL; dsc = NULL;
} }
return dsc; return dsc.release ();
} }
/* Implement the "displaced_step_fixup" gdbarch method. */ /* Implement the "displaced_step_fixup" gdbarch method. */
void void
aarch64_displaced_step_fixup (struct gdbarch *gdbarch, aarch64_displaced_step_fixup (struct gdbarch *gdbarch,
struct displaced_step_closure *dsc, struct displaced_step_closure *dsc_,
CORE_ADDR from, CORE_ADDR to, CORE_ADDR from, CORE_ADDR to,
struct regcache *regs) struct regcache *regs)
{ {
aarch64_displaced_step_closure *dsc = (aarch64_displaced_step_closure *) dsc_;
if (dsc->cond) if (dsc->cond)
{ {
ULONGEST pc; ULONGEST pc;

View File

@ -46,6 +46,7 @@
#include "producer.h" #include "producer.h"
#include "ax.h" #include "ax.h"
#include "ax-gdb.h" #include "ax-gdb.h"
#include "common/byte-vector.h"
/* Note that the AMD64 architecture was previously known as x86-64. /* Note that the AMD64 architecture was previously known as x86-64.
The latter is (forever) engraved into the canonical system name as The latter is (forever) engraved into the canonical system name as
@ -1047,22 +1048,22 @@ struct amd64_insn
gdb_byte *raw_insn; gdb_byte *raw_insn;
}; };
struct displaced_step_closure struct amd64_displaced_step_closure : public displaced_step_closure
{ {
amd64_displaced_step_closure (int insn_buf_len)
: insn_buf (insn_buf_len, 0)
{}
/* For rip-relative insns, saved copy of the reg we use instead of %rip. */ /* For rip-relative insns, saved copy of the reg we use instead of %rip. */
int tmp_used; int tmp_used = 0;
int tmp_regno; int tmp_regno;
ULONGEST tmp_save; ULONGEST tmp_save;
/* Details of the instruction. */ /* Details of the instruction. */
struct amd64_insn insn_details; struct amd64_insn insn_details;
/* Amount of space allocated to insn_buf. */ /* The possibly modified insn. */
int max_len; gdb::byte_vector insn_buf;
/* The possibly modified insn.
This is a variable-length field. */
gdb_byte insn_buf[1];
}; };
/* WARNING: Keep onebyte_has_modrm, twobyte_has_modrm in sync with /* WARNING: Keep onebyte_has_modrm, twobyte_has_modrm in sync with
@ -1303,7 +1304,7 @@ amd64_get_insn_details (gdb_byte *insn, struct amd64_insn *details)
We set base = pc + insn_length so we can leave disp unchanged. */ We set base = pc + insn_length so we can leave disp unchanged. */
static void static void
fixup_riprel (struct gdbarch *gdbarch, struct displaced_step_closure *dsc, fixup_riprel (struct gdbarch *gdbarch, amd64_displaced_step_closure *dsc,
CORE_ADDR from, CORE_ADDR to, struct regcache *regs) CORE_ADDR from, CORE_ADDR to, struct regcache *regs)
{ {
const struct amd64_insn *insn_details = &dsc->insn_details; const struct amd64_insn *insn_details = &dsc->insn_details;
@ -1318,8 +1319,8 @@ fixup_riprel (struct gdbarch *gdbarch, struct displaced_step_closure *dsc,
++insn; ++insn;
/* Compute the rip-relative address. */ /* Compute the rip-relative address. */
insn_length = gdb_buffered_insn_length (gdbarch, dsc->insn_buf, insn_length = gdb_buffered_insn_length (gdbarch, dsc->insn_buf.data (),
dsc->max_len, from); dsc->insn_buf.size (), from);
rip_base = from + insn_length; rip_base = from + insn_length;
/* We need a register to hold the address. /* We need a register to hold the address.
@ -1353,7 +1354,7 @@ fixup_riprel (struct gdbarch *gdbarch, struct displaced_step_closure *dsc,
static void static void
fixup_displaced_copy (struct gdbarch *gdbarch, fixup_displaced_copy (struct gdbarch *gdbarch,
struct displaced_step_closure *dsc, amd64_displaced_step_closure *dsc,
CORE_ADDR from, CORE_ADDR to, struct regcache *regs) CORE_ADDR from, CORE_ADDR to, struct regcache *regs)
{ {
const struct amd64_insn *details = &dsc->insn_details; const struct amd64_insn *details = &dsc->insn_details;
@ -1380,15 +1381,11 @@ amd64_displaced_step_copy_insn (struct gdbarch *gdbarch,
/* Extra space for sentinels so fixup_{riprel,displaced_copy} don't have to /* Extra space for sentinels so fixup_{riprel,displaced_copy} don't have to
continually watch for running off the end of the buffer. */ continually watch for running off the end of the buffer. */
int fixup_sentinel_space = len; int fixup_sentinel_space = len;
struct displaced_step_closure *dsc amd64_displaced_step_closure *dsc
= ((struct displaced_step_closure *) = new amd64_displaced_step_closure (len + fixup_sentinel_space);
xmalloc (sizeof (*dsc) + len + fixup_sentinel_space));
gdb_byte *buf = &dsc->insn_buf[0]; gdb_byte *buf = &dsc->insn_buf[0];
struct amd64_insn *details = &dsc->insn_details; struct amd64_insn *details = &dsc->insn_details;
dsc->tmp_used = 0;
dsc->max_len = len + fixup_sentinel_space;
read_memory (from, buf, len); read_memory (from, buf, len);
/* Set up the sentinel space so we don't have to worry about running /* Set up the sentinel space so we don't have to worry about running
@ -1583,14 +1580,15 @@ amd64_insn_is_jump (struct gdbarch *gdbarch, CORE_ADDR addr)
void void
amd64_displaced_step_fixup (struct gdbarch *gdbarch, amd64_displaced_step_fixup (struct gdbarch *gdbarch,
struct displaced_step_closure *dsc, struct displaced_step_closure *dsc_,
CORE_ADDR from, CORE_ADDR to, CORE_ADDR from, CORE_ADDR to,
struct regcache *regs) struct regcache *regs)
{ {
amd64_displaced_step_closure *dsc = (amd64_displaced_step_closure *) dsc_;
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
/* The offset we applied to the instruction's address. */ /* The offset we applied to the instruction's address. */
ULONGEST insn_offset = to - from; ULONGEST insn_offset = to - from;
gdb_byte *insn = dsc->insn_buf; gdb_byte *insn = dsc->insn_buf.data ();
const struct amd64_insn *insn_details = &dsc->insn_details; const struct amd64_insn *insn_details = &dsc->insn_details;
if (debug_displaced) if (debug_displaced)

View File

@ -950,7 +950,7 @@ arm_linux_software_single_step (struct regcache *regcache)
static void static void
arm_linux_cleanup_svc (struct gdbarch *gdbarch, arm_linux_cleanup_svc (struct gdbarch *gdbarch,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
ULONGEST apparent_pc; ULONGEST apparent_pc;
int within_scratch; int within_scratch;
@ -978,7 +978,7 @@ arm_linux_cleanup_svc (struct gdbarch *gdbarch,
static int static int
arm_linux_copy_svc (struct gdbarch *gdbarch, struct regcache *regs, arm_linux_copy_svc (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
CORE_ADDR return_to = 0; CORE_ADDR return_to = 0;
@ -1069,7 +1069,7 @@ arm_linux_copy_svc (struct gdbarch *gdbarch, struct regcache *regs,
static void static void
cleanup_kernel_helper_return (struct gdbarch *gdbarch, cleanup_kernel_helper_return (struct gdbarch *gdbarch,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
displaced_write_reg (regs, dsc, ARM_LR_REGNUM, dsc->tmp[0], CANNOT_WRITE_PC); displaced_write_reg (regs, dsc, ARM_LR_REGNUM, dsc->tmp[0], CANNOT_WRITE_PC);
displaced_write_reg (regs, dsc, ARM_PC_REGNUM, dsc->tmp[0], BRANCH_WRITE_PC); displaced_write_reg (regs, dsc, ARM_PC_REGNUM, dsc->tmp[0], BRANCH_WRITE_PC);
@ -1078,7 +1078,7 @@ cleanup_kernel_helper_return (struct gdbarch *gdbarch,
static void static void
arm_catch_kernel_helper_return (struct gdbarch *gdbarch, CORE_ADDR from, arm_catch_kernel_helper_return (struct gdbarch *gdbarch, CORE_ADDR from,
CORE_ADDR to, struct regcache *regs, CORE_ADDR to, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@ -1112,7 +1112,7 @@ arm_linux_displaced_step_copy_insn (struct gdbarch *gdbarch,
CORE_ADDR from, CORE_ADDR to, CORE_ADDR from, CORE_ADDR to,
struct regcache *regs) struct regcache *regs)
{ {
struct displaced_step_closure *dsc = XNEW (struct displaced_step_closure); arm_displaced_step_closure *dsc = new arm_displaced_step_closure;
/* Detect when we enter an (inaccessible by GDB) Linux kernel helper, and /* Detect when we enter an (inaccessible by GDB) Linux kernel helper, and
stop at the return location. */ stop at the return location. */

View File

@ -399,8 +399,9 @@ arm_pc_is_thumb (struct gdbarch *gdbarch, CORE_ADDR memaddr)
{ {
struct bound_minimal_symbol sym; struct bound_minimal_symbol sym;
char type; char type;
struct displaced_step_closure* dsc arm_displaced_step_closure *dsc
= get_displaced_step_closure_by_addr(memaddr); = ((arm_displaced_step_closure * )
get_displaced_step_closure_by_addr (memaddr));
/* If checking the mode of displaced instruction in copy area, the mode /* If checking the mode of displaced instruction in copy area, the mode
should be determined by instruction on the original address. */ should be determined by instruction on the original address. */
@ -4413,7 +4414,7 @@ arm_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
location. */ location. */
ULONGEST ULONGEST
displaced_read_reg (struct regcache *regs, struct displaced_step_closure *dsc, displaced_read_reg (struct regcache *regs, arm_displaced_step_closure *dsc,
int regno) int regno)
{ {
ULONGEST ret; ULONGEST ret;
@ -4461,7 +4462,7 @@ displaced_in_arm_mode (struct regcache *regs)
/* Write to the PC as from a branch instruction. */ /* Write to the PC as from a branch instruction. */
static void static void
branch_write_pc (struct regcache *regs, struct displaced_step_closure *dsc, branch_write_pc (struct regcache *regs, arm_displaced_step_closure *dsc,
ULONGEST val) ULONGEST val)
{ {
if (!dsc->is_thumb) if (!dsc->is_thumb)
@ -4507,7 +4508,7 @@ bx_write_pc (struct regcache *regs, ULONGEST val)
/* Write to the PC as if from a load instruction. */ /* Write to the PC as if from a load instruction. */
static void static void
load_write_pc (struct regcache *regs, struct displaced_step_closure *dsc, load_write_pc (struct regcache *regs, arm_displaced_step_closure *dsc,
ULONGEST val) ULONGEST val)
{ {
if (DISPLACED_STEPPING_ARCH_VERSION >= 5) if (DISPLACED_STEPPING_ARCH_VERSION >= 5)
@ -4519,7 +4520,7 @@ load_write_pc (struct regcache *regs, struct displaced_step_closure *dsc,
/* Write to the PC as if from an ALU instruction. */ /* Write to the PC as if from an ALU instruction. */
static void static void
alu_write_pc (struct regcache *regs, struct displaced_step_closure *dsc, alu_write_pc (struct regcache *regs, arm_displaced_step_closure *dsc,
ULONGEST val) ULONGEST val)
{ {
if (DISPLACED_STEPPING_ARCH_VERSION >= 7 && !dsc->is_thumb) if (DISPLACED_STEPPING_ARCH_VERSION >= 7 && !dsc->is_thumb)
@ -4533,7 +4534,7 @@ alu_write_pc (struct regcache *regs, struct displaced_step_closure *dsc,
this is controlled by the WRITE_PC argument. */ this is controlled by the WRITE_PC argument. */
void void
displaced_write_reg (struct regcache *regs, struct displaced_step_closure *dsc, displaced_write_reg (struct regcache *regs, arm_displaced_step_closure *dsc,
int regno, ULONGEST val, enum pc_write_style write_pc) int regno, ULONGEST val, enum pc_write_style write_pc)
{ {
if (regno == ARM_PC_REGNUM) if (regno == ARM_PC_REGNUM)
@ -4617,7 +4618,7 @@ insn_references_pc (uint32_t insn, uint32_t bitmask)
static int static int
arm_copy_unmodified (struct gdbarch *gdbarch, uint32_t insn, arm_copy_unmodified (struct gdbarch *gdbarch, uint32_t insn,
const char *iname, struct displaced_step_closure *dsc) const char *iname, arm_displaced_step_closure *dsc)
{ {
if (debug_displaced) if (debug_displaced)
fprintf_unfiltered (gdb_stdlog, "displaced: copying insn %.8lx, " fprintf_unfiltered (gdb_stdlog, "displaced: copying insn %.8lx, "
@ -4632,7 +4633,7 @@ arm_copy_unmodified (struct gdbarch *gdbarch, uint32_t insn,
static int static int
thumb_copy_unmodified_32bit (struct gdbarch *gdbarch, uint16_t insn1, thumb_copy_unmodified_32bit (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, const char *iname, uint16_t insn2, const char *iname,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
if (debug_displaced) if (debug_displaced)
fprintf_unfiltered (gdb_stdlog, "displaced: copying insn %.4x %.4x, " fprintf_unfiltered (gdb_stdlog, "displaced: copying insn %.4x %.4x, "
@ -4651,7 +4652,7 @@ thumb_copy_unmodified_32bit (struct gdbarch *gdbarch, uint16_t insn1,
static int static int
thumb_copy_unmodified_16bit (struct gdbarch *gdbarch, uint16_t insn, thumb_copy_unmodified_16bit (struct gdbarch *gdbarch, uint16_t insn,
const char *iname, const char *iname,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
if (debug_displaced) if (debug_displaced)
fprintf_unfiltered (gdb_stdlog, "displaced: copying insn %.4x, " fprintf_unfiltered (gdb_stdlog, "displaced: copying insn %.4x, "
@ -4667,7 +4668,7 @@ thumb_copy_unmodified_16bit (struct gdbarch *gdbarch, uint16_t insn,
static void static void
cleanup_preload (struct gdbarch *gdbarch, cleanup_preload (struct gdbarch *gdbarch,
struct regcache *regs, struct displaced_step_closure *dsc) struct regcache *regs, arm_displaced_step_closure *dsc)
{ {
displaced_write_reg (regs, dsc, 0, dsc->tmp[0], CANNOT_WRITE_PC); displaced_write_reg (regs, dsc, 0, dsc->tmp[0], CANNOT_WRITE_PC);
if (!dsc->u.preload.immed) if (!dsc->u.preload.immed)
@ -4676,7 +4677,7 @@ cleanup_preload (struct gdbarch *gdbarch,
static void static void
install_preload (struct gdbarch *gdbarch, struct regcache *regs, install_preload (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc, unsigned int rn) arm_displaced_step_closure *dsc, unsigned int rn)
{ {
ULONGEST rn_val; ULONGEST rn_val;
/* Preload instructions: /* Preload instructions:
@ -4695,7 +4696,7 @@ install_preload (struct gdbarch *gdbarch, struct regcache *regs,
static int static int
arm_copy_preload (struct gdbarch *gdbarch, uint32_t insn, struct regcache *regs, arm_copy_preload (struct gdbarch *gdbarch, uint32_t insn, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned int rn = bits (insn, 16, 19); unsigned int rn = bits (insn, 16, 19);
@ -4715,7 +4716,7 @@ arm_copy_preload (struct gdbarch *gdbarch, uint32_t insn, struct regcache *regs,
static int static int
thumb2_copy_preload (struct gdbarch *gdbarch, uint16_t insn1, uint16_t insn2, thumb2_copy_preload (struct gdbarch *gdbarch, uint16_t insn1, uint16_t insn2,
struct regcache *regs, struct displaced_step_closure *dsc) struct regcache *regs, arm_displaced_step_closure *dsc)
{ {
unsigned int rn = bits (insn1, 0, 3); unsigned int rn = bits (insn1, 0, 3);
unsigned int u_bit = bit (insn1, 7); unsigned int u_bit = bit (insn1, 7);
@ -4765,7 +4766,7 @@ thumb2_copy_preload (struct gdbarch *gdbarch, uint16_t insn1, uint16_t insn2,
static void static void
install_preload_reg(struct gdbarch *gdbarch, struct regcache *regs, install_preload_reg(struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc, unsigned int rn, arm_displaced_step_closure *dsc, unsigned int rn,
unsigned int rm) unsigned int rm)
{ {
ULONGEST rn_val, rm_val; ULONGEST rn_val, rm_val;
@ -4790,7 +4791,7 @@ install_preload_reg(struct gdbarch *gdbarch, struct regcache *regs,
static int static int
arm_copy_preload_reg (struct gdbarch *gdbarch, uint32_t insn, arm_copy_preload_reg (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned int rn = bits (insn, 16, 19); unsigned int rn = bits (insn, 16, 19);
unsigned int rm = bits (insn, 0, 3); unsigned int rm = bits (insn, 0, 3);
@ -4814,7 +4815,7 @@ arm_copy_preload_reg (struct gdbarch *gdbarch, uint32_t insn,
static void static void
cleanup_copro_load_store (struct gdbarch *gdbarch, cleanup_copro_load_store (struct gdbarch *gdbarch,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
ULONGEST rn_val = displaced_read_reg (regs, dsc, 0); ULONGEST rn_val = displaced_read_reg (regs, dsc, 0);
@ -4826,7 +4827,7 @@ cleanup_copro_load_store (struct gdbarch *gdbarch,
static void static void
install_copro_load_store (struct gdbarch *gdbarch, struct regcache *regs, install_copro_load_store (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc, arm_displaced_step_closure *dsc,
int writeback, unsigned int rn) int writeback, unsigned int rn)
{ {
ULONGEST rn_val; ULONGEST rn_val;
@ -4854,7 +4855,7 @@ install_copro_load_store (struct gdbarch *gdbarch, struct regcache *regs,
static int static int
arm_copy_copro_load_store (struct gdbarch *gdbarch, uint32_t insn, arm_copy_copro_load_store (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned int rn = bits (insn, 16, 19); unsigned int rn = bits (insn, 16, 19);
@ -4875,7 +4876,7 @@ arm_copy_copro_load_store (struct gdbarch *gdbarch, uint32_t insn,
static int static int
thumb2_copy_copro_load_store (struct gdbarch *gdbarch, uint16_t insn1, thumb2_copy_copro_load_store (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs, uint16_t insn2, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned int rn = bits (insn1, 0, 3); unsigned int rn = bits (insn1, 0, 3);
@ -4903,7 +4904,7 @@ thumb2_copy_copro_load_store (struct gdbarch *gdbarch, uint16_t insn1,
static void static void
cleanup_branch (struct gdbarch *gdbarch, struct regcache *regs, cleanup_branch (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
uint32_t status = displaced_read_reg (regs, dsc, ARM_PS_REGNUM); uint32_t status = displaced_read_reg (regs, dsc, ARM_PS_REGNUM);
int branch_taken = condition_true (dsc->u.branch.cond, status); int branch_taken = condition_true (dsc->u.branch.cond, status);
@ -4934,7 +4935,7 @@ cleanup_branch (struct gdbarch *gdbarch, struct regcache *regs,
static void static void
install_b_bl_blx (struct gdbarch *gdbarch, struct regcache *regs, install_b_bl_blx (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc, arm_displaced_step_closure *dsc,
unsigned int cond, int exchange, int link, long offset) unsigned int cond, int exchange, int link, long offset)
{ {
/* Implement "BL<cond> <label>" as: /* Implement "BL<cond> <label>" as:
@ -4963,7 +4964,7 @@ install_b_bl_blx (struct gdbarch *gdbarch, struct regcache *regs,
} }
static int static int
arm_copy_b_bl_blx (struct gdbarch *gdbarch, uint32_t insn, arm_copy_b_bl_blx (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs, struct displaced_step_closure *dsc) struct regcache *regs, arm_displaced_step_closure *dsc)
{ {
unsigned int cond = bits (insn, 28, 31); unsigned int cond = bits (insn, 28, 31);
int exchange = (cond == 0xf); int exchange = (cond == 0xf);
@ -4993,7 +4994,7 @@ arm_copy_b_bl_blx (struct gdbarch *gdbarch, uint32_t insn,
static int static int
thumb2_copy_b_bl_blx (struct gdbarch *gdbarch, uint16_t insn1, thumb2_copy_b_bl_blx (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs, uint16_t insn2, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
int link = bit (insn2, 14); int link = bit (insn2, 14);
int exchange = link && !bit (insn2, 12); int exchange = link && !bit (insn2, 12);
@ -5048,7 +5049,7 @@ thumb2_copy_b_bl_blx (struct gdbarch *gdbarch, uint16_t insn1,
/* Copy B Thumb instructions. */ /* Copy B Thumb instructions. */
static int static int
thumb_copy_b (struct gdbarch *gdbarch, uint16_t insn, thumb_copy_b (struct gdbarch *gdbarch, uint16_t insn,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned int cond = 0; unsigned int cond = 0;
int offset = 0; int offset = 0;
@ -5088,7 +5089,7 @@ thumb_copy_b (struct gdbarch *gdbarch, uint16_t insn,
static void static void
install_bx_blx_reg (struct gdbarch *gdbarch, struct regcache *regs, install_bx_blx_reg (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc, int link, arm_displaced_step_closure *dsc, int link,
unsigned int cond, unsigned int rm) unsigned int cond, unsigned int rm)
{ {
/* Implement {BX,BLX}<cond> <reg>" as: /* Implement {BX,BLX}<cond> <reg>" as:
@ -5111,7 +5112,7 @@ install_bx_blx_reg (struct gdbarch *gdbarch, struct regcache *regs,
static int static int
arm_copy_bx_blx_reg (struct gdbarch *gdbarch, uint32_t insn, arm_copy_bx_blx_reg (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs, struct displaced_step_closure *dsc) struct regcache *regs, arm_displaced_step_closure *dsc)
{ {
unsigned int cond = bits (insn, 28, 31); unsigned int cond = bits (insn, 28, 31);
/* BX: x12xxx1x /* BX: x12xxx1x
@ -5132,7 +5133,7 @@ arm_copy_bx_blx_reg (struct gdbarch *gdbarch, uint32_t insn,
static int static int
thumb_copy_bx_blx_reg (struct gdbarch *gdbarch, uint16_t insn, thumb_copy_bx_blx_reg (struct gdbarch *gdbarch, uint16_t insn,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
int link = bit (insn, 7); int link = bit (insn, 7);
unsigned int rm = bits (insn, 3, 6); unsigned int rm = bits (insn, 3, 6);
@ -5153,7 +5154,7 @@ thumb_copy_bx_blx_reg (struct gdbarch *gdbarch, uint16_t insn,
static void static void
cleanup_alu_imm (struct gdbarch *gdbarch, cleanup_alu_imm (struct gdbarch *gdbarch,
struct regcache *regs, struct displaced_step_closure *dsc) struct regcache *regs, arm_displaced_step_closure *dsc)
{ {
ULONGEST rd_val = displaced_read_reg (regs, dsc, 0); ULONGEST rd_val = displaced_read_reg (regs, dsc, 0);
displaced_write_reg (regs, dsc, 0, dsc->tmp[0], CANNOT_WRITE_PC); displaced_write_reg (regs, dsc, 0, dsc->tmp[0], CANNOT_WRITE_PC);
@ -5163,7 +5164,7 @@ cleanup_alu_imm (struct gdbarch *gdbarch,
static int static int
arm_copy_alu_imm (struct gdbarch *gdbarch, uint32_t insn, struct regcache *regs, arm_copy_alu_imm (struct gdbarch *gdbarch, uint32_t insn, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned int rn = bits (insn, 16, 19); unsigned int rn = bits (insn, 16, 19);
unsigned int rd = bits (insn, 12, 15); unsigned int rd = bits (insn, 12, 15);
@ -5212,7 +5213,7 @@ arm_copy_alu_imm (struct gdbarch *gdbarch, uint32_t insn, struct regcache *regs,
static int static int
thumb2_copy_alu_imm (struct gdbarch *gdbarch, uint16_t insn1, thumb2_copy_alu_imm (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs, uint16_t insn2, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned int op = bits (insn1, 5, 8); unsigned int op = bits (insn1, 5, 8);
unsigned int rn, rm, rd; unsigned int rn, rm, rd;
@ -5265,7 +5266,7 @@ thumb2_copy_alu_imm (struct gdbarch *gdbarch, uint16_t insn1,
static void static void
cleanup_alu_reg (struct gdbarch *gdbarch, cleanup_alu_reg (struct gdbarch *gdbarch,
struct regcache *regs, struct displaced_step_closure *dsc) struct regcache *regs, arm_displaced_step_closure *dsc)
{ {
ULONGEST rd_val; ULONGEST rd_val;
int i; int i;
@ -5280,7 +5281,7 @@ cleanup_alu_reg (struct gdbarch *gdbarch,
static void static void
install_alu_reg (struct gdbarch *gdbarch, struct regcache *regs, install_alu_reg (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc, arm_displaced_step_closure *dsc,
unsigned int rd, unsigned int rn, unsigned int rm) unsigned int rd, unsigned int rn, unsigned int rm)
{ {
ULONGEST rd_val, rn_val, rm_val; ULONGEST rd_val, rn_val, rm_val;
@ -5313,7 +5314,7 @@ install_alu_reg (struct gdbarch *gdbarch, struct regcache *regs,
static int static int
arm_copy_alu_reg (struct gdbarch *gdbarch, uint32_t insn, struct regcache *regs, arm_copy_alu_reg (struct gdbarch *gdbarch, uint32_t insn, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned int op = bits (insn, 21, 24); unsigned int op = bits (insn, 21, 24);
int is_mov = (op == 0xd); int is_mov = (op == 0xd);
@ -5338,7 +5339,7 @@ arm_copy_alu_reg (struct gdbarch *gdbarch, uint32_t insn, struct regcache *regs,
static int static int
thumb_copy_alu_reg (struct gdbarch *gdbarch, uint16_t insn, thumb_copy_alu_reg (struct gdbarch *gdbarch, uint16_t insn,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned rm, rd; unsigned rm, rd;
@ -5364,7 +5365,7 @@ thumb_copy_alu_reg (struct gdbarch *gdbarch, uint16_t insn,
static void static void
cleanup_alu_shifted_reg (struct gdbarch *gdbarch, cleanup_alu_shifted_reg (struct gdbarch *gdbarch,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
ULONGEST rd_val = displaced_read_reg (regs, dsc, 0); ULONGEST rd_val = displaced_read_reg (regs, dsc, 0);
int i; int i;
@ -5377,7 +5378,7 @@ cleanup_alu_shifted_reg (struct gdbarch *gdbarch,
static void static void
install_alu_shifted_reg (struct gdbarch *gdbarch, struct regcache *regs, install_alu_shifted_reg (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc, arm_displaced_step_closure *dsc,
unsigned int rd, unsigned int rn, unsigned int rm, unsigned int rd, unsigned int rn, unsigned int rm,
unsigned rs) unsigned rs)
{ {
@ -5416,7 +5417,7 @@ install_alu_shifted_reg (struct gdbarch *gdbarch, struct regcache *regs,
static int static int
arm_copy_alu_shifted_reg (struct gdbarch *gdbarch, uint32_t insn, arm_copy_alu_shifted_reg (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned int op = bits (insn, 21, 24); unsigned int op = bits (insn, 21, 24);
int is_mov = (op == 0xd); int is_mov = (op == 0xd);
@ -5449,7 +5450,7 @@ arm_copy_alu_shifted_reg (struct gdbarch *gdbarch, uint32_t insn,
static void static void
cleanup_load (struct gdbarch *gdbarch, struct regcache *regs, cleanup_load (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
ULONGEST rt_val, rt_val2 = 0, rn_val; ULONGEST rt_val, rt_val2 = 0, rn_val;
@ -5478,7 +5479,7 @@ cleanup_load (struct gdbarch *gdbarch, struct regcache *regs,
static void static void
cleanup_store (struct gdbarch *gdbarch, struct regcache *regs, cleanup_store (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
ULONGEST rn_val = displaced_read_reg (regs, dsc, 2); ULONGEST rn_val = displaced_read_reg (regs, dsc, 2);
@ -5501,7 +5502,7 @@ cleanup_store (struct gdbarch *gdbarch, struct regcache *regs,
static int static int
arm_copy_extra_ld_st (struct gdbarch *gdbarch, uint32_t insn, int unprivileged, arm_copy_extra_ld_st (struct gdbarch *gdbarch, uint32_t insn, int unprivileged,
struct regcache *regs, struct displaced_step_closure *dsc) struct regcache *regs, arm_displaced_step_closure *dsc)
{ {
unsigned int op1 = bits (insn, 20, 24); unsigned int op1 = bits (insn, 20, 24);
unsigned int op2 = bits (insn, 5, 6); unsigned int op2 = bits (insn, 5, 6);
@ -5575,7 +5576,7 @@ arm_copy_extra_ld_st (struct gdbarch *gdbarch, uint32_t insn, int unprivileged,
static void static void
install_load_store (struct gdbarch *gdbarch, struct regcache *regs, install_load_store (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc, int load, arm_displaced_step_closure *dsc, int load,
int immed, int writeback, int size, int usermode, int immed, int writeback, int size, int usermode,
int rt, int rm, int rn) int rt, int rm, int rn)
{ {
@ -5631,7 +5632,7 @@ install_load_store (struct gdbarch *gdbarch, struct regcache *regs,
static int static int
thumb2_copy_load_literal (struct gdbarch *gdbarch, uint16_t insn1, thumb2_copy_load_literal (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs, uint16_t insn2, struct regcache *regs,
struct displaced_step_closure *dsc, int size) arm_displaced_step_closure *dsc, int size)
{ {
unsigned int u_bit = bit (insn1, 7); unsigned int u_bit = bit (insn1, 7);
unsigned int rt = bits (insn2, 12, 15); unsigned int rt = bits (insn2, 12, 15);
@ -5687,7 +5688,7 @@ thumb2_copy_load_literal (struct gdbarch *gdbarch, uint16_t insn1,
static int static int
thumb2_copy_load_reg_imm (struct gdbarch *gdbarch, uint16_t insn1, thumb2_copy_load_reg_imm (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs, uint16_t insn2, struct regcache *regs,
struct displaced_step_closure *dsc, arm_displaced_step_closure *dsc,
int writeback, int immed) int writeback, int immed)
{ {
unsigned int rt = bits (insn2, 12, 15); unsigned int rt = bits (insn2, 12, 15);
@ -5736,7 +5737,7 @@ thumb2_copy_load_reg_imm (struct gdbarch *gdbarch, uint16_t insn1,
static int static int
arm_copy_ldr_str_ldrb_strb (struct gdbarch *gdbarch, uint32_t insn, arm_copy_ldr_str_ldrb_strb (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc, arm_displaced_step_closure *dsc,
int load, int size, int usermode) int load, int size, int usermode)
{ {
int immed = !bit (insn, 25); int immed = !bit (insn, 25);
@ -5820,7 +5821,7 @@ arm_copy_ldr_str_ldrb_strb (struct gdbarch *gdbarch, uint32_t insn,
static void static void
cleanup_block_load_all (struct gdbarch *gdbarch, struct regcache *regs, cleanup_block_load_all (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
int inc = dsc->u.block.increment; int inc = dsc->u.block.increment;
int bump_before = dsc->u.block.before ? (inc ? 4 : -4) : 0; int bump_before = dsc->u.block.before ? (inc ? 4 : -4) : 0;
@ -5881,7 +5882,7 @@ cleanup_block_load_all (struct gdbarch *gdbarch, struct regcache *regs,
static void static void
cleanup_block_store_pc (struct gdbarch *gdbarch, struct regcache *regs, cleanup_block_store_pc (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
uint32_t status = displaced_read_reg (regs, dsc, ARM_PS_REGNUM); uint32_t status = displaced_read_reg (regs, dsc, ARM_PS_REGNUM);
int store_executed = condition_true (dsc->u.block.cond, status); int store_executed = condition_true (dsc->u.block.cond, status);
@ -5932,7 +5933,7 @@ cleanup_block_store_pc (struct gdbarch *gdbarch, struct regcache *regs,
static void static void
cleanup_block_load_pc (struct gdbarch *gdbarch, cleanup_block_load_pc (struct gdbarch *gdbarch,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
uint32_t status = displaced_read_reg (regs, dsc, ARM_PS_REGNUM); uint32_t status = displaced_read_reg (regs, dsc, ARM_PS_REGNUM);
int load_executed = condition_true (dsc->u.block.cond, status); int load_executed = condition_true (dsc->u.block.cond, status);
@ -6012,7 +6013,7 @@ cleanup_block_load_pc (struct gdbarch *gdbarch,
static int static int
arm_copy_block_xfer (struct gdbarch *gdbarch, uint32_t insn, arm_copy_block_xfer (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
int load = bit (insn, 20); int load = bit (insn, 20);
int user = bit (insn, 22); int user = bit (insn, 22);
@ -6126,7 +6127,7 @@ arm_copy_block_xfer (struct gdbarch *gdbarch, uint32_t insn,
static int static int
thumb2_copy_block_xfer (struct gdbarch *gdbarch, uint16_t insn1, uint16_t insn2, thumb2_copy_block_xfer (struct gdbarch *gdbarch, uint16_t insn1, uint16_t insn2,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
int rn = bits (insn1, 0, 3); int rn = bits (insn1, 0, 3);
int load = bit (insn1, 4); int load = bit (insn1, 4);
@ -6272,7 +6273,7 @@ arm_software_single_step (struct regcache *regcache)
static void static void
cleanup_svc (struct gdbarch *gdbarch, struct regcache *regs, cleanup_svc (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
CORE_ADDR resume_addr = dsc->insn_addr + dsc->insn_size; CORE_ADDR resume_addr = dsc->insn_addr + dsc->insn_size;
@ -6288,7 +6289,7 @@ cleanup_svc (struct gdbarch *gdbarch, struct regcache *regs,
static int static int
install_svc (struct gdbarch *gdbarch, struct regcache *regs, install_svc (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
/* Preparation: none. /* Preparation: none.
Insn: unmodified svc. Insn: unmodified svc.
@ -6310,7 +6311,7 @@ install_svc (struct gdbarch *gdbarch, struct regcache *regs,
static int static int
arm_copy_svc (struct gdbarch *gdbarch, uint32_t insn, arm_copy_svc (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs, struct displaced_step_closure *dsc) struct regcache *regs, arm_displaced_step_closure *dsc)
{ {
if (debug_displaced) if (debug_displaced)
@ -6324,7 +6325,7 @@ arm_copy_svc (struct gdbarch *gdbarch, uint32_t insn,
static int static int
thumb_copy_svc (struct gdbarch *gdbarch, uint16_t insn, thumb_copy_svc (struct gdbarch *gdbarch, uint16_t insn,
struct regcache *regs, struct displaced_step_closure *dsc) struct regcache *regs, arm_displaced_step_closure *dsc)
{ {
if (debug_displaced) if (debug_displaced)
@ -6340,7 +6341,7 @@ thumb_copy_svc (struct gdbarch *gdbarch, uint16_t insn,
static int static int
arm_copy_undef (struct gdbarch *gdbarch, uint32_t insn, arm_copy_undef (struct gdbarch *gdbarch, uint32_t insn,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
if (debug_displaced) if (debug_displaced)
fprintf_unfiltered (gdb_stdlog, fprintf_unfiltered (gdb_stdlog,
@ -6354,7 +6355,7 @@ arm_copy_undef (struct gdbarch *gdbarch, uint32_t insn,
static int static int
thumb_32bit_copy_undef (struct gdbarch *gdbarch, uint16_t insn1, uint16_t insn2, thumb_32bit_copy_undef (struct gdbarch *gdbarch, uint16_t insn1, uint16_t insn2,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
if (debug_displaced) if (debug_displaced)
@ -6373,7 +6374,7 @@ thumb_32bit_copy_undef (struct gdbarch *gdbarch, uint16_t insn1, uint16_t insn2,
static int static int
arm_copy_unpred (struct gdbarch *gdbarch, uint32_t insn, arm_copy_unpred (struct gdbarch *gdbarch, uint32_t insn,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
if (debug_displaced) if (debug_displaced)
fprintf_unfiltered (gdb_stdlog, "displaced: copying unpredictable insn " fprintf_unfiltered (gdb_stdlog, "displaced: copying unpredictable insn "
@ -6390,7 +6391,7 @@ arm_copy_unpred (struct gdbarch *gdbarch, uint32_t insn,
static int static int
arm_decode_misc_memhint_neon (struct gdbarch *gdbarch, uint32_t insn, arm_decode_misc_memhint_neon (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned int op1 = bits (insn, 20, 26), op2 = bits (insn, 4, 7); unsigned int op1 = bits (insn, 20, 26), op2 = bits (insn, 4, 7);
unsigned int rn = bits (insn, 16, 19); unsigned int rn = bits (insn, 16, 19);
@ -6450,7 +6451,7 @@ arm_decode_misc_memhint_neon (struct gdbarch *gdbarch, uint32_t insn,
static int static int
arm_decode_unconditional (struct gdbarch *gdbarch, uint32_t insn, arm_decode_unconditional (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
if (bit (insn, 27) == 0) if (bit (insn, 27) == 0)
return arm_decode_misc_memhint_neon (gdbarch, insn, regs, dsc); return arm_decode_misc_memhint_neon (gdbarch, insn, regs, dsc);
@ -6535,7 +6536,7 @@ arm_decode_unconditional (struct gdbarch *gdbarch, uint32_t insn,
static int static int
arm_decode_miscellaneous (struct gdbarch *gdbarch, uint32_t insn, arm_decode_miscellaneous (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned int op2 = bits (insn, 4, 6); unsigned int op2 = bits (insn, 4, 6);
unsigned int op = bits (insn, 21, 22); unsigned int op = bits (insn, 21, 22);
@ -6585,7 +6586,7 @@ arm_decode_miscellaneous (struct gdbarch *gdbarch, uint32_t insn,
static int static int
arm_decode_dp_misc (struct gdbarch *gdbarch, uint32_t insn, arm_decode_dp_misc (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
if (bit (insn, 25)) if (bit (insn, 25))
switch (bits (insn, 20, 24)) switch (bits (insn, 20, 24))
@ -6631,7 +6632,7 @@ arm_decode_dp_misc (struct gdbarch *gdbarch, uint32_t insn,
static int static int
arm_decode_ld_st_word_ubyte (struct gdbarch *gdbarch, uint32_t insn, arm_decode_ld_st_word_ubyte (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
int a = bit (insn, 25), b = bit (insn, 4); int a = bit (insn, 25), b = bit (insn, 4);
uint32_t op1 = bits (insn, 20, 24); uint32_t op1 = bits (insn, 20, 24);
@ -6667,7 +6668,7 @@ arm_decode_ld_st_word_ubyte (struct gdbarch *gdbarch, uint32_t insn,
static int static int
arm_decode_media (struct gdbarch *gdbarch, uint32_t insn, arm_decode_media (struct gdbarch *gdbarch, uint32_t insn,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
switch (bits (insn, 20, 24)) switch (bits (insn, 20, 24))
{ {
@ -6724,7 +6725,7 @@ arm_decode_media (struct gdbarch *gdbarch, uint32_t insn,
static int static int
arm_decode_b_bl_ldmstm (struct gdbarch *gdbarch, uint32_t insn, arm_decode_b_bl_ldmstm (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
if (bit (insn, 25)) if (bit (insn, 25))
return arm_copy_b_bl_blx (gdbarch, insn, regs, dsc); return arm_copy_b_bl_blx (gdbarch, insn, regs, dsc);
@ -6735,7 +6736,7 @@ arm_decode_b_bl_ldmstm (struct gdbarch *gdbarch, uint32_t insn,
static int static int
arm_decode_ext_reg_ld_st (struct gdbarch *gdbarch, uint32_t insn, arm_decode_ext_reg_ld_st (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned int opcode = bits (insn, 20, 24); unsigned int opcode = bits (insn, 20, 24);
@ -6768,7 +6769,7 @@ arm_decode_ext_reg_ld_st (struct gdbarch *gdbarch, uint32_t insn,
static int static int
thumb2_decode_dp_shift_reg (struct gdbarch *gdbarch, uint16_t insn1, thumb2_decode_dp_shift_reg (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs, uint16_t insn2, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
/* PC is only allowed to be used in instruction MOV. */ /* PC is only allowed to be used in instruction MOV. */
@ -6789,7 +6790,7 @@ thumb2_decode_dp_shift_reg (struct gdbarch *gdbarch, uint16_t insn1,
static int static int
thumb2_decode_ext_reg_ld_st (struct gdbarch *gdbarch, uint16_t insn1, thumb2_decode_ext_reg_ld_st (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs, uint16_t insn2, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned int opcode = bits (insn1, 4, 8); unsigned int opcode = bits (insn1, 4, 8);
@ -6824,7 +6825,7 @@ thumb2_decode_ext_reg_ld_st (struct gdbarch *gdbarch, uint16_t insn1,
static int static int
arm_decode_svc_copro (struct gdbarch *gdbarch, uint32_t insn, arm_decode_svc_copro (struct gdbarch *gdbarch, uint32_t insn,
struct regcache *regs, struct displaced_step_closure *dsc) struct regcache *regs, arm_displaced_step_closure *dsc)
{ {
unsigned int op1 = bits (insn, 20, 25); unsigned int op1 = bits (insn, 20, 25);
int op = bit (insn, 4); int op = bit (insn, 4);
@ -6870,7 +6871,7 @@ arm_decode_svc_copro (struct gdbarch *gdbarch, uint32_t insn,
static int static int
thumb2_decode_svc_copro (struct gdbarch *gdbarch, uint16_t insn1, thumb2_decode_svc_copro (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs, uint16_t insn2, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned int coproc = bits (insn2, 8, 11); unsigned int coproc = bits (insn2, 8, 11);
unsigned int bit_5_8 = bits (insn1, 5, 8); unsigned int bit_5_8 = bits (insn1, 5, 8);
@ -6910,7 +6911,7 @@ thumb2_decode_svc_copro (struct gdbarch *gdbarch, uint16_t insn1,
static void static void
install_pc_relative (struct gdbarch *gdbarch, struct regcache *regs, install_pc_relative (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc, int rd) arm_displaced_step_closure *dsc, int rd)
{ {
/* ADR Rd, #imm /* ADR Rd, #imm
@ -6928,7 +6929,7 @@ install_pc_relative (struct gdbarch *gdbarch, struct regcache *regs,
static int static int
thumb_copy_pc_relative_16bit (struct gdbarch *gdbarch, struct regcache *regs, thumb_copy_pc_relative_16bit (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc, arm_displaced_step_closure *dsc,
int rd, unsigned int imm) int rd, unsigned int imm)
{ {
@ -6943,7 +6944,7 @@ thumb_copy_pc_relative_16bit (struct gdbarch *gdbarch, struct regcache *regs,
static int static int
thumb_decode_pc_relative_16bit (struct gdbarch *gdbarch, uint16_t insn, thumb_decode_pc_relative_16bit (struct gdbarch *gdbarch, uint16_t insn,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned int rd = bits (insn, 8, 10); unsigned int rd = bits (insn, 8, 10);
unsigned int imm8 = bits (insn, 0, 7); unsigned int imm8 = bits (insn, 0, 7);
@ -6959,7 +6960,7 @@ thumb_decode_pc_relative_16bit (struct gdbarch *gdbarch, uint16_t insn,
static int static int
thumb_copy_pc_relative_32bit (struct gdbarch *gdbarch, uint16_t insn1, thumb_copy_pc_relative_32bit (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs, uint16_t insn2, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned int rd = bits (insn2, 8, 11); unsigned int rd = bits (insn2, 8, 11);
/* Since immediate has the same encoding in ADR ADD and SUB, so we simply /* Since immediate has the same encoding in ADR ADD and SUB, so we simply
@ -6996,7 +6997,7 @@ thumb_copy_pc_relative_32bit (struct gdbarch *gdbarch, uint16_t insn1,
static int static int
thumb_copy_16bit_ldr_literal (struct gdbarch *gdbarch, uint16_t insn1, thumb_copy_16bit_ldr_literal (struct gdbarch *gdbarch, uint16_t insn1,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned int rt = bits (insn1, 8, 10); unsigned int rt = bits (insn1, 8, 10);
unsigned int pc; unsigned int pc;
@ -7046,7 +7047,7 @@ thumb_copy_16bit_ldr_literal (struct gdbarch *gdbarch, uint16_t insn1,
static int static int
thumb_copy_cbnz_cbz (struct gdbarch *gdbarch, uint16_t insn1, thumb_copy_cbnz_cbz (struct gdbarch *gdbarch, uint16_t insn1,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
int non_zero = bit (insn1, 11); int non_zero = bit (insn1, 11);
unsigned int imm5 = (bit (insn1, 9) << 6) | (bits (insn1, 3, 7) << 1); unsigned int imm5 = (bit (insn1, 9) << 6) | (bits (insn1, 3, 7) << 1);
@ -7084,7 +7085,7 @@ thumb_copy_cbnz_cbz (struct gdbarch *gdbarch, uint16_t insn1,
static int static int
thumb2_copy_table_branch (struct gdbarch *gdbarch, uint16_t insn1, thumb2_copy_table_branch (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs, uint16_t insn2, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
ULONGEST rn_val, rm_val; ULONGEST rn_val, rm_val;
int is_tbh = bit (insn2, 4); int is_tbh = bit (insn2, 4);
@ -7127,7 +7128,7 @@ thumb2_copy_table_branch (struct gdbarch *gdbarch, uint16_t insn1,
static void static void
cleanup_pop_pc_16bit_all (struct gdbarch *gdbarch, struct regcache *regs, cleanup_pop_pc_16bit_all (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
/* PC <- r7 */ /* PC <- r7 */
int val = displaced_read_reg (regs, dsc, 7); int val = displaced_read_reg (regs, dsc, 7);
@ -7145,7 +7146,7 @@ cleanup_pop_pc_16bit_all (struct gdbarch *gdbarch, struct regcache *regs,
static int static int
thumb_copy_pop_pc_16bit (struct gdbarch *gdbarch, uint16_t insn1, thumb_copy_pop_pc_16bit (struct gdbarch *gdbarch, uint16_t insn1,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
dsc->u.block.regmask = insn1 & 0x00ff; dsc->u.block.regmask = insn1 & 0x00ff;
@ -7218,7 +7219,7 @@ thumb_copy_pop_pc_16bit (struct gdbarch *gdbarch, uint16_t insn1,
static void static void
thumb_process_displaced_16bit_insn (struct gdbarch *gdbarch, uint16_t insn1, thumb_process_displaced_16bit_insn (struct gdbarch *gdbarch, uint16_t insn1,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
unsigned short op_bit_12_15 = bits (insn1, 12, 15); unsigned short op_bit_12_15 = bits (insn1, 12, 15);
unsigned short op_bit_10_11 = bits (insn1, 10, 11); unsigned short op_bit_10_11 = bits (insn1, 10, 11);
@ -7322,7 +7323,7 @@ static int
decode_thumb_32bit_ld_mem_hints (struct gdbarch *gdbarch, decode_thumb_32bit_ld_mem_hints (struct gdbarch *gdbarch,
uint16_t insn1, uint16_t insn2, uint16_t insn1, uint16_t insn2,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
int rt = bits (insn2, 12, 15); int rt = bits (insn2, 12, 15);
int rn = bits (insn1, 0, 3); int rn = bits (insn1, 0, 3);
@ -7401,7 +7402,7 @@ decode_thumb_32bit_ld_mem_hints (struct gdbarch *gdbarch,
static void static void
thumb_process_displaced_32bit_insn (struct gdbarch *gdbarch, uint16_t insn1, thumb_process_displaced_32bit_insn (struct gdbarch *gdbarch, uint16_t insn1,
uint16_t insn2, struct regcache *regs, uint16_t insn2, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
int err = 0; int err = 0;
unsigned short op = bit (insn2, 15); unsigned short op = bit (insn2, 15);
@ -7529,7 +7530,7 @@ thumb_process_displaced_32bit_insn (struct gdbarch *gdbarch, uint16_t insn1,
static void static void
thumb_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from, thumb_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from,
struct regcache *regs, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
uint16_t insn1 uint16_t insn1
@ -7554,7 +7555,7 @@ thumb_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from,
void void
arm_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from, arm_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from,
CORE_ADDR to, struct regcache *regs, CORE_ADDR to, struct regcache *regs,
struct displaced_step_closure *dsc) arm_displaced_step_closure *dsc)
{ {
int err = 0; int err = 0;
enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
@ -7613,7 +7614,7 @@ arm_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from,
void void
arm_displaced_init_closure (struct gdbarch *gdbarch, CORE_ADDR from, arm_displaced_init_closure (struct gdbarch *gdbarch, CORE_ADDR from,
CORE_ADDR to, struct displaced_step_closure *dsc) CORE_ADDR to, arm_displaced_step_closure *dsc)
{ {
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
unsigned int i, len, offset; unsigned int i, len, offset;
@ -7670,10 +7671,12 @@ arm_displaced_init_closure (struct gdbarch *gdbarch, CORE_ADDR from,
void void
arm_displaced_step_fixup (struct gdbarch *gdbarch, arm_displaced_step_fixup (struct gdbarch *gdbarch,
struct displaced_step_closure *dsc, struct displaced_step_closure *dsc_,
CORE_ADDR from, CORE_ADDR to, CORE_ADDR from, CORE_ADDR to,
struct regcache *regs) struct regcache *regs)
{ {
arm_displaced_step_closure *dsc = (arm_displaced_step_closure *) dsc_;
if (dsc->cleanup) if (dsc->cleanup)
dsc->cleanup (gdbarch, regs, dsc); dsc->cleanup (gdbarch, regs, dsc);

View File

@ -28,6 +28,7 @@ struct arm_get_next_pcs;
struct gdb_get_next_pcs; struct gdb_get_next_pcs;
#include "arch/arm.h" #include "arch/arm.h"
#include "infrun.h"
#include <vector> #include <vector>
@ -153,7 +154,7 @@ struct gdbarch_tdep
sequence) and any scratch words, etc. */ sequence) and any scratch words, etc. */
#define DISPLACED_MODIFIED_INSNS 8 #define DISPLACED_MODIFIED_INSNS 8
struct displaced_step_closure struct arm_displaced_step_closure : public displaced_step_closure
{ {
ULONGEST tmp[DISPLACED_TEMPS]; ULONGEST tmp[DISPLACED_TEMPS];
int rd; int rd;
@ -200,7 +201,7 @@ struct displaced_step_closure
/* If non-NULL, override generic SVC handling (e.g. for a particular /* If non-NULL, override generic SVC handling (e.g. for a particular
OS). */ OS). */
int (*copy_svc_os) (struct gdbarch *gdbarch, struct regcache *regs, int (*copy_svc_os) (struct gdbarch *gdbarch, struct regcache *regs,
struct displaced_step_closure *dsc); arm_displaced_step_closure *dsc);
} svc; } svc;
} u; } u;
@ -219,7 +220,7 @@ struct displaced_step_closure
CORE_ADDR insn_addr; CORE_ADDR insn_addr;
CORE_ADDR scratch_base; CORE_ADDR scratch_base;
void (*cleanup) (struct gdbarch *, struct regcache *, void (*cleanup) (struct gdbarch *, struct regcache *,
struct displaced_step_closure *); arm_displaced_step_closure *);
}; };
/* Values for the WRITE_PC argument to displaced_write_reg. If the register /* Values for the WRITE_PC argument to displaced_write_reg. If the register
@ -238,16 +239,16 @@ enum pc_write_style
extern void extern void
arm_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from, arm_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from,
CORE_ADDR to, struct regcache *regs, CORE_ADDR to, struct regcache *regs,
struct displaced_step_closure *dsc); arm_displaced_step_closure *dsc);
extern void extern void
arm_displaced_init_closure (struct gdbarch *gdbarch, CORE_ADDR from, arm_displaced_init_closure (struct gdbarch *gdbarch, CORE_ADDR from,
CORE_ADDR to, struct displaced_step_closure *dsc); CORE_ADDR to, arm_displaced_step_closure *dsc);
extern ULONGEST extern ULONGEST
displaced_read_reg (struct regcache *regs, struct displaced_step_closure *dsc, displaced_read_reg (struct regcache *regs, arm_displaced_step_closure *dsc,
int regno); int regno);
extern void extern void
displaced_write_reg (struct regcache *regs, displaced_write_reg (struct regcache *regs,
struct displaced_step_closure *dsc, int regno, arm_displaced_step_closure *dsc, int regno,
ULONGEST val, enum pc_write_style write_pc); ULONGEST val, enum pc_write_style write_pc);
CORE_ADDR arm_skip_stub (struct frame_info *, CORE_ADDR); CORE_ADDR arm_skip_stub (struct frame_info *, CORE_ADDR);

View File

@ -802,21 +802,21 @@ i386_linux_displaced_step_copy_insn (struct gdbarch *gdbarch,
CORE_ADDR from, CORE_ADDR to, CORE_ADDR from, CORE_ADDR to,
struct regcache *regs) struct regcache *regs)
{ {
struct displaced_step_closure *closure; displaced_step_closure *closure_
= i386_displaced_step_copy_insn (gdbarch, from, to, regs);
closure = i386_displaced_step_copy_insn (gdbarch, from, to, regs);
if (i386_linux_get_syscall_number_from_regcache (regs) != -1) if (i386_linux_get_syscall_number_from_regcache (regs) != -1)
{ {
/* The closure returned by i386_displaced_step_copy_insn is simply a /* The closure returned by i386_displaced_step_copy_insn is simply a
buffer with a copy of the instruction. */ buffer with a copy of the instruction. */
gdb_byte *insn = (gdb_byte *) closure; i386_displaced_step_closure *closure
= (i386_displaced_step_closure *) closure_;
/* Fake nop. */ /* Fake nop. */
insn[0] = 0x90; closure->buf[0] = 0x90;
} }
return closure; return closure_;
} }
static void static void

View File

@ -802,7 +802,8 @@ i386_displaced_step_copy_insn (struct gdbarch *gdbarch,
struct regcache *regs) struct regcache *regs)
{ {
size_t len = gdbarch_max_insn_length (gdbarch); size_t len = gdbarch_max_insn_length (gdbarch);
gdb_byte *buf = (gdb_byte *) xmalloc (len); i386_displaced_step_closure *closure = new i386_displaced_step_closure (len);
gdb_byte *buf = closure->buf.data ();
read_memory (from, buf, len); read_memory (from, buf, len);
@ -827,7 +828,7 @@ i386_displaced_step_copy_insn (struct gdbarch *gdbarch,
displaced_step_dump_bytes (gdb_stdlog, buf, len); displaced_step_dump_bytes (gdb_stdlog, buf, len);
} }
return (struct displaced_step_closure *) buf; return closure;
} }
/* Fix up the state of registers and memory after having single-stepped /* Fix up the state of registers and memory after having single-stepped
@ -835,7 +836,7 @@ i386_displaced_step_copy_insn (struct gdbarch *gdbarch,
void void
i386_displaced_step_fixup (struct gdbarch *gdbarch, i386_displaced_step_fixup (struct gdbarch *gdbarch,
struct displaced_step_closure *closure, struct displaced_step_closure *closure_,
CORE_ADDR from, CORE_ADDR to, CORE_ADDR from, CORE_ADDR to,
struct regcache *regs) struct regcache *regs)
{ {
@ -847,8 +848,9 @@ i386_displaced_step_fixup (struct gdbarch *gdbarch,
applying it. */ applying it. */
ULONGEST insn_offset = to - from; ULONGEST insn_offset = to - from;
/* Our closure is a copy of the instruction. */ i386_displaced_step_closure *closure
gdb_byte *insn = (gdb_byte *) closure; = (i386_displaced_step_closure *) closure_;
gdb_byte *insn = closure->buf.data ();
/* The start of the insn, needed in case we see some prefixes. */ /* The start of the insn, needed in case we see some prefixes. */
gdb_byte *insn_start = insn; gdb_byte *insn_start = insn;

View File

@ -20,6 +20,8 @@
#ifndef I386_TDEP_H #ifndef I386_TDEP_H
#define I386_TDEP_H #define I386_TDEP_H
#include "infrun.h"
struct frame_info; struct frame_info;
struct gdbarch; struct gdbarch;
struct reggroup; struct reggroup;
@ -416,6 +418,8 @@ extern void
void *cb_data, void *cb_data,
const struct regcache *regcache); const struct regcache *regcache);
typedef buf_displaced_step_closure i386_displaced_step_closure;
extern struct displaced_step_closure *i386_displaced_step_copy_insn extern struct displaced_step_closure *i386_displaced_step_copy_insn
(struct gdbarch *gdbarch, CORE_ADDR from, CORE_ADDR to, (struct gdbarch *gdbarch, CORE_ADDR from, CORE_ADDR to,
struct regcache *regs); struct regcache *regs);

View File

@ -1445,8 +1445,6 @@ step_over_info_valid_p (void)
same effect the instruction would have had if we had executed it same effect the instruction would have had if we had executed it
at its original address. We use this in step n3. at its original address. We use this in step n3.
- gdbarch_displaced_step_free_closure provides cleanup.
The gdbarch_displaced_step_copy_insn and The gdbarch_displaced_step_copy_insn and
gdbarch_displaced_step_fixup functions must be written so that gdbarch_displaced_step_fixup functions must be written so that
copying an instruction with gdbarch_displaced_step_copy_insn, copying an instruction with gdbarch_displaced_step_copy_insn,
@ -1484,6 +1482,10 @@ step_over_info_valid_p (void)
displaced step operation on it. See displaced_step_prepare and displaced step operation on it. See displaced_step_prepare and
displaced_step_fixup for details. */ displaced_step_fixup for details. */
/* Default destructor for displaced_step_closure. */
displaced_step_closure::~displaced_step_closure () = default;
/* Per-inferior displaced stepping state. */ /* Per-inferior displaced stepping state. */
struct displaced_step_inferior_state struct displaced_step_inferior_state
{ {
@ -1709,7 +1711,7 @@ displaced_step_clear (struct displaced_step_inferior_state *displaced)
/* Indicate that there is no cleanup pending. */ /* Indicate that there is no cleanup pending. */
displaced->step_ptid = null_ptid; displaced->step_ptid = null_ptid;
xfree (displaced->step_closure); delete displaced->step_closure;
displaced->step_closure = NULL; displaced->step_closure = NULL;
} }

View File

@ -19,6 +19,7 @@
#define INFRUN_H 1 #define INFRUN_H 1
#include "symtab.h" #include "symtab.h"
#include "common/byte-vector.h"
struct target_waitstatus; struct target_waitstatus;
struct frame_info; struct frame_info;
@ -243,4 +244,22 @@ extern void all_uis_check_sync_execution_done (void);
started or re-started). */ started or re-started). */
extern void all_uis_on_sync_execution_starting (void); extern void all_uis_on_sync_execution_starting (void);
/* Base class for displaced stepping closures (the arch-specific data). */
struct displaced_step_closure
{
virtual ~displaced_step_closure () = 0;
};
/* A simple displaced step closure that contains only a byte buffer. */
struct buf_displaced_step_closure : displaced_step_closure
{
buf_displaced_step_closure (int buf_size)
: buf (buf_size)
{}
gdb::byte_vector buf;
};
#endif /* INFRUN_H */ #endif /* INFRUN_H */

View File

@ -1014,6 +1014,8 @@ typedef BP_MANIPULATION_ENDIAN (little_breakpoint, big_breakpoint)
|| (insn & STORE_CONDITIONAL_MASK) == STHCX_INSTRUCTION \ || (insn & STORE_CONDITIONAL_MASK) == STHCX_INSTRUCTION \
|| (insn & STORE_CONDITIONAL_MASK) == STQCX_INSTRUCTION) || (insn & STORE_CONDITIONAL_MASK) == STQCX_INSTRUCTION)
typedef buf_displaced_step_closure ppc_displaced_step_closure;
/* We can't displaced step atomic sequences. */ /* We can't displaced step atomic sequences. */
static struct displaced_step_closure * static struct displaced_step_closure *
@ -1022,8 +1024,9 @@ ppc_displaced_step_copy_insn (struct gdbarch *gdbarch,
struct regcache *regs) struct regcache *regs)
{ {
size_t len = gdbarch_max_insn_length (gdbarch); size_t len = gdbarch_max_insn_length (gdbarch);
gdb_byte *buf = (gdb_byte *) xmalloc (len); std::unique_ptr<ppc_displaced_step_closure> closure
struct cleanup *old_chain = make_cleanup (xfree, buf); (new ppc_displaced_step_closure (len));
gdb_byte *buf = closure->buf.data ();
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int insn; int insn;
@ -1041,7 +1044,7 @@ ppc_displaced_step_copy_insn (struct gdbarch *gdbarch,
"atomic sequence at %s\n", "atomic sequence at %s\n",
paddress (gdbarch, from)); paddress (gdbarch, from));
} }
do_cleanups (old_chain);
return NULL; return NULL;
} }
@ -1054,22 +1057,22 @@ ppc_displaced_step_copy_insn (struct gdbarch *gdbarch,
displaced_step_dump_bytes (gdb_stdlog, buf, len); displaced_step_dump_bytes (gdb_stdlog, buf, len);
} }
discard_cleanups (old_chain); return closure.release ();
return (struct displaced_step_closure *) buf;
} }
/* Fix up the state of registers and memory after having single-stepped /* Fix up the state of registers and memory after having single-stepped
a displaced instruction. */ a displaced instruction. */
static void static void
ppc_displaced_step_fixup (struct gdbarch *gdbarch, ppc_displaced_step_fixup (struct gdbarch *gdbarch,
struct displaced_step_closure *closure, struct displaced_step_closure *closure_,
CORE_ADDR from, CORE_ADDR to, CORE_ADDR from, CORE_ADDR to,
struct regcache *regs) struct regcache *regs)
{ {
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
/* Our closure is a copy of the instruction. */ /* Our closure is a copy of the instruction. */
ULONGEST insn = extract_unsigned_integer ((gdb_byte *) closure, ppc_displaced_step_closure *closure = (ppc_displaced_step_closure *) closure_;
PPC_INSN_SIZE, byte_order); ULONGEST insn = extract_unsigned_integer (closure->buf.data (),
PPC_INSN_SIZE, byte_order);
ULONGEST opcode = 0; ULONGEST opcode = 0;
/* Offset for non PC-relative instructions. */ /* Offset for non PC-relative instructions. */
LONGEST offset = PPC_INSN_SIZE; LONGEST offset = PPC_INSN_SIZE;

View File

@ -1861,6 +1861,8 @@ is_non_branch_ril (gdb_byte *insn)
return 0; return 0;
} }
typedef buf_displaced_step_closure s390_displaced_step_closure;
/* Implementation of gdbarch_displaced_step_copy_insn. */ /* Implementation of gdbarch_displaced_step_copy_insn. */
static struct displaced_step_closure * static struct displaced_step_closure *
@ -1869,8 +1871,9 @@ s390_displaced_step_copy_insn (struct gdbarch *gdbarch,
struct regcache *regs) struct regcache *regs)
{ {
size_t len = gdbarch_max_insn_length (gdbarch); size_t len = gdbarch_max_insn_length (gdbarch);
gdb_byte *buf = (gdb_byte *) xmalloc (len); std::unique_ptr<s390_displaced_step_closure> closure
struct cleanup *old_chain = make_cleanup (xfree, buf); (new s390_displaced_step_closure (len));
gdb_byte *buf = closure->buf.data ();
read_memory (from, buf, len); read_memory (from, buf, len);
@ -1898,7 +1901,7 @@ s390_displaced_step_copy_insn (struct gdbarch *gdbarch,
"RIL instruction: offset %s out of range\n", "RIL instruction: offset %s out of range\n",
plongest (offset)); plongest (offset));
} }
do_cleanups (old_chain);
return NULL; return NULL;
} }
@ -1914,20 +1917,21 @@ s390_displaced_step_copy_insn (struct gdbarch *gdbarch,
displaced_step_dump_bytes (gdb_stdlog, buf, len); displaced_step_dump_bytes (gdb_stdlog, buf, len);
} }
discard_cleanups (old_chain); return closure.release ();
return (struct displaced_step_closure *) buf;
} }
/* Fix up the state of registers and memory after having single-stepped /* Fix up the state of registers and memory after having single-stepped
a displaced instruction. */ a displaced instruction. */
static void static void
s390_displaced_step_fixup (struct gdbarch *gdbarch, s390_displaced_step_fixup (struct gdbarch *gdbarch,
struct displaced_step_closure *closure, struct displaced_step_closure *closure_,
CORE_ADDR from, CORE_ADDR to, CORE_ADDR from, CORE_ADDR to,
struct regcache *regs) struct regcache *regs)
{ {
/* Our closure is a copy of the instruction. */ /* Our closure is a copy of the instruction. */
gdb_byte *insn = (gdb_byte *) closure; s390_displaced_step_closure *closure
= (s390_displaced_step_closure *) closure_;
gdb_byte *insn = closure->buf.data ();
static int s390_instrlen[] = { 2, 4, 4, 6 }; static int s390_instrlen[] = { 2, 4, 4, 6 };
int insnlen = s390_instrlen[insn[0] >> 6]; int insnlen = s390_instrlen[insn[0] >> 6];