#define SC_OPCODE 0x38
#define SCD_OPCODE 0x3c
-static int
-mips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
- struct address_space *aspace, CORE_ADDR pc)
+static VEC (CORE_ADDR) *
+mips_deal_with_atomic_sequence (struct gdbarch *gdbarch, CORE_ADDR pc)
{
CORE_ADDR breaks[2] = {-1, -1};
CORE_ADDR loc = pc;
int index;
int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */
const int atomic_sequence_length = 16; /* Instruction sequence length. */
+ VEC (CORE_ADDR) *next_pcs = NULL;
insn = mips_fetch_instruction (gdbarch, ISA_MIPS, loc, NULL);
/* Assume all atomic sequences start with a ll/lld instruction. */
if (itype_op (insn) != LL_OPCODE && itype_op (insn) != LLD_OPCODE)
- return 0;
+ return NULL;
/* Assume that no atomic sequence is longer than "atomic_sequence_length"
instructions. */
/* Assume that the atomic sequence ends with a sc/scd instruction. */
if (itype_op (insn) != SC_OPCODE && itype_op (insn) != SCD_OPCODE)
- return 0;
+ return NULL;
loc += MIPS_INSN32_SIZE;
/* Effectively inserts the breakpoints. */
for (index = 0; index <= last_breakpoint; index++)
- insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
+ VEC_safe_push (CORE_ADDR, next_pcs, breaks[index]);
- return 1;
+ return next_pcs;
}
-static int
+static VEC (CORE_ADDR) *
micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
- struct address_space *aspace,
CORE_ADDR pc)
{
const int atomic_sequence_length = 16; /* Instruction sequence length. */
ULONGEST insn;
int insn_count;
int index;
+ VEC (CORE_ADDR) *next_pcs = NULL;
/* Assume all atomic sequences start with a ll/lld instruction. */
insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, loc, NULL);
if (micromips_op (insn) != 0x18) /* POOL32C: bits 011000 */
- return 0;
+ return NULL;
loc += MIPS_INSN16_SIZE;
insn <<= 16;
insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS, loc, NULL);
if ((b12s4_op (insn) & 0xb) != 0x3) /* LL, LLD: bits 011000 0x11 */
- return 0;
+ return NULL;
loc += MIPS_INSN16_SIZE;
/* Assume all atomic sequences end with an sc/scd instruction. Assume
&& b5s5_op (insn) != 0x18)
/* JRADDIUSP: bits 010001 11000 */
break;
- return 0; /* Fall back to the standard single-step code. */
+ return NULL; /* Fall back to the standard single-step code. */
case 0x33: /* B16: bits 110011 */
- return 0; /* Fall back to the standard single-step code. */
+ return NULL; /* Fall back to the standard single-step code. */
}
break;
}
if (is_branch)
{
if (last_breakpoint >= 1)
- return 0; /* More than one branch found, fallback to the
+ return NULL; /* More than one branch found, fallback to the
standard single-step code. */
breaks[1] = branch_bp;
last_breakpoint++;
}
}
if (!sc_found)
- return 0;
+ return NULL;
/* Insert a breakpoint right after the end of the atomic sequence. */
breaks[0] = loc;
/* Effectively inserts the breakpoints. */
for (index = 0; index <= last_breakpoint; index++)
- insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
+ VEC_safe_push (CORE_ADDR, next_pcs, breaks[index]);
- return 1;
+ return next_pcs;
}
-static int
-deal_with_atomic_sequence (struct gdbarch *gdbarch,
- struct address_space *aspace, CORE_ADDR pc)
+static VEC (CORE_ADDR) *
+deal_with_atomic_sequence (struct gdbarch *gdbarch, CORE_ADDR pc)
{
if (mips_pc_is_mips (pc))
- return mips_deal_with_atomic_sequence (gdbarch, aspace, pc);
+ return mips_deal_with_atomic_sequence (gdbarch, pc);
else if (mips_pc_is_micromips (gdbarch, pc))
- return micromips_deal_with_atomic_sequence (gdbarch, aspace, pc);
+ return micromips_deal_with_atomic_sequence (gdbarch, pc);
else
- return 0;
+ return NULL;
}
/* mips_software_single_step() is called just before we want to resume
or kernel single-step support (MIPS on GNU/Linux for example). We find
the target of the coming instruction and breakpoint it. */
-int
+VEC (CORE_ADDR) *
mips_software_single_step (struct frame_info *frame)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
- struct address_space *aspace = get_frame_address_space (frame);
CORE_ADDR pc, next_pc;
+ VEC (CORE_ADDR) *next_pcs;
pc = get_frame_pc (frame);
- if (deal_with_atomic_sequence (gdbarch, aspace, pc))
- return 1;
+ next_pcs = deal_with_atomic_sequence (gdbarch, pc);
+ if (next_pcs != NULL)
+ return next_pcs;
next_pc = mips_next_pc (frame, pc);
- insert_single_step_breakpoint (gdbarch, aspace, next_pc);
- return 1;
+ VEC_safe_push (CORE_ADDR, next_pcs, next_pc);
+ return next_pcs;
}
/* Test whether the PC points to the return instruction at the
return gdb_print_insn_mips (memaddr, info);
}
+/* Implement the breakpoint_kind_from_pc gdbarch method. */
+
static int
mips_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
return MIPS_BP_KIND_MIPS32;
}
+/* Implement the sw_breakpoint_from_kind gdbarch method. */
+
static const gdb_byte *
mips_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
{
};
}
-/* 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)
-{
- *kindptr = mips_breakpoint_kind_from_pc (gdbarch, pcptr);
-}
-
/* Return non-zero if the standard MIPS instruction INST has a branch
delay slot (i.e. it is a jump or branch instruction). This function
is based on mips32_next_pc. */
set_gdbarch_value_to_register (gdbarch, mips_value_to_register);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- SET_GDBARCH_BREAKPOINT_MANIPULATION (mips);
- set_gdbarch_remote_breakpoint_from_pc (gdbarch,
- mips_remote_breakpoint_from_pc);
+ set_gdbarch_breakpoint_kind_from_pc (gdbarch, mips_breakpoint_kind_from_pc);
+ set_gdbarch_sw_breakpoint_from_kind (gdbarch, mips_sw_breakpoint_from_kind);
set_gdbarch_adjust_breakpoint_address (gdbarch,
mips_adjust_breakpoint_address);