[gnu.gdb.bug] gdb lazy evaluation feature

bill@HARVARD.HARVARD.EDU (07/08/89)

Dear gdb wizards:

I have been using gdb for debugging programs which declare very large
static structures.  Until I made the changes below, the response
time for examining elements of these structures was many seconds on
my sun3/4 workstations.  That was because the entire struct was being
ptrace-fetched, then the element was extracted from the copy.

These changes delay the data fetching until an actual value is
required by gdb.  They seem to me to be within the spirit of the
implementation; although extensive they were completed within about
two days elapsed time, including debugging.  (Any changes associated
with C++ have not been tested.)

The basic idea is to modify VALUE_CONTENTS to test the new VALUE_LAZY
flag and call value_lazy to fetch the value only if necessary.
VALUE_CONTENTS_RAW is substituted for VALUE_CONTENTS in cases
where the test is inappropriate.

I've also added tests for the quit_flag in the ptrace loop to allow
the user to abort long fetches.

I also modified the print-line logic to print filename:linenum in
most cases; this is useful when you use the command 'list routine-name',
without knowing what file the routine is in.

Here's rcsdiff -c (the context diff switch set):

*** /tmp/,RCSt1a13484	Fri Jul  7 18:25:38 1989
--- value.h	Fri Mar 24 09:51:46 1989
***************
*** 83,90 ****
         if you take a field of a structure that is stored in a
         register.  Shouldn't it be?  */
      short regno;
      /* Actual contents of the value.  For use of this value; setting
!        it uses the stuff above.  */
      long contents[1];
    };
  
--- 83,93 ----
         if you take a field of a structure that is stored in a
         register.  Shouldn't it be?  */
      short regno;
+     /* Flag for lazy evaluation of lval's; if non-zero, contents have not
+        yet been fetched and must not be used.  */
+     short lazy;
      /* Actual contents of the value.  For use of this value; setting
!        it uses the stuff above.  Not valid yet if lazy is true.  */
      long contents[1];
    };
  
***************
*** 91,97 ****
  typedef struct value *value;
  
  #define VALUE_TYPE(val) (val)->type
! #define VALUE_CONTENTS(val) ((char *) (val)->contents)
  #define VALUE_LVAL(val) (val)->lval
  #define VALUE_ADDRESS(val) (val)->location.address
  #define VALUE_INTERNALVAR(val) (val)->location.internalvar
--- 94,103 ----
  typedef struct value *value;
  
  #define VALUE_TYPE(val) (val)->type
! #define VALUE_LAZY(val) (val)->lazy
! #define VALUE_CONTENTS_RAW(val) ((char *) (val)->contents)
! #define VALUE_CONTENTS(val) ((VALUE_LAZY(val) && value_lazy(val)),    \
! 			     VALUE_CONTENTS_RAW(val))
  #define VALUE_LVAL(val) (val)->lval
  #define VALUE_ADDRESS(val) (val)->location.address
  #define VALUE_INTERNALVAR(val) (val)->location.internalvar
***************
*** 147,152 ****
--- 153,159 ----
  value value_from_long ();
  value value_from_double ();
  value value_at ();
+ value value_at_lazy ();
  value value_from_register ();
  value value_of_variable ();
  value value_of_register ();
