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);
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))
{
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, 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),
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, 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),
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:
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;
else
{
fr = block_innermost_frame (b);
- if (fr == NULL)
+ if (fr == NULL && symbol_read_needs_frame (var))
{
if (BLOCK_FUNCTION (b) != NULL
&& SYMBOL_NAME (BLOCK_FUNCTION (b)) != NULL)
#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. */
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... */
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;
char format[80];
sprintf (format, "at %s", local_hex_format ());
name = alloca (80);
- sprintf (name, format, funaddr);
+ 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 (name, 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);
}
}
/* 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)
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--)
{
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);
}
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,
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),