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]

Re: [rfc/rfa:doc] INTEGER_TO_ADDRESS; Was: INTEGER_TO_ADDRESS(), thoughts?


> Hello,
> 
> Following up the thread on gdb@sources, this introduces an INTEGER_TO_ADDRESS() method which both the d10v and the MIPS use.
> 
> Since JimB gave a very good explination as to the problems it has and a guideline to its use, I included that at the point it is used.  I think including ``pragmatics'' such as that is a good thing.  The other possability is to add it to the doco.
> 
> The only thing I'm not sure about is the name.  The type of the input parameter isn't necessary an integer.  The name reflecting more the intent that the target first convert it to an integer and then to an address.
> 

Attached is a revised patch.  I've also added a pragmatics section to 
the relevant documentation.

Comments (on the doco?).

Andrew

2001-10-01  Andrew Cagney  <ac131313@redhat.com>

	* mips-tdep.c (mips_integer_to_address): New function.
	(mips_gdbarch_init): Initialize pointer_to_address,
	address_to_pointer and integer_to_address.

	* config/mips/tm-mips.h (POINTER_TO_ADDRESS): Delete
	(ADDRESS_TO_POINTER): Delete.

	* d10v-tdep.c (d10v_integer_to_address): New function.
	(d10v_gdbarch_init): Initialize integer_to_address.

	* values.c (value_as_pointer): Use INTEGER_TO_ADDRESS when
	available.

	* gdbarch.sh (INTEGER_TO_ADDRESS): New predicate and function.
	* gdbarch.h, gdbarch.c: Regenerate.

Index: doc/ChangeLog
2001-10-01  Andrew Cagney  <ac131313@redhat.com>

	* gdbint.texinfo (Target Architecture Definition): Default
	POINTER_TO_ADDRESS functions assume unsigned addresses.
	(INTEGER_TO_ADDRESS): Document.
	
Index: d10v-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/d10v-tdep.c,v
retrieving revision 1.24
diff -p -r1.24 d10v-tdep.c
*** d10v-tdep.c	2001/09/05 23:44:43	1.24
--- d10v-tdep.c	2001/10/01 19:50:00
*************** d10v_pointer_to_address (struct type *ty
*** 419,424 ****
--- 419,439 ----
      return d10v_make_daddr (addr);
  }
  
+ static CORE_ADDR
+ d10v_integer_to_address (struct type *type, void *buf)
+ {
+   LONGEST val;
+   val = unpack_long (type, buf);
+   if (TYPE_CODE (type) == TYPE_CODE_INT
+       && TYPE_LENGTH (type) <= TYPE_LENGTH (builtin_type_void_data_ptr))
+     /* Convert small integers that would would be directly copied into
+        a pointer variable into an address pointing into data space.  */
+     return d10v_make_daddr (val & 0xffff);
+   else
+     /* The value is too large to fit in a pointer.  Assume this was
+        intentional and that the user in fact specified a raw address.  */
+     return val;
+ }
  
  /* Store the address of the place in which to copy the structure the
     subroutine will return.  This is called from call_function. 
*************** d10v_gdbarch_init (struct gdbarch_info i
*** 1478,1483 ****
--- 1493,1499 ----
    set_gdbarch_addr_bit (gdbarch, 32);
    set_gdbarch_address_to_pointer (gdbarch, d10v_address_to_pointer);
    set_gdbarch_pointer_to_address (gdbarch, d10v_pointer_to_address);
+   set_gdbarch_integer_to_address (gdbarch, d10v_integer_to_address);
    set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
    set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
    set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.79
diff -p -r1.79 gdbarch.sh
*** gdbarch.sh	2001/09/30 16:54:28	1.79
--- gdbarch.sh	2001/10/01 19:50:00
*************** f:2:STORE_PSEUDO_REGISTER:void:store_pse
*** 472,477 ****
--- 472,478 ----
  #
  f:2:POINTER_TO_ADDRESS:CORE_ADDR:pointer_to_address:struct type *type, void *buf:type, buf:::unsigned_pointer_to_address::0
  f:2:ADDRESS_TO_POINTER:void:address_to_pointer:struct type *type, void *buf, CORE_ADDR addr:type, buf, addr:::unsigned_address_to_pointer::0
+ F:2:INTEGER_TO_ADDRESS:CORE_ADDR:integer_to_address:struct type *type, void *buf:type, buf
  #
  f:2:RETURN_VALUE_ON_STACK:int:return_value_on_stack:struct type *type:type:::generic_return_value_on_stack_not::0
  f:2:EXTRACT_RETURN_VALUE:void:extract_return_value:struct type *type, char *regbuf, char *valbuf:type, regbuf, valbuf::0:0
Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.59
diff -p -r1.59 mips-tdep.c
*** mips-tdep.c	2001/07/24 16:28:36	1.59
--- mips-tdep.c	2001/10/01 19:50:00
*************** mips_ecoff_reg_to_regnum (int num)
*** 3950,3955 ****
--- 3950,3969 ----
      return num + FP0_REGNUM - 32;
  }
  
+ /* Convert an integer into an address.  By first converting the value
+    into a pointer and then extracting it signed, the address is
+    guarenteed to be correctly sign extended.  */
+ 
+ static CORE_ADDR
+ mips_integer_to_address (struct type *type, void *buf)
+ {
+   char *tmp = alloca (TYPE_LENGTH (builtin_type_void_data_ptr));
+   LONGEST val = unpack_long (type, buf);
+   store_signed_integer (tmp, TYPE_LENGTH (builtin_type_void_data_ptr), val);
+   return extract_signed_integer (tmp,
+ 				 TYPE_LENGTH (builtin_type_void_data_ptr));
+ }
+ 
  static struct gdbarch *
  mips_gdbarch_init (struct gdbarch_info info,
  		   struct gdbarch_list *arches)
*************** mips_gdbarch_init (struct gdbarch_info i
*** 4259,4264 ****
--- 4273,4281 ----
    set_gdbarch_skip_prologue (gdbarch, mips_skip_prologue);
    set_gdbarch_saved_pc_after_call (gdbarch, mips_saved_pc_after_call);
  
+   set_gdbarch_pointer_to_address (gdbarch, signed_pointer_to_address);
+   set_gdbarch_address_to_pointer (gdbarch, address_to_signed_pointer);
+   set_gdbarch_integer_to_address (gdbarch, mips_integer_to_address);
    return gdbarch;
  }
  
Index: values.c
===================================================================
RCS file: /cvs/src/src/gdb/values.c,v
retrieving revision 1.23
diff -p -r1.23 values.c
*** values.c	2001/09/24 17:16:53	1.23
--- values.c	2001/10/01 19:50:00
*************** value_as_pointer (value_ptr val)
*** 572,606 ****
    return ADDR_BITS_REMOVE (value_as_long (val));
  #else
    COERCE_ARRAY (val);
!   /* In converting VAL to an address (CORE_ADDR), any small integers
!      are first cast to a generic pointer.  The function unpack_long
!      will then correctly convert that pointer into a canonical address
!      (using POINTER_TO_ADDRESS).
! 
!      Without the cast, the MIPS gets: 0xa0000000 -> (unsigned int)
!      0xa0000000 -> (LONGEST) 0x00000000a0000000
! 
!      With the cast, the MIPS gets: 0xa0000000 -> (unsigned int)
!      0xa0000000 -> (void*) 0xa0000000 -> (LONGEST) 0xffffffffa0000000.
! 
!      If the user specifies an integer that is larger than the target
!      pointer type, it is assumed that it was intentional and the value
!      is converted directly into an ADDRESS.  This ensures that no
!      information is discarded.
! 
!      NOTE: The cast operation may eventualy be converted into a TARGET
!      method (see POINTER_TO_ADDRESS() and ADDRESS_TO_POINTER()) so
!      that the TARGET ISA/ABI can apply an arbitrary conversion.
! 
!      NOTE: In pure harvard architectures function and data pointers
!      can be different and may require different integer to pointer
!      conversions. */
!   if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT
!       && (TYPE_LENGTH (VALUE_TYPE (val))
! 	  <= TYPE_LENGTH (builtin_type_void_data_ptr)))
!     {
!       val = value_cast (builtin_type_void_data_ptr, val);
!     }
    return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val));
  #endif
  }
--- 572,620 ----
    return ADDR_BITS_REMOVE (value_as_long (val));
  #else
    COERCE_ARRAY (val);