*** /tmp/,RCSt1a13489	Fri Jul  7 18:25:41 1989
--- findvar.c	Tue Mar 28 17:38:54 1989
***************
*** 44,50 ****
  
  #ifdef HAVE_REGISTER_WINDOWS
    /* We assume that a register in a register window will only be saved
!      in one place (since the name changes and dissapears as you go
       towards inner frames), so we only call get_frame_saved_regs on
       the current frame.  This is directly in contradiction to the
       usage below, which assumes that registers used in a frame must be
--- 44,50 ----
  
  #ifdef HAVE_REGISTER_WINDOWS
    /* We assume that a register in a register window will only be saved
!      in one place (since the name changes and disappears as you go
       towards inner frames), so we only call get_frame_saved_regs on
       the current frame.  This is directly in contradiction to the
       usage below, which assumes that registers used in a frame must be
***************
*** 144,150 ****
  
    REGISTER_CONVERT_TO_VIRTUAL (regnum, raw_buffer, virtual_buffer);
    val = allocate_value (REGISTER_VIRTUAL_TYPE (regnum));
!   bcopy (virtual_buffer, VALUE_CONTENTS (val), REGISTER_VIRTUAL_SIZE (regnum));
    VALUE_LVAL (val) = addr ? lval_memory : lval_register;
    VALUE_ADDRESS (val) = addr ? addr : REGISTER_BYTE (regnum);
    VALUE_REGNO (val) = regnum;
--- 144,151 ----
  
    REGISTER_CONVERT_TO_VIRTUAL (regnum, raw_buffer, virtual_buffer);
    val = allocate_value (REGISTER_VIRTUAL_TYPE (regnum));
!   bcopy (virtual_buffer, VALUE_CONTENTS_RAW (val), 
! 	 REGISTER_VIRTUAL_SIZE (regnum));
    VALUE_LVAL (val) = addr ? lval_memory : lval_register;
    VALUE_ADDRESS (val) = addr ? addr : REGISTER_BYTE (regnum);
    VALUE_REGNO (val) = regnum;
***************
*** 255,266 ****
      {
      case LOC_CONST:
      case LOC_LABEL:
!       bcopy (&val, VALUE_CONTENTS (v), len);
        VALUE_LVAL (v) = not_lval;
        return v;
  
      case LOC_CONST_BYTES:
!       bcopy (val, VALUE_CONTENTS (v), len);
        VALUE_LVAL (v) = not_lval;
        return v;
  
--- 256,267 ----
      {
      case LOC_CONST:
      case LOC_LABEL:
!       bcopy (&val, VALUE_CONTENTS_RAW (v), len);
        VALUE_LVAL (v) = not_lval;
        return v;
  
      case LOC_CONST_BYTES:
!       bcopy (val, VALUE_CONTENTS_RAW (v), len);
        VALUE_LVAL (v) = not_lval;
        return v;
  
***************
*** 291,298 ****
        return v;
      }
  
-   read_memory (addr, VALUE_CONTENTS (v), len);
    VALUE_ADDRESS (v) = addr;
    return v;
  }
  
--- 292,299 ----
        return v;
      }
  
    VALUE_ADDRESS (v) = addr;
+   VALUE_LAZY (v) = 1;
    return v;
  }
  
***************
*** 383,394 ****
  	fatal ("value_from_register: Value not stored anywhere!");
        
        /* Any structure stored in more than one register will always be
! 	 an inegral number of registers.  Otherwise, you'd need to do
  	 some fiddling with the last register copied here for little
  	 endian machines.  */
  
        /* Copy into the contents section of the value.  */
!       bcopy (value_bytes, VALUE_CONTENTS (v), len);
  
        return v;
      }
--- 384,395 ----
  	fatal ("value_from_register: Value not stored anywhere!");
        
        /* Any structure stored in more than one register will always be
! 	 an integral number of registers.  Otherwise, you'd need to do
  	 some fiddling with the last register copied here for little
  	 endian machines.  */
  
        /* Copy into the contents section of the value.  */
!       bcopy (value_bytes, VALUE_CONTENTS_RAW (v), len);
  
        return v;
      }
***************
*** 435,445 ****
  	     with raw type `extended' and virtual type `double'.
  	     Fetch it as a `double' and then convert to `float'.  */
  	  v = allocate_value (REGISTER_VIRTUAL_TYPE (regnum));
! 	  bcopy (virtual_buffer, VALUE_CONTENTS (v), len);
  	  v = value_cast (type, v);
  	}
        else
! 	bcopy (virtual_buffer, VALUE_CONTENTS (v), len);
      }
    else
      {
--- 436,446 ----
  	     with raw type `extended' and virtual type `double'.
  	     Fetch it as a `double' and then convert to `float'.  */
  	  v = allocate_value (REGISTER_VIRTUAL_TYPE (regnum));
! 	  bcopy (virtual_buffer, VALUE_CONTENTS_RAW (v), len);
  	  v = value_cast (type, v);
  	}
        else
! 	bcopy (virtual_buffer, VALUE_CONTENTS_RAW (v), len);
      }
    else
      {
***************
*** 456,462 ****
  	}
        
        bcopy (virtual_buffer + VALUE_OFFSET (v),
! 	     VALUE_CONTENTS (v), len);
      }
    
    return v;
--- 457,463 ----
  	}
        
        bcopy (virtual_buffer + VALUE_OFFSET (v),
! 	     VALUE_CONTENTS_RAW (v), len);
      }
    
    return v;
