When the match is successful, fill INSN[i] with what PATTERN[i]
matched. If PATTERN[i] is optional, and the instruction wasn't
- present, set INSN[i] to 0 (an invalid instruction on the PPC).
- INSN should have as many elements as PATTERN. Note that, if
- PATTERN contains optional instructions which aren't present in
- memory, then INSN will have holes, so INSN[i] isn't necessarily the
- i'th instruction in memory. */
+ present, set INSN[i] to -1. INSN should have as many elements as
+ PATTERN. Note that, if PATTERN contains optional instructions
+ which aren't present in memory, then INSN will have holes, so
+ INSN[i] isn't necessarily the i'th instruction in memory. */
static int
insns_match_pattern (CORE_ADDR pc,
struct insn_pattern *pattern,
}
+/* If DESC is the address of a 64-bit PowerPC Linux function
+ descriptor, return the descriptor's entry point. */
+static CORE_ADDR
+ppc64_desc_entry_point (CORE_ADDR desc)
+{
+ /* The first word of the descriptor is the entry point. */
+ return (CORE_ADDR) read_memory_unsigned_integer (desc, 8);
+}
+
+
/* Pattern for the standard linkage function. These are built by
build_plt_stub in elf64-ppc.c, whose GLINK argument is always
zero. */
+ insn_ds_field (insn[2]));
/* The first word of the descriptor is the entry point. Return that. */
- return (CORE_ADDR) read_memory_unsigned_integer (desc, 8);
+ return ppc64_desc_entry_point (desc);
}
}
+/* On 64-bit PowerPC Linux, the ELF header's e_entry field is the
+ address of a function descriptor for the entry point function, not
+ the actual entry point itself. So to find the actual address at
+ which execution should begin, we need to fetch the function's entry
+ point from that descriptor. */
+static CORE_ADDR
+ppc64_call_dummy_address (void)
+{
+ return ppc64_desc_entry_point (entry_point_address ());
+}
+
+
enum {
ELF_NGREG = 48,
ELF_NFPREG = 33,
set_gdbarch_memory_remove_breakpoint (gdbarch,
ppc_linux_memory_remove_breakpoint);
+ /* Shared library handling. */
+ set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
+ set_gdbarch_skip_trampoline_code (gdbarch,
+ ppc_linux_skip_trampoline_code);
set_solib_svr4_fetch_link_map_offsets
(gdbarch, ppc_linux_svr4_fetch_link_map_offsets);
}
+
+ if (tdep->wordsize == 8)
+ {
+ set_gdbarch_call_dummy_address (gdbarch, ppc64_call_dummy_address);
- /* Shared library handling. */
- set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
- set_gdbarch_skip_trampoline_code (gdbarch, ppc_linux_skip_trampoline_code);
+ set_gdbarch_in_solib_call_trampoline
+ (gdbarch, ppc64_in_solib_call_trampoline);
+ set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);
+ }
}
void