This is the mail archive of the gdb-patches@sourceware.cygnus.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: distinguish between pointers and addresses



The following patch needs approval from:
- David Taylor       (the bulk of it)
- Andrew Cagney      (new gdbarch entries)
- Michael Snyder     (tracepoint.c changes)
- Jeff Law           (hppa-tdep.c changes)
- Eli Zaretskii      (doc changes)

This is part of a project whose deadline is coming up, so I'd be very
grateful if people could look at it quickly.

This patch allows GDB to cope with machines where pointers are not
simply byte addresses.  For example, some machines with small word
sizes use word addresses for code pointers, to steal a few more
address bits.  The D10V is such a processor; I think this patch makes
it possible to replace all those ugly GDB_TARGET_IS_D10V conditionals
in GDB's architecture-independent code with functions nicely isolated
in d10v-tdep.c.

The patch adds a full description of the issue to doc/gdbint.texinfo;
if you'd like more details on the patch, read that first.

The patch should have no noticeable effect on any existing port.  I
wrote it for a port I'm doing now, which isn't public yet, so I can't
provide full details there.

I've tested this patch and found no regressions on Linux, the MIPS
Tx-39, Solaris SPARC, and another unreleased target that uses the
gdbarch mechanism (for folks on the inside, it's the one Stan did).


gdb/ChangeLog:
2000-04-10  Jim Blandy  <jimb@redhat.com>

	Provide the hooks needed to support architectures on which
	pointers are not always simple byte addresses.

	* gdbarch.sh (POINTER_TO_ADDRESS, ADDRESS_TO_POINTER): Two new
	functions which architectures can redefine, defaulting to
	generic_pointer_to_address and generic_address_to_pointer.
	* findvar.c (extract_typed_address, store_typed_address,
	generic_pointer_to_address, generic_address_to_pointer): New
	functions.
	(POINTER_TO_ADDRESS, ADDRESS_TO_POINTER): Provide default
	definitions.
	(extract_address, store_address): Doc fixes.
	* values.c (value_as_pointer): Doc fix.
	(value_from_pointer): New function.
	* defs.h (extract_typed_address, store_typed_address): New
	declarations.
	* inferior.h (generic_address_to_pointer,
	generic_pointer_to_address): New declarations.
	* value.h (value_from_pointer): New declaration.
	
	The following changes are all of the general form "Use these
	functions instead of these other functions."  In each case, the
	change is because the new calls provide enough information to do
	the appropriate address / pointer conversions, where the old calls
	did not, or because the new functions are more appropriately named
	for the operation being performed.
	
	* ax-gdb.c (const_var_ref): Use value_from_pointer, not
	value_from_longest.
	* blockframe.c (generic_push_dummy_frame): Use read_pc and
	read_sp, not read_register.
	* c-valprint.c (c_val_print): Use extract_typed_address instead of
	extract_address to extract vtable entries and references.
	* cp-valprint.c (cp_print_value_fields): Use value_from_pointer
	instead of value_from_longest to extract the vtable's address.
	* eval.c (evaluate_subexp_standard): Use value_from_pointer
	instead of value_from_longest to compute `this', and for doing
	pointer-to-member dereferencing.
	* findvar.c (read_register): Use extract_unsigned_integer, not
	extract_address.
	(read_var_value): Use store_typed_address instead of store_address
	for building label values.
	(locate_var_value): Use value_from_pointer instead of
	value_from_longest.
	* hppa-tdep.c (find_stub_with_shl_get): Use value_from_pointer,
	instead of value_from_longest, to build arguments to __d_shl_get.
	* printcmd.c (set_next_address): Use value_from_pointer, not
	value_from_longest.
	(x_command): Use value_from_pointer, not value_from_longest.
	* tracepoint.c (set_traceframe_context): Use value_from_pointer,
	not value_from_longest.
	* valarith.c (value_add, value_sub): Use value_from_pointer, not
	value_from_longest.
	* valops.c (find_function_in_inferior, value_coerce_array,
	value_coerce_function, value_addr, hand_function_call): Same.
	* value.h (COERCE_REF): Use unpack_pointer, not unpack_long. 
	* values.c (unpack_long): Use extract_typed_address to produce
	addresses from pointers and references, not extract_address.
	(value_from_longest): Use store_typed_address instead of
	store_address to produce pointer and reference values.


Index: gdb/doc/gdbint.texinfo
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/doc/gdbint.texinfo,v
retrieving revision 1.149
diff -c -r1.149 gdbint.texinfo
*** gdb/doc/gdbint.texinfo	2000/04/10 08:35:39	1.149
--- gdb/doc/gdbint.texinfo	2000/04/10 18:22:42
***************
*** 1153,1158 ****
--- 1153,1315 ----
  
  GDB can handle big-endian, little-endian, and bi-endian architectures.
  
+ @section Pointers Are Not Always Addresses
+ @cindex pointer representation
+ @cindex address representation
+ @cindex word-addressed machines
+ @cindex separate data and code address spaces
+ @cindex spaces, separate data and code address
+ @cindex address spaces, separate data and code
+ @cindex code pointers, word-addressed
+ @cindex converting between pointers and addresses
+ @cindex D10V addresses
+ 
+ On almost all 32-bit architectures, the representation of a pointer is
+ indistinguishable from the representation of some fixed-length number
+ whose value is the byte address of the object pointed to.  On such
+ machines, the words `pointer' and `address' can be used interchangeably.
+ However, architectures with smaller word sizes are often cramped for
+ address space, so they may choose a pointer representation that breaks this
+ identity, and allows a larger code address space.
+ 
+ For example, the Mitsubishi D10V is a 16-bit processor that uses 32-bit
+ instructions.@footnote{Some D10V instructions are actually pairs of
+ 16-bit instructions, but you can't jump into the middle of a pair, so
+ they're effectively 32-bit instructions, for the sake of this
+ discussion.}  If the D10V used ordinary byte addresses to refer to code
+ locations, then the processor would only be able to address 64kb of
+ instructions.  However, since instructions must be aligned on a
+ four-byte boundary, the low two bits of any valid instruction address
+ are always zero --- byte addresses waste two bits in every address.  So
+ instead of byte addresses, the D10V uses word addresses --- byte
+ addresses shifted right two bits --- to refer to code.  Thus, the D10V
+ can use 16-bit words to address 256kb of code space.
+ 
+ However, this means that code pointers and data pointers have different
+ forms on the D10V.  The 16-bit word @code{0xC020} refers to byte address
+ @code{0xC020} when used as a data address, but refers to byte address
+ @code{0x30080} when used as a code address.
+ 
+ (The D10V also uses separate code and data address spaces, which also
+ affects the correspondence between pointers and addresses, but we're
+ going to ignore that here; this example is already too long.)
+ 
+ To cope with architectures like this --- the D10V is not the only one!
+ --- GDB tries to distinguish between @code{addresses}, which are byte
+ numbers, and @code{pointers}, which are the target's representation of
+ an address of a particular type of data.  In the example above,
+ @code{0xC020} is the pointer, which refers to one of the addresses
+ @code{0xC020} or @code{0x30080}, depending on the type imposed upon it.
+ GDB provides functions for turning a pointer into an address and vice
+ versa, in the appropriate way for the current architecture.
+ 
+ Unfortunately, since addresses and pointers are identical on almost all
+ processors, this distinction tends to bit-rot pretty quickly.  Thus,
+ each time you port GDB to an architecture which does distinguish between
+ pointers and addresses, you'll probably need to clean up some
+ architecture-independent code.
+ 
+ Here are functions which convert between pointers and addresses:
+ 
+ @deftypefun CORE_ADDR extract_typed_address (void *@var{buf}, struct type *@var{type})
+ Treat the bytes at @var{buf} as a pointer or reference of type
+ @var{type}, and return the address it represents, in a manner
+ appropriate for the current architecture.  This yields an address
+ appropriate GDB can use to read target memory, disassemble, etc.
+ Note that @var{buf} refers to a buffer in GDB's memory, not the inferior's.
+ 
+ For example, if the current architecture is the Intel x86, this function
+ extracts a little-endian integer of the appropriate length from
+ @var{buf} and returns it.  However, if the current architecture is the
+ D10V, this function will return a 16-bit integer extracted from
+ @var{buf}, multiplied by four if @var{type} is a pointer to a function.
+ 
+ If @var{type} is not a pointer or reference type, then this function
+ will signal an internal error.
+ @end deftypefun
+ 
+ @deftypefun CORE_ADDR store_typed_address (void *@var{buf}, struct type *@var{type}, CORE_ADDR @var{addr})
+ Store the address @var{addr} in @var{buf}, in the proper format for a
+ pointer of type @var{type} in the current architecture.  Note that
+ @var{buf} refers to a buffer in GDB's memory, not the inferior's.
+ 
+ For example, if the current architecture is the Intel x86, this function
+ stores @var{addr} unmodified as a little-endian integer of the
+ appropriate length in @var{buf}.  However, if the current architecture
+ is the D10V, this function divides @var{addr} by four if @var{type} is
+ a pointer to a function, and then stores it in @var{buf}.
+ 
+ If @var{type} is not a pointer or reference type, then this function
+ will signal an internal error.
+ @end deftypefun
+ 
+ @deftypefun CORE_ADDR value_as_pointer (value_ptr @var{val})
+ Assuming that @var{val} is a pointer, return the address it represents,
+ as appropriate for the current architecture.
+ 
+ This function actually works on integral values, as well as pointers.
+ For pointers, it performs architecture-specific conversions as
+ described above for @code{extract_typed_address}.
+ @end deftypefun
+ 
+ @deftypefun CORE_ADDR value_from_pointer (struct type *@var{type}, CORE_ADDR @var{addr})
+ Create and return a value representing a pointer of type @var{type} to
+ the address @var{addr}, as appropriate for the current architecture.
+ This function performs architecture-specific conversions as described
+ above for @code{store_typed_address}.
+ @end deftypefun
+ 
+ 
+ GDB also provides functions that do the same tasks, but assume that
+ pointers are simply byte addresses; they aren't sensitive to the current
+ architecture, beyond knowing the appropriate endianness.
+ 
+ @deftypefun CORE_ADDR extract_address (void *@var{addr}, int len)
+ Extract a @var{len}-byte number from @var{addr} in the appropriate
+ endianness for the current architecture, and return it.  Note that
+ @var{addr} refers to GDB's memory, not the inferior's.
+ 
+ This function should only be used in architecture-specific code; it
+ doesn't have enough information to turn bits into a true address in the
+ appropriate way for the current architecture.  If you can, use
+ @code{extract_typed_address} instead.
+ @end deftypefun
+ 
+ @deftypefun void store_address (void *@var{addr}, int @var{len}, LONGEST @var{val})
+ Store @var{val} at @var{addr} as a @var{len}-byte integer, in the
+ appropriate endianness for the current architecture.  Note that
+ @var{addr} refers to a buffer in GDB's memory, not the inferior's.
+ 
+ This function should only be used in architecture-specific code; it
+ doesn't have enough information to turn a true address into bits in the
+ appropriate way for the current architecture.  If you can, use
+ @code{store_typed_address} instead.
+ @end deftypefun
+ 
+ 
+ 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
+ appropriate format for the current architecture.  Return the byte
+ address the pointer refers to.
+ 
+ This function may safely assume that @var{type} is either a pointer or a
+ C++ reference type.
+ @end deftypefn
+ 
+ @deftypefn {Target Macro} void ADDRESS_TO_POINTER (struct type *@var{type}, char *@var{buf}, CORE_ADDR @var{addr})
+ Store in @var{buf} a pointer of type @var{type} representing the address
+ @var{addr}, in the appropriate format for the current architecture.
+ 
+ This function may safely assume that @var{type} is either a pointer or a
+ C++ reference type.
+ @end deftypefn
+ 
+ 
  @section Using Different Register and Memory Data Representations
  @cindex raw representation
  @cindex virtual representation
***************
*** 1278,1283 ****
--- 1435,1447 ----
  address of the instruction.  ADDR_BITS_REMOVE should filter out these
  bits with an expression such as @code{((addr) & ~3)}.
  
+ @item ADDRESS_TO_POINTER (@var{type}, @var{buf}, @var{addr})
+ Store in @var{buf} a pointer of type @var{type} representing the address
+ @var{addr}, in the appropriate format for the current architecture.
+ This macro may safely assume that @var{type} is either a pointer or a
+ C++ reference type.
+ @xref{Target Architecture Definition, , Pointers Are Not Always Addresses}.
+ 
  @item BEFORE_MAIN_LOOP_HOOK
  Define this to expand into any code that you want to execute before the
  main loop starts.  Although this is not, strictly speaking, a target
***************
*** 1674,1679 ****
--- 1838,1849 ----
  
  @item NO_HIF_SUPPORT
  (Specific to the a29k.)
+ 
+ @item POINTER_TO_ADDRESS (@var{type}, @var{buf})
+ Assume that @var{buf} holds a pointer of type @var{type}, in the
+ appropriate format for the current architecture.  Return the byte
+ address the pointer refers to.
+ @xref{Target Architecture Definition, , Pointers Are Not Always Addresses}.
  
  @item REGISTER_CONVERTIBLE (@var{reg})
  Return non-zero if @var{reg} uses different raw and virtual formats.
Index: gdb/ax-gdb.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/ax-gdb.c,v
retrieving revision 1.15
diff -c -r1.15 ax-gdb.c
*** gdb/ax-gdb.c	2000/02/01 03:08:59	1.15
--- gdb/ax-gdb.c	2000/04/10 18:22:20
***************
*** 185,191 ****
        return value_from_longest (type, (LONGEST) SYMBOL_VALUE (var));
  
      case LOC_LABEL:
!       return value_from_longest (type, (LONGEST) SYMBOL_VALUE_ADDRESS (var));
  
      default:
        return 0;
--- 185,191 ----
        return value_from_longest (type, (LONGEST) SYMBOL_VALUE (var));
  
      case LOC_LABEL:
!       return value_from_pointer (type, (CORE_ADDR) SYMBOL_VALUE_ADDRESS (var));
  
      default:
        return 0;
Index: gdb/blockframe.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/blockframe.c,v
retrieving revision 1.100
diff -c -r1.100 blockframe.c
*** gdb/blockframe.c	1999/12/21 21:21:58	1.100
--- gdb/blockframe.c	2000/04/10 18:22:21
***************
*** 1213,1220 ****
    dummy_frame = xmalloc (sizeof (struct dummy_frame));
    dummy_frame->registers = xmalloc (REGISTER_BYTES);
  
!   dummy_frame->pc = read_register (PC_REGNUM);
!   dummy_frame->sp = read_register (SP_REGNUM);
    dummy_frame->top = dummy_frame->sp;
    dummy_frame->fp = fp;
    read_register_bytes (0, dummy_frame->registers, REGISTER_BYTES);
--- 1213,1220 ----
    dummy_frame = xmalloc (sizeof (struct dummy_frame));
    dummy_frame->registers = xmalloc (REGISTER_BYTES);
  
!   dummy_frame->pc = read_pc ();
!   dummy_frame->sp = read_sp ();
    dummy_frame->top = dummy_frame->sp;
    dummy_frame->fp = fp;
    read_register_bytes (0, dummy_frame->registers, REGISTER_BYTES);
Index: gdb/c-valprint.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/c-valprint.c,v
retrieving revision 2.47
diff -c -r2.47 c-valprint.c
*** gdb/c-valprint.c	2000/04/10 07:47:24	2.47
--- gdb/c-valprint.c	2000/04/10 18:22:21
***************
*** 135,142 ****
  	  /* Print the unmangled name if desired.  */
  	  /* Print vtable entry - we only get here if we ARE using
  	     -fvtable_thunks.  (Otherwise, look under TYPE_CODE_STRUCT.) */
! 	  print_address_demangle (extract_address (valaddr + embedded_offset, TYPE_LENGTH (type)),
! 				  stream, demangle);
  	  break;
  	}
        elttype = check_typedef (TYPE_TARGET_TYPE (type));
