* inftarg.c (child_thread_alive): New function to see if a
[deliverable/binutils-gdb.git] / gdb / findvar.c
index 531075eabcc8506538954c9056f0a15b5a072fa2..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)
     {
-      retval = (retval << 8) | *p;
+      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
+    {
+      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)
+    {
+      for (p = endaddr - 1; p >= startaddr; --p)
+       {
+         *p = val & 0xff;
+         val >>= 8;
+       }
+    }
+  else
     {
-      *p = val & 0xff;
-      val >>= 8;
+      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,28 +188,27 @@ store_address (addr, len, val)
   store_unsigned_integer (addr, len, (LONGEST)val);
 }
 \f
-/* Swap LEN bytes at BUFFER between target and host byte-order.  This is
-   the wrong way to do byte-swapping because it assumes that you have a way
-   to have a host variable of exactly the right size.  Once extract_floating
-   and store_floating have been fixed, this can go away.  */
-#if TARGET_BYTE_ORDER == HOST_BYTE_ORDER
-#define SWAP_TARGET_AND_HOST(buffer,len)
-#else /* Target and host byte order differ.  */
-#define SWAP_TARGET_AND_HOST(buffer,len) \
-  {                                                                     \
-    char tmp;                                                           \
-    char *p = (char *)(buffer);                                                 \
-    char *q = ((char *)(buffer)) + len - 1;                             \
-    for (; p < q; p++, q--)                                             \
-      {                                                                         \
-        tmp = *q;                                                       \
-        *q = *p;                                                        \
-        *p = tmp;                                                       \
-      }                                                                         \
-  }
-#endif /* Target and host byte order differ.  */
-
-/* There are many problems with floating point cross-debugging.
+/* 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,
@@ -213,14 +232,14 @@ extract_floating (addr, len)
     {
       float retval;
       memcpy (&retval, addr, sizeof (retval));
-      SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
+      SWAP_FLOATING (&retval, sizeof (retval));
       return retval;
     }
   else if (len == sizeof (double))
     {
       double retval;
       memcpy (&retval, addr, sizeof (retval));
-      SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
+      SWAP_FLOATING (&retval, sizeof (retval));
       return retval;
     }
   else
@@ -238,12 +257,12 @@ store_floating (addr, len, val)
   if (len == sizeof (float))
     {
       float floatval = val;
-      SWAP_TARGET_AND_HOST (&floatval, sizeof (floatval));
+      SWAP_FLOATING (&floatval, sizeof (floatval));
       memcpy (addr, &floatval, sizeof (floatval));
     }
   else if (len == sizeof (double))
     {
-      SWAP_TARGET_AND_HOST (&val, sizeof (val));
+      SWAP_FLOATING (&val, sizeof (val));
       memcpy (addr, &val, sizeof (val));
     }
   else
@@ -261,16 +280,15 @@ store_floating (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
@@ -290,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 */
@@ -318,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];
     }
@@ -347,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;
@@ -416,13 +434,13 @@ 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 reg_val;
+  register value_ptr reg_val;
   char raw_buffer[MAX_REGISTER_RAW_SIZE];
   enum lval_type lval;
 
@@ -465,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;
 }
 
@@ -479,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;
 }
 
@@ -494,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);
@@ -514,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)],
@@ -529,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);
@@ -542,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);
 
@@ -549,13 +603,33 @@ 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)
@@ -570,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);
@@ -577,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 ();
 
@@ -592,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.  */
@@ -601,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));
 
@@ -610,6 +717,111 @@ 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
@@ -657,13 +869,12 @@ symbol_read_needs_frame (sym)
    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;
@@ -672,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))
     {
@@ -703,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);
@@ -730,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;
 
@@ -766,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;
 
@@ -796,16 +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];
   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;
@@ -985,13 +1191,11 @@ value_from_register (type, regnum, frame)
     {
       /* 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), raw_buffer + VALUE_OFFSET (v), len);
     }
@@ -1004,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.030923 seconds and 4 git commands to generate.