* inftarg.c (child_thread_alive): New function to see if a
[deliverable/binutils-gdb.git] / gdb / findvar.c
index 36c72f6e65aa1008f7d759174a5c0979d0e9d8d2..591dc7f987f863c32398f1297565278e436f09cf 100644 (file)
@@ -1,5 +1,5 @@
 /* Find a variable's value in memory, for GDB, the GNU debugger.
-   Copyright 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
+   Copyright 1986, 1987, 1989, 1991, 1994, 1995 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -25,6 +25,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "gdbcore.h"
 #include "inferior.h"
 #include "target.h"
+#include <string.h>
+
+static void write_register_pid PARAMS ((int regno, LONGEST val, int pid));
 
 /* Basic byte-swapping routines.  GDB has needed these for a long time...
    All extract a target-format integer at ADDR which is LEN bytes long.  */
@@ -54,20 +57,21 @@ That operation is not available on integers of more than %d bytes.",
 
   /* Start at the most significant end of the integer, and work towards
      the least significant.  */
-#if TARGET_BYTE_ORDER == BIG_ENDIAN
-  p = startaddr;
-#else
-  p = endaddr - 1;
-#endif
-  /* Do the sign extension once at the start.  */
-  retval = ((LONGEST)*p ^ 0x80) - 0x80;
-#if TARGET_BYTE_ORDER == BIG_ENDIAN
-  for (++p; p < endaddr; ++p)
-#else
-  for (--p; p >= startaddr; --p)
-#endif
+  if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+    {
+      p = startaddr;
+      /* Do the sign extension once at the start.  */
+      retval = ((LONGEST)*p ^ 0x80) - 0x80;
+      for (++p; p < endaddr; ++p)
+       retval = (retval << 8) | *p;
+    }
+  else
     {
-      retval = (retval << 8) | *p;
+      p = endaddr - 1;
+      /* Do the sign extension once at the start.  */
+      retval = ((LONGEST)*p ^ 0x80) - 0x80;
+      for (--p; p >= startaddr; --p)
+       retval = (retval << 8) | *p;
     }
   return retval;
 }
@@ -90,13 +94,15 @@ That operation is not available on integers of more than %d bytes.",
   /* Start at the most significant end of the integer, and work towards
      the least significant.  */
   retval = 0;
-#if TARGET_BYTE_ORDER == BIG_ENDIAN
-  for (p = startaddr; p < endaddr; ++p)
-#else
-  for (p = endaddr - 1; p >= startaddr; --p)
-#endif
+  if (TARGET_BYTE_ORDER == BIG_ENDIAN)
     {
-      retval = (retval << 8) | *p;
+      for (p = startaddr; p < endaddr; ++p)
+       retval = (retval << 8) | *p;
+    }
+  else
+    {
+      for (p = endaddr - 1; p >= startaddr; --p)
+       retval = (retval << 8) | *p;
     }
   return retval;
 }
@@ -123,14 +129,21 @@ store_signed_integer (addr, len, val)
 
   /* Start at the least significant end of the integer, and work towards
      the most significant.  */
-#if TARGET_BYTE_ORDER == BIG_ENDIAN
-  for (p = endaddr - 1; p >= startaddr; --p)
-#else
-  for (p = startaddr; p < endaddr; ++p)
-#endif
+  if (TARGET_BYTE_ORDER == BIG_ENDIAN)
     {
-      *p = val & 0xff;
-      val >>= 8;
+      for (p = endaddr - 1; p >= startaddr; --p)
+       {
+         *p = val & 0xff;
+         val >>= 8;
+       }
+    }
+  else
+    {
+      for (p = startaddr; p < endaddr; ++p)
+       {
+         *p = val & 0xff;
+         val >>= 8;
+       }
     }
 }
 
@@ -146,14 +159,21 @@ store_unsigned_integer (addr, len, val)
 
   /* Start at the least significant end of the integer, and work towards
      the most significant.  */