--- 135,143 ----
  	  /* Print the unmangled name if desired.  */
  	  /* Print vtable entry - we only get here if we ARE using
  	     -fvtable_thunks.  (Otherwise, look under TYPE_CODE_STRUCT.) */
! 	  CORE_ADDR addr
! 	    = extract_typed_address (valaddr + embedded_offset, type);
! 	  print_address_demangle (addr, stream, demangle);
  	  break;
  	}
        elttype = check_typedef (TYPE_TARGET_TYPE (type));
***************
*** 249,258 ****
  	}
        if (addressprint)
  	{
  	  fprintf_filtered (stream, "@");
! 	  print_address_numeric
! 	    (extract_address (valaddr + embedded_offset,
! 			      TARGET_PTR_BIT / HOST_CHAR_BIT), 1, stream);
  	  if (deref_ref)
  	    fputs_filtered (": ", stream);
  	}
--- 250,259 ----
  	}
        if (addressprint)
  	{
+ 	  CORE_ADDR addr
+ 	    = extract_typed_address (valaddr + embedded_offset, type);
  	  fprintf_filtered (stream, "@");
! 	  print_address_numeric (addr, 1, stream);
  	  if (deref_ref)
  	    fputs_filtered (": ", stream);
  	}
***************
*** 295,305 ****
  	  /* Print the unmangled name if desired.  */
  	  /* Print vtable entry - we only get here if NOT using
  	     -fvtable_thunks.  (Otherwise, look under TYPE_CODE_PTR.) */
