* hppabsd-tdep.c: Include "symtab.h", "objfiles.h", "target.h",
authorMark Kettenis <kettenis@gnu.org>
Tue, 21 Jun 2005 05:32:00 +0000 (05:32 +0000)
committerMark Kettenis <kettenis@gnu.org>
Tue, 21 Jun 2005 05:32:00 +0000 (05:32 +0000)
"value.h" and "elf/common.h".
(hppabsd_supply_gregset): Use `gdb_byte *' for byte buffer.
(hppabsd_find_global_pointer): New function.
(hppabsd_init_abi): Set TDEP->find_global_pointer to
hppabsd_find_global_pointer.
* Makefile.in (hppabsd-tdep.o): Update dependencies.

gdb/ChangeLog
gdb/Makefile.in
gdb/hppabsd-tdep.c

index ca7db2b6329ca3c2ec97c0021826becfe0a01a10..e442c7055f2b8a715c42f80ae053390a59b6edda 100644 (file)
@@ -1,3 +1,13 @@
+2005-06-20  Mark Kettenis  <kettenis@gnu.org>
+
+       * hppabsd-tdep.c: Include "symtab.h", "objfiles.h", "target.h",
+       "value.h" and "elf/common.h".
+       (hppabsd_supply_gregset): Use `gdb_byte *' for byte buffer.
+       (hppabsd_find_global_pointer): New function.
+       (hppabsd_init_abi): Set TDEP->find_global_pointer to
+       hppabsd_find_global_pointer.
+       * Makefile.in (hppabsd-tdep.o): Update dependencies.
+
 2005-06-12  Mark Kettenis  <kettenis@gnu.org>
 
        * hppa-tdep.c (hppa_pointer_to_address_hack): Remove function.
index 2cdb1b70e4a7cec026998ba7c19285ad2940c74f..3a2bc4c4513f20f5e8c503607ec99f0863c92464 100644 (file)
@@ -2003,8 +2003,9 @@ hpacc-abi.o: hpacc-abi.c $(defs_h) $(value_h) $(gdb_regex_h) $(gdb_string_h) \
        $(gdbtypes_h) $(gdbcore_h) $(cp_abi_h) $(gnu_v2_abi_h)
 hppabsd-nat.o: hppabsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
        $(target_h) $(hppa_tdep_h) $(inf_ptrace_h)
-hppabsd-tdep.o: hppabsd-tdep.c $(defs_h) $(arch_utils_h) $(osabi_h) \
-       $(regcache_h) $(regset_h) $(gdb_assert_h) $(gdb_string_h) \
+hppabsd-tdep.o: hppabsd-tdep.c $(defs_h) $(arch_utils_h) $(symtab_h) \
+       $(objfiles_h) $(osabi_h) $(regcache_h) $(regset_h) $(target_h) \
+       $(value_h) $(gdb_assert_h) $(gdb_string_h) $(elf_common_h) \
        $(hppa_tdep_h) $(solib_svr4_h)
 hppa-hpux-nat.o: hppa-hpux-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
        $(target_h) $(gdb_assert_h) $(hppa_tdep_h) $(inf_ptrace_h) \
index 8cbebb9ca8ae969af99487fecebb8352d1c9f962..9c9e666b2f3c1146e1c8d247cacf7400faa6a976 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for HP PA-RISC BSD's.
 
-   Copyright 2004 Free Software Foundation, Inc.
+   Copyright 2004, 2005 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
 #include "defs.h"
 #include "arch-utils.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 +50,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,6 +92,78 @@ 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)
 {
@@ -96,6 +174,7 @@ hppabsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
     (gdbarch, hppabsd_regset_from_core_section);
 
   /* OpenBSD and NetBSD use ELF.  */
+  tdep->find_global_pointer = hppabsd_find_global_pointer;
   tdep->is_elf = 1;
 
   /* OpenBSD and NetBSD uses SVR4-style shared libraries.  */