-#if TARGET_BYTE_ORDER == BIG_ENDIAN
-  for (p = endaddr - 1; p >= startaddr; --p)
-#else
-  for (p = startaddr; p < endaddr; ++p)
-#endif
+  if (TARGET_BYTE_ORDER == BIG_ENDIAN)
     {
-      *p = val & 0xff;
-      val >>= 8;
+      for (p = endaddr - 1; p >= startaddr; --p)
+       {
+         *p = val & 0xff;
+         val >>= 8;
+       }
+    }
+  else
+    {
+      for (p = startaddr; p < endaddr; ++p)
+       {
+         *p = val & 0xff;
+         val >>= 8;
+       }
     }
 }
 
@@ -168,6 +188,89 @@ store_address (addr, len, val)
   store_unsigned_integer (addr, len, (LONGEST)val);
 }
 \f
+/* Swap LEN bytes at BUFFER between target and host byte-order.  */
+#define SWAP_FLOATING(buffer,len) \
+  do                                                                    \
+    {                                                                   \
+      if (TARGET_BYTE_ORDER != HOST_BYTE_ORDER)                         \
+        {                                                               \
+          char tmp;                                                     \
+          char *p = (char *)(buffer);                                   \
+          char *q = ((char *)(buffer)) + len - 1;                       \
+          for (; p < q; p++, q--)                                       \
+            {                                                           \
+              tmp = *q;                                                 \
+              *q = *p;                                                  \
+              *p = tmp;                                                 \
+            }                                                           \
+        }                                                               \
+    }                                                                   \
+  while (0)
+
+/* There are various problems with the extract_floating and store_floating
+   routines.
+
+   1.  These routines only handle byte-swapping, not conversion of
+   formats.  So if host is IEEE floating and target is VAX floating,
+   or vice-versa, it loses.  This means that we can't (yet) use these
+   routines for extendeds.  Extendeds are handled by
+   REGISTER_CONVERTIBLE.  What we want is to use floatformat.h, but that
+   doesn't yet handle VAX floating at all.
+
+   2.  We can't deal with it if there is more than one floating point
+   format in use.  This has to be fixed at the unpack_double level.
+
+   3.  We probably should have a LONGEST_DOUBLE or DOUBLEST or whatever
+   we want to call it which is long double where available.  */
+
+double
+extract_floating (addr, len)
+     PTR addr;
+     int len;
+{
+  if (len == sizeof (float))
+    {
+      float retval;
+      memcpy (&retval, addr, sizeof (retval));
+      SWAP_FLOATING (&retval, sizeof (retval));
+      return retval;
+    }
+  else if (len == sizeof (double))
+    {
+      double retval;
+      memcpy (&retval, addr, sizeof (retval));
+      SWAP_FLOATING (&retval, sizeof (retval));
+      return retval;
+    }
+  else
+    {
+      error ("Can't deal with a floating point number of %d bytes.", len);
+    }
+}
+
+void
+store_floating (addr, len, val)
+     PTR addr;
+     int len;
+     double val;
+{
+  if (len == sizeof (float))
+    {
+      float floatval = val;
+      SWAP_FLOATING (&floatval, sizeof (floatval));
+      memcpy (addr, &floatval, sizeof (floatval));
+    }
+  else if (len == sizeof (double))
+    {
+      SWAP_FLOATING (&val, sizeof (val));
+      memcpy (addr, &val, sizeof (val));
+    }
+  else
+    {
+      error ("Can't deal with a floating point number of %d bytes.", len);
+    }
+}
+\f
 #if !defined (GET_SAVED_REGISTER)
 
 /* Return the address in which frame FRAME's value of register REGNUM
@@ -177,16 +280,15 @@ store_address (addr, len, val)
 
 CORE_ADDR
 find_saved_register (frame, regnum)
-     FRAME frame;
+     struct frame_info *frame;
      int regnum;
 {
-  struct frame_info *fi;
   struct frame_saved_regs saved_regs;
 
-  register FRAME frame1 = 0;
+  register struct frame_info *frame1 = NULL;
   register CORE_ADDR addr = 0;
 
-  if (frame == 0)              /* No regs saved if want current frame */
+  if (frame == NULL)           /* No regs saved if want current frame */
     return 0;
 
 #ifdef HAVE_REGISTER_WINDOWS
