return 0;
}
-/* Implementation of gdbarch_in_function_epilogue_p. */
+/* Implement the stack_frame_destroyed_p gdbarch method. */
static int
-rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+rs6000_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
return rs6000_in_function_epilogue_frame_p (get_current_frame (),
gdbarch, pc);
#define BXL_INSN 0x4c000000
#define BP_INSN 0x7C000008
+/* Instruction masks used during single-stepping of atomic
+ sequences. */
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7c000028
+#define LDARX_INSTRUCTION 0x7c0000A8
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define STDCX_INSTRUCTION 0x7c0001ad
+
+/* We can't displaced step atomic sequences. Otherwise this is just
+ like simple_displaced_step_copy_insn. */
+
+static struct displaced_step_closure *
+ppc_displaced_step_copy_insn (struct gdbarch *gdbarch,
+ CORE_ADDR from, CORE_ADDR to,
+ struct regcache *regs)
+{
+ size_t len = gdbarch_max_insn_length (gdbarch);
+ gdb_byte *buf = xmalloc (len);
+ struct cleanup *old_chain = make_cleanup (xfree, buf);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ int insn;
+
+ read_memory (from, buf, len);
+
+ insn = extract_signed_integer (buf, PPC_INSN_SIZE, byte_order);
+
+ /* Assume all atomic sequences start with a lwarx/ldarx instruction. */
+ if ((insn & LWARX_MASK) == LWARX_INSTRUCTION
+ || (insn & LWARX_MASK) == LDARX_INSTRUCTION)
+ {
+ if (debug_displaced)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "displaced: can't displaced step "
+ "atomic sequence at %s\n",
+ paddress (gdbarch, from));
+ }
+ do_cleanups (old_chain);
+ return NULL;
+ }
+
+ write_memory (to, buf, len);
+
+ if (debug_displaced)
+ {
+ fprintf_unfiltered (gdb_stdlog, "displaced: copy %s->%s: ",
+ paddress (gdbarch, from), paddress (gdbarch, to));
+ displaced_step_dump_bytes (gdb_stdlog, buf, len);
+ }
+
+ discard_cleanups (old_chain);
+ return (struct displaced_step_closure *) buf;
+}
+
/* Fix up the state of registers and memory after having single-stepped
a displaced instruction. */
static void
struct regcache *regs)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- /* Since we use simple_displaced_step_copy_insn, our closure is a
- copy of the instruction. */
+ /* Our closure is a copy of the instruction. */
ULONGEST insn = extract_unsigned_integer ((gdb_byte *) closure,
PPC_INSN_SIZE, byte_order);
ULONGEST opcode = 0;
return 1;
}
-/* Instruction masks used during single-stepping of atomic sequences. */
-#define LWARX_MASK 0xfc0007fe
-#define LWARX_INSTRUCTION 0x7c000028
-#define LDARX_INSTRUCTION 0x7c0000A8
-#define STWCX_MASK 0xfc0007ff
-#define STWCX_INSTRUCTION 0x7c00012d
-#define STDCX_INSTRUCTION 0x7c0001ad
-
/* Checks for an atomic sequence of instructions beginning with a LWARX/LDARX
instruction and ending with a STWCX/STDCX instruction. If such a sequence
is found, attempt to step through it. A breakpoint is placed at the end of
rs6000_in_solib_return_trampoline (struct gdbarch *gdbarch,
CORE_ADDR pc, const char *name)
{
- return name && !strncmp (name, "@FIX", 4);
+ return name && startswith (name, "@FIX");
}
/* Skip code that the user doesn't want to see when stepping:
static struct rs6000_frame_cache *
rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
{
- volatile struct gdb_exception ex;
struct rs6000_frame_cache *cache;
struct gdbarch *gdbarch = get_frame_arch (this_frame);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
(*this_cache) = cache;
cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
- TRY_CATCH (ex, RETURN_MASK_ERROR)
+ TRY
{
/* At this point the stack looks as if we just entered the
function, and the return address is stored in LR. */
trad_frame_set_value (cache->saved_regs,
gdbarch_pc_regnum (gdbarch), lr);
}
- if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
- throw_exception (ex);
+ CATCH (ex, RETURN_MASK_ERROR)
+ {
+ if (ex.error != NOT_AVAILABLE_ERROR)
+ throw_exception (ex);
+ }
+ END_CATCH
return cache;
}
set_gdbarch_push_dummy_call (gdbarch, ppc64_sysv_abi_push_dummy_call);
set_gdbarch_skip_prologue (gdbarch, rs6000_skip_prologue);
- set_gdbarch_in_function_epilogue_p (gdbarch, rs6000_in_function_epilogue_p);
+ set_gdbarch_stack_frame_destroyed_p (gdbarch, rs6000_stack_frame_destroyed_p);
set_gdbarch_skip_main_prologue (gdbarch, rs6000_skip_main_prologue);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
/* Setup displaced stepping. */
set_gdbarch_displaced_step_copy_insn (gdbarch,
- simple_displaced_step_copy_insn);
+ ppc_displaced_step_copy_insn);
set_gdbarch_displaced_step_hw_singlestep (gdbarch,
ppc_displaced_step_hw_singlestep);
set_gdbarch_displaced_step_fixup (gdbarch, ppc_displaced_step_fixup);
struct cmd_list_element *c)
{
struct gdbarch_info info;
- enum powerpc_vector_abi vector_abi;
+ int vector_abi;
for (vector_abi = POWERPC_VEC_AUTO;
vector_abi != POWERPC_VEC_LAST;
if (strcmp (powerpc_vector_abi_string,
powerpc_vector_strings[vector_abi]) == 0)
{
- powerpc_vector_abi_global = vector_abi;
+ powerpc_vector_abi_global = (enum powerpc_vector_abi) vector_abi;
break;
}