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]

RFA: Avoid converting functions to pointers and back



2001-10-25  Jim Blandy  <jimb@redhat.com>

	* values.c (value_as_address): If VAL is a function or method,
	just return its address; don't let COERCE_ARRAY convert its
	address to a pointer, and then have unpack_long convert it back to
	an address.

Index: gdb/values.c
===================================================================
RCS file: /cvs/src/src/gdb/values.c,v
retrieving revision 1.25
diff -c -r1.25 values.c
*** gdb/values.c	2001/10/16 01:58:07	1.25
--- gdb/values.c	2001/10/25 18:15:46
***************
*** 571,576 ****
--- 571,618 ----
       for pointers to char, in which the low bits *are* significant.  */
    return ADDR_BITS_REMOVE (value_as_long (val));
  #else
+ 
+   /* There are several targets (IA-64, PowerPC, and others) which
+      don't represent pointers to functions as simply the address of
+      the function's entry point.  For example, on the IA-64, a
+      function pointer points to a two-word descriptor, generated by
+      the linker, which contains the function's entry point, and the
+      value the IA-64 "global pointer" register should have --- to
+      support position-independent code.  The linker generates
+      descriptors only for those functions whose addresses are taken.
+ 
+      On such targets, it's difficult for GDB to convert an arbitrary
+      function address into a function pointer; it has to either find
+      an existing descriptor for that function, or call malloc and
+      build its own.  On some targets, it is impossible for GDB to
+      build a descriptor at all: the descriptor must contain a jump
+      instruction; data memory cannot be executed; and code memory
+      cannot be modified.
+ 
+      Upon entry to this function, if VAL is a value of type `function'
+      (that is, TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FUNC), then
+      VALUE_ADDRESS (val) is the address of the function.  This is what
+      you'll get if you evaluate an expression like `main'.  The call
+      to COERCE_ARRAY below actually does all the usual unary
+      conversions, which includes converting values of type `function'
+      to `pointer to function'.  This is the challenging conversion
+      discussed above.  Then, `unpack_long' will convert that pointer
+      back into an address.
+ 
+      So, suppose the user types `disassemble foo' on an architecture
+      with a strange function pointer representation, on which GDB
+      cannot build its own descriptors, and suppose further that `foo'
+      has no linker-built descriptor.  The address->pointer conversion
+      will signal an error and prevent the command from running, even
+      though the next step would have been to convert the pointer
+      directly back into the same address.
+ 
+      The following shortcut avoids this whole mess.  If VAL is a
+      function, just return its address directly.  */
+   if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FUNC
+       || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_METHOD)
+     return VALUE_ADDRESS (val);
+ 
    COERCE_ARRAY (val);
  
    /* Some architectures (e.g. Harvard), map instruction and data


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