@@ -206,20 +308,17 @@ find_saved_register (frame, regnum)
      stack pointer saved for *this* frame; this is returned from the
      next frame.  */
      
-
   if (REGISTER_IN_WINDOW_P(regnum))
     {
       frame1 = get_next_frame (frame);
-      if (!frame1) return 0;   /* Registers of this frame are
-                                  active.  */
+      if (!frame1) return 0;   /* Registers of this frame are active.  */
       
       /* Get the SP from the next frame in; it will be this
         current frame.  */
       if (regnum != SP_REGNUM)
        frame1 = frame; 
          
-      fi = get_frame_info (frame1);
-      get_frame_saved_regs (fi, &saved_regs);
+      get_frame_saved_regs (frame1, &saved_regs);
       return saved_regs.regs[regnum];  /* ... which might be zero */
     }
 #endif /* HAVE_REGISTER_WINDOWS */
@@ -234,8 +333,7 @@ find_saved_register (frame, regnum)
       frame1 = get_prev_frame (frame1);
       if (frame1 == 0 || frame1 == frame)
        break;
-      fi = get_frame_info (frame1);
-      get_frame_saved_regs (fi, &saved_regs);
+      get_frame_saved_regs (frame1, &saved_regs);
       if (saved_regs.regs[regnum])
        addr = saved_regs.regs[regnum];
     }
@@ -263,11 +361,15 @@ get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
      char *raw_buffer;
      int *optimized;
      CORE_ADDR *addrp;
-     FRAME frame;
+     struct frame_info *frame;
      int regnum;
      enum lval_type *lval;
 {
   CORE_ADDR addr;
+
+  if (!target_has_registers)
+    error ("No registers.");
+
   /* Normal systems don't optimize out things with register numbers.  */
   if (optimized != NULL)
     *optimized = 0;
@@ -332,29 +434,38 @@ read_relative_register_raw_bytes (regnum, myaddr)
    in its virtual format, with the type specified by
    REGISTER_VIRTUAL_TYPE.  */
 
-value
+value_ptr
 value_of_register (regnum)
      int regnum;
 {
   CORE_ADDR addr;
   int optim;
-  register value val;
+  register value_ptr reg_val;
   char raw_buffer[MAX_REGISTER_RAW_SIZE];
-  char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
   enum lval_type lval;
 
   get_saved_register (raw_buffer, &optim, &addr,
                      selected_frame, regnum, &lval);
 
-  REGISTER_CONVERT_TO_VIRTUAL (regnum, raw_buffer, virtual_buffer);
-  val = allocate_value (REGISTER_VIRTUAL_TYPE (regnum));
-  memcpy (VALUE_CONTENTS_RAW (val), virtual_buffer,
-         REGISTER_VIRTUAL_SIZE (regnum));
-  VALUE_LVAL (val) = lval;
-  VALUE_ADDRESS (val) = addr;
-  VALUE_REGNO (val) = regnum;
-  VALUE_OPTIMIZED_OUT (val) = optim;
-  return val;
+  reg_val = allocate_value (REGISTER_VIRTUAL_TYPE (regnum));
+
+  /* Convert raw data to virtual format if necessary.  */
+
+#ifdef REGISTER_CONVERTIBLE
+  if (REGISTER_CONVERTIBLE (regnum))
+    {
+      REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum),
+                                  raw_buffer, VALUE_CONTENTS_RAW (reg_val));
+    }
+  else
+#endif
+    memcpy (VALUE_CONTENTS_RAW (reg_val), raw_buffer,
+           REGISTER_RAW_SIZE (regnum));
+  VALUE_LVAL (reg_val) = lval;
+  VALUE_ADDRESS (reg_val) = addr;
+  VALUE_REGNO (reg_val) = regnum;
+  VALUE_OPTIMIZED_OUT (reg_val) = optim;
+  return reg_val;
 }
 \f
 /* Low level examining and depositing of registers.
@@ -372,12 +483,21 @@ char registers[REGISTER_BYTES + /* SLOP */ 256];
 /* Nonzero if that register has been fetched.  */
 char register_valid[NUM_REGS];
 