! 	  print_address_demangle (extract_address (
! 						 valaddr + embedded_offset +
! 			   TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8,
! 		  TYPE_LENGTH (TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET))),
! 				  stream, demangle);
  	}
        else
  	cp_print_value_fields (type, type, valaddr, embedded_offset, address, stream, format,
--- 296,308 ----
  	  /* Print the unmangled name if desired.  */
  	  /* Print vtable entry - we only get here if NOT using
  	     -fvtable_thunks.  (Otherwise, look under TYPE_CODE_PTR.) */
! 	  int offset = (embedded_offset +
! 			TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8);
! 	  struct type *field_type = TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET);
! 	  CORE_ADDR addr
! 	    = extract_typed_address (valaddr + offset, field_type);
! 
! 	  print_address_demangle (addr, stream, demangle);
  	}
        else
  	cp_print_value_fields (type, type, valaddr, embedded_offset, address, stream, format,
Index: gdb/cp-valprint.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/cp-valprint.c,v
retrieving revision 2.44
diff -c -r2.44 cp-valprint.c
*** gdb/cp-valprint.c	2000/02/01 03:09:00	2.44
--- gdb/cp-valprint.c	2000/04/10 18:22:21
***************
*** 429,435 ****
        /* pai: FIXME 32x64 problem? */
        /* Not sure what the best notation is in the case where there is no
           baseclass name.  */
!       v = value_from_longest (lookup_pointer_type (builtin_type_unsigned_long),
  			      *(unsigned long *) (valaddr + offset));
  
        val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, 0,
--- 429,435 ----
        /* pai: FIXME 32x64 problem? */
        /* Not sure what the best notation is in the case where there is no
           baseclass name.  */
!       v = value_from_pointer (lookup_pointer_type (builtin_type_unsigned_long),
  			      *(unsigned long *) (valaddr + offset));
  
        val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, 0,
Index: gdb/defs.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/defs.h,v
retrieving revision 1.304
diff -c -r1.304 defs.h
*** gdb/defs.h	2000/03/30 18:56:26	1.304
--- gdb/defs.h	2000/04/10 18:22:23
***************
*** 1067,1077 ****
--- 1067,1081 ----
  
  extern CORE_ADDR extract_address (void *, int);
  
+ extern CORE_ADDR extract_typed_address (void *buf, struct type *type);
+ 
  extern void store_signed_integer (void *, int, LONGEST);
  
  extern void store_unsigned_integer (void *, int, ULONGEST);
  
  extern void store_address (void *, int, LONGEST);
+ 
+ extern void store_typed_address (void *buf, struct type *type, CORE_ADDR addr);
  
  /* Setup definitions for host and target floating point formats.  We need to
     consider the format for `float', `double', and `long double' for both target
Index: gdb/eval.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/eval.c,v
retrieving revision 1.109
diff -c -r1.109 eval.c
*** gdb/eval.c	2000/04/10 07:47:24	1.109
--- gdb/eval.c	2000/04/10 18:22:25
***************
*** 832,839 ****
  	  /* Method invocation : stuff "this" as first parameter */
  	  /* pai: this used to have lookup_pointer_type for some reason,
  	   * but temp is already a pointer to the object */
! 	  argvec[1] = value_from_longest (VALUE_TYPE (temp),
! 				VALUE_ADDRESS (temp) + VALUE_OFFSET (temp));
  	  /* Name of method from expression */
  	  strcpy (tstr, &exp->elts[pc2 + 2].string);
  
--- 832,840 ----
  	  /* Method invocation : stuff "this" as first parameter */
  	  /* pai: this used to have lookup_pointer_type for some reason,
  	   * but temp is already a pointer to the object */
! 	  argvec[1]
! 	    = value_from_pointer (VALUE_TYPE (temp),
! 				  VALUE_ADDRESS (temp) + VALUE_OFFSET (temp));
  	  /* Name of method from expression */
  	  strcpy (tstr, &exp->elts[pc2 + 2].string);
  
***************
*** 1122,1128 ****
        /* Now, convert these values to an address.  */
        arg1 = value_cast (lookup_pointer_type (TYPE_DOMAIN_TYPE (type)),
  			 arg1);
!       arg3 = value_from_longest (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
  				 value_as_long (arg1) + mem_offset);
        return value_ind (arg3);
      bad_pointer_to_member:
--- 1123,1129 ----
        /* Now, convert these values to an address.  */
        arg1 = value_cast (lookup_pointer_type (TYPE_DOMAIN_TYPE (type)),
  			 arg1);
!       arg3 = value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
  				 value_as_long (arg1) + mem_offset);
        return value_ind (arg3);
      bad_pointer_to_member:
