]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
*** empty log message ***
authorJim Blandy <jimb@codesourcery.com>
Tue, 10 Jun 2003 17:40:22 +0000 (17:40 +0000)
committerJim Blandy <jimb@codesourcery.com>
Tue, 10 Jun 2003 17:40:22 +0000 (17:40 +0000)
gdb/ppc-linux-tdep.c

index 5f6bb604a3c07566577efc31e95427cb8c65ab9b..78c90fdb1554393c0bbf3893ad84bd9ae1833564 100644 (file)
@@ -685,11 +685,10 @@ struct insn_pattern
 
    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,
@@ -731,6 +730,16 @@ insn_ds_field (unsigned int insn)
 }
 
 
+/* 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.  */
@@ -865,7 +874,7 @@ ppc64_standard_linkage_target (CORE_ADDR pc, unsigned int *insn)
        + 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);
 }
 
 
@@ -884,6 +893,18 @@ ppc64_skip_trampoline_code (CORE_ADDR pc)
 }
 
 
+/* 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,
@@ -995,13 +1016,22 @@ ppc_linux_init_abi (struct gdbarch_info info,
 
       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