This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[commit] Fix calling library functions on OpenBSD/hppa


This makes sure we can call library functions from withing gdb without
things crashing.  Since this also makes calling malloc(3) work, this
fixes tons of testsuite failures involving string manipulation.

In principle this functions is very similar to the code used for
Linux, but there's a slight twist.  On OpenBSD and NetBSD, ld.so
doesn't relocate DT_PLTGOT, so the Linux version gives the wrong
answer.

Committed,

Mark

Index: ChangeLog
from  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.

Index: hppabsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/hppabsd-tdep.c,v
retrieving revision 1.2
diff -u -p -r1.2 hppabsd-tdep.c
--- hppabsd-tdep.c 31 Oct 2004 19:43:30 -0000 1.2
+++ hppabsd-tdep.c 20 Jun 2005 20:27:09 -0000
@@ -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.
 
@@ -21,13 +21,19 @@
 
 #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
 }
 
 
+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;
+}
+
+
 static void
 hppabsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -96,6 +174,7 @@ hppabsd_init_abi (struct gdbarch_info in
     (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.  */
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.736
diff -u -p -r1.736 Makefile.in
--- Makefile.in 13 Jun 2005 16:15:34 -0000 1.736
+++ Makefile.in 20 Jun 2005 20:27:12 -0000
@@ -2003,8 +2003,9 @@ hpacc-abi.o: hpacc-abi.c $(defs_h) $(val
 	$(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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]