Index: gdb/findvar.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/findvar.c,v
retrieving revision 1.114
diff -c -r1.114 findvar.c
*** gdb/findvar.c	2000/04/03 07:19:10	1.114
--- gdb/findvar.c	2000/04/10 18:22:26
***************
*** 169,174 ****
--- 169,188 ----
    return 0;
  }
  
+ 
+ /* Treat the LEN bytes at ADDR as a target-format address, and return
+    that address.  ADDR is a buffer in the GDB process, not in the
+    inferior.
+ 
+    This function should only be used by target-specific code.  It
+    assumes that a pointer has the same representation as that thing's
+    address represented as an integer.  Some machines use word
+    addresses, or similarly munged things, for certain types of
+    pointers, so that assumption doesn't hold everywhere.
+ 
+    Common code should use extract_typed_address instead, or something
+    else based on POINTER_TO_ADDRESS.  */
+ 
  CORE_ADDR
  extract_address (void *addr, int len)
  {
***************
*** 177,182 ****
--- 191,215 ----
    return (CORE_ADDR) extract_unsigned_integer (addr, len);
  }
  
+ 
+ #ifndef POINTER_TO_ADDRESS
+ #define POINTER_TO_ADDRESS generic_pointer_to_address
+ #endif
+ 
+ /* Treat the bytes at BUF as a pointer of type TYPE, and return the
+    address it represents.  */
+ CORE_ADDR
+ extract_typed_address (void *buf, struct type *type)
+ {
+   if (TYPE_CODE (type) != TYPE_CODE_PTR
+       && TYPE_CODE (type) != TYPE_CODE_REF)
+     internal_error ("findvar.c (generic_pointer_to_address): "
+ 		    "type is not a pointer or reference");
+ 
+   return POINTER_TO_ADDRESS (type, buf);
+ }
+ 
+ 
  void
  store_signed_integer (void *addr, int len, LONGEST val)
  {
***************
*** 230,244 ****
  	}
      }
  }
  
! /* Store the literal address "val" into
!    gdb-local memory pointed to by "addr"
!    for "len" bytes. */
  void
  store_address (void *addr, int len, LONGEST val)
  {
    store_unsigned_integer (addr, len, val);
  }
  
  /* Extract a floating-point number from a target-order byte-stream at ADDR.
     Returns the value as type DOUBLEST.
--- 263,306 ----
  	}
      }
  }
+ 
+ /* Store the address VAL as a LEN-byte value in target byte order at
+    ADDR.  ADDR is a buffer in the GDB process, not in the inferior.
  
!    This function should only be used by target-specific code.  It
!    assumes that a pointer has the same representation as that thing's
!    address represented as an integer.  Some machines use word
!    addresses, or similarly munged things, for certain types of
!    pointers, so that assumption doesn't hold everywhere.
! 
!    Common code should use store_typed_address instead, or something else
!    based on ADDRESS_TO_POINTER.  */
  void
  store_address (void *addr, int len, LONGEST val)
  {
    store_unsigned_integer (addr, len, val);
  }
+ 
+ 
+ #ifndef ADDRESS_TO_POINTER
+ #define ADDRESS_TO_POINTER generic_address_to_pointer
+ #endif
+ 
+ /* Store the address ADDR as a pointer of type TYPE at BUF, in target
+    form.  */
+ void
+ store_typed_address (void *buf, struct type *type, CORE_ADDR addr)
+ {
+   if (TYPE_CODE (type) != TYPE_CODE_PTR
+       && TYPE_CODE (type) != TYPE_CODE_REF)
+     internal_error ("findvar.c (generic_address_to_pointer): "
+ 		    "type is not a pointer or reference");
+ 
+   ADDRESS_TO_POINTER (type, buf, addr);
+ }
+ 
+ 
+ 
  
  /* Extract a floating-point number from a target-order byte-stream at ADDR.
     Returns the value as type DOUBLEST.
***************
*** 445,451 ****
  	  if (raw_buffer != NULL)
  	    {
  	      /* Put it back in target format.  */
! 	      store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), (LONGEST) addr);
  	    }
  	  if (addrp != NULL)
  	    *addrp = 0;
--- 507,514 ----
  	  if (raw_buffer != NULL)
  	    {
  	      /* Put it back in target format.  */
! 	      store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
! 			     (LONGEST) addr);
  	    }
  	  if (addrp != NULL)
  	    *addrp = 0;
***************
*** 831,838 ****
    if (!register_valid[regno])
      target_fetch_registers (regno);
  
!   return (CORE_ADDR) extract_address (&registers[REGISTER_BYTE (regno)],
! 				      REGISTER_RAW_SIZE (regno));
  }
  
  CORE_ADDR
--- 894,902 ----
    if (!register_valid[regno])
      target_fetch_registers (regno);
  
!   return ((CORE_ADDR)
! 	  extract_unsigned_integer (&registers[REGISTER_BYTE (regno)],
! 				    REGISTER_RAW_SIZE (regno)));
  }
  
  CORE_ADDR
***************
*** 1150,1155 ****
--- 1214,1238 ----
  {
    TARGET_WRITE_FP (val);
  }
+ 
+ 
+ /* Given a pointer of type TYPE in target form in BUF, return the
+    address it represents.  */
+ CORE_ADDR
+ generic_pointer_to_address (struct type *type, char *buf)
+ {
+   return extract_address (buf, TYPE_LENGTH (type));
+ }
+ 
+ 
+ /* Given an address, store it as a pointer of type TYPE in target
+    format in BUF.  */
+ void
+ generic_address_to_pointer (struct type *type, char *buf, CORE_ADDR addr)
+ {
+   store_address (buf, TYPE_LENGTH (type), addr);
+ }
+ 
  
  /* Will calling read_var_value or locate_var_value on SYM end
     up caring what frame it is being evaluated relative to?  SYM must
***************
*** 1231,1242 ****
      case LOC_LABEL:
        /* Put the constant back in target format.  */
        if (overlay_debugging)
! 	store_address (VALUE_CONTENTS_RAW (v), len,
! 	     (LONGEST) symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var),
! 						 SYMBOL_BFD_SECTION (var)));
        else
! 	store_address (VALUE_CONTENTS_RAW (v), len,
! 		       (LONGEST) SYMBOL_VALUE_ADDRESS (var));
        VALUE_LVAL (v) = not_lval;
        return v;
  
--- 1314,1328 ----
      case LOC_LABEL:
        /* Put the constant back in target format.  */
        if (overlay_debugging)
! 	{
! 	  CORE_ADDR addr
! 	    = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var),
! 					SYMBOL_BFD_SECTION (var));
! 	  store_typed_address (VALUE_CONTENTS_RAW (v), type, addr);
! 	}
        else
! 	store_typed_address (VALUE_CONTENTS_RAW (v), type,
! 			      SYMBOL_VALUE_ADDRESS (var));
        VALUE_LVAL (v) = not_lval;
        return v;
  
***************
*** 1678,1684 ****
        value_ptr val;
  
        addr = VALUE_ADDRESS (lazy_value);
!       val = value_from_longest (lookup_pointer_type (type), (LONGEST) addr);
        VALUE_BFD_SECTION (val) = VALUE_BFD_SECTION (lazy_value);
        return val;
      }
--- 1764,1770 ----
        value_ptr val;
  
        addr = VALUE_ADDRESS (lazy_value);
!       val = value_from_pointer (lookup_pointer_type (type), addr);
        VALUE_BFD_SECTION (val) = VALUE_BFD_SECTION (lazy_value);
        return val;
      }
Index: gdb/gdbarch.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/gdbarch.c,v
retrieving revision 2.66
diff -c -r2.66 gdbarch.c
*** gdb/gdbarch.c	2000/04/10 07:47:24	2.66
--- gdb/gdbarch.c	2000/04/10 18:22:27
***************
*** 175,180 ****
--- 175,182 ----
    gdbarch_register_convertible_ftype *register_convertible;
    gdbarch_register_convert_to_virtual_ftype *register_convert_to_virtual;
    gdbarch_register_convert_to_raw_ftype *register_convert_to_raw;
+   gdbarch_pointer_to_address_ftype *pointer_to_address;
+   gdbarch_address_to_pointer_ftype *address_to_pointer;
    gdbarch_extract_return_value_ftype *extract_return_value;
    gdbarch_push_arguments_ftype *push_arguments;
    gdbarch_push_dummy_frame_ftype *push_dummy_frame;
***************
*** 309,314 ****
--- 311,318 ----
    0,
    0,
    0,
+   0,
+   0,
    /* startup_gdbarch() */
  };
  struct gdbarch *current_gdbarch = &startup_gdbarch;
***************
*** 351,356 ****
--- 355,362 ----
    gdbarch->call_dummy_stack_adjust_p = -1;
    gdbarch->coerce_float_to_double = default_coerce_float_to_double;
    gdbarch->register_convertible = generic_register_convertible_not;
+   gdbarch->pointer_to_address = generic_pointer_to_address;
+   gdbarch->address_to_pointer = generic_address_to_pointer;
    gdbarch->breakpoint_from_pc = legacy_breakpoint_from_pc;
    gdbarch->memory_insert_breakpoint = default_memory_insert_breakpoint;
    gdbarch->memory_remove_breakpoint = default_memory_remove_breakpoint;
***************
*** 517,522 ****
--- 523,530 ----
    /* Skip verify of register_convertible, invalid_p == 0 */
    /* Skip verify of register_convert_to_virtual, invalid_p == 0 */
    /* Skip verify of register_convert_to_raw, invalid_p == 0 */
+   /* Skip verify of pointer_to_address, invalid_p == 0 */
+   /* Skip verify of address_to_pointer, invalid_p == 0 */
    if ((GDB_MULTI_ARCH >= 2)
        && (gdbarch->extract_return_value == 0))
      internal_error ("gdbarch: verify_gdbarch: extract_return_value invalid");
***************
*** 793,798 ****
--- 801,814 ----
                        (long) current_gdbarch->register_convert_to_raw
                        /*REGISTER_CONVERT_TO_RAW ()*/);
    fprintf_unfiltered (gdb_stdlog,
+                       "gdbarch_update: POINTER_TO_ADDRESS = 0x%08lx\n",
+                       (long) current_gdbarch->pointer_to_address
+                       /*POINTER_TO_ADDRESS ()*/);
+   fprintf_unfiltered (gdb_stdlog,
+                       "gdbarch_update: ADDRESS_TO_POINTER = 0x%08lx\n",
+                       (long) current_gdbarch->address_to_pointer
+                       /*ADDRESS_TO_POINTER ()*/);
+   fprintf_unfiltered (gdb_stdlog,
                        "gdbarch_update: EXTRACT_RETURN_VALUE = 0x%08lx\n",
                        (long) current_gdbarch->extract_return_value
                        /*EXTRACT_RETURN_VALUE ()*/);
***************
*** 1778,1784 ****
--- 1794,1834 ----
    gdbarch->register_convert_to_raw = register_convert_to_raw;
  }
  
+ CORE_ADDR
+ gdbarch_pointer_to_address (struct gdbarch *gdbarch, struct type *type, char *buf)
+ {
+   if (gdbarch->pointer_to_address == 0)
+     internal_error ("gdbarch: gdbarch_pointer_to_address invalid");
+   if (gdbarch_debug >= 2)
+     fprintf_unfiltered (gdb_stdlog, "gdbarch_pointer_to_address called\n");
+   return gdbarch->pointer_to_address (type, buf);
+ }
+ 
+ void
+ set_gdbarch_pointer_to_address (struct gdbarch *gdbarch,
+                                 gdbarch_pointer_to_address_ftype pointer_to_address)
+ {
+   gdbarch->pointer_to_address = pointer_to_address;
+ }
+ 
+ void
+ gdbarch_address_to_pointer (struct gdbarch *gdbarch, struct type *type, char *buf, CORE_ADDR addr)
+ {
+   if (gdbarch->address_to_pointer == 0)
+     internal_error ("gdbarch: gdbarch_address_to_pointer invalid");
+   if (gdbarch_debug >= 2)
+     fprintf_unfiltered (gdb_stdlog, "gdbarch_address_to_pointer called\n");
+   gdbarch->address_to_pointer (type, buf, addr);
+ }
+ 
  void
+ set_gdbarch_address_to_pointer (struct gdbarch *gdbarch,
+                                 gdbarch_address_to_pointer_ftype address_to_pointer)
+ {
+   gdbarch->address_to_pointer = address_to_pointer;
+ }
+ 
+ void
  gdbarch_extract_return_value (struct gdbarch *gdbarch, struct type *type, char *regbuf, char *valbuf)
  {
    if (gdbarch->extract_return_value == 0)
***************
*** 3093,3098 ****
--- 3143,3149 ----
    return 0;
  }
    
