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]

Re: Does anybody remember...


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);


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