This is the mail archive of the gdb-patches@sourceware.org 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]

[hppa-hpux] Fix passing function pointers into dummy call


hppa is one of the platforms that uses function descriptors. When calling an inferior function from gdb and passing a function pointer, we need to make sure that we are passing the function descriptor address instead of the function entry point. Fix this case for hppa64-*

This fixes all the interesting cases in callfuncs.exp, including two tests that were marked kfail.

note that for hppa-*, we do not need to worry about this because the compiler puts in additional code to handle this at runtime.

I'll check this in over the weekend if there are no comments. (at that point i'll remove the kfails as well)

randolph
2005-11-18  Randolph Chung  <tausq@debian.org>

	* hppa-tdep.c (hppa64_convert_code_addr_to_fptr): New function.
	(hppa64_push_dummy_call): If passing a function pointer, ensure
	it is a function description address instead of the function entry
	point.

Index: hppa-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/hppa-tdep.c,v
retrieving revision 1.212
diff -u -p -r1.212 hppa-tdep.c
--- hppa-tdep.c	3 Oct 2005 20:53:00 -0000	1.212
+++ hppa-tdep.c	18 Nov 2005 15:23:03 -0000
@@ -882,6 +882,50 @@ hppa64_floating_p (const struct type *ty
   return 0;
 }
 
+/* If CODE points to a function entry address, try to look up the corresponding
+   function descriptor and return its address instead.  If CODE is not a
+   function entry address, then just return it unchanged.  */
+static CORE_ADDR
+hppa64_convert_code_addr_to_fptr (CORE_ADDR code)
+{
+  struct obj_section *sec, *opd;
+
+  sec = find_pc_section (code);
+
+  if (!sec)
+    return code;
+
+  /* If CODE is in a data section, assume it's already a fptr.  */
+  if (!(sec->the_bfd_section->flags & SEC_CODE))
+    return code;
+
+  ALL_OBJFILE_OSECTIONS (sec->objfile, opd)
+    {
+      if (strcmp (opd->the_bfd_section->name, ".opd") == 0)
+        break;
+    }
+
+  if (opd < sec->objfile->sections_end)
+    {
+      CORE_ADDR addr;
+
+      for (addr = opd->addr; addr < opd->endaddr; addr += 2 * 8)
+        {
+	  ULONGEST opdaddr;
+	  char tmp[8];
+
+	  if (target_read_memory (addr, tmp, sizeof (tmp)))
+	      break;
+	  opdaddr = extract_unsigned_integer (tmp, sizeof (tmp));
+
+          if (opdaddr == code)
+	    return addr - 16;
+	}
+    }
+
+  return code;
+}
+
 static CORE_ADDR
 hppa64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 			struct regcache *regcache, CORE_ADDR bp_addr,
@@ -902,6 +946,7 @@ hppa64_push_dummy_call (struct gdbarch *
       struct type *type = value_type (arg);
       int len = TYPE_LENGTH (type);
       const bfd_byte *valbuf;
+      bfd_byte fptrbuf[8];
       int regnum;
 
       /* "Each parameter begins on a 64-bit (8-byte) boundary."  */
@@ -977,10 +1022,26 @@ hppa64_push_dummy_call (struct gdbarch *
 	    }
 	}
 
+      /* If we are passing a function pointer, make sure we pass a function
+         descriptor instead of the function entry address.  */
+      if (TYPE_CODE (type) == TYPE_CODE_PTR
+          && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC)
+        {
+	  ULONGEST codeptr, fptr;
+
+	  codeptr = unpack_long (type, value_contents (arg));
+	  fptr = hppa64_convert_code_addr_to_fptr (codeptr);
+	  store_unsigned_integer (fptrbuf, TYPE_LENGTH (type), fptr);
+	  valbuf = fptrbuf;
+	}
+      else
+        {
+          valbuf = value_contents (arg);
+	}
+
       /* Always store the argument in memory.  */
-      write_memory (sp + offset, value_contents (arg), len);
+      write_memory (sp + offset, valbuf, len);
 
-      valbuf = value_contents (arg);
       regnum = HPPA_ARG0_REGNUM - offset / 8;
       while (regnum > HPPA_ARG0_REGNUM - 8 && len > 0)
 	{

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]