+ 
  /* Disassembler */
  
  /* Pointer to the target-dependent disassembly function.  */
Index: gdb/gdbarch.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/gdbarch.h,v
retrieving revision 2.66
diff -c -r2.66 gdbarch.h
*** gdb/gdbarch.h	2000/04/03 07:19:10	2.66
--- gdb/gdbarch.h	2000/04/10 18:22:27
***************
*** 510,515 ****
--- 510,533 ----
  #endif
  #endif
  
+ typedef CORE_ADDR (gdbarch_pointer_to_address_ftype) (struct type *type, char *buf);
+ extern CORE_ADDR gdbarch_pointer_to_address (struct gdbarch *gdbarch, struct type *type, char *buf);
+ extern void set_gdbarch_pointer_to_address (struct gdbarch *gdbarch, gdbarch_pointer_to_address_ftype *pointer_to_address);
+ #if GDB_MULTI_ARCH
+ #if (GDB_MULTI_ARCH > 1) || !defined (POINTER_TO_ADDRESS)
+ #define POINTER_TO_ADDRESS(type, buf) (gdbarch_pointer_to_address (current_gdbarch, type, buf))
+ #endif
+ #endif
+ 
+ typedef void (gdbarch_address_to_pointer_ftype) (struct type *type, char *buf, CORE_ADDR addr);
+ extern void gdbarch_address_to_pointer (struct gdbarch *gdbarch, struct type *type, char *buf, CORE_ADDR addr);
+ extern void set_gdbarch_address_to_pointer (struct gdbarch *gdbarch, gdbarch_address_to_pointer_ftype *address_to_pointer);
+ #if GDB_MULTI_ARCH
+ #if (GDB_MULTI_ARCH > 1) || !defined (ADDRESS_TO_POINTER)
+ #define ADDRESS_TO_POINTER(type, buf, addr) (gdbarch_address_to_pointer (current_gdbarch, type, buf, addr))
+ #endif
+ #endif
+ 
  typedef void (gdbarch_extract_return_value_ftype) (struct type *type, char *regbuf, char *valbuf);
  extern void gdbarch_extract_return_value (struct gdbarch *gdbarch, struct type *type, char *regbuf, char *valbuf);
  extern void set_gdbarch_extract_return_value (struct gdbarch *gdbarch, gdbarch_extract_return_value_ftype *extract_return_value);
Index: gdb/gdbarch.sh
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/gdbarch.sh,v
retrieving revision 2.49
diff -c -r2.49 gdbarch.sh
*** gdb/gdbarch.sh	2000/04/03 07:19:10	2.49
--- gdb/gdbarch.sh	2000/04/10 18:22:28
***************
*** 239,244 ****
--- 239,247 ----
  f:2:REGISTER_CONVERT_TO_VIRTUAL:void:register_convert_to_virtual:int regnum, struct type *type, char *from, char *to:regnum, type, from, to:::0:0
  f:2:REGISTER_CONVERT_TO_RAW:void:register_convert_to_raw:struct type *type, int regnum, char *from, char *to:type, regnum, from, to:::0:0
  #
+ f:2:POINTER_TO_ADDRESS:CORE_ADDR:pointer_to_address:struct type *type, char *buf:type, buf:::generic_pointer_to_address:0
+ f:2:ADDRESS_TO_POINTER:void:address_to_pointer:struct type *type, char *buf, CORE_ADDR addr:type, buf, addr:::generic_address_to_pointer:0
+ #
  f:2:EXTRACT_RETURN_VALUE:void:extract_return_value:struct type *type, char *regbuf, char *valbuf:type, regbuf, valbuf::0:0
  f:1:PUSH_ARGUMENTS:CORE_ADDR:push_arguments:int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr:nargs, args, sp, struct_return, struct_addr::0:0
  f:2:PUSH_DUMMY_FRAME:void:push_dummy_frame:void:-:::0
***************
*** 1953,1958 ****
--- 1956,1962 ----
    return 0;
  }
    
+ 
  /* Disassembler */
  
  /* Pointer to the target-dependent disassembly function.  */
Index: gdb/hppa-tdep.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/hppa-tdep.c,v
retrieving revision 2.150
diff -c -r2.150 hppa-tdep.c
*** gdb/hppa-tdep.c	2000/02/09 08:53:12	2.150
--- gdb/hppa-tdep.c	2000/04/10 18:22:31
***************
*** 2005,2015 ****
    /* now prepare the arguments for the call */
  
    args[0] = value_from_longest (TYPE_FIELD_TYPE (ftype, 0), 12);
!   args[1] = value_from_longest (TYPE_FIELD_TYPE (ftype, 1), SYMBOL_VALUE_ADDRESS (msymbol));
!   args[2] = value_from_longest (TYPE_FIELD_TYPE (ftype, 2), endo_buff_addr);
    args[3] = value_from_longest (TYPE_FIELD_TYPE (ftype, 3), TYPE_PROCEDURE);
!   args[4] = value_from_longest (TYPE_FIELD_TYPE (ftype, 4), value_return_addr);
!   args[5] = value_from_longest (TYPE_FIELD_TYPE (ftype, 5), errno_return_addr);
  
    /* now call the function */
  
--- 2005,2015 ----
    /* now prepare the arguments for the call */
  
    args[0] = value_from_longest (TYPE_FIELD_TYPE (ftype, 0), 12);
!   args[1] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 1), SYMBOL_VALUE_ADDRESS (msymbol));
!   args[2] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 2), endo_buff_addr);
    args[3] = value_from_longest (TYPE_FIELD_TYPE (ftype, 3), TYPE_PROCEDURE);
!   args[4] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 4), value_return_addr);
!   args[5] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 5), errno_return_addr);
  
    /* now call the function */
  
Index: gdb/inferior.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/inferior.h,v
retrieving revision 1.77
diff -c -r1.77 inferior.h
*** gdb/inferior.h	2000/02/29 13:54:01	1.77
--- gdb/inferior.h	2000/04/10 18:22:31
***************
*** 156,161 ****
--- 156,166 ----
  
  extern void generic_target_write_fp PARAMS ((CORE_ADDR));
  
+ extern CORE_ADDR generic_pointer_to_address (struct type *type, char *buf);
+ 
+ extern void generic_address_to_pointer (struct type *type, char *buf,
+ 					CORE_ADDR addr);
+ 
  extern void wait_for_inferior PARAMS ((void));
  
  extern void fetch_inferior_event PARAMS ((void *));
