2007-08-17 Michael Snyder <msnyder@access-company.com>
[deliverable/binutils-gdb.git] / gdb / hppabsd-tdep.c
index 0a54371527d32d975d4d64cbb13c2b02363e774a..14a399e9fcd4c4e1d9709df5fda26cb8358ab718 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for HP PA-RISC BSD's.
 
-   Copyright 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "arch-utils.h"
+#include "gdbtypes.h"
+#include "symtab.h"
+#include "objfiles.h"
 #include "osabi.h"
 #include "regcache.h"
 #include "regset.h"
+#include "target.h"
+#include "value.h"
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
 
+#include "elf/common.h"
+
 #include "hppa-tdep.h"
 #include "solib-svr4.h"
 
@@ -44,7 +51,7 @@ static void
 hppabsd_supply_gregset (const struct regset *regset, struct regcache *regcache,
                     int regnum, const void *gregs, size_t len)
 {
-  const char *regs = gregs;
+  const gdb_byte *regs = gregs;
   size_t offset;
   int i;
 
@@ -86,21 +93,98 @@ hppabsd_regset_from_core_section (struct gdbarch *gdbarch,
 }
 \f
 
+CORE_ADDR
+hppabsd_find_global_pointer (struct value *function)
+{
+  CORE_ADDR faddr = value_as_address (function);
+  struct obj_section *faddr_sec;
+  gdb_byte buf[4];
+
+  /* Is this a plabel? If so, dereference it to get the Global Pointer
+     value.  */
+  if (faddr & 2)
+    {
+      if (target_read_memory ((faddr & ~3) + 4, buf, sizeof buf) == 0)
+       return extract_unsigned_integer (buf, sizeof buf);
+    }
+
+  /* If the address is in the .plt section, then the real function
+     hasn't yet been fixed up by the linker so we cannot determine the
+     Global Pointer for that function.  */
+  if (in_plt_section (faddr, NULL))
+    return 0;
+
+  faddr_sec = find_pc_section (faddr);
+  if (faddr_sec != NULL)
+    {
+      struct obj_section *sec;
+
+      ALL_OBJFILE_OSECTIONS (faddr_sec->objfile, sec)
+       {
+         if (strcmp (sec->the_bfd_section->name, ".dynamic") == 0)
+           break;
+       }
+
+      if (sec < faddr_sec->objfile->sections_end)
+       {
+         CORE_ADDR addr = sec->addr;
+
+         while (addr < sec->endaddr)
+           {
+             gdb_byte buf[4];
+             LONGEST tag;
+
+             if (target_read_memory (addr, buf, sizeof buf) != 0)
+               break;
+
+             tag = extract_signed_integer (buf, sizeof buf);
+             if (tag == DT_PLTGOT)
+               {
+                 CORE_ADDR pltgot;
+
+                 if (target_read_memory (addr + 4, buf, sizeof buf) != 0)
+                   break;
+
+                 /* The OpenBSD ld.so doesn't relocate DT_PLTGOT, so
+                    we have to do it ourselves.  */
+                 pltgot = extract_unsigned_integer (buf, sizeof buf);
+                 pltgot += ANOFFSET (sec->objfile->section_offsets,
+                                     SECT_OFF_TEXT (sec->objfile));
+                 return pltgot;
+               }
+
+             if (tag == DT_NULL)
+               break;
+
+             addr += 8;
+           }
+       }
+    }
+
+  return 0;
+}
+\f
+
 static void
 hppabsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
+  /* OpenBSD and NetBSD have a 64-bit 'long double'.  */
+  set_gdbarch_long_double_bit (gdbarch, 64);
+  set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
+
   /* Core file support.  */
   set_gdbarch_regset_from_core_section
     (gdbarch, hppabsd_regset_from_core_section);
 
   /* OpenBSD and NetBSD use ELF.  */
   tdep->is_elf = 1;
+  tdep->find_global_pointer = hppabsd_find_global_pointer;
+  tdep->in_solib_call_trampoline = hppa_in_solib_call_trampoline;
+  set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code);
 
-  /* OpenBSD and NetBSD uses SVR4-style shared libraries.  */
-  set_gdbarch_in_solib_call_trampoline
-    (gdbarch, generic_in_solib_call_trampoline);
+  /* OpenBSD and NetBSD use SVR4-style shared libraries.  */
   set_solib_svr4_fetch_link_map_offsets
     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
 }
This page took 0.024227 seconds and 4 git commands to generate.