*** /tmp/,RCSt1a13494	Fri Jul  7 18:25:45 1989
--- default-dep.c	Fri Mar 24 16:55:19 1989
***************
*** 194,199 ****
--- 194,201 ----
  	buffer[i] = ptrace (1, inferior_pid, addr, 0);
        if (errno)
  	return errno;
+       if (quit_flag)
+ 	error("abandoning read from remote memory");
      }
  
    /* Copy appropriate bytes out of the buffer.  */
*** /tmp/,RCSt1a13499	Fri Jul  7 18:25:48 1989
--- gould-dep.c	Fri Mar 24 16:55:16 1989
***************
*** 189,194 ****
--- 189,196 ----
  	buffer[i] = ptrace (1, inferior_pid, addr, 0);
        if (errno)
  	return errno;
+       if (quit_flag)
+ 	error("abandoning read from remote memory");
      }
  
    /* Copy appropriate bytes out of the buffer.  */
*** /tmp/,RCSt1a13504	Fri Jul  7 18:25:51 1989
--- umax-dep.c	Fri Mar 24 16:55:12 1989
***************
*** 220,225 ****
--- 220,227 ----
  	buffer[i] = ptrace (1, inferior_pid, addr, 0);
        if (errno)
  	return errno;
+       if (quit_flag)
+ 	error("abandoning read from remote memory");
      }
  
    /* Copy appropriate bytes out of the buffer.  */
*** /tmp/,RCSt1a13509	Fri Jul  7 18:25:54 1989
--- news-dep.c	Fri Mar 24 16:55:07 1989
***************
*** 193,198 ****
--- 193,200 ----
  	buffer[i] = ptrace (1, inferior_pid, addr, 0);
        if (errno)
  	return errno;
+       if (quit_flag)
+ 	error("abandoning read from remote memory");
      }
  
    /* Copy appropriate bytes out of the buffer.  */
*** /tmp/,RCSt1a13514	Fri Jul  7 18:25:57 1989
--- source.c	Fri Mar 24 16:55:03 1989
***************
*** 684,695 ****
  			sal_end.line + 1, 0);
    else if (sal.symtab == 0)
      error ("No default source file yet.  Do \"help list\".");
-   else if (no_end)
-     print_source_lines (sal.symtab, max (sal.line - 5, 1), sal.line + 5, 0);
    else
!     print_source_lines (sal.symtab, sal.line,
! 			dummy_end ? sal.line + 10 : sal_end.line + 1,
! 			0);
  }
  
  /* Print info on range of pc's in a specified line.  */
--- 684,702 ----
  			sal_end.line + 1, 0);
    else if (sal.symtab == 0)
      error ("No default source file yet.  Do \"help list\".");
    else
!     {
!       if (! linenum_beg)
! 	printf ("(%s:%d)\n", sal.symtab->filename, sal.line);
! 
!       if (no_end)
! 	print_source_lines (sal.symtab, max (sal.line - 5, 1), 
! 			    sal.line + 5, 0);
!       else
! 	print_source_lines (sal.symtab, sal.line,
! 			    dummy_end ? sal.line + 10 : sal_end.line + 1,
! 			    0);
!     }
  }
  
  /* Print info on range of pc's in a specified line.  */
*** /tmp/,RCSt1a13519	Fri Jul  7 18:26:01 1989
--- sun3-dep.c	Fri Mar 24 16:48:37 1989
***************
*** 226,231 ****
--- 226,233 ----
  	buffer[i] = ptrace (1, inferior_pid, addr, 0);
        if (errno)
  	return errno;
+       if (quit_flag)
+ 	error("abandoning read from remote memory");
      }
  
    /* Copy appropriate bytes out of the buffer.  */
*** /tmp/,RCSt1a13524	Fri Jul  7 18:26:05 1989
--- sparc-dep.c	Fri Mar 24 16:48:06 1989
***************
*** 350,355 ****
--- 350,357 ----
  	buffer[i] = ptrace (1, inferior_pid, addr, 0);
        if (errno)
  	return errno;
+       if (quit_flag)
+ 	error("abandoning read from remote memory");
      }
  
    /* Copy appropriate bytes out of the buffer.  */
*** /tmp/,RCSt1a13529	Fri Jul  7 18:26:09 1989
--- hp9k320-dep.c	Fri Mar 24 16:47:00 1989
***************
*** 267,272 ****
--- 267,274 ----
  	buffer[i] = ptrace (1, inferior_pid, addr, 0);
        if (errno)
  	return errno;