+/* The thread/process associated with the current set of registers.  For now,
+   -1 is special, and means `no current process'.  */
+int registers_pid = -1;
+
 /* Indicate that registers may have changed, so invalidate the cache.  */
+
 void
 registers_changed ()
 {
   int i;
-  for (i = 0; i < NUM_REGS; i++)
+  int numregs = ARCH_NUM_REGS;
+
+  registers_pid = -1;
+
+  for (i = 0; i < numregs; i++)
     register_valid[i] = 0;
 }
 
@@ -386,7 +506,8 @@ void
 registers_fetched ()
 {
   int i;
-  for (i = 0; i < NUM_REGS; i++)
+  int numregs = ARCH_NUM_REGS;
+  for (i = 0; i < numregs; i++)
     register_valid[i] = 1;
 }
 
@@ -401,8 +522,16 @@ read_register_bytes (regbyte, myaddr, len)
      int len;
 {
   /* Fetch all registers.  */
-  int i;
-  for (i = 0; i < NUM_REGS; i++)
+  int i, numregs;
+
+  if (registers_pid != inferior_pid)
+    {
+      registers_changed ();
+      registers_pid = inferior_pid;
+    }
+
+  numregs = ARCH_NUM_REGS;
+  for (i = 0; i < numregs; i++)
     if (!register_valid[i])
       {
        target_fetch_registers (-1);
@@ -421,6 +550,12 @@ read_register_gen (regno, myaddr)
      int regno;
      char *myaddr;
 {
+  if (registers_pid != inferior_pid)
+    {
+      registers_changed ();
+      registers_pid = inferior_pid;
+    }
+
   if (!register_valid[regno])
     target_fetch_registers (regno);
   memcpy (myaddr, &registers[REGISTER_BYTE (regno)],
@@ -436,6 +571,12 @@ write_register_bytes (regbyte, myaddr, len)
      char *myaddr;
      int len;
 {
+  if (registers_pid != inferior_pid)
+    {
+      registers_changed ();
+      registers_pid = inferior_pid;
+    }
+
   /* Make sure the entire registers array is valid.  */
   read_register_bytes (0, (char *)NULL, REGISTER_BYTES);
   memcpy (&registers[regbyte], myaddr, len);
@@ -449,6 +590,12 @@ CORE_ADDR
 read_register (regno)
      int regno;
 {
+  if (registers_pid != inferior_pid)
+    {
+      registers_changed ();
+      registers_pid = inferior_pid;
+    }
+
   if (!register_valid[regno])
     target_fetch_registers (regno);
 
@@ -456,18 +603,38 @@ read_register (regno)
                          REGISTER_RAW_SIZE(regno));
 }
 
+CORE_ADDR
+read_register_pid (regno, pid)
+     int regno, pid;
+{
+  int save_pid;
+  CORE_ADDR retval;
+
+  if (pid == inferior_pid)
+    return read_register (regno);
+
+  save_pid = inferior_pid;
+
+  inferior_pid = pid;
+
+  retval = read_register (regno);
+
+  inferior_pid = save_pid;
+
+  return retval;
+}
+
 /* Registers we shouldn't try to store.  */
 #if !defined (CANNOT_STORE_REGISTER)
 #define CANNOT_STORE_REGISTER(regno) 0
 #endif
 
 /* Store VALUE, into the raw contents of register number REGNO.  */
-/* FIXME: The val arg should probably be a LONGEST.  */
 
 void
 write_register (regno, val)
      int regno;
-     long val;
+     LONGEST val;
 {
   PTR buf;
   int size;
@@ -477,6 +644,12 @@ write_register (regno, val)
   if (CANNOT_STORE_REGISTER (regno))
     return;
 
+  if (registers_pid != inferior_pid)
+    {
+      registers_changed ();
+      registers_pid = inferior_pid;
+    }
+
   size = REGISTER_RAW_SIZE(regno);
   buf = alloca (size);
   store_signed_integer (buf, size, (LONGEST) val);
@@ -484,11 +657,9 @@ write_register (regno, val)
   /* If we have a valid copy of the register, and new value == old value,
      then don't bother doing the actual store. */
 
-  if (register_valid [regno]) 
-    {
-      if (memcmp (&registers[REGISTER_BYTE (regno)], buf, size) == 0)
-       return;
-    }
+  if (register_valid [regno]
+      && memcmp (&registers[REGISTER_BYTE (regno)], buf, size) == 0)
+    return;
   
   target_prepare_to_store ();
 
@@ -499,6 +670,29 @@ write_register (regno, val)
   target_store_registers (regno);
 }
 
+static void
+write_register_pid (regno, val, pid)
+     int regno;
+     LONGEST val;
+     int pid;
+{
+  int save_pid;
+
+  if (pid == inferior_pid)
+    {
+      write_register (regno, val);
+      return;
+    }
+
+  save_pid = inferior_pid;
+
+  inferior_pid = pid;
+
+  write_register (regno, val);
+
+  inferior_pid = save_pid;
+}
+
 /* Record that register REGNO contains VAL.
    This is used when the value is obtained from the inferior or core dump,
    so there is no need to store the value there.  */
@@ -508,6 +702,12 @@ supply_register (regno, val)
      int regno;
      char *val;
 {
+  if (registers_pid != inferior_pid)
+    {
+      registers_changed ();
+      registers_pid = inferior_pid;
+    }
+
   register_valid[regno] = 1;
   memcpy (&registers[REGISTER_BYTE (regno)], val, REGISTER_RAW_SIZE (regno));
 
@@ -517,20 +717,164 @@ supply_register (regno, val)
   CLEAN_UP_REGISTER_VALUE(regno, &registers[REGISTER_BYTE(regno)]);
 #endif
 }
+
+
+/* This routine is getting awfully cluttered with #if's.  It's probably
+   time to turn this into READ_PC and define it in the tm.h file.
+   Ditto for write_pc.  */
+
+CORE_ADDR
+read_pc ()
+{
+#ifdef TARGET_READ_PC
+  return TARGET_READ_PC (inferior_pid);
+#else
+  return ADDR_BITS_REMOVE ((CORE_ADDR) read_register_pid (PC_REGNUM, inferior_pid));
+#endif
+}
+
+CORE_ADDR
+read_pc_pid (pid)
+     int pid;
+{
+#ifdef TARGET_READ_PC
+  return TARGET_READ_PC (pid);
+#else
+  return ADDR_BITS_REMOVE ((CORE_ADDR) read_register_pid (PC_REGNUM, pid));
+#endif
+}
+
+void
+write_pc (val)
+     CORE_ADDR val;
+{
+#ifdef TARGET_WRITE_PC
+  TARGET_WRITE_PC (val, inferior_pid);
+#else
+  write_register_pid (PC_REGNUM, val, inferior_pid);
+#ifdef NPC_REGNUM
+  write_register_pid (NPC_REGNUM, val + 4, inferior_pid);
+#ifdef NNPC_REGNUM
+  write_register_pid (NNPC_REGNUM, val + 8, inferior_pid);
+#endif
+#endif
+#endif
+}
+
+void
+write_pc_pid (val, pid)
+     CORE_ADDR val;
+     int pid;
+{
+#ifdef TARGET_WRITE_PC
+  TARGET_WRITE_PC (val, pid);
+#else
+  write_register_pid (PC_REGNUM, val, pid);
+#ifdef NPC_REGNUM
+  write_register_pid (NPC_REGNUM, val + 4, pid);
+#ifdef NNPC_REGNUM
+  write_register_pid (NNPC_REGNUM, val + 8, pid);
+#endif
+#endif
+#endif
+}
+
+/* Cope with strage ways of getting to the stack and frame pointers */
+
+CORE_ADDR
+read_sp ()
+{
+#ifdef TARGET_READ_SP
+  return TARGET_READ_SP ();
+#else
+  return read_register (SP_REGNUM);
+#endif
+}
+
+void
+write_sp (val)
+     CORE_ADDR val;
+{
+#ifdef TARGET_WRITE_SP
+  TARGET_WRITE_SP (val);
+#else
+  write_register (SP_REGNUM, val);
+#endif
+}
+
+CORE_ADDR
+read_fp ()
+{
+#ifdef TARGET_READ_FP
+  return TARGET_READ_FP ();
+#else
+  return read_register (FP_REGNUM);
+#endif
+}
+
+void
+write_fp (val)
+     CORE_ADDR val;
+{
+#ifdef TARGET_WRITE_FP
+  TARGET_WRITE_FP (val);
+#else
+  write_register (FP_REGNUM, val);
+#endif
+}
 \f
+/* Will calling read_var_value or locate_var_value on SYM end
+   up caring what frame it is being evaluated relative to?  SYM must
+   be non-NULL.  */
+int
+symbol_read_needs_frame (sym)
+     struct symbol *sym;
+{
+  switch (SYMBOL_CLASS (sym))
+    {
+      /* All cases listed explicitly so that gcc -Wall will detect it if
+        we failed to consider one.  */
+    case LOC_REGISTER:
+    case LOC_ARG:
+    case LOC_REF_ARG:
+    case LOC_REGPARM:
+    case LOC_REGPARM_ADDR:
+    case LOC_LOCAL:
+    case LOC_LOCAL_ARG:
+    case LOC_BASEREG:
+    case LOC_BASEREG_ARG:
+      return 1;
+
+    case LOC_UNDEF:
+    case LOC_CONST:
+    case LOC_STATIC:
+    case LOC_TYPEDEF:
+
+    case LOC_LABEL:
+      /* Getting the address of a label can be done independently of the block,
+        even if some *uses* of that address wouldn't work so well without
+        the right frame.  */
+
+    case LOC_BLOCK:
+    case LOC_CONST_BYTES:
+    case LOC_OPTIMIZED_OUT:
+      return 0;
+    }
+  return 1;
+}
+
 /* Given a struct symbol for a variable,
    and a stack frame id, read the value of the variable
    and return a (pointer to a) struct value containing the value. 
    If the variable cannot be found, return a zero pointer.
    If FRAME is NULL, use the selected_frame.  */
 
-value
+value_ptr
 read_var_value (var, frame)
      register struct symbol *var;
-     FRAME frame;
+     struct frame_info *frame;
 {
-  register value v;
-  struct frame_info *fi;
+  register value_ptr v;
   struct type *type = SYMBOL_TYPE (var);
   CORE_ADDR addr;
   register int len;
@@ -539,7 +883,7 @@ read_var_value (var, frame)
   VALUE_LVAL (v) = lval_memory;        /* The most likely possibility.  */
   len = TYPE_LENGTH (type);
 
-  if (frame == 0) frame = selected_frame;
+  if (frame == NULL) frame = selected_frame;
 
   switch (SYMBOL_CLASS (var))
     {
@@ -570,26 +914,20 @@ read_var_value (var, frame)
       break;
 
     case LOC_ARG:
-      fi = get_frame_info (frame);
-      if (fi == NULL)
+      if (frame == NULL)
        return 0;
-      addr = FRAME_ARGS_ADDRESS (fi);
+      addr = FRAME_ARGS_ADDRESS (frame);
       if (!addr)
-       {
-         return 0;
-       }
+       return 0;
       addr += SYMBOL_VALUE (var);
       break;
 
     case LOC_REF_ARG:
-      fi = get_frame_info (frame);
-      if (fi == NULL)
+      if (frame == NULL)
        return 0;
-      addr = FRAME_ARGS_ADDRESS (fi);
+      addr = FRAME_ARGS_ADDRESS (frame);
       if (!addr)
-       {
-         return 0;
-       }
+       return 0;
       addr += SYMBOL_VALUE (var);
       addr = read_memory_unsigned_integer
        (addr, TARGET_PTR_BIT / TARGET_CHAR_BIT);
@@ -597,10 +935,9 @@ read_var_value (var, frame)
 
     case LOC_LOCAL:
     case LOC_LOCAL_ARG:
-      fi = get_frame_info (frame);
-      if (fi == NULL)
+      if (frame == NULL)
        return 0;
-      addr = FRAME_LOCALS_ADDRESS (fi);
+      addr = FRAME_LOCALS_ADDRESS (frame);
       addr += SYMBOL_VALUE (var);
       break;
 
@@ -633,15 +970,17 @@ read_var_value (var, frame)
          return 0;
        b = get_frame_block (frame);
        
-       v = value_from_register (type, SYMBOL_VALUE (var), frame);
 
        if (SYMBOL_CLASS (var) == LOC_REGPARM_ADDR)
          {
-           addr = *(CORE_ADDR *)VALUE_CONTENTS (v);
+           addr =
+             value_as_pointer (value_from_register (lookup_pointer_type (type),
+                                                    SYMBOL_VALUE (var),
+                                                    frame));
            VALUE_LVAL (v) = lval_memory;
          }
        else
-         return v;
+         return value_from_register (type, SYMBOL_VALUE (var), frame);
       }
       break;
 
@@ -663,17 +1002,16 @@ read_var_value (var, frame)
 /* Return a value of type TYPE, stored in register REGNUM, in frame
    FRAME. */
 
-value
+value_ptr
 value_from_register (type, regnum, frame)
      struct type *type;
      int regnum;
-     FRAME frame;
+     struct frame_info *frame;
 {
   char raw_buffer [MAX_REGISTER_RAW_SIZE];
-  char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
   CORE_ADDR addr;
   int optim;
-  value v = allocate_value (type);
+  value_ptr v = allocate_value (type);
   int len = TYPE_LENGTH (type);
   char *value_bytes = 0;
   int value_bytes_copied = 0;
@@ -839,44 +1177,27 @@ value_from_register (type, regnum, frame)
   VALUE_OPTIMIZED_OUT (v) = optim;
   VALUE_LVAL (v) = lval;
   VALUE_ADDRESS (v) = addr;
+
+  /* Convert raw data to virtual format if necessary.  */
   
-  /* Convert the raw contents to virtual contents.
-     (Just copy them if the formats are the same.)  */
-  
-  REGISTER_CONVERT_TO_VIRTUAL (regnum, raw_buffer, virtual_buffer);
-  
+#ifdef REGISTER_CONVERTIBLE
   if (REGISTER_CONVERTIBLE (regnum))
     {
-      /* When the raw and virtual formats differ, the virtual format
-        corresponds to a specific data type.  If we want that type,
-        copy the data into the value.
-        Otherwise, do a type-conversion.  */
-      
-      if (type != REGISTER_VIRTUAL_TYPE (regnum))
-       {
-         /* eg a variable of type `float' in a 68881 register
-            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));
-         memcpy (VALUE_CONTENTS_RAW (v), virtual_buffer, len);
-         v = value_cast (type, v);
-       }
-      else
-       memcpy (VALUE_CONTENTS_RAW (v), virtual_buffer, len);
+      REGISTER_CONVERT_TO_VIRTUAL (regnum, type,
+                                  raw_buffer, VALUE_CONTENTS_RAW (v));
     }
   else
+#endif
     {
       /* Raw and virtual formats are the same for this register.  */
 
-#if TARGET_BYTE_ORDER == BIG_ENDIAN
-      if (len < REGISTER_RAW_SIZE (regnum))
+      if (TARGET_BYTE_ORDER == BIG_ENDIAN && len < REGISTER_RAW_SIZE (regnum))
        {
          /* Big-endian, and we want less than full size.  */
          VALUE_OFFSET (v) = REGISTER_RAW_SIZE (regnum) - len;
        }
-#endif
 
-      memcpy (VALUE_CONTENTS_RAW (v), virtual_buffer + VALUE_OFFSET (v), len);
+      memcpy (VALUE_CONTENTS_RAW (v), raw_buffer + VALUE_OFFSET (v), len);
     }
   
   return v;
@@ -887,14 +1208,14 @@ value_from_register (type, regnum, frame)
    return a (pointer to a) struct value containing the properly typed
    address.  */
 
-value
+value_ptr
 locate_var_value (var, frame)
      register struct symbol *var;
-     FRAME frame;
+     struct frame_info *frame;
 {
   CORE_ADDR addr = 0;
   struct type *type = SYMBOL_TYPE (var);
-  value lazy_value;
+  value_ptr lazy_value;
 
   /* Evaluate it first; if the result is a memory address, we're fine.
      Lazy evaluation pays off here. */
This page took 0.032489 seconds and 4 git commands to generate.