Skip to content
This repository has been archived by the owner on Aug 17, 2022. It is now read-only.

Commit

Permalink
Split breakpoint_from_pc to breakpoint_kind_from_pc and sw_breakpoint…
Browse files Browse the repository at this point in the history
…_from_kind

We convert each ARCH_breakpoint_from_pc to ARCH_breakpoint_kind_from_pc
and ARCH_sw_breakpoint_from_kind.  Note that gdbarch doesn't have methods
breakpoint_kind_from_pc and sw_breakpoint_from_kind so far.

gdb:

2016-11-03  Yao Qi  <[email protected]>

	* 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.
  • Loading branch information
Yao Qi committed Nov 3, 2016
1 parent 44f1c4d commit d19280a
Show file tree
Hide file tree
Showing 18 changed files with 522 additions and 386 deletions.
30 changes: 30 additions & 0 deletions gdb/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
2016-11-03 Yao Qi <[email protected]>

* 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 <[email protected]>

* mips-tdep.c (mips_breakpoint_kind): New enum.
Expand Down
34 changes: 21 additions & 13 deletions gdb/arc-tdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,9 +715,7 @@ static const gdb_byte arc_brk_s_le[] = { 0xff, 0x7f };
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
Expand All @@ -734,15 +732,12 @@ static const gdb_byte arc_brk_le[] = { 0x6f, 0x25, 0x3f, 0x00 };
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);

Expand All @@ -751,21 +746,34 @@ arc_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *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
Expand Down Expand Up @@ -1229,7 +1237,7 @@ arc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
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))
Expand Down
28 changes: 28 additions & 0 deletions gdb/arch-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ struct minimal_symbol;
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, \
Expand All @@ -39,6 +50,23 @@ struct gdbarch_info;
#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.
Expand Down
61 changes: 38 additions & 23 deletions gdb/arm-tdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -7843,16 +7843,8 @@ static const gdb_byte arm_default_arm_be_breakpoint[] = ARM_BE_BREAKPOINT;
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);
Expand All @@ -7866,38 +7858,61 @@ arm_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
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
Expand Down Expand Up @@ -9407,7 +9422,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
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);

Expand Down
36 changes: 22 additions & 14 deletions gdb/bfin-tdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -568,35 +568,43 @@ bfin_reg_to_regnum (struct gdbarch *gdbarch, int reg)
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;
else
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,
Expand Down Expand Up @@ -826,7 +834,7 @@ bfin_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
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);
Expand Down
28 changes: 18 additions & 10 deletions gdb/cris-tdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -1391,27 +1391,35 @@ cris_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
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;
else
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. */

Expand Down Expand Up @@ -4123,7 +4131,7 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* 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);
Expand Down
Loading

0 comments on commit d19280a

Please sign in to comment.