Split breakpoint_from_pc to breakpoint_kind_from_pc and sw_breakpoint_from_kind
authorYao Qi <yao.qi@linaro.org>
Thu, 3 Nov 2016 14:35:13 +0000 (14:35 +0000)
committerYao Qi <yao.qi@linaro.org>
Thu, 3 Nov 2016 14:35:13 +0000 (14:35 +0000)
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  <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.

18 files changed:
gdb/ChangeLog
gdb/arc-tdep.c
gdb/arch-utils.h
gdb/arm-tdep.c
gdb/bfin-tdep.c
gdb/cris-tdep.c
gdb/iq2000-tdep.c
gdb/m32r-tdep.c
gdb/mips-tdep.c
gdb/mt-tdep.c
gdb/nios2-tdep.c
gdb/rs6000-tdep.c
gdb/score-tdep.c
gdb/sh-tdep.c
gdb/sh64-tdep.c
gdb/tic6x-tdep.c
gdb/v850-tdep.c
gdb/xtensa-tdep.c

index f4f3e8b20120479f81ddfac629f6eab0398e8673..22cbedbf551bff592a01dbc19c5253b4c50dfc05 100644 (file)
@@ -1,3 +1,33 @@
+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.
index c848dc294e5a5a651ba4a13fa5ac812816894a14..fe8d38d082fe7a5a600a63b5e57cddc08a397b45 100644 (file)
@@ -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
@@ -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);
 
@@ -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
@@ -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))
index 5bf6da5fa6273a6bf61eba98b0a40d24a0aa5451..2ccf19180855f074809a6e9ad51387e55a3cf818 100644 (file)
@@ -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,                \
@@ -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.
index 645825f74262fafe3a0ebe6b3d349fcff06be46d..183c36567d854f4829909be8e7cfe79bc90c6a48 100644 (file)
@@ -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);
@@ -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
@@ -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);
 
index d07bf6e795df1c679a1edffbeb369d462e584683..d89599738e4ef0bd6114d23bcd85e67905087a51 100644 (file)
@@ -568,28 +568,28 @@ 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;
@@ -597,6 +597,14 @@ bfin_breakpoint_from_pc (struct gdbarch *gdbarch,
     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,
@@ -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);
index 1d2952472b4bb3cbbc7124b3addc137b75e94f70..bee95cfc702b3bff01a14adfb7c13ac9b940fa33 100644 (file)
@@ -1391,20 +1391,20 @@ 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;
@@ -1412,6 +1412,14 @@ cris_breakpoint_from_pc (struct gdbarch *gdbarch,
     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.  */
 
@@ -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);
index 600d70a15f87317e71ce10089e561af8aa047043..ecd90747846aae186ba99b351d2a675f0cf7e65a 100644 (file)
@@ -469,22 +469,29 @@ static const struct frame_base iq2000_frame_base = {
   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
@@ -826,7 +833,7 @@ iq2000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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);
index 8e1d79e51286081eb8cbcbfefe26f4da9927cb33..2ca89401a76e3e1186ad6fe207247929f3cd63d7 100644 (file)
@@ -165,9 +165,17 @@ m32r_memory_remove_breakpoint (struct gdbarch *gdbarch,
   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
@@ -175,39 +183,22 @@ m32r_breakpoint_from_pc (struct gdbarch *gdbarch,
   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",
@@ -929,7 +920,7 @@ m32r_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   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,
index 627b9c0d342a39935a9c8a1121647d1c3f341641..aaf7872d43de0724224cbdae176f82fac3a6b33f 100644 (file)
@@ -7035,113 +7035,105 @@ gdb_print_insn_mips_n64 (bfd_vma memaddr, struct disassemble_info *info)
   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
index 5d7f31cda5ac00ac08e305935c0e0a2539e09489..0adf413c74b820a79a16d6979206ec74ce958c91 100644 (file)
@@ -449,26 +449,33 @@ mt_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
   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.  */
 
@@ -1162,7 +1169,7 @@ mt_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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);
index 3ff325fe0e37cef34caa6fd255a68560a450db5e..57fd331fc05a4ac73a8dfc8708b62c0d88c13dc1 100644 (file)
@@ -1694,9 +1694,30 @@ nios2_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
   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)."
@@ -1704,54 +1725,53 @@ nios2_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
    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
@@ -2316,7 +2336,7 @@ nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   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);
index ca4d66863e2df34d73e15ae06abfb8aed7a60bc4..7cb7a9ea612c8ca7b0f2fe331fb314a5c2f88115 100644 (file)
@@ -967,18 +967,11 @@ rs6000_fetch_pointer_argument (struct frame_info *frame, int argi,
 
 /* 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
@@ -6486,7 +6479,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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.  */
index 8e08d0553283df3caa0aee8c316eecd6d4bdf732..c325d48cd8ceb9e7c358e38dc27eb298f21f9ba9 100644 (file)
@@ -306,69 +306,82 @@ score3_adjust_pc_and_fetch_inst (CORE_ADDR *pcptr, int *lenptr,
   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 },
@@ -379,20 +392,14 @@ score3_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
     { 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)
 {
@@ -1485,7 +1492,7 @@ score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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);
@@ -1497,7 +1504,7 @@ score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       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);
index 12aedbbbe628d6d33b9226dacbf5f8246a5361b7..6100d922f26a066425e58abbe1e1437b13e64c04 100644 (file)
@@ -418,11 +418,16 @@ sh_sh4al_dsp_register_name (struct gdbarch *gdbarch, int reg_nr)
   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)
@@ -431,21 +436,22 @@ sh_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
       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
@@ -2274,7 +2280,7 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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);
index f51186ac68b80c6c1978bc1b4b2ad695715d00d6..97e5a587f1eadb533a30ffaf5ec124c040461244 100644 (file)
@@ -253,11 +253,24 @@ pc_is_isa32 (bfd_vma memaddr)
     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 */
@@ -267,44 +280,34 @@ sh64_breakpoint_from_pc (struct gdbarch *gdbarch,
      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]
@@ -2410,7 +2413,7 @@ sh64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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);
index adb7f5054651ad5e0ca751f2e2c955798bcebf6d..995794730043de28be96d22c89cf30329b9bd144 100644 (file)
@@ -318,15 +318,18 @@ tic6x_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
                                 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)
     {
@@ -339,6 +342,10 @@ tic6x_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
     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
@@ -1295,7 +1302,7 @@ tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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);
index d03334e17eac66d1be0ca7ba0c1331908fea28fc..9cc1b8b396a2eea9b43efbd36ef40d176489b46b 100644 (file)
@@ -1168,13 +1168,18 @@ v850_return_value (struct gdbarch *gdbarch, struct value *function,
   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:
@@ -1199,6 +1204,8 @@ v850_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
     }
 }
 
+GDBARCH_BREAKPOINT_FROM_PC (v850)
+
 static struct v850_frame_cache *
 v850_alloc_frame_cache (struct frame_info *this_frame)
 {
@@ -1448,7 +1455,7 @@ v850_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   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);
index aafb1757322ed94a41957140822aa7605077b3a5..90da611e9d3152c7e218d2f4231dfd0949d1708c 100644 (file)
@@ -1959,6 +1959,14 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
   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
@@ -1969,45 +1977,36 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
 #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".  */ 
@@ -3239,7 +3238,7 @@ xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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.  */