+       if (quit_flag)
+ 	error("abandoning read from remote memory");
      }
  
    /* Copy appropriate bytes out of the buffer.  */
*** /tmp/,RCSt1a13534	Fri Jul  7 18:26:13 1989
--- i386-dep.c	Fri Mar 24 16:45:08 1989
***************
*** 202,207 ****
--- 202,209 ----
  	buffer[i] = ptrace (1, inferior_pid, addr, 0);
        if (errno)
  	return errno;
+       if (quit_flag)
+ 	error("abandoning read from remote memory");
      }
  
    /* Copy appropriate bytes out of the buffer.  */
*** /tmp/,RCSt1a13539	Fri Jul  7 18:26:17 1989
--- valops.c	Fri Mar 24 12:07:31 1989
***************
*** 60,66 ****
      }
    else if (VALUE_LVAL (arg2) == lval_memory)
      {
!       return value_at (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2));
      }
    else
      error ("Invalid cast.");
--- 60,66 ----
      }
    else if (VALUE_LVAL (arg2) == lval_memory)
      {
!       return value_at_lazy (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2));
      }
    else
      error ("Invalid cast.");
***************
*** 76,82 ****
    register value val = allocate_value (type);
    int temp;
  
!   temp = read_memory (addr, VALUE_CONTENTS (val), TYPE_LENGTH (type));
    if (temp)
      {
        if (have_inferior_p ())
--- 76,82 ----
    register value val = allocate_value (type);
    int temp;
  
!   temp = read_memory (addr, VALUE_CONTENTS_RAW (val), TYPE_LENGTH (type));
    if (temp)
      {
        if (have_inferior_p ())
***************
*** 91,96 ****
--- 91,134 ----
    return val;
  }
  
+ /* Return a lazy value with a specified type located at specified address.  */
+ 
+ value
+ value_at_lazy (type, addr)
+      struct type *type;
+      CORE_ADDR addr;
+ {
+   register value val = allocate_value (type);
+ 
+   VALUE_LVAL (val) = lval_memory;
+   VALUE_ADDRESS (val) = addr;
+   VALUE_LAZY (val) = 1;
+ 
+   return val;
+ }
+ 
+ /* Get the real value for lazy evaluation. */
+ 
+ value_lazy (val)
+      register value val;
+ {
+   CORE_ADDR addr = VALUE_ADDRESS (val) + VALUE_OFFSET (val);
+   int temp;
+ 
+   temp = read_memory (addr, 
+ 		      VALUE_CONTENTS_RAW (val), 
+ 		      TYPE_LENGTH (VALUE_TYPE (val)));
+   if (temp)
+     {
+       if (have_inferior_p ())
+ 	print_sys_errmsg ("ptrace", temp);
+       /* Actually, address between addr and addr + len was out of bounds. */
+       error ("Cannot read memory: address 0x%x out of bounds.", addr);
+     }
+ 
+   VALUE_LAZY (val) = 0;
+ }
+ 
  /* Store the contents of FROMVAL into the location of TOVAL.
     Return a new value with the location of TOVAL and contents of FROMVAL.  */
  
***************
*** 258,265 ****
    /* Return a value just like TOVAL except with the contents of FROMVAL.  */
  
    val = allocate_value (type);
!   bcopy (toval, val, VALUE_CONTENTS (val) - (char *) val);
!   bcopy (VALUE_CONTENTS (fromval), VALUE_CONTENTS (val), TYPE_LENGTH (type));
  
    return val;
  }
--- 296,303 ----
    /* Return a value just like TOVAL except with the contents of FROMVAL.  */
  
    val = allocate_value (type);
!   bcopy (toval, val, VALUE_CONTENTS_RAW (val) - (char *) val);
!   bcopy (VALUE_CONTENTS (fromval), VALUE_CONTENTS_RAW (val), TYPE_LENGTH (type));
  
    return val;
  }
***************
*** 281,287 ****
    val = allocate_repeat_value (VALUE_TYPE (arg1), count);
  
    read_memory (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1),
! 	       VALUE_CONTENTS (val),
  	       TYPE_LENGTH (VALUE_TYPE (val)) * count);
    VALUE_LVAL (val) = lval_memory;
    VALUE_ADDRESS (val) = VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1);
--- 319,325 ----
    val = allocate_repeat_value (VALUE_TYPE (arg1), count);
  
    read_memory (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1),
! 	       VALUE_CONTENTS_RAW (val),
  	       TYPE_LENGTH (VALUE_TYPE (val)) * count);
    VALUE_LVAL (val) = lval_memory;
    VALUE_ADDRESS (val) = VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1);
***************
*** 374,380 ****
      return value_at (builtin_type_long,
  		     (CORE_ADDR) value_as_long (arg1));
    else if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR)
!     return value_at (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)),
  		     (CORE_ADDR) value_as_long (arg1));
    else if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF)
      return value_at (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)),
--- 412,418 ----
      return value_at (builtin_type_long,
  		     (CORE_ADDR) value_as_long (arg1));
    else if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR)
!     return value_at_lazy (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)),
  		     (CORE_ADDR) value_as_long (arg1));
    else if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF)
      return value_at (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)),
*** /tmp/,RCSt1a13544	Fri Jul  7 18:26:22 1989
--- valarith.c	Fri Mar 24 11:07:35 1989
***************
*** 326,332 ****
  	}
  
        val = allocate_value (builtin_type_double);
!       *(double *) VALUE_CONTENTS (val) = v;
      }
    else
      {
--- 326,332 ----
  	}
  
        val = allocate_value (builtin_type_double);
!       *(double *) VALUE_CONTENTS_RAW (val) = v;
      }
    else
      {
***************
*** 397,403 ****
  	}
  
        val = allocate_value (BUILTIN_TYPE_LONGEST);
!       *(LONGEST *) VALUE_CONTENTS (val) = v;
      }
  
    return val;
--- 397,403 ----
  	}
  
        val = allocate_value (BUILTIN_TYPE_LONGEST);
!       *(LONGEST *) VALUE_CONTENTS_RAW (val) = v;
      }
  
    return val;
*** /tmp/,RCSt1a13549	Fri Jul  7 18:26:25 1989
--- eval.c	Fri Mar 24 11:07:27 1989
***************
*** 707,713 ****
        arg1 = evaluate_subexp (expect_type, exp, pos, noside);
        if (noside == EVAL_SKIP)
  	goto nosideret;
!       return value_at (exp->elts[pc + 1].type,
  		       (CORE_ADDR) value_as_long (arg1));
  
      case UNOP_PREINCREMENT:
--- 707,713 ----
        arg1 = evaluate_subexp (expect_type, exp, pos, noside);
        if (noside == EVAL_SKIP)
  	goto nosideret;
!       return value_at_lazy (exp->elts[pc + 1].type,
  		       (CORE_ADDR) value_as_long (arg1));
  
      case UNOP_PREINCREMENT:
*** /tmp/,RCSt1a13554	Fri Jul  7 18:26:29 1989
--- values.c	Thu Mar 23 17:46:48 1989
***************
*** 73,78 ****
--- 73,79 ----
    VALUE_REPEATED (val) = 0;
    VALUE_REPETITIONS (val) = 0;
    VALUE_REGNO (val) = -1;
+   VALUE_LAZY (val) = 0;
    return val;
  }
  
***************
*** 99,104 ****
--- 100,106 ----
    VALUE_REPEATED (val) = 1;
    VALUE_REPETITIONS (val) = count;
    VALUE_REGNO (val) = -1;
+   VALUE_LAZY (val) = 0;
    return val;
  }
  
***************
*** 164,172 ****
    VALUE_BITPOS (val) = VALUE_BITPOS (arg);
    VALUE_BITSIZE (val) = VALUE_BITSIZE (arg);
    VALUE_REGNO (val) = VALUE_REGNO (arg);
!   bcopy (VALUE_CONTENTS (arg), VALUE_CONTENTS (val),
! 	 TYPE_LENGTH (VALUE_TYPE (arg))
! 	 * (VALUE_REPEATED (arg) ? VALUE_REPETITIONS (arg) : 1));
    return val;
  }
  
--- 166,178 ----
    VALUE_BITPOS (val) = VALUE_BITPOS (arg);
    VALUE_BITSIZE (val) = VALUE_BITSIZE (arg);
    VALUE_REGNO (val) = VALUE_REGNO (arg);
!   VALUE_LAZY (val) = VALUE_LAZY (arg);
!   if (!VALUE_LAZY (val))
!     {
!       bcopy (VALUE_CONTENTS_RAW (arg), VALUE_CONTENTS_RAW (val),
! 	     TYPE_LENGTH (VALUE_TYPE (arg))
! 	     * (VALUE_REPEATED (arg) ? VALUE_REPETITIONS (arg) : 1));
!     }
    return val;
  }
  
***************
*** 340,346 ****
       int offset, bitpos, bitsize;
       value newval;
  {
!   register char *addr = VALUE_CONTENTS (var->value) + offset;
    if (bitsize)
      modify_field (addr, (int) value_as_long (newval),
  		  bitpos, bitsize);
--- 346,352 ----
       int offset, bitpos, bitsize;
       value newval;
  {
!   register char *addr = VALUE_CONTENTS_RAW (var->value) + offset;
    if (bitsize)
      modify_field (addr, (int) value_as_long (newval),
  		  bitpos, bitsize);
***************
*** 595,603 ****
    else
      {
        v = allocate_value (type);
!       bcopy (VALUE_CONTENTS (arg1) + offset,
! 	     VALUE_CONTENTS (v),
! 	     TYPE_LENGTH (type));
      }
    VALUE_LVAL (v) = VALUE_LVAL (arg1);
    if (VALUE_LVAL (arg1) == lval_internalvar)
--- 601,612 ----
    else
      {
        v = allocate_value (type);
!       if (VALUE_LAZY (arg1))
! 	VALUE_LAZY (v) = 1;
!       else
! 	bcopy (VALUE_CONTENTS_RAW (arg1) + offset,
! 	       VALUE_CONTENTS_RAW (v),
! 	       TYPE_LENGTH (type));
      }
    VALUE_LVAL (v) = VALUE_LVAL (arg1);
    if (VALUE_LVAL (arg1) == lval_internalvar)
***************
*** 801,816 ****
    if (code == TYPE_CODE_INT || code == TYPE_CODE_ENUM)
      {
        if (len == sizeof (char))
! 	* (char *) VALUE_CONTENTS (val) = num;
        else if (len == sizeof (short))
! 	* (short *) VALUE_CONTENTS (val) = num;
        else if (len == sizeof (int))
! 	* (int *) VALUE_CONTENTS (val) = num;
        else if (len == sizeof (long))
! 	* (long *) VALUE_CONTENTS (val) = num;
  #ifdef LONG_LONG
        else if (len == sizeof (long long))
! 	* (long long *) VALUE_CONTENTS (val) = num;
  #endif
        else
  	error ("Integer type encountered with unexpected data length.");
--- 810,825 ----
    if (code == TYPE_CODE_INT || code == TYPE_CODE_ENUM)
      {
        if (len == sizeof (char))
! 	* (char *) VALUE_CONTENTS_RAW (val) = num;
        else if (len == sizeof (short))
! 	* (short *) VALUE_CONTENTS_RAW (val) = num;
        else if (len == sizeof (int))
! 	* (int *) VALUE_CONTENTS_RAW (val) = num;
        else if (len == sizeof (long))
! 	* (long *) VALUE_CONTENTS_RAW (val) = num;
  #ifdef LONG_LONG
        else if (len == sizeof (long long))
! 	* (long long *) VALUE_CONTENTS_RAW (val) = num;
  #endif
        else
  	error ("Integer type encountered with unexpected data length.");
***************
*** 833,841 ****
    if (code == TYPE_CODE_FLT)
      {
        if (len == sizeof (float))
! 	* (float *) VALUE_CONTENTS (val) = num;
        else if (len == sizeof (double))
! 	* (double *) VALUE_CONTENTS (val) = num;
        else
  	error ("Floating type encountered with unexpected data length.");
      }
--- 842,850 ----
    if (code == TYPE_CODE_FLT)
      {
        if (len == sizeof (float))
! 	* (float *) VALUE_CONTENTS_RAW (val) = num;
        else if (len == sizeof (double))
! 	* (double *) VALUE_CONTENTS_RAW (val) = num;
        else
  	error ("Floating type encountered with unexpected data length.");
      }
***************
*** 871,877 ****
      return value_at (valtype, EXTRACT_STRUCT_VALUE_ADDRESS (retbuf));
  
    val = allocate_value (valtype);
!   EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS (val));
  
    return val;
  }
--- 880,886 ----
      return value_at (valtype, EXTRACT_STRUCT_VALUE_ADDRESS (retbuf));
  
    val = allocate_value (valtype);
!   EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val));
  
    return val;
  }

That's all folks -- bill mann