! 
!   /* Some architectures (e.g. Harvard), map instruction and data
!      addresses onto a single large unified address space.  For
!      instance: An architecture may consider a large integer in the
!      range 0x10000000 .. 0x1000ffff to already represent a data
!      addresses (hence not need a pointer to address conversion) while
!      a small integer would still need to be converted integer to
!      pointer to address.  Just assume such architectures handle all
!      integer conversions in a single function.  */
! 
!   /* JimB writes:
! 
!      I think INTEGER_TO_ADDRESS is a good idea as proposed --- but we
!      must admonish GDB hackers to make sure its behavior matches the
!      compiler's, whenever possible.
! 
!      In general, I think GDB should evaluate expressions the same way
!      the compiler does.  When the user copies an expression out of
!      their source code and hands it to a `print' command, they should
!      get the same value the compiler would have computed.  Any
!      deviation from this rule can cause major confusion and annoyance,
!      and needs to be justified carefully.  In other words, GDB doesn't
!      really have the freedom to do these conversions in clever and
!      useful ways.
! 
!      AndrewC pointed out that users aren't complaining about how GDB
!      casts integers to pointers; they are complaining that they can't
!      take an address from a disassembly listing and give it to `x/i'.
!      This is certainly important.
! 
!      Adding an architecture method like INTEGER_TO_ADDRESS certainly
!      makes it possible for GDB to "get it right" in all circumstances
!      --- the target has complete control over how things get done, so
!      people can Do The Right Thing for their target without breaking
!      anyone else.  The standard doesn't specify how integers get
!      converted to pointers; usually, the ABI doesn't either, but
!      ABI-specific code is a more reasonable place to handle it.  */
! 
!   if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_PTR
!       && TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_REF
!       && INTEGER_TO_ADDRESS_P ())
!     return INTEGER_TO_ADDRESS (VALUE_TYPE (val), VALUE_CONTENTS (val));
! 
    return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val));
  #endif
  }
Index: config/mips/tm-mips.h
===================================================================
RCS file: /cvs/src/src/gdb/config/mips/tm-mips.h,v
retrieving revision 1.21
diff -p -r1.21 tm-mips.h
*** tm-mips.h	2001/07/05 23:30:43	1.21
--- tm-mips.h	2001/10/01 19:50:01
*************** typedef unsigned long t_inst;	/* Integer
*** 499,507 ****
  extern void mips_set_processor_type_command (char *, int);
  
  
- /* MIPS sign extends addresses */
- #define POINTER_TO_ADDRESS(TYPE,BUF) (signed_pointer_to_address (TYPE, BUF))
- #define ADDRESS_TO_POINTER(TYPE,BUF,ADDR) (address_to_signed_pointer (TYPE, BUF, ADDR))
- 
  /* Single step based on where the current instruction will take us.  */
  extern void mips_software_single_step (enum target_signal, int);
--- 499,503 ----
Index: doc/gdbint.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdbint.texinfo,v
retrieving revision 1.39
diff -p -r1.39 gdbint.texinfo
*** gdbint.texinfo	2001/09/08 10:53:45	1.39
--- gdbint.texinfo	2001/10/01 19:50:05
*************** appropriate way for the current architec
*** 2489,2495 ****
  Here are some macros which architectures can define to indicate the
  relationship between pointers and addresses.  These have default
  definitions, appropriate for architectures on which all pointers are
! simple byte addresses.
  
  @deftypefn {Target Macro} CORE_ADDR POINTER_TO_ADDRESS (struct type *@var{type}, char *@var{buf})
  Assume that @var{buf} holds a pointer of type @var{type}, in the
--- 2489,2495 ----
  Here are some macros which architectures can define to indicate the
  relationship between pointers and addresses.  These have default
  definitions, appropriate for architectures on which all pointers are
! simple unsigned byte addresses.
  
  @deftypefn {Target Macro} CORE_ADDR POINTER_TO_ADDRESS (struct type *@var{type}, char *@var{buf})
  Assume that @var{buf} holds a pointer of type @var{type}, in the
*************** should continue to get past the dynamic 
*** 3140,3145 ****
--- 3140,3167 ----
  function.  A zero value indicates that it is not important or necessary
  to set a breakpoint to get through the dynamic linker and that single
  stepping will suffice.
+ 
+ @item INTEGER_TO_ADDRESS (@var{type}, @var{buf})
+ @findex INTEGER_TO_ADDRESS
+ Define this when the architecture needs to handle non-pointer to address
+ conversions specially.  Converts that value to an address according to
+ the current architectures conventions.
+ 
+ @emph{Pragmatics: GDB should evaluate expressions the same way the
+ compiler does.  When the user copies a well defined expression from
+ their source code and hand it to a @code{print} command, they should get
+ the same value as would have been computed by the target program.  Any
+ deviation from this rule can cause major confusion and annoyance, and
+ needs to be justified carefully.  In other words, GDB doesn't really
+ have the freedom to do these conversions in clever and useful ways. It
+ has, however, been pointed out that users aren't complaining about how
+ GDB casts integers to pointers; they are complaining that they can't
+ take an address from a disassembly listing and give it to @code{x/i}.
+ Adding an architecture method like @code{INTEGER_TO_ADDRESS} certainly
+ makes it possible for GDB to "get it right" in all circumstances.}
+ 
+ @xref{Target Architecture Definition, , Pointers Are Not Always
+ Addresses}.
  
  @item IS_TRAPPED_INTERNALVAR (@var{name})
  @findex IS_TRAPPED_INTERNALVAR

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