Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Does anybody remember...
@ 2002-05-24 17:02 Michael Snyder
  2002-05-25 10:54 ` Jim Blandy
  0 siblings, 1 reply; 3+ messages in thread
From: Michael Snyder @ 2002-05-24 17:02 UTC (permalink / raw)
  To: gdb-patches, jimb

Does anybody remember a Harvard Architecture issue, wherein you did
something
like take the address of a function, which caused gdb to scrunch the
address
down into the target-pointer format and then re-expand it into the
unified-address
format, with possible loss of information in the process?

I think Jim Blandy did something to prevent this from happening, 
but it seems to have crept back in again.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Does anybody remember...
  2002-05-24 17:02 Does anybody remember Michael Snyder
@ 2002-05-25 10:54 ` Jim Blandy
  2002-05-29 17:02   ` Michael Snyder
  0 siblings, 1 reply; 3+ messages in thread
From: Jim Blandy @ 2002-05-25 10:54 UTC (permalink / raw)
  To: Michael Snyder; +Cc: gdb-patches

Michael Snyder <msnyder@redhat.com> writes:

> Does anybody remember a Harvard Architecture issue, wherein you did
> something
> like take the address of a function, which caused gdb to scrunch the
> address
> down into the target-pointer format and then re-expand it into the
> unified-address
> format, with possible loss of information in the process?
> 
> I think Jim Blandy did something to prevent this from happening, 
> but it seems to have crept back in again.

Here's what I think you're referring to, from values.c.  The comment
only talks about non-Harvard architectures, but `descriptors' are also
used often in Harvard architectures to keep data and function pointers
the same size even when the code space is much larger than the data
space.

/* Extract a value as a C pointer. Does not deallocate the value.  
   Note that val's type may not actually be a pointer; value_as_long
   handles all the cases.  */
CORE_ADDR
value_as_address (struct value *val)
{
  /* Assume a CORE_ADDR can fit in a LONGEST (for now).  Not sure
     whether we want this to be true eventually.  */
#if 0
  /* ADDR_BITS_REMOVE is wrong if we are being called for a
     non-address (e.g. argument to "signal", "info break", etc.), or
     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);


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Does anybody remember...
  2002-05-25 10:54 ` Jim Blandy
@ 2002-05-29 17:02   ` Michael Snyder
  0 siblings, 0 replies; 3+ messages in thread
From: Michael Snyder @ 2002-05-29 17:02 UTC (permalink / raw)
  To: Jim Blandy; +Cc: gdb-patches

Jim Blandy wrote:
> 
> Michael Snyder <msnyder@redhat.com> writes:
> 
> > Does anybody remember a Harvard Architecture issue, wherein you did
> > something
> > like take the address of a function, which caused gdb to scrunch the
> > address
> > down into the target-pointer format and then re-expand it into the
> > unified-address
> > format, with possible loss of information in the process?
> >
> > I think Jim Blandy did something to prevent this from happening,
> > but it seems to have crept back in again.
> 
> Here's what I think you're referring to, from values.c.  The comment
> only talks about non-Harvard architectures, but `descriptors' are also
> used often in Harvard architectures to keep data and function pointers
> the same size even when the code space is much larger than the data
> space.

OK, good.  Now I know what I need to talk to you about, which is:
back in April of 2000, you made a change in "locate_var_value"
so that, if the var is a function pointer, it will call
value_from_pointer
instead of value_from_long.  This has exactly the same effect as the one
you are trying to avoid with the code shown below:  the address of the
function is crunched down into a pointer (which could be eg. 16 bits), 
and then later converted back to an address (with loss of information).

Can you help me see how to avoid this?


> 
> /* Extract a value as a C pointer. Does not deallocate the value.
>    Note that val's type may not actually be a pointer; value_as_long
>    handles all the cases.  */
> CORE_ADDR
> value_as_address (struct value *val)
> {
>   /* Assume a CORE_ADDR can fit in a LONGEST (for now).  Not sure
>      whether we want this to be true eventually.  */
> #if 0
>   /* ADDR_BITS_REMOVE is wrong if we are being called for a
>      non-address (e.g. argument to "signal", "info break", etc.), or
>      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);


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2002-05-29 19:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-05-24 17:02 Does anybody remember Michael Snyder
2002-05-25 10:54 ` Jim Blandy
2002-05-29 17:02   ` Michael Snyder

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox