2009-06-23 Sami Wagiaalla <swagiaal@redhat.com>
[deliverable/binutils-gdb.git] / gdb / ppc-linux-tdep.c
index ccf40855c7f7c11118167e0da9c981533ec6d845..2bb88b36cebd8ef05e3734f861101861082f4faf 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-dependent code for GDB, the GNU debugger.
 
    Copyright (C) 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
    This file is part of GDB.
 #include "features/rs6000/powerpc-32l.c"
 #include "features/rs6000/powerpc-altivec32l.c"
 #include "features/rs6000/powerpc-vsx32l.c"
+#include "features/rs6000/powerpc-isa205-32l.c"
+#include "features/rs6000/powerpc-isa205-altivec32l.c"
+#include "features/rs6000/powerpc-isa205-vsx32l.c"
 #include "features/rs6000/powerpc-64l.c"
 #include "features/rs6000/powerpc-altivec64l.c"
 #include "features/rs6000/powerpc-vsx64l.c"
+#include "features/rs6000/powerpc-isa205-64l.c"
+#include "features/rs6000/powerpc-isa205-altivec64l.c"
+#include "features/rs6000/powerpc-isa205-vsx64l.c"
 #include "features/rs6000/powerpc-e500l.c"
 
 
    else in the event that some other platform has similar needs with
    regard to removing breakpoints in some potentially self modifying
    code.  */
-int
+static int
 ppc_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
                                    struct bp_target_info *bp_tgt)
 {
@@ -491,7 +497,7 @@ ppc64_standard_linkage1_target (struct frame_info *frame,
   return ppc64_desc_entry_point (desc);
 }
 
-static struct core_regset_section ppc_linux_regset_sections[] =
+static struct core_regset_section ppc_linux_vsx_regset_sections[] =
 {
   { ".reg", 268 },
   { ".reg2", 264 },
@@ -500,6 +506,21 @@ static struct core_regset_section ppc_linux_regset_sections[] =
   { NULL, 0}
 };
 
+static struct core_regset_section ppc_linux_vmx_regset_sections[] =
+{
+  { ".reg", 268 },
+  { ".reg2", 264 },
+  { ".reg-ppc-vmx", 544 },
+  { NULL, 0}
+};
+
+static struct core_regset_section ppc_linux_fp_regset_sections[] =
+{
+  { ".reg", 268 },
+  { ".reg2", 264 },
+  { NULL, 0}
+};
+
 static CORE_ADDR
 ppc64_standard_linkage2_target (struct frame_info *frame,
                                CORE_ADDR pc, unsigned int *insn)
@@ -600,11 +621,40 @@ ppc64_linux_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
                                        CORE_ADDR addr,
                                        struct target_ops *targ)
 {
-  struct section_table *s = target_section_by_addr (targ, addr);
+  struct target_section *s = target_section_by_addr (targ, addr);
 
   /* Check if ADDR points to a function descriptor.  */
   if (s && strcmp (s->the_bfd_section->name, ".opd") == 0)
-    return get_target_memory_unsigned (targ, addr, 8);
+    {
+      /* There may be relocations that need to be applied to the .opd 
+        section.  Unfortunately, this function may be called at a time
+        where these relocations have not yet been performed -- this can
+        happen for example shortly after a library has been loaded with
+        dlopen, but ld.so has not yet applied the relocations.
+
+        To cope with both the case where the relocation has been applied,
+        and the case where it has not yet been applied, we do *not* read
+        the (maybe) relocated value from target memory, but we instead
+        read the non-relocated value from the BFD, and apply the relocation
+        offset manually.
+
+        This makes the assumption that all .opd entries are always relocated
+        by the same offset the section itself was relocated.  This should
+        always be the case for GNU/Linux executables and shared libraries.
+        Note that other kind of object files (e.g. those added via
+        add-symbol-files) will currently never end up here anyway, as this
+        function accesses *target* sections only; only the main exec and
+        shared libraries are ever added to the target.  */
+
+      gdb_byte buf[8];
+      int res;
+
+      res = bfd_get_section_contents (s->bfd, s->the_bfd_section,
+                                     &buf, addr - s->addr, 8);
+      if (res != 0)
+       return extract_unsigned_integer (buf, 8)
+               - bfd_section_vma (s->bfd, s->the_bfd_section) + s->addr;
+   }
 
   return addr;
 }
@@ -1052,6 +1102,12 @@ ppc_linux_init_abi (struct gdbarch_info info,
       /* Trampolines.  */
       tramp_frame_prepend_unwinder (gdbarch, &ppc32_linux_sigaction_tramp_frame);
       tramp_frame_prepend_unwinder (gdbarch, &ppc32_linux_sighandler_tramp_frame);
+
+      /* BFD target for core files.  */
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
+       set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpcle");
+      else
+       set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc");
     }
   
   if (tdep->wordsize == 8)
@@ -1069,12 +1125,25 @@ ppc_linux_init_abi (struct gdbarch_info info,
       /* Trampolines.  */
       tramp_frame_prepend_unwinder (gdbarch, &ppc64_linux_sigaction_tramp_frame);
       tramp_frame_prepend_unwinder (gdbarch, &ppc64_linux_sighandler_tramp_frame);
+
+      /* BFD target for core files.  */
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
+       set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpcle");
+      else
+       set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpc");
     }
   set_gdbarch_regset_from_core_section (gdbarch, ppc_linux_regset_from_core_section);
   set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description);
 
   /* Supported register sections.  */
-  set_gdbarch_core_regset_sections (gdbarch, ppc_linux_regset_sections);
+  if (tdesc_find_feature (info.target_desc,
+                         "org.gnu.gdb.power.vsx"))
+    set_gdbarch_core_regset_sections (gdbarch, ppc_linux_vsx_regset_sections);
+  else if (tdesc_find_feature (info.target_desc,
+                              "org.gnu.gdb.power.altivec"))
+    set_gdbarch_core_regset_sections (gdbarch, ppc_linux_vmx_regset_sections);
+  else
+    set_gdbarch_core_regset_sections (gdbarch, ppc_linux_fp_regset_sections);
 
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
@@ -1103,6 +1172,9 @@ ppc_linux_init_abi (struct gdbarch_info info,
     }
 }
 
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern initialize_file_ftype _initialize_ppc_linux_tdep;
+
 void
 _initialize_ppc_linux_tdep (void)
 {
@@ -1119,8 +1191,14 @@ _initialize_ppc_linux_tdep (void)
   initialize_tdesc_powerpc_32l ();
   initialize_tdesc_powerpc_altivec32l ();
   initialize_tdesc_powerpc_vsx32l ();
+  initialize_tdesc_powerpc_isa205_32l ();
+  initialize_tdesc_powerpc_isa205_altivec32l ();
+  initialize_tdesc_powerpc_isa205_vsx32l ();
   initialize_tdesc_powerpc_64l ();
   initialize_tdesc_powerpc_altivec64l ();
   initialize_tdesc_powerpc_vsx64l ();
+  initialize_tdesc_powerpc_isa205_64l ();
+  initialize_tdesc_powerpc_isa205_altivec64l ();
+  initialize_tdesc_powerpc_isa205_vsx64l ();
   initialize_tdesc_powerpc_e500l ();
 }
This page took 0.0270899999999999 seconds and 4 git commands to generate.