static const char *arm_fallback_mode_string = "auto";
static const char *arm_force_mode_string = "auto";
-/* Internal override of the execution mode. -1 means no override,
- 0 means override to ARM mode, 1 means override to Thumb mode.
- The effect is the same as if arm_force_mode has been set by the
- user (except the internal override has precedence over a user's
- arm_force_mode override). */
-static int arm_override_mode = -1;
-
/* Number of different reg name sets (options). */
static int num_disassembly_options;
if (IS_THUMB_ADDR (memaddr))
return 1;
- /* Respect internal mode override if active. */
- if (arm_override_mode != -1)
- return arm_override_mode;
-
/* If the user wants to override the symbol table, let him. */
if (strcmp (arm_force_mode_string, "arm") == 0)
return 0;
&d, dbl);
}
-/* Like insert_single_step_breakpoint, but make sure we use a breakpoint
- of the appropriate mode (as encoded in the PC value), even if this
- differs from what would be expected according to the symbol tables. */
-
-void
-arm_insert_single_step_breakpoint (struct gdbarch *gdbarch,
- struct address_space *aspace,
- CORE_ADDR pc)
-{
- scoped_restore save_override_mode
- = make_scoped_restore (&arm_override_mode,
- (int) IS_THUMB_ADDR (pc));
- pc = gdbarch_addr_bits_remove (gdbarch, pc);
-
- insert_single_step_breakpoint (gdbarch, aspace, pc);
-}
-
/* Given BUF, which is OLD_LEN bytes ending at ENDADDR, expand
the buffer to be NEW_LEN bytes ending at ENDADDR. Return
NULL if an error occurs. BUF is freed. */
next_pcs = arm_get_next_pcs (&next_pcs_ctx);
for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); i++)
- arm_insert_single_step_breakpoint (gdbarch, aspace, pc);
+ {
+ pc = gdbarch_addr_bits_remove (gdbarch, pc);
+ insert_single_step_breakpoint (gdbarch, aspace, pc);
+ }
do_cleanups (old_chain);
}
}
-/* 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. */
+/* Implement the breakpoint_kind_from_current_state gdbarch method. */
-GDBARCH_BREAKPOINT_FROM_PC (arm)
-
-static void
-arm_remote_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
- int *kindptr)
+static int
+arm_breakpoint_kind_from_current_state (struct gdbarch *gdbarch,
+ struct regcache *regcache,
+ CORE_ADDR *pcptr)
{
+ gdb_byte buf[4];
+
+ /* Check the memory pointed by PC is readable. */
+ if (target_read_memory (regcache_read_pc (regcache), buf, 4) == 0)
+ {
+ struct arm_get_next_pcs next_pcs_ctx;
+ CORE_ADDR pc;
+ int i;
+ VEC (CORE_ADDR) *next_pcs = NULL;
+ struct cleanup *old_chain
+ = make_cleanup (VEC_cleanup (CORE_ADDR), &next_pcs);
+
+ arm_get_next_pcs_ctor (&next_pcs_ctx,
+ &arm_get_next_pcs_ops,
+ gdbarch_byte_order (gdbarch),
+ gdbarch_byte_order_for_code (gdbarch),
+ 0,
+ regcache);
+
+ next_pcs = arm_get_next_pcs (&next_pcs_ctx);
+
+ /* If MEMADDR is the next instruction of current pc, do the
+ software single step computation, and get the thumb mode by
+ the destination address. */
+ for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); i++)
+ {
+ if (UNMAKE_THUMB_ADDR (pc) == *pcptr)
+ {
+ do_cleanups (old_chain);
+
+ if (IS_THUMB_ADDR (pc))
+ {
+ *pcptr = MAKE_THUMB_ADDR (*pcptr);
+ return arm_breakpoint_kind_from_pc (gdbarch, pcptr);
+ }
+ else
+ return ARM_BP_KIND_ARM;
+ }
+ }
+
+ do_cleanups (old_chain);
+ }
- *kindptr = arm_breakpoint_kind_from_pc (gdbarch, pcptr);
+ return 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_MANIPULATION (arm);
- set_gdbarch_remote_breakpoint_from_pc (gdbarch,
- arm_remote_breakpoint_from_pc);
+ set_gdbarch_breakpoint_kind_from_pc (gdbarch, arm_breakpoint_kind_from_pc);
+ set_gdbarch_sw_breakpoint_from_kind (gdbarch, arm_sw_breakpoint_from_kind);
+ set_gdbarch_breakpoint_kind_from_current_state (gdbarch,
+ arm_breakpoint_kind_from_current_state);
/* Information about registers, etc. */
set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM);