* findvar.c (value_of_register, value_from_register),
[deliverable/binutils-gdb.git] / gdb / valops.c
index c0931c52d836bbb28d5582bc260760f88eff72a3..ebddb5b90b4d5f1dad4b2c17da86730652c7f879 100644 (file)
@@ -26,11 +26,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "gdbcore.h"
 #include "target.h"
 #include "demangle.h"
+#include "language.h"
 
 #include <errno.h>
 
 /* Local functions.  */
 
+static int
+typecmp PARAMS ((int staticp, struct type *t1[], value t2[]));
+
 static CORE_ADDR
 find_function_addr PARAMS ((value, struct type **));
 
@@ -77,7 +81,7 @@ allocate_space_in_inferior (len)
        {
          error ("\"malloc\" exists in this program but is not a function.");
        }
-      val = value_of_variable (sym);
+      val = value_of_variable (sym, NULL);
     }
   else
     {
@@ -108,7 +112,7 @@ allocate_space_in_inferior (len)
 /* Cast value ARG2 to type TYPE and return as a value.
    More general than a C cast: accepts any two types of the same length,
    and if ARG2 is an lvalue it can be cast into anything at all.  */
-/* In C++, casts may change pointer representations.  */
+/* In C++, casts may change pointer or object representations.  */
 
 value
 value_cast (type, arg2)
@@ -129,6 +133,21 @@ value_cast (type, arg2)
   scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_FLT
            || code2 == TYPE_CODE_ENUM);
 
+  if (   code1 == TYPE_CODE_STRUCT
+      && code2 == TYPE_CODE_STRUCT
+      && TYPE_NAME (type) != 0)
+    {
+      /* Look in the type of the source to see if it contains the
+        type of the target as a superclass.  If so, we'll need to
+        offset the object in addition to changing its type.  */
+      value v = search_struct_field (type_name_no_tag (type),
+                                    arg2, 0, VALUE_TYPE (arg2), 1);
+      if (v)
+       {
+         VALUE_TYPE (v) = type;
+         return v;
+       }
+    }
   if (code1 == TYPE_CODE_FLT && scalar)
     return value_from_double (type, value_as_double (arg2));
   else if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_ENUM)
@@ -267,7 +286,6 @@ value_assign (toval, fromval)
   register struct type *type = VALUE_TYPE (toval);
   register value val;
   char raw_buffer[MAX_REGISTER_RAW_SIZE];
-  char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
   int use_buffer = 0;
 
   COERCE_ARRAY (fromval);
@@ -281,17 +299,19 @@ value_assign (toval, fromval)
      convert FROMVAL's contents now, with result in `raw_buffer',
      and set USE_BUFFER to the number of bytes to write.  */
 
+#ifdef REGISTER_CONVERTIBLE
   if (VALUE_REGNO (toval) >= 0
       && REGISTER_CONVERTIBLE (VALUE_REGNO (toval)))
     {
       int regno = VALUE_REGNO (toval);
-      if (VALUE_TYPE (fromval) != REGISTER_VIRTUAL_TYPE (regno))
-       fromval = value_cast (REGISTER_VIRTUAL_TYPE (regno), fromval);
-      memcpy (virtual_buffer, VALUE_CONTENTS (fromval),
-            REGISTER_VIRTUAL_SIZE (regno));
-      REGISTER_CONVERT_TO_RAW (regno, virtual_buffer, raw_buffer);
-      use_buffer = REGISTER_RAW_SIZE (regno);
+      if (REGISTER_CONVERTIBLE (regno))
+       {
+         REGISTER_CONVERT_TO_RAW (VALUE_TYPE (fromval), regno,
+                                  VALUE_CONTENTS (fromval), raw_buffer);
+         use_buffer = REGISTER_RAW_SIZE (regno);
+       }
     }
+#endif
 
   switch (VALUE_LVAL (toval))
     {
@@ -310,13 +330,24 @@ value_assign (toval, fromval)
     case lval_memory:
       if (VALUE_BITSIZE (toval))
        {
-         int v;                /* FIXME, this won't work for large bitfields */
+         char buffer[sizeof (LONGEST)];
+         /* We assume that the argument to read_memory is in units of
+            host chars.  FIXME:  Is that correct?  */
+         int len = (VALUE_BITPOS (toval)
+                    + VALUE_BITSIZE (toval)
+                    + HOST_CHAR_BIT - 1)
+                   / HOST_CHAR_BIT;
+
+         if (len > sizeof (LONGEST))
+           error ("Can't handle bitfields which don't fit in a %d bit word.",
+                  sizeof (LONGEST) * HOST_CHAR_BIT);
+
          read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
-                      (char *) &v, sizeof v);
-         modify_field ((char *) &v, (int) value_as_long (fromval),
+                      buffer, len);
+         modify_field (buffer, value_as_long (fromval),
                        VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
          write_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
-                       (char *)&v, sizeof v);
+                       buffer, len);
        }
       else if (use_buffer)
        write_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
@@ -329,21 +360,50 @@ value_assign (toval, fromval)
     case lval_register:
       if (VALUE_BITSIZE (toval))
        {
-         int v;
-
-         read_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
-                              (char *) &v, sizeof v);
-         modify_field ((char *) &v, (int) value_as_long (fromval),
-                       VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
-         write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
-                               (char *) &v, sizeof v);
+         char buffer[sizeof (LONGEST)];
+          int len = REGISTER_RAW_SIZE (VALUE_REGNO (toval));
+
+         if (len > sizeof (LONGEST))
+           error ("Can't handle bitfields in registers larger than %d bits.",
+                  sizeof (LONGEST) * HOST_CHAR_BIT);
+
+         if (VALUE_BITPOS (toval) + VALUE_BITSIZE (toval)
+             > len * HOST_CHAR_BIT)
+           /* Getting this right would involve being very careful about
+              byte order.  */
+           error ("\
+Can't handle bitfield which doesn't fit in a single register.");
+
+          read_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
+                               buffer, len);
+          modify_field (buffer, value_as_long (fromval),
+                        VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
+          write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
+                                buffer, len);
        }
       else if (use_buffer)
        write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
                              raw_buffer, use_buffer);
       else
-       write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
-                             VALUE_CONTENTS (fromval), TYPE_LENGTH (type));
+        {
+         /* Do any conversion necessary when storing this type to more
+            than one register.  */
+#ifdef REGISTER_CONVERT_FROM_TYPE
+         memcpy (raw_buffer, VALUE_CONTENTS (fromval), TYPE_LENGTH (type));
+         REGISTER_CONVERT_FROM_TYPE(VALUE_REGNO (toval), type, raw_buffer);
+         write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
+                               raw_buffer, TYPE_LENGTH (type));
+#else
+         write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
+                               VALUE_CONTENTS (fromval), TYPE_LENGTH (type));
+#endif
+       }
+      /* Assigning to the stack pointer, frame pointer, and other
+        (architecture and calling convention specific) registers may
+        cause the frame cache to be out of date.  We just do this
+        on all assignments to registers for simplicity; I doubt the slowdown
+        matters.  */
+      reinit_frame_cache ();
       break;
 
     case lval_reg_frame_relative:
@@ -356,7 +416,12 @@ value_assign (toval, fromval)
        int byte_offset = VALUE_OFFSET (toval) % reg_size;
        int reg_offset = VALUE_OFFSET (toval) / reg_size;
        int amount_copied;
-       char *buffer = (char *) alloca (amount_to_copy);
+
+       /* Make the buffer large enough in all cases.  */
+       char *buffer = (char *) alloca (amount_to_copy
+                                       + sizeof (LONGEST)
+                                       + MAX_REGISTER_RAW_SIZE);
+
        int regno;
        FRAME frame;
 
@@ -385,7 +450,7 @@ value_assign (toval, fromval)
        /* Modify what needs to be modified.  */
        if (VALUE_BITSIZE (toval))
          modify_field (buffer + byte_offset,
-                       (int) value_as_long (fromval),
+                       value_as_long (fromval),
                        VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
        else if (use_buffer)
          memcpy (buffer + byte_offset, raw_buffer, use_buffer);
@@ -468,12 +533,30 @@ value_repeat (arg1, count)
 }
 
 value
-value_of_variable (var)
+value_of_variable (var, b)
      struct symbol *var;
+     struct block *b;
 {
   value val;
+  FRAME fr;
 
-  val = read_var_value (var, (FRAME) 0);
+  if (b == NULL)
+    /* Use selected frame.  */
+    fr = NULL;
+  else
+    {
+      fr = block_innermost_frame (b);
+      if (fr == NULL && symbol_read_needs_frame (var))
+       {
+         if (BLOCK_FUNCTION (b) != NULL
+             && SYMBOL_NAME (BLOCK_FUNCTION (b)) != NULL)
+           error ("No frame is currently executing in block %s.",
+                  SYMBOL_NAME (BLOCK_FUNCTION (b)));
+         else
+           error ("No frame is currently executing in specified block");
+       }
+    }
+  val = read_var_value (var, fr);
   if (val == 0)
     error ("Address of symbol \"%s\" is unknown.", SYMBOL_SOURCE_NAME (var));
   return val;
@@ -597,18 +680,19 @@ value_ind (arg1)
 /* Push one word (the size of object that a register holds).  */
 
 CORE_ADDR
-push_word (sp, buffer)
+push_word (sp, word)
      CORE_ADDR sp;
-     REGISTER_TYPE buffer;
+     REGISTER_TYPE word;
 {
   register int len = sizeof (REGISTER_TYPE);
+  char buffer[MAX_REGISTER_RAW_SIZE];
 
-  SWAP_TARGET_AND_HOST (&buffer, len);
+  store_unsigned_integer (buffer, len, word);
 #if 1 INNER_THAN 2
   sp -= len;
-  write_memory (sp, (char *)&buffer, len);
+  write_memory (sp, buffer, len);
 #else /* stack grows upward */
-  write_memory (sp, (char *)&buffer, len);
+  write_memory (sp, buffer, len);
   sp += len;
 #endif /* stack grows upward */
 
@@ -663,7 +747,22 @@ value_arg_coerce (arg)
 {
   register struct type *type;
 
-  COERCE_ENUM (arg);
+  /* FIXME: We should coerce this according to the prototype (if we have
+     one).  Right now we do a little bit of this in typecmp(), but that
+     doesn't always get called.  For example, if passing a ref to a function
+     without a prototype, we probably should de-reference it.  Currently
+     we don't.  */
+
+  if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ENUM)
+    arg = value_cast (builtin_type_unsigned_int, arg);
+
+#if 1  /* FIXME:  This is only a temporary patch.  -fnf */
+  if (VALUE_REPEATED (arg)
+      || TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ARRAY)
+    arg = value_coerce_array (arg);
+  if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_FUNC)
+    arg = value_coerce_function (arg);
+#endif
 
   type = VALUE_TYPE (arg);
 
@@ -791,7 +890,7 @@ call_function_by_hand (function, nargs, args)
      they are saved on the stack in the inferior.  */
   PUSH_DUMMY_FRAME;
 
-  old_sp = sp = read_register (SP_REGNUM);
+  old_sp = sp = read_sp ();
 
 #if 1 INNER_THAN 2             /* Stack grows down */
   sp -= sizeof dummy;
@@ -817,13 +916,13 @@ call_function_by_hand (function, nargs, args)
 
   /* Create a call sequence customized for this function
      and the number of arguments for it.  */
-  memcpy (dummy1, dummy, sizeof dummy);
   for (i = 0; i < sizeof dummy / sizeof (REGISTER_TYPE); i++)
-    SWAP_TARGET_AND_HOST (&dummy1[i], sizeof (REGISTER_TYPE));
+    store_unsigned_integer (&dummy1[i], sizeof (REGISTER_TYPE),
+                           (unsigned LONGEST)dummy[i]);
 
 #ifdef GDB_TARGET_IS_HPPA
-  FIX_CALL_DUMMY (dummy1, start_sp, real_pc, funaddr, nargs, args,
-                 value_type, using_gcc);
+  real_pc = FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args,
+                           value_type, using_gcc);
 #else
   FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args,
                  value_type, using_gcc);
@@ -832,8 +931,8 @@ call_function_by_hand (function, nargs, args)
 
 #if CALL_DUMMY_LOCATION == ON_STACK
   write_memory (start_sp, (char *)dummy1, sizeof dummy);
+#endif /* On stack.  */
 
-#else /* Not on stack.  */
 #if CALL_DUMMY_LOCATION == BEFORE_TEXT_END
   /* Convex Unix prohibits executing in the stack segment. */
   /* Hope there is empty room at the top of the text segment. */
@@ -846,21 +945,26 @@ call_function_by_hand (function, nargs, args)
          error ("text segment full -- no place to put call");
     checked = 1;
     sp = old_sp;
-    start_sp = text_end - sizeof dummy;
-    write_memory (start_sp, (char *)dummy1, sizeof dummy);
+    real_pc = text_end - sizeof dummy;
+    write_memory (real_pc, (char *)dummy1, sizeof dummy);
   }
-#else /* After text_end.  */
+#endif /* Before text_end.  */
+
+#if CALL_DUMMY_LOCATION == AFTER_TEXT_END
   {
     extern CORE_ADDR text_end;
     int errcode;
     sp = old_sp;
-    start_sp = text_end;
-    errcode = target_write_memory (start_sp, (char *)dummy1, sizeof dummy);
+    real_pc = text_end;
+    errcode = target_write_memory (real_pc, (char *)dummy1, sizeof dummy);
     if (errcode != 0)
       error ("Cannot write text segment -- call_function failed");
   }
 #endif /* After text_end.  */
-#endif /* Not on stack.  */
+
+#if CALL_DUMMY_LOCATION == AT_ENTRY_POINT
+  real_pc = funaddr;
+#endif /* At entry point.  */
 
 #ifdef lint
   sp = old_sp;         /* It really is used, for some ifdef's... */
@@ -963,20 +1067,72 @@ call_function_by_hand (function, nargs, args)
   /* Write the stack pointer.  This is here because the statements above
      might fool with it.  On SPARC, this write also stores the register
      window into the right place in the new stack frame, which otherwise
-     wouldn't happen.  (See write_inferior_registers in sparc-xdep.c.)  */
-  write_register (SP_REGNUM, sp);
+     wouldn't happen.  (See store_inferior_registers in sparc-nat.c.)  */
+  write_sp (sp);
 
-  /* Figure out the value returned by the function.  */
   {
     char retbuf[REGISTER_BYTES];
+    char *name;
+    struct symbol *symbol;
+
+    name = NULL;
+    symbol = find_pc_function (funaddr);
+    if (symbol)
+      {
+       name = SYMBOL_SOURCE_NAME (symbol);
+      }
+    else
+      {
+       /* Try the minimal symbols.  */
+       struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (funaddr);
+
+       if (msymbol)
+         {
+           name = SYMBOL_SOURCE_NAME (msymbol);
+         }
+      }
+    if (name == NULL)
+      {
+       char format[80];
+       sprintf (format, "at %s", local_hex_format ());
+       name = alloca (80);
+       sprintf (name, format, (unsigned long) funaddr);
+      }
 
     /* Execute the stack dummy routine, calling FUNCTION.
        When it is done, discard the empty frame
        after storing the contents of all regs into retbuf.  */
-    run_stack_dummy (real_pc + CALL_DUMMY_START_OFFSET, retbuf);
+    if (run_stack_dummy (real_pc + CALL_DUMMY_START_OFFSET, retbuf))
+      {
+       /* We stopped somewhere besides the call dummy.  */
+
+       /* If we did the cleanups, we would print a spurious error message
+          (Unable to restore previously selected frame), would write the
+          registers from the inf_status (which is wrong), and would do other
+          wrong things (like set stop_bpstat to the wrong thing).  */
+       discard_cleanups (old_chain);
+       /* Prevent memory leak.  */
+       bpstat_clear (&inf_status.stop_bpstat);
+
+       /* The following error message used to say "The expression
+          which contained the function call has been discarded."  It
+          is a hard concept to explain in a few words.  Ideally, GDB
+          would be able to resume evaluation of the expression when
+          the function finally is done executing.  Perhaps someday
+          this will be implemented (it would not be easy).  */
+
+       /* FIXME: Insert a bunch of wrap_here; name can be very long if it's
+          a C++ name with arguments and stuff.  */
+       error ("\
+The program being debugged stopped while in a function called from GDB.\n\
+When the function (%s) is done executing, GDB will silently\n\
+stop (instead of continuing to evaluate the expression containing\n\
+the function call).", name);
+      }
 
     do_cleanups (old_chain);
 
+    /* Figure out the value returned by the function.  */
     return value_being_returned (value_type, retbuf, struct_return);
   }
 }
@@ -1089,8 +1245,11 @@ value_string (ptr, len)
   return (val);
 }
 \f
-/* Compare two argument lists and return the position in which they differ,
-   or zero if equal.
+/* See if we can pass arguments in T2 to a function which takes arguments
+   of types T1.  Both t1 and t2 are NULL-terminated vectors.  If some
+   arguments need coercion of some sort, then the coerced values are written
+   into T2.  Return value is 0 if the arguments could be matched, or the
+   position at which they differ if not.
 
    STATICP is nonzero if the T1 argument list came from a
    static member function.
@@ -1122,8 +1281,22 @@ typecmp (staticp, t1, t2)
       if (! t2[i])
        return i+1;
       if (TYPE_CODE (t1[i]) == TYPE_CODE_REF
-         && TYPE_TARGET_TYPE (t1[i]) == VALUE_TYPE (t2[i]))
+         /* We should be doing hairy argument matching, as below.  */
+         && (TYPE_CODE (TYPE_TARGET_TYPE (t1[i]))
+             == TYPE_CODE (VALUE_TYPE (t2[i]))))
+       {
+         t2[i] = value_addr (t2[i]);
+         continue;
+       }
+
+      if (TYPE_CODE (t1[i]) == TYPE_CODE_PTR
+         && TYPE_CODE (VALUE_TYPE (t2[i])) == TYPE_CODE_ARRAY)
+       /* Array to pointer is a `trivial conversion' according to the ARM.  */
        continue;
+
+      /* We should be doing much hairier argument matching (see section 13.2
+        of the ARM), but as a quick kludge, just check for the same type
+        code.  */
       if (TYPE_CODE (t1[i]) != TYPE_CODE (VALUE_TYPE (t2[i])))
        return i+1;
     }
@@ -1182,8 +1355,10 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
     {
       value v;
       /* If we are looking for baseclasses, this is what we get when we
-        hit them.  */
+        hit them.  But it could happen that the base part's member name
+        is not yet filled in.  */
       int found_baseclass = (looking_for_baseclass
+                            && TYPE_BASECLASS_NAME (type, i) != NULL
                             && STREQ (name, TYPE_BASECLASS_NAME (type, i)));
 
       if (BASETYPE_VIA_VIRTUAL (type, i))
@@ -1214,7 +1389,8 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
 /* Helper function used by value_struct_elt to recurse through baseclasses.
    Look for a field NAME in ARG1. Adjust the address of ARG1 by OFFSET bytes,
    and search in it assuming it has (class) type TYPE.
-   If found, return value, else return NULL. */
+   If found, return value, else if name matched and args not return (value)-1,
+   else return NULL. */
 
 static value
 search_struct_method (name, arg1p, args, offset, static_memfuncp, type)
@@ -1224,6 +1400,7 @@ search_struct_method (name, arg1p, args, offset, static_memfuncp, type)
      register struct type *type;
 {
   int i;
+  static int name_matched = 0;
 
   check_stub_type (type);
   for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--)
@@ -1233,6 +1410,7 @@ search_struct_method (name, arg1p, args, offset, static_memfuncp, type)
        {
          int j = TYPE_FN_FIELDLIST_LENGTH (type, i) - 1;
          struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
+         name_matched = 1; 
 
          if (j > 0 && args == 0)
            error ("cannot resolve overloaded method `%s'", name);
@@ -1271,14 +1449,19 @@ search_struct_method (name, arg1p, args, offset, static_memfuncp, type)
         }
       v = search_struct_method (name, arg1p, args, base_offset + offset,
                                static_memfuncp, TYPE_BASECLASS (type, i));
-      if (v)
+      if (v == (value) -1)
+       {
+         name_matched = 1;
+       }
+      else if (v)
        {
 /* FIXME-bothner:  Why is this commented out?  Why is it here?  */
 /*       *arg1p = arg1_tmp;*/
          return v;
         }
     }
-  return NULL;
+  if (name_matched) return (value) -1;
+  else return NULL;
 }
 
 /* Given *ARGP, a value of type (pointer to a)* structure/union,
@@ -1376,7 +1559,11 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
   else
     v = search_struct_method (name, argp, args, 0, static_memfuncp, t);
 
-  if (v == 0)
+  if (v == (value) -1)
+    {
+       error("Argument list of %s mismatch with component in the structure.", name);
+    }
+  else if (v == 0)
     {
       /* See if user tried to invoke data as function.  If so,
         hand it back.  If it's not callable (i.e., a pointer to function),
This page took 0.029127 seconds and 4 git commands to generate.