Index: gdb/printcmd.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/printcmd.c,v
retrieving revision 1.162
diff -c -r1.162 printcmd.c
*** gdb/printcmd.c	2000/04/05 00:35:58	1.162
--- gdb/printcmd.c	2000/04/10 18:22:33
***************
*** 537,544 ****
  
    /* Make address available to the user as $_.  */
    set_internalvar (lookup_internalvar ("_"),
! 		value_from_longest (lookup_pointer_type (builtin_type_void),
! 				    (LONGEST) addr));
  }
  
  /* Optionally print address ADDR symbolically as <SYMBOL+OFFSET> on STREAM,
--- 537,544 ----
  
    /* Make address available to the user as $_.  */
    set_internalvar (lookup_internalvar ("_"),
! 		   value_from_pointer (lookup_pointer_type (builtin_type_void),
! 				       addr));
  }
  
  /* Optionally print address ADDR symbolically as <SYMBOL+OFFSET> on STREAM,
***************
*** 1396,1405 ****
      {
        /* Make last address examined available to the user as $_.  Use
           the correct pointer type.  */
        set_internalvar (lookup_internalvar ("_"),
! 		       value_from_longest (
! 		      lookup_pointer_type (VALUE_TYPE (last_examine_value)),
! 					    (LONGEST) last_examine_address));
  
        /* Make contents of last address examined available to the user as $__. */
        /* If the last value has not been fetched from memory then don't
--- 1396,1406 ----
      {
        /* Make last address examined available to the user as $_.  Use
           the correct pointer type.  */
+       struct type *pointer_type
+ 	= lookup_pointer_type (VALUE_TYPE (last_examine_value));
        set_internalvar (lookup_internalvar ("_"),
! 		       value_from_pointer (pointer_type,
! 					   last_examine_address));
  
        /* Make contents of last address examined available to the user as $__. */
        /* If the last value has not been fetched from memory then don't
Index: gdb/tracepoint.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/tracepoint.c,v
retrieving revision 2.52
diff -c -r2.52 tracepoint.c
*** gdb/tracepoint.c	1999/12/13 01:37:21	2.52
--- gdb/tracepoint.c	2000/04/10 18:22:34
***************
*** 268,278 ****
        traceframe_sal.pc = traceframe_sal.line = 0;
        traceframe_sal.symtab = NULL;
        set_internalvar (lookup_internalvar ("trace_func"),
! 		       value_from_longest (charstar, (LONGEST) 0));
        set_internalvar (lookup_internalvar ("trace_file"),
! 		       value_from_longest (charstar, (LONGEST) 0));
        set_internalvar (lookup_internalvar ("trace_line"),
! 		       value_from_longest (builtin_type_int, (LONGEST) - 1));
        return;
      }
  
--- 268,278 ----
        traceframe_sal.pc = traceframe_sal.line = 0;
        traceframe_sal.symtab = NULL;
        set_internalvar (lookup_internalvar ("trace_func"),
! 		       value_from_pointer (charstar, (LONGEST) 0));
        set_internalvar (lookup_internalvar ("trace_file"),
! 		       value_from_pointer (charstar, (LONGEST) 0));
        set_internalvar (lookup_internalvar ("trace_line"),
! 		       value_from_pointer (builtin_type_int, (LONGEST) - 1));
        return;
      }
  
***************
*** 289,295 ****
    if (traceframe_fun == NULL ||
        SYMBOL_NAME (traceframe_fun) == NULL)
      set_internalvar (lookup_internalvar ("trace_func"),
! 		     value_from_longest (charstar, (LONGEST) 0));
    else
      {
        len = strlen (SYMBOL_NAME (traceframe_fun));
--- 289,295 ----
    if (traceframe_fun == NULL ||
        SYMBOL_NAME (traceframe_fun) == NULL)
      set_internalvar (lookup_internalvar ("trace_func"),
! 		     value_from_pointer (charstar, (LONGEST) 0));
    else
      {
        len = strlen (SYMBOL_NAME (traceframe_fun));
***************
*** 310,316 ****
    if (traceframe_sal.symtab == NULL ||
        traceframe_sal.symtab->filename == NULL)
      set_internalvar (lookup_internalvar ("trace_file"),
! 		     value_from_longest (charstar, (LONGEST) 0));
    else
      {
        len = strlen (traceframe_sal.symtab->filename);
--- 310,316 ----
    if (traceframe_sal.symtab == NULL ||
        traceframe_sal.symtab->filename == NULL)
      set_internalvar (lookup_internalvar ("trace_file"),
! 		     value_from_pointer (charstar, (LONGEST) 0));
    else
      {
        len = strlen (traceframe_sal.symtab->filename);
Index: gdb/valarith.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/valarith.c,v
retrieving revision 1.60
diff -c -r1.60 valarith.c
*** gdb/valarith.c	1999/12/13 18:00:13	1.60
--- gdb/valarith.c	2000/04/10 18:22:35
***************
*** 79,86 ****
        len = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (valptrtype)));
        if (len == 0)
  	len = 1;		/* For (void *) */
!       retval = value_from_longest (valptrtype,
! 				   value_as_long (valptr)
  				   + (len * value_as_long (valint)));
        VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (valptr);
        return retval;
--- 79,86 ----
        len = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (valptrtype)));
        if (len == 0)
  	len = 1;		/* For (void *) */
!       retval = value_from_pointer (valptrtype,
! 				   value_as_pointer (valptr)
  				   + (len * value_as_long (valint)));
        VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (valptr);
        return retval;
***************
*** 105,113 ****
  	{
  	  /* pointer - integer.  */
  	  LONGEST sz = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1)));
! 	  return value_from_longest
! 	    (VALUE_TYPE (arg1),
! 	     value_as_long (arg1) - (sz * value_as_long (arg2)));
  	}
        else if (TYPE_CODE (type2) == TYPE_CODE_PTR
  	       && TYPE_LENGTH (TYPE_TARGET_TYPE (type1))
--- 105,113 ----
  	{
  	  /* pointer - integer.  */
  	  LONGEST sz = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1)));
