+2016-11-03 Yao Qi <yao.qi@linaro.org>
+
+ * arch-utils.h (GDBARCH_BREAKPOINT_FROM_PC): New macro.
+ (GDBARCH_BREAKPOINT_MANIPULATION_ENDIAN): New macro.
+ * arm-tdep.c (arm_breakpoint_from_pc): Remove.
+ (arm_breakpoint_kind_from_pc): New function.
+ (arm_sw_breakpoint_from_kind): New function.
+ (arm_breakpoint_from_pc): Call arm_breakpoint_kind_from_pc
+ and arm_sw_breakpoint_from_kind.
+ Use GDBARCH_BREAKPOINT_FROM_PC.
+ (arm_remote_breakpoint_from_pc): Call
+ arm_breakpoint_kind_from_pc.
+ (arm_gdbarch_init): Replace set_gdbarch_breakpoint_from_pc
+ with SET_GDBARCH_BREAKPOINT_MANIPULATION.
+ * arc-tdep.c: Likewise.
+ * bfin-tdep.c: Likewise.
+ * cris-tdep.c: Likewise.
+ * iq2000-tdep.c: Likewise.
+ * m32r-tdep.c: Likewise.
+ * mips-tdep.c: Likewise.
+ * mt-tdep.c: Likewise.
+ * nios2-tdep.c: Likewise.
+ * rs6000-tdep.c: Likewise.
+ * score-tdep.c: Likewise.
+ * sh-tdep.c: Likewise.
+ * sh64-tdep.c: Likewise.
+ * tic6x-tdep.c: Likewise.
+ * v850-tdep.c: Likewise.
+ * xtensa-tdep.c: Likewise.
+
2016-11-03 Yao Qi <yao.qi@linaro.org>
* mips-tdep.c (mips_breakpoint_kind): New enum.
static const gdb_byte arc_brk_be[] = { 0x25, 0x6f, 0x00, 0x3f };
static const gdb_byte arc_brk_le[] = { 0x6f, 0x25, 0x3f, 0x00 };
-/* Implement the "breakpoint_from_pc" gdbarch method.
-
- For ARC ELF, breakpoint uses the 16-bit BRK_S instruction, which is 0x7fff
+/* For ARC ELF, breakpoint uses the 16-bit BRK_S instruction, which is 0x7fff
(little endian) or 0xff7f (big endian). We used to insert BRK_S even
instead of 32-bit instructions, which works mostly ok, unless breakpoint is
inserted into delay slot instruction. In this case if branch is taken
NB: Baremetal GDB uses BRK[_S], while user-space GDB uses TRAP_S. BRK[_S]
is much better because it doesn't commit unlike TRAP_S, so it can be set in
delay slots; however it cannot be used in user-mode, hence usage of TRAP_S
- in GDB for user-space.
+ in GDB for user-space. */
- PCPTR is a pointer to the PC where we want to place a breakpoint. LENPTR
- is a number of bytes used by the breakpoint. Returns the byte sequence of
- a breakpoint instruction. */
+/* Implement the "breakpoint_kind_from_pc" gdbarch method. */
-static const gdb_byte *
-arc_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
- int *lenptr)
+static int
+arc_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
size_t length_with_limm = gdb_insn_length (gdbarch, *pcptr);
bytes for 32-bit instructions. */
if ((length_with_limm == 4 || length_with_limm == 8)
&& !arc_mach_is_arc600 (gdbarch))
+ return sizeof (arc_brk_le);
+ else
+ return sizeof (arc_brk_s_le);
+}
+
+/* Implement the "sw_breakpoint_from_kind" gdbarch method. */
+
+static const gdb_byte *
+arc_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
+{
+ *size = kind;
+
+ if (kind == sizeof (arc_brk_le))
{
- *lenptr = sizeof (arc_brk_le);
return ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
? arc_brk_be
: arc_brk_le);
}
else
{
- *lenptr = sizeof (arc_brk_s_le);
return ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
? arc_brk_s_be
: arc_brk_s_le);
}
}
+GDBARCH_BREAKPOINT_FROM_PC (arc)
+
/* Implement the "unwind_pc" gdbarch method. */
static CORE_ADDR
set_gdbarch_skip_prologue (gdbarch, arc_skip_prologue);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_breakpoint_from_pc (gdbarch, arc_breakpoint_from_pc);
+ SET_GDBARCH_BREAKPOINT_MANIPULATION (arc);
/* On ARC 600 BRK_S instruction advances PC, unlike other ARC cores. */
if (!arc_mach_is_arc600 (gdbarch))
struct type;
struct gdbarch_info;
+#define GDBARCH_BREAKPOINT_FROM_PC(ARCH) \
+ static const gdb_byte * \
+ ARCH##_breakpoint_from_pc (struct gdbarch *gdbarch, \
+ CORE_ADDR *pcptr, \
+ int *lenptr) \
+ { \
+ int kind = ARCH##_breakpoint_kind_from_pc (gdbarch, pcptr); \
+ \
+ return ARCH##_sw_breakpoint_from_kind (gdbarch, kind, lenptr); \
+ }
+
#define GDBARCH_BREAKPOINT_MANIPULATION(ARCH,BREAK_INSN) \
static const gdb_byte * \
ARCH##_breakpoint_from_pc (struct gdbarch *gdbarch, \
#define SET_GDBARCH_BREAKPOINT_MANIPULATION(ARCH) \
set_gdbarch_breakpoint_from_pc (gdbarch, ARCH##_breakpoint_from_pc)
+#define GDBARCH_BREAKPOINT_MANIPULATION_ENDIAN(ARCH, \
+ LITTLE_BREAK_INSN, \
+ BIG_BREAK_INSN) \
+ static const gdb_byte * \
+ ARCH##_breakpoint_from_pc (struct gdbarch *gdbarch, \
+ CORE_ADDR *pcptr, \
+ int *lenptr) \
+ { \
+ gdb_static_assert (ARRAY_SIZE (LITTLE_BREAK_INSN) \
+ == ARRAY_SIZE (BIG_BREAK_INSN)); \
+ *lenptr = sizeof (LITTLE_BREAK_INSN); \
+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) \
+ return BIG_BREAK_INSN; \
+ else \
+ return LITTLE_BREAK_INSN; \
+ }
+
/* An implementation of gdbarch_displaced_step_copy_insn for
processors that don't need to modify the instruction before
single-stepping the displaced copy.
static const gdb_byte arm_default_thumb_le_breakpoint[] = THUMB_LE_BREAKPOINT;
static const gdb_byte arm_default_thumb_be_breakpoint[] = THUMB_BE_BREAKPOINT;
-/* Determine the type and size of breakpoint to insert at PCPTR. Uses
- the program counter value to determine whether a 16-bit or 32-bit
- breakpoint should be used. It returns a pointer to a string of
- bytes that encode a breakpoint instruction, stores the length of
- the string to *lenptr, and adjusts the program counter (if
- necessary) to point to the actual memory location where the
- breakpoint should be inserted. */
-
-static const unsigned char *
-arm_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
+static int
+arm_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
if (tdep->thumb2_breakpoint != NULL)
{
gdb_byte buf[2];
+
if (target_read_memory (*pcptr, buf, 2) == 0)
{
unsigned short inst1;
+
inst1 = extract_unsigned_integer (buf, 2, byte_order_for_code);
if (thumb_insn_size (inst1) == 4)
- {
- *lenptr = tdep->thumb2_breakpoint_size;
- return tdep->thumb2_breakpoint;
- }
+ return ARM_BP_KIND_THUMB2;
}
}
- *lenptr = tdep->thumb_breakpoint_size;
- return tdep->thumb_breakpoint;
+ return ARM_BP_KIND_THUMB;
}
else
+ return ARM_BP_KIND_ARM;
+
+}
+
+static const gdb_byte *
+arm_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ switch (kind)
{
- *lenptr = tdep->arm_breakpoint_size;
+ case ARM_BP_KIND_ARM:
+ *size = tdep->arm_breakpoint_size;
return tdep->arm_breakpoint;
+ case ARM_BP_KIND_THUMB:
+ *size = tdep->thumb_breakpoint_size;
+ return tdep->thumb_breakpoint;
+ case ARM_BP_KIND_THUMB2:
+ *size = tdep->thumb2_breakpoint_size;
+ return tdep->thumb2_breakpoint;
+ default:
+ gdb_assert_not_reached ("unexpected arm breakpoint kind");
}
}
+/* Determine the type and size of breakpoint to insert at PCPTR. Uses
+ the program counter value to determine whether a 16-bit or 32-bit
+ breakpoint should be used. It returns a pointer to a string of
+ bytes that encode a breakpoint instruction, stores the length of
+ the string to *lenptr, and adjusts the program counter (if
+ necessary) to point to the actual memory location where the
+ breakpoint should be inserted. */
+
+GDBARCH_BREAKPOINT_FROM_PC (arm)
+
static void
arm_remote_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
int *kindptr)
{
- arm_breakpoint_from_pc (gdbarch, pcptr, kindptr);
- if (arm_pc_is_thumb (gdbarch, *pcptr) && *kindptr == 4)
- /* The documented magic value for a 32-bit Thumb-2 breakpoint, so
- that this is not confused with a 32-bit ARM breakpoint. */
- *kindptr = ARM_BP_KIND_THUMB2;
+ *kindptr = arm_breakpoint_kind_from_pc (gdbarch, pcptr);
}
/* Extract from an array REGBUF containing the (raw) register state a
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
/* Breakpoint manipulation. */
- set_gdbarch_breakpoint_from_pc (gdbarch, arm_breakpoint_from_pc);
+ SET_GDBARCH_BREAKPOINT_MANIPULATION (arm);
set_gdbarch_remote_breakpoint_from_pc (gdbarch,
arm_remote_breakpoint_from_pc);
return map_gcc_gdb[reg];
}
-/* This function implements the 'breakpoint_from_pc' gdbarch method.
- It returns a pointer to a string of bytes that encode a breakpoint
- instruction, stores the length of the string to *lenptr, and
- adjusts the program counter (if necessary) to point to the actual
- memory location where the breakpoint should be inserted. */
-
-static const unsigned char *
-bfin_breakpoint_from_pc (struct gdbarch *gdbarch,
- CORE_ADDR *pcptr, int *lenptr)
+static int
+bfin_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
unsigned short iw;
- static unsigned char bfin_breakpoint[] = {0xa1, 0x00, 0x00, 0x00};
- static unsigned char bfin_sim_breakpoint[] = {0x25, 0x00, 0x00, 0x00};
iw = read_memory_unsigned_integer (*pcptr, 2, byte_order);
if ((iw & 0xf000) >= 0xc000)
/* 32-bit instruction. */
- *lenptr = 4;
+ return 4;
else
- *lenptr = 2;
+ return 2;
+}
+
+static const gdb_byte *
+bfin_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
+{
+ static unsigned char bfin_breakpoint[] = {0xa1, 0x00, 0x00, 0x00};
+ static unsigned char bfin_sim_breakpoint[] = {0x25, 0x00, 0x00, 0x00};
+
+ *size = kind;
if (strcmp (target_shortname, "sim") == 0)
return bfin_sim_breakpoint;
return bfin_breakpoint;
}
+/* This function implements the 'breakpoint_from_pc' gdbarch method.
+ It returns a pointer to a string of bytes that encode a breakpoint
+ instruction, stores the length of the string to *lenptr, and
+ adjusts the program counter (if necessary) to point to the actual
+ memory location where the breakpoint should be inserted. */
+
+GDBARCH_BREAKPOINT_FROM_PC (bfin)
+
static void
bfin_extract_return_value (struct type *type,
struct regcache *regs,
set_gdbarch_return_value (gdbarch, bfin_return_value);
set_gdbarch_skip_prologue (gdbarch, bfin_skip_prologue);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_breakpoint_from_pc (gdbarch, bfin_breakpoint_from_pc);
+ SET_GDBARCH_BREAKPOINT_MANIPULATION (bfin);
set_gdbarch_decr_pc_after_break (gdbarch, 2);
set_gdbarch_frame_args_skip (gdbarch, 8);
set_gdbarch_unwind_pc (gdbarch, bfin_unwind_pc);
return sp;
}
-/* Use the program counter to determine the contents and size of a breakpoint
- instruction. It returns a pointer to a string of bytes that encode a
- breakpoint instruction, stores the length of the string to *lenptr, and
- adjusts pcptr (if necessary) to point to the actual memory location where
- the breakpoint should be inserted. */
+static int
+cris_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
+{
+ return 2;
+}
-static const unsigned char *
-cris_breakpoint_from_pc (struct gdbarch *gdbarch,
- CORE_ADDR *pcptr, int *lenptr)
+static const gdb_byte *
+cris_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
static unsigned char break8_insn[] = {0x38, 0xe9};
static unsigned char break15_insn[] = {0x3f, 0xe9};
- *lenptr = 2;
+
+ *size = kind;
if (tdep->cris_mode == cris_mode_guru)
return break15_insn;
return break8_insn;
}
+/* Use the program counter to determine the contents and size of a breakpoint
+ instruction. It returns a pointer to a string of bytes that encode a
+ breakpoint instruction, stores the length of the string to *lenptr, and
+ adjusts pcptr (if necessary) to point to the actual memory location where
+ the breakpoint should be inserted. */
+
+GDBARCH_BREAKPOINT_FROM_PC (cris)
+
/* Returns 1 if spec_reg is applicable to the current gdbarch's CRIS version,
0 otherwise. */
/* The stack grows downward. */
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_breakpoint_from_pc (gdbarch, cris_breakpoint_from_pc);
+ SET_GDBARCH_BREAKPOINT_MANIPULATION (cris);
set_gdbarch_unwind_pc (gdbarch, cris_unwind_pc);
set_gdbarch_unwind_sp (gdbarch, cris_unwind_sp);
iq2000_frame_base_address
};
-static const unsigned char *
-iq2000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
- int *lenptr)
+static int
+iq2000_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
- static const unsigned char big_breakpoint[] = { 0x00, 0x00, 0x00, 0x0d };
- static const unsigned char little_breakpoint[] = { 0x0d, 0x00, 0x00, 0x00 };
-
if ((*pcptr & 3) != 0)
error (_("breakpoint_from_pc: invalid breakpoint address 0x%lx"),
(long) *pcptr);
- *lenptr = 4;
+ return 4;
+}
+
+static const gdb_byte *
+iq2000_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
+{
+ static const unsigned char big_breakpoint[] = { 0x00, 0x00, 0x00, 0x0d };
+ static const unsigned char little_breakpoint[] = { 0x0d, 0x00, 0x00, 0x00 };
+ *size = kind;
+
return (gdbarch_byte_order (gdbarch)
== BFD_ENDIAN_BIG) ? big_breakpoint : little_breakpoint;
}
+GDBARCH_BREAKPOINT_FROM_PC (iq2000)
+
/* Target function return value methods: */
/* Function: store_return_value
set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
set_gdbarch_return_value (gdbarch, iq2000_return_value);
- set_gdbarch_breakpoint_from_pc (gdbarch, iq2000_breakpoint_from_pc);
+ SET_GDBARCH_BREAKPOINT_MANIPULATION (iq2000);
set_gdbarch_frame_args_skip (gdbarch, 0);
set_gdbarch_skip_prologue (gdbarch, iq2000_skip_prologue);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
return val;
}
+static int
+m32r_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
+{
+ if ((*pcptr & 3) == 0)
+ return 4;
+ else
+ return 2;
+}
+
static const gdb_byte *
-m32r_breakpoint_from_pc (struct gdbarch *gdbarch,
- CORE_ADDR *pcptr, int *lenptr)
+m32r_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
{
static gdb_byte be_bp_entry[] = {
0x10, 0xf1, 0x70, 0x00
static gdb_byte le_bp_entry[] = {
0x00, 0x70, 0xf1, 0x10
}; /* dpt -> nop */
- gdb_byte *bp;
+
+ *size = kind;
/* Determine appropriate breakpoint. */
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
- {
- if ((*pcptr & 3) == 0)
- {
- bp = be_bp_entry;
- *lenptr = 4;
- }
- else
- {
- bp = be_bp_entry;
- *lenptr = 2;
- }
- }
+ return be_bp_entry;
else
{
- if ((*pcptr & 3) == 0)
- {
- bp = le_bp_entry;
- *lenptr = 4;
- }
+ if (kind == 4)
+ return le_bp_entry;
else
- {
- bp = le_bp_entry + 2;
- *lenptr = 2;
- }
+ return le_bp_entry + 2;
}
-
- return bp;
}
+GDBARCH_BREAKPOINT_FROM_PC (m32r)
char *m32r_register_names[] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
set_gdbarch_skip_prologue (gdbarch, m32r_skip_prologue);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_breakpoint_from_pc (gdbarch, m32r_breakpoint_from_pc);
+ SET_GDBARCH_BREAKPOINT_MANIPULATION (m32r);
set_gdbarch_memory_insert_breakpoint (gdbarch,
m32r_memory_insert_breakpoint);
set_gdbarch_memory_remove_breakpoint (gdbarch,
return gdb_print_insn_mips (memaddr, info);
}
-/* This function implements gdbarch_breakpoint_from_pc. It uses the
- program counter value to determine whether a 16- or 32-bit breakpoint
- should be used. It returns a pointer to a string of bytes that encode a
- breakpoint instruction, stores the length of the string to *lenptr, and
- adjusts pc (if necessary) to point to the actual memory location where
- the breakpoint should be inserted. */
-
-static const gdb_byte *
-mips_breakpoint_from_pc (struct gdbarch *gdbarch,
- CORE_ADDR *pcptr, int *lenptr)
+static int
+mips_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
CORE_ADDR pc = *pcptr;
- if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+ if (mips_pc_is_mips16 (gdbarch, pc))
{
- if (mips_pc_is_mips16 (gdbarch, pc))
- {
- static gdb_byte mips16_big_breakpoint[] = { 0xe8, 0xa5 };
- *pcptr = unmake_compact_addr (pc);
- *lenptr = sizeof (mips16_big_breakpoint);
- return mips16_big_breakpoint;
- }
- else if (mips_pc_is_micromips (gdbarch, pc))
- {
- static gdb_byte micromips16_big_breakpoint[] = { 0x46, 0x85 };
- static gdb_byte micromips32_big_breakpoint[] = { 0, 0x5, 0, 0x7 };
- ULONGEST insn;
- int err;
- int size;
-
- insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &err);
- size = err ? 2 : mips_insn_size (ISA_MICROMIPS, insn);
- *pcptr = unmake_compact_addr (pc);
- *lenptr = size;
- return (size == 2) ? micromips16_big_breakpoint
- : micromips32_big_breakpoint;
- }
- else
- {
- static gdb_byte big_breakpoint[] = { 0, 0x5, 0, 0xd };
+ *pcptr = unmake_compact_addr (pc);
+ return MIPS_BP_KIND_MIPS16;
+ }
+ else if (mips_pc_is_micromips (gdbarch, pc))
+ {
+ ULONGEST insn;
+ int status;
- *lenptr = sizeof (big_breakpoint);
- return big_breakpoint;
- }
+ *pcptr = unmake_compact_addr (pc);
+ insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &status);
+ if (status || (mips_insn_size (ISA_MICROMIPS, insn) == 2))
+ return MIPS_BP_KIND_MICROMIPS16;
+ else
+ return MIPS_BP_KIND_MICROMIPS32;
}
else
+ return MIPS_BP_KIND_MIPS32;
+}
+
+static const gdb_byte *
+mips_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
+{
+ enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
+
+ switch (kind)
{
- if (mips_pc_is_mips16 (gdbarch, pc))
- {
- static gdb_byte mips16_little_breakpoint[] = { 0xa5, 0xe8 };
- *pcptr = unmake_compact_addr (pc);
- *lenptr = sizeof (mips16_little_breakpoint);
+ case MIPS_BP_KIND_MIPS16:
+ {
+ static gdb_byte mips16_big_breakpoint[] = { 0xe8, 0xa5 };
+ static gdb_byte mips16_little_breakpoint[] = { 0xa5, 0xe8 };
+
+ *size = 2;
+ if (byte_order_for_code == BFD_ENDIAN_BIG)
+ return mips16_big_breakpoint;
+ else
return mips16_little_breakpoint;
- }
- else if (mips_pc_is_micromips (gdbarch, pc))
- {
- static gdb_byte micromips16_little_breakpoint[] = { 0x85, 0x46 };
- static gdb_byte micromips32_little_breakpoint[] = { 0x5, 0, 0x7, 0 };
- ULONGEST insn;
- int err;
- int size;
-
- insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &err);
- size = err ? 2 : mips_insn_size (ISA_MICROMIPS, insn);
- *pcptr = unmake_compact_addr (pc);
- *lenptr = size;
- return (size == 2) ? micromips16_little_breakpoint
- : micromips32_little_breakpoint;
- }
- else
- {
- static gdb_byte little_breakpoint[] = { 0xd, 0, 0x5, 0 };
+ }
+ case MIPS_BP_KIND_MICROMIPS16:
+ {
+ static gdb_byte micromips16_big_breakpoint[] = { 0x46, 0x85 };
+ static gdb_byte micromips16_little_breakpoint[] = { 0x85, 0x46 };
+
+ *size = 2;
+
+ if (byte_order_for_code == BFD_ENDIAN_BIG)
+ return micromips16_big_breakpoint;
+ else
+ return micromips16_little_breakpoint;
+ }
+ case MIPS_BP_KIND_MICROMIPS32:
+ {
+ static gdb_byte micromips32_big_breakpoint[] = { 0, 0x5, 0, 0x7 };
+ static gdb_byte micromips32_little_breakpoint[] = { 0x5, 0, 0x7, 0 };
+
+ *size = 4;
+ if (byte_order_for_code == BFD_ENDIAN_BIG)
+ return micromips32_big_breakpoint;
+ else
+ return micromips32_little_breakpoint;
+ }
+ case MIPS_BP_KIND_MIPS32:
+ {
+ static gdb_byte big_breakpoint[] = { 0, 0x5, 0, 0xd };
+ static gdb_byte little_breakpoint[] = { 0xd, 0, 0x5, 0 };
- *lenptr = sizeof (little_breakpoint);
+ *size = 4;
+ if (byte_order_for_code == BFD_ENDIAN_BIG)
+ return big_breakpoint;
+ else
return little_breakpoint;
- }
- }
+ }
+ default:
+ gdb_assert_not_reached ("unexpected mips breakpoint kind");
+ };
}
+/* This function implements gdbarch_breakpoint_from_pc. It uses the
+ program counter value to determine whether a 16- or 32-bit breakpoint
+ should be used. It returns a pointer to a string of bytes that encode a
+ breakpoint instruction, stores the length of the string to *lenptr, and
+ adjusts pc (if necessary) to point to the actual memory location where
+ the breakpoint should be inserted. */
+
+GDBARCH_BREAKPOINT_FROM_PC (mips)
+
/* Determine the remote breakpoint kind suitable for the PC. */
static void
mips_remote_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
int *kindptr)
{
- CORE_ADDR pc = *pcptr;
-
- if (mips_pc_is_mips16 (gdbarch, pc))
- {
- *pcptr = unmake_compact_addr (pc);
- *kindptr = MIPS_BP_KIND_MIPS16;
- }
- else if (mips_pc_is_micromips (gdbarch, pc))
- {
- ULONGEST insn;
- int status;
-
- insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &status);
- if (status || (mips_insn_size (ISA_MICROMIPS, insn) == 2))
- *kindptr = MIPS_BP_KIND_MICROMIPS16;
- else
- *kindptr = MIPS_BP_KIND_MICROMIPS32;
-
- *pcptr = unmake_compact_addr (pc);
- }
- else
- *kindptr = MIPS_BP_KIND_MIPS32;
+ *kindptr = mips_breakpoint_kind_from_pc (gdbarch, pcptr);
}
/* Return non-zero if the standard MIPS instruction INST has a branch
return pc;
}
-/* The breakpoint instruction must be the same size as the smallest
- instruction in the instruction set.
-
- The BP for ms1 is defined as 0x68000000 (BREAK).
- The BP for ms2 is defined as 0x69000000 (illegal). */
+static int
+mt_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
+{
+ return 4;
+}
static const gdb_byte *
-mt_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
- int *bp_size)
+mt_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
{
+ /* The breakpoint instruction must be the same size as the smallest
+ instruction in the instruction set.
+
+ The BP for ms1 is defined as 0x68000000 (BREAK).
+ The BP for ms2 is defined as 0x69000000 (illegal). */
static gdb_byte ms1_breakpoint[] = { 0x68, 0, 0, 0 };
static gdb_byte ms2_breakpoint[] = { 0x69, 0, 0, 0 };
- *bp_size = 4;
+ *size = kind;
+
if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_ms2)
return ms2_breakpoint;
-
+
return ms1_breakpoint;
}
+GDBARCH_BREAKPOINT_FROM_PC (mt)
+
/* Select the correct coprocessor register bank. Return the pseudo
regnum we really want to read. */
set_gdbarch_pseudo_register_write (gdbarch, mt_pseudo_register_write);
set_gdbarch_skip_prologue (gdbarch, mt_skip_prologue);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_breakpoint_from_pc (gdbarch, mt_breakpoint_from_pc);
+ SET_GDBARCH_BREAKPOINT_MANIPULATION (mt);
set_gdbarch_decr_pc_after_break (gdbarch, 0);
set_gdbarch_frame_args_skip (gdbarch, 0);
set_gdbarch_print_insn (gdbarch, print_insn_mt);
return nios2_analyze_prologue (gdbarch, start_pc, start_pc, &cache, NULL);
}
-/* Implement the breakpoint_from_pc gdbarch hook.
+static int
+nios2_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
+{
+ unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
+
+ if (mach == bfd_mach_nios2r2)
+ {
+ unsigned int insn;
+ const struct nios2_opcode *op
+ = nios2_fetch_insn (gdbarch, *pcptr, &insn);
+
+ if (op && op->size == NIOS2_CDX_OPCODE_SIZE)
+ return NIOS2_CDX_OPCODE_SIZE;
+ else
+ return NIOS2_OPCODE_SIZE;
+ }
+ else
+ return NIOS2_OPCODE_SIZE;
+}
- The Nios II ABI for Linux says: "Userspace programs should not use
+static const gdb_byte *
+nios2_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
+{
+/* The Nios II ABI for Linux says: "Userspace programs should not use
the break instruction and userspace debuggers should not insert
one." and "Userspace breakpoints are accomplished using the trap
instruction with immediate operand 31 (all ones)."
So, we use "trap 31" consistently as the breakpoint on bare-metal
as well as Linux targets. */
-static const gdb_byte*
-nios2_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
- int *bp_size)
-{
- enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
- unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
+ /* R2 trap encoding:
+ ((0x2d << 26) | (0x1f << 21) | (0x1d << 16) | (0x20 << 0))
+ 0xb7fd0020
+ CDX trap.n encoding:
+ ((0xd << 12) | (0x1f << 6) | (0x9 << 0))
+ 0xd7c9
+ Note that code is always little-endian on R2. */
+ *size = kind;
- if (mach == bfd_mach_nios2r2)
+ if (kind == NIOS2_CDX_OPCODE_SIZE)
{
- /* R2 trap encoding:
- ((0x2d << 26) | (0x1f << 21) | (0x1d << 16) | (0x20 << 0))
- 0xb7fd0020
- CDX trap.n encoding:
- ((0xd << 12) | (0x1f << 6) | (0x9 << 0))
- 0xd7c9
- Note that code is always little-endian on R2. */
- static const gdb_byte r2_breakpoint_le[] = {0x20, 0x00, 0xfd, 0xb7};
static const gdb_byte cdx_breakpoint_le[] = {0xc9, 0xd7};
- unsigned int insn;
- const struct nios2_opcode *op
- = nios2_fetch_insn (gdbarch, *bp_addr, &insn);
- if (op && op->size == NIOS2_CDX_OPCODE_SIZE)
+ return cdx_breakpoint_le;
+ }
+ else
+ {
+ unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
+
+ if (mach == bfd_mach_nios2r2)
{
- *bp_size = NIOS2_CDX_OPCODE_SIZE;
- return cdx_breakpoint_le;
+ static const gdb_byte r2_breakpoint_le[] = {0x20, 0x00, 0xfd, 0xb7};
+
+ return r2_breakpoint_le;
}
else
{
- *bp_size = NIOS2_OPCODE_SIZE;
- return r2_breakpoint_le;
+ enum bfd_endian byte_order_for_code
+ = gdbarch_byte_order_for_code (gdbarch);
+ /* R1 trap encoding:
+ ((0x1d << 17) | (0x2d << 11) | (0x1f << 6) | (0x3a << 0))
+ 0x003b6ffa */
+ static const gdb_byte r1_breakpoint_le[] = {0xfa, 0x6f, 0x3b, 0x0};
+ static const gdb_byte r1_breakpoint_be[] = {0x0, 0x3b, 0x6f, 0xfa};
+
+ if (byte_order_for_code == BFD_ENDIAN_BIG)
+ return r1_breakpoint_be;
+ else
+ return r1_breakpoint_le;
}
}
- else
- {
- /* R1 trap encoding:
- ((0x1d << 17) | (0x2d << 11) | (0x1f << 6) | (0x3a << 0))
- 0x003b6ffa */
- static const gdb_byte r1_breakpoint_le[] = {0xfa, 0x6f, 0x3b, 0x0};
- static const gdb_byte r1_breakpoint_be[] = {0x0, 0x3b, 0x6f, 0xfa};
- *bp_size = NIOS2_OPCODE_SIZE;
- if (byte_order_for_code == BFD_ENDIAN_BIG)
- return r1_breakpoint_be;
- else
- return r1_breakpoint_le;
- }
}
+/* Implement the breakpoint_from_pc gdbarch hook. */
+
+GDBARCH_BREAKPOINT_FROM_PC (nios2)
+
/* Implement the print_insn gdbarch method. */
static int
set_gdbarch_skip_prologue (gdbarch, nios2_skip_prologue);
set_gdbarch_stack_frame_destroyed_p (gdbarch, nios2_stack_frame_destroyed_p);
- set_gdbarch_breakpoint_from_pc (gdbarch, nios2_breakpoint_from_pc);
+ SET_GDBARCH_BREAKPOINT_MANIPULATION (nios2);
set_gdbarch_dummy_id (gdbarch, nios2_dummy_id);
set_gdbarch_unwind_pc (gdbarch, nios2_unwind_pc);
/* Sequence of bytes for breakpoint instruction. */
-static const unsigned char *
-rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
- int *bp_size)
-{
- static unsigned char big_breakpoint[] = { 0x7d, 0x82, 0x10, 0x08 };
- static unsigned char little_breakpoint[] = { 0x08, 0x10, 0x82, 0x7d };
- *bp_size = 4;
- if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
- return big_breakpoint;
- else
- return little_breakpoint;
-}
+static unsigned char big_breakpoint[] = { 0x7d, 0x82, 0x10, 0x08 };
+static unsigned char little_breakpoint[] = { 0x08, 0x10, 0x82, 0x7d };
+
+GDBARCH_BREAKPOINT_MANIPULATION_ENDIAN (rs6000, little_breakpoint,
+ big_breakpoint)
/* Instruction masks for displaced stepping. */
#define BRANCH_MASK 0xfc000000
set_gdbarch_skip_main_prologue (gdbarch, rs6000_skip_main_prologue);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc);
+ SET_GDBARCH_BREAKPOINT_MANIPULATION (rs6000);
/* The value of symbols of type N_SO and N_FUN maybe null when
it shouldn't be. */
return &inst;
}
-static const gdb_byte *
-score7_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
- int *lenptr)
+static int
+score7_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- gdb_byte buf[SCORE_INSTLEN] = { 0 };
int ret;
unsigned int raw;
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ gdb_byte buf[SCORE_INSTLEN] = { 0 };
if ((ret = target_read_memory (*pcptr & ~0x3, buf, SCORE_INSTLEN)) != 0)
{
error (_("Error: target_read_memory in file:%s, line:%d!"),
- __FILE__, __LINE__);
+ __FILE__, __LINE__);
}
raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);
- if (byte_order == BFD_ENDIAN_BIG)
+ if (!(raw & 0x80008000))
{
- if (!(raw & 0x80008000))
- {
- /* 16bits instruction. */
- static gdb_byte big_breakpoint16[] = { 0x60, 0x02 };
- *pcptr &= ~0x1;
- *lenptr = sizeof (big_breakpoint16);
- return big_breakpoint16;
- }
+ /* 16bits instruction. */
+ *pcptr &= ~0x1;
+ return 2;
+ }
+ else
+ {
+ /* 32bits instruction. */
+ *pcptr &= ~0x3;
+ return 4;
+ }
+}
+
+static const gdb_byte *
+score7_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
+{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
+ *size = kind;
+
+ if (kind == 4)
+ {
+ static gdb_byte big_breakpoint32[] = { 0x80, 0x00, 0x80, 0x06 };
+ static gdb_byte little_breakpoint32[] = { 0x06, 0x80, 0x00, 0x80 };
+
+ if (byte_order == BFD_ENDIAN_BIG)
+ return big_breakpoint32;
else
- {
- /* 32bits instruction. */
- static gdb_byte big_breakpoint32[] = { 0x80, 0x00, 0x80, 0x06 };
- *pcptr &= ~0x3;
- *lenptr = sizeof (big_breakpoint32);
- return big_breakpoint32;
- }
+ return little_breakpoint32;
}
else
{
- if (!(raw & 0x80008000))
- {
- /* 16bits instruction. */
- static gdb_byte little_breakpoint16[] = { 0x02, 0x60 };
- *pcptr &= ~0x1;
- *lenptr = sizeof (little_breakpoint16);
- return little_breakpoint16;
- }
+ static gdb_byte big_breakpoint16[] = { 0x60, 0x02 };
+ static gdb_byte little_breakpoint16[] = { 0x02, 0x60 };
+
+ if (byte_order == BFD_ENDIAN_BIG)
+ return big_breakpoint16;
else
- {
- /* 32bits instruction. */
- static gdb_byte little_breakpoint32[] = { 0x06, 0x80, 0x00, 0x80 };
- *pcptr &= ~0x3;
- *lenptr = sizeof (little_breakpoint32);
- return little_breakpoint32;
- }
+ return little_breakpoint16;
}
}
-static const gdb_byte *
-score3_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
- int *lenptr)
+GDBARCH_BREAKPOINT_FROM_PC (score7)
+
+static int
+score3_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR adjust_pc = *pcptr;
int len;
+
+ score3_adjust_pc_and_fetch_inst (pcptr, &len, byte_order);
+
+ return len;
+}
+
+static const gdb_byte *
+score3_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
+{
+ int index = 0;
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
static gdb_byte score_break_insns[6][6] = {
/* The following three instructions are big endian. */
{ 0x00, 0x20 },
{ 0x00, 0x80, 0x06, 0x00 },
{ 0x00, 0x80, 0x00, 0x80, 0x00, 0x00 }};
- gdb_byte *p = NULL;
- int index = 0;
-
- score3_adjust_pc_and_fetch_inst (&adjust_pc, &len, byte_order);
-
- index = ((byte_order == BFD_ENDIAN_BIG) ? 0 : 3) + (len / 2 - 1);
- p = score_break_insns[index];
+ *size = kind;
- *pcptr = adjust_pc;
- *lenptr = len;
-
- return p;
+ index = ((byte_order == BFD_ENDIAN_BIG) ? 0 : 3) + (kind / 2 - 1);
+ return score_break_insns[index];
}
+GDBARCH_BREAKPOINT_FROM_PC (score3)
+
static CORE_ADDR
score_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
{
switch (target_mach)
{
case bfd_mach_score7:
- set_gdbarch_breakpoint_from_pc (gdbarch, score7_breakpoint_from_pc);
+ SET_GDBARCH_BREAKPOINT_MANIPULATION (score7);
set_gdbarch_skip_prologue (gdbarch, score7_skip_prologue);
set_gdbarch_stack_frame_destroyed_p (gdbarch,
score7_stack_frame_destroyed_p);
break;
case bfd_mach_score3:
- set_gdbarch_breakpoint_from_pc (gdbarch, score3_breakpoint_from_pc);
+ SET_GDBARCH_BREAKPOINT_MANIPULATION (score3);
set_gdbarch_skip_prologue (gdbarch, score3_skip_prologue);
set_gdbarch_stack_frame_destroyed_p (gdbarch,
score3_stack_frame_destroyed_p);
return register_names[reg_nr];
}
-static const unsigned char *
-sh_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
+static int
+sh_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
- /* 0xc3c3 is trapa #c3, and it works in big and little endian modes. */
- static unsigned char breakpoint[] = { 0xc3, 0xc3 };
+ return 2;
+}
+
+static const gdb_byte *
+sh_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
+{
+ *size = kind;
/* For remote stub targets, trapa #20 is used. */
if (strcmp (target_shortname, "remote") == 0)
static unsigned char little_remote_breakpoint[] = { 0x20, 0xc3 };
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
- {
- *lenptr = sizeof (big_remote_breakpoint);
- return big_remote_breakpoint;
- }
+ return big_remote_breakpoint;
else
- {
- *lenptr = sizeof (little_remote_breakpoint);
- return little_remote_breakpoint;
- }
+ return little_remote_breakpoint;
}
+ else
+ {
+ /* 0xc3c3 is trapa #c3, and it works in big and little endian
+ modes. */
+ static unsigned char breakpoint[] = { 0xc3, 0xc3 };
- *lenptr = sizeof (breakpoint);
- return breakpoint;
+ return breakpoint;
+ }
}
+GDBARCH_BREAKPOINT_FROM_PC (sh)
+
/* Prologue looks like
mov.l r14,@-r15
sts.l pr,@-r15
set_gdbarch_register_type (gdbarch, sh_default_register_type);
set_gdbarch_register_reggroup_p (gdbarch, sh_register_reggroup_p);
- set_gdbarch_breakpoint_from_pc (gdbarch, sh_breakpoint_from_pc);
+ SET_GDBARCH_BREAKPOINT_MANIPULATION (sh);
set_gdbarch_print_insn (gdbarch, print_insn_sh);
set_gdbarch_register_sim_regno (gdbarch, legacy_register_sim_regno);
return 0;
}
-static const unsigned char *
-sh64_breakpoint_from_pc (struct gdbarch *gdbarch,
- CORE_ADDR *pcptr, int *lenptr)
+static int
+sh64_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
- /* The BRK instruction for shmedia is
+ if (pc_is_isa32 (*pcptr))
+ {
+ *pcptr = UNMAKE_ISA32_ADDR (*pcptr);
+ return 4;
+ }
+ else
+ return 2;
+}
+
+static const gdb_byte *
+sh64_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
+{
+ *size = kind;
+
+ /* The BRK instruction for shmedia is
01101111 11110101 11111111 11110000
which translates in big endian mode to 0x6f, 0xf5, 0xff, 0xf0
and in little endian mode to 0xf0, 0xff, 0xf5, 0x6f */
which translates in big endian mode to 0x0, 0x3b
and in little endian mode to 0x3b, 0x0 */
- if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+ if (kind == 4)
{
- if (pc_is_isa32 (*pcptr))
- {
- static unsigned char big_breakpoint_media[] = {
- 0x6f, 0xf5, 0xff, 0xf0
- };
- *pcptr = UNMAKE_ISA32_ADDR (*pcptr);
- *lenptr = sizeof (big_breakpoint_media);
- return big_breakpoint_media;
- }
+ static unsigned char big_breakpoint_media[] = {
+ 0x6f, 0xf5, 0xff, 0xf0
+ };
+ static unsigned char little_breakpoint_media[] = {
+ 0xf0, 0xff, 0xf5, 0x6f
+ };
+
+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+ return big_breakpoint_media;
else
- {
- static unsigned char big_breakpoint_compact[] = {0x0, 0x3b};
- *lenptr = sizeof (big_breakpoint_compact);
- return big_breakpoint_compact;
- }
+ return little_breakpoint_media;
}
else
{
- if (pc_is_isa32 (*pcptr))
- {
- static unsigned char little_breakpoint_media[] = {
- 0xf0, 0xff, 0xf5, 0x6f
- };
- *pcptr = UNMAKE_ISA32_ADDR (*pcptr);
- *lenptr = sizeof (little_breakpoint_media);
- return little_breakpoint_media;
- }
+ static unsigned char big_breakpoint_compact[] = {0x0, 0x3b};
+ static unsigned char little_breakpoint_compact[] = {0x3b, 0x0};
+
+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+ return big_breakpoint_compact;
else
- {
- static unsigned char little_breakpoint_compact[] = {0x3b, 0x0};
- *lenptr = sizeof (little_breakpoint_compact);
- return little_breakpoint_compact;
- }
+ return little_breakpoint_compact;
}
}
+GDBARCH_BREAKPOINT_FROM_PC (sh64)
+
/* Prologue looks like
[mov.l <regs>,@-r15]...
[sts.l pr,@-r15]
set_gdbarch_pseudo_register_read (gdbarch, sh64_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, sh64_pseudo_register_write);
- set_gdbarch_breakpoint_from_pc (gdbarch, sh64_breakpoint_from_pc);
+ SET_GDBARCH_BREAKPOINT_MANIPULATION (sh64);
set_gdbarch_print_insn (gdbarch, print_insn_sh);
set_gdbarch_register_sim_regno (gdbarch, legacy_register_sim_regno);
NULL);
}
-/* This is the implementation of gdbarch method breakpiont_from_pc. */
+static int
+tic6x_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
+{
+ return 4;
+}
static const gdb_byte *
-tic6x_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
- int *bp_size)
+tic6x_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- *bp_size = 4;
+ *size = kind;
if (tdep == NULL || tdep->breakpoint == NULL)
{
return tdep->breakpoint;
}
+/* This is the implementation of gdbarch method breakpiont_from_pc. */
+
+GDBARCH_BREAKPOINT_FROM_PC (tic6x)
+
/* This is the implementation of gdbarch method print_insn. */
static int
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
set_gdbarch_skip_prologue (gdbarch, tic6x_skip_prologue);
- set_gdbarch_breakpoint_from_pc (gdbarch, tic6x_breakpoint_from_pc);
+ SET_GDBARCH_BREAKPOINT_MANIPULATION (tic6x);
set_gdbarch_unwind_pc (gdbarch, tic6x_unwind_pc);
set_gdbarch_unwind_sp (gdbarch, tic6x_unwind_sp);
return RETURN_VALUE_REGISTER_CONVENTION;
}
-static const unsigned char *
-v850_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
- int *lenptr)
+static int
+v850_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
- *lenptr = 2;
+ return 2;
+}
- switch (gdbarch_bfd_arch_info (gdbarch)->mach)
+static const gdb_byte *
+v850_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
+{
+ *size = kind;
+
+ switch (gdbarch_bfd_arch_info (gdbarch)->mach)
{
case bfd_mach_v850e2:
case bfd_mach_v850e2v3:
}
}
+GDBARCH_BREAKPOINT_FROM_PC (v850)
+
static struct v850_frame_cache *
v850_alloc_frame_cache (struct frame_info *this_frame)
{
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_breakpoint_from_pc (gdbarch, v850_breakpoint_from_pc);
+ SET_GDBARCH_BREAKPOINT_MANIPULATION (v850);
set_gdbarch_return_value (gdbarch, v850_return_value);
set_gdbarch_push_dummy_call (gdbarch, v850_push_dummy_call);
set_gdbarch_skip_prologue (gdbarch, v850_skip_prologue);
return sp + SP_ALIGNMENT;
}
+static int
+xtensa_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
+{
+ if (gdbarch_tdep (gdbarch)->isa_use_density_instructions)
+ return 2;
+ else
+ return 4;
+}
/* Return a breakpoint for the current location of PC. We always use
the density version if we have density instructions (regardless of the
#define DENSITY_BIG_BREAKPOINT { 0xd2, 0x0f }
#define DENSITY_LITTLE_BREAKPOINT { 0x2d, 0xf0 }
-static const unsigned char *
-xtensa_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
- int *lenptr)
+static const gdb_byte *
+xtensa_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
{
- static unsigned char big_breakpoint[] = BIG_BREAKPOINT;
- static unsigned char little_breakpoint[] = LITTLE_BREAKPOINT;
- static unsigned char density_big_breakpoint[] = DENSITY_BIG_BREAKPOINT;
- static unsigned char density_little_breakpoint[] = DENSITY_LITTLE_BREAKPOINT;
+ *size = kind;
- DEBUGTRACE ("xtensa_breakpoint_from_pc (pc = 0x%08x)\n", (int) *pcptr);
-
- if (gdbarch_tdep (gdbarch)->isa_use_density_instructions)
+ if (kind == 4)
{
+ static unsigned char big_breakpoint[] = BIG_BREAKPOINT;
+ static unsigned char little_breakpoint[] = LITTLE_BREAKPOINT;
+
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
- {
- *lenptr = sizeof (density_big_breakpoint);
- return density_big_breakpoint;
- }
+ return big_breakpoint;
else
- {
- *lenptr = sizeof (density_little_breakpoint);
- return density_little_breakpoint;
- }
+ return little_breakpoint;
}
else
{
+ static unsigned char density_big_breakpoint[] = DENSITY_BIG_BREAKPOINT;
+ static unsigned char density_little_breakpoint[]
+ = DENSITY_LITTLE_BREAKPOINT;
+
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
- {
- *lenptr = sizeof (big_breakpoint);
- return big_breakpoint;
- }
+ return density_big_breakpoint;
else
- {
- *lenptr = sizeof (little_breakpoint);
- return little_breakpoint;
- }
+ return density_little_breakpoint;
}
}
+GDBARCH_BREAKPOINT_FROM_PC (xtensa)
+
/* Call0 ABI support routines. */
/* Return true, if PC points to "ret" or "ret.n". */
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
/* Set breakpoints. */
- set_gdbarch_breakpoint_from_pc (gdbarch, xtensa_breakpoint_from_pc);
+ SET_GDBARCH_BREAKPOINT_MANIPULATION (xtensa);
/* After breakpoint instruction or illegal instruction, pc still
points at break instruction, so don't decrement. */