! 	  return value_from_pointer (VALUE_TYPE (arg1),
! 				     (value_as_pointer (arg1)
! 				      - (sz * value_as_long (arg2))));
  	}
        else if (TYPE_CODE (type2) == TYPE_CODE_PTR
  	       && TYPE_LENGTH (TYPE_TARGET_TYPE (type1))
Index: gdb/valops.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/valops.c,v
retrieving revision 1.189
diff -c -r1.189 valops.c
*** gdb/valops.c	2000/04/10 07:47:25	1.189
--- gdb/valops.c	2000/04/10 18:22:37
***************
*** 108,119 ****
        if (msymbol != NULL)
  	{
  	  struct type *type;
! 	  LONGEST maddr;
  	  type = lookup_pointer_type (builtin_type_char);
  	  type = lookup_function_type (type);
  	  type = lookup_pointer_type (type);
! 	  maddr = (LONGEST) SYMBOL_VALUE_ADDRESS (msymbol);
! 	  return value_from_longest (type, maddr);
  	}
        else
  	{
--- 108,119 ----
        if (msymbol != NULL)
  	{
  	  struct type *type;
! 	  CORE_ADDR maddr;
  	  type = lookup_pointer_type (builtin_type_char);
  	  type = lookup_function_type (type);
  	  type = lookup_pointer_type (type);
! 	  maddr = SYMBOL_VALUE_ADDRESS (msymbol);
! 	  return value_from_pointer (type, maddr);
  	}
        else
  	{
***************
*** 901,908 ****
    if (VALUE_LVAL (arg1) != lval_memory)
      error ("Attempt to take address of value not located in memory.");
  
!   return value_from_longest (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
! 		    (LONGEST) (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1)));
  }
  
  /* Given a value which is a function, return a value which is a pointer
--- 901,908 ----
    if (VALUE_LVAL (arg1) != lval_memory)
      error ("Attempt to take address of value not located in memory.");
  
!   return value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
! 			     (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1)));
  }
  
  /* Given a value which is a function, return a value which is a pointer
***************
*** 917,924 ****
    if (VALUE_LVAL (arg1) != lval_memory)
      error ("Attempt to take address of value not located in memory.");
  
!   retval = value_from_longest (lookup_pointer_type (VALUE_TYPE (arg1)),
! 		    (LONGEST) (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1)));
    VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (arg1);
    return retval;
  }
--- 917,924 ----
    if (VALUE_LVAL (arg1) != lval_memory)
      error ("Attempt to take address of value not located in memory.");
  
!   retval = value_from_pointer (lookup_pointer_type (VALUE_TYPE (arg1)),
! 			       (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1)));
    VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (arg1);
    return retval;
  }
***************
*** 948,957 ****
      error ("Attempt to take address of value not located in memory.");
  
    /* Get target memory address */
!   arg2 = value_from_longest (lookup_pointer_type (VALUE_TYPE (arg1)),
! 			     (LONGEST) (VALUE_ADDRESS (arg1)
! 					+ VALUE_OFFSET (arg1)
! 					+ VALUE_EMBEDDED_OFFSET (arg1)));
  
    /* This may be a pointer to a base subobject; so remember the
       full derived object's type ... */
--- 948,957 ----
      error ("Attempt to take address of value not located in memory.");
  
    /* Get target memory address */
!   arg2 = value_from_pointer (lookup_pointer_type (VALUE_TYPE (arg1)),
! 			     (VALUE_ADDRESS (arg1)
! 			      + VALUE_OFFSET (arg1)
! 			      + VALUE_EMBEDDED_OFFSET (arg1)));
  
    /* This may be a pointer to a base subobject; so remember the
       full derived object's type ... */
***************
*** 1582,1589 ****
  	       we just pushed.  */
  	    /*args[i] = value_from_longest (lookup_pointer_type (value_type),
  	       (LONGEST) addr); */
! 	    args[i] = value_from_longest (lookup_pointer_type (arg_type),
! 					  (LONGEST) addr);
  	  }
        }
    }
--- 1582,1589 ----
  	       we just pushed.  */
  	    /*args[i] = value_from_longest (lookup_pointer_type (value_type),
  	       (LONGEST) addr); */
! 	    args[i] = value_from_pointer (lookup_pointer_type (arg_type),
! 					  addr);
  	  }
        }
    }
Index: gdb/value.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/value.h,v
retrieving revision 1.86
diff -c -r1.86 value.h
*** gdb/value.h	2000/02/22 22:29:24	1.86
--- gdb/value.h	2000/04/10 18:22:38
***************
*** 186,193 ****
  do { struct type *value_type_arg_tmp = check_typedef (VALUE_TYPE (arg));\
       if (TYPE_CODE (value_type_arg_tmp) == TYPE_CODE_REF)		\
  	 arg = value_at_lazy (TYPE_TARGET_TYPE (value_type_arg_tmp),	\
! 			      unpack_long (VALUE_TYPE (arg),		\
! 					   VALUE_CONTENTS (arg)),       \
  			      VALUE_BFD_SECTION (arg));			\
      } while (0)
  
--- 186,193 ----
  do { struct type *value_type_arg_tmp = check_typedef (VALUE_TYPE (arg));\
       if (TYPE_CODE (value_type_arg_tmp) == TYPE_CODE_REF)		\
  	 arg = value_at_lazy (TYPE_TARGET_TYPE (value_type_arg_tmp),	\
! 			      unpack_pointer (VALUE_TYPE (arg),		\
! 					      VALUE_CONTENTS (arg)),    \
  			      VALUE_BFD_SECTION (arg));			\
      } while (0)
  
***************
*** 263,268 ****
--- 263,270 ----
  					     int fieldno));
  
  extern value_ptr value_from_longest PARAMS ((struct type * type, LONGEST num));
+ 
+ extern value_ptr value_from_pointer (struct type *type, CORE_ADDR addr);
  
  extern value_ptr value_from_double PARAMS ((struct type * type, DOUBLEST num));
  
Index: gdb/values.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/values.c,v
retrieving revision 1.117
diff -c -r1.117 values.c
*** gdb/values.c	2000/04/10 07:47:25	1.117
--- gdb/values.c	2000/04/10 18:22:39
***************
*** 580,587 ****
      error ("Invalid floating value found in program.");
    return foo;
  }
! /* Extract a value as a C pointer.
!    Does not deallocate the value.  */
  CORE_ADDR
  value_as_pointer (val)
       value_ptr val;
--- 580,588 ----
      error ("Invalid floating value found in program.");
    return foo;
  }
! /* 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_pointer (val)
       value_ptr val;
***************
*** 649,655 ****
        if (GDB_TARGET_IS_D10V
  	  && len == 2)
  	return D10V_MAKE_DADDR (extract_address (valaddr, len));
!       return extract_address (valaddr, len);
  
      case TYPE_CODE_MEMBER:
        error ("not implemented: member types in unpack_long");
--- 650,656 ----
        if (GDB_TARGET_IS_D10V
  	  && len == 2)
  	return D10V_MAKE_DADDR (extract_address (valaddr, len));
!       return extract_typed_address (valaddr, type);
  
      case TYPE_CODE_MEMBER:
        error ("not implemented: member types in unpack_long");
***************
*** 731,736 ****
--- 732,738 ----
       whether we want this to be true eventually.  */
    return unpack_long (type, valaddr);
  }
+ 
  
  /* Get the value of the FIELDN'th field (which must be static) of TYPE. */
  
***************
*** 1420,1428 ****
  
      case TYPE_CODE_REF:
      case TYPE_CODE_PTR:
!       /* This assumes that all pointers of a given length
!          have the same form.  */
!       store_address (VALUE_CONTENTS_RAW (val), len, (CORE_ADDR) num);
        break;
  
      default:
--- 1422,1428 ----
  
      case TYPE_CODE_REF:
      case TYPE_CODE_PTR:
!       store_typed_address (VALUE_CONTENTS_RAW (val), type, (CORE_ADDR) num);
        break;
  
      default:
***************
*** 1430,1435 ****
--- 1430,1447 ----
      }
    return val;
  }
+ 
+ 
+ /* Create a value representing a pointer of type TYPE to the address
+    ADDR.  */
+ value_ptr
+ value_from_pointer (struct type *type, CORE_ADDR addr)
+ {
+   value_ptr val = allocate_value (type);
+   store_typed_address (VALUE_CONTENTS_RAW (val), type, addr);
+   return val;
+ }
+ 
  
  /* Create a value for a string constant to be stored locally
     (not in the inferior's memory space, but in GDB memory).

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