The dummy's frame is automatically popped whenever that break is hit.
If that is the first time the program stops, run_stack_dummy
returns to its caller with that frame already gone.
- Otherwise, the caller never gets returned to. */
+ Otherwise, the caller never gets returned to.
+
+ NAME is a string to print to identify the function which we are calling.
+ It is not guaranteed to be the name of a function, it could be something
+ like "at 0x4370" if a name can't be found for the function. */
/* DEBUG HOOK: 4 => return instead of letting the stack dummy run. */
static int stack_dummy_testing = 0;
void
-run_stack_dummy (addr, buffer)
+run_stack_dummy (name, addr, buffer)
+ char *name;
CORE_ADDR addr;
char buffer[REGISTER_BYTES];
{
if (!stop_stack_dummy)
/* This used to say
- "Cannot continue previously requested operation". */
+ "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). */
error ("\
The program being debugged stopped while in a function called from GDB.\n\
-The expression which contained the function call has been discarded.");
+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);
/* On return, the stack dummy has been popped already. */
? SYMBOL_DEMANGLED_NAME (symbol) \
: SYMBOL_NAME (symbol))
+/* From utils.c. */
+extern int demangle;
+extern int asm_demangle;
+
/* Macro that tests a symbol for a match against a specified name string.
First test the unencoded name, then looks for and test a C++ encoded
name if it exists. Note that whitespace is ignored while attempting to
int nsyms;
- /* The symbols. */
+ /* The symbols. If some of them are arguments, then they must be
+ in the order in which we would like to print them. */
struct symbol *sym[1];
};
#define BLOCK_SUPERBLOCK(bl) (bl)->superblock
#define BLOCK_GCC_COMPILED(bl) (bl)->gcc_compile_flag
-/* Nonzero if symbols of block BL should be sorted alphabetically. */
+/* Nonzero if symbols of block BL should be sorted alphabetically.
+ Don't sort a block which corresponds to a function. If we did the
+ sorting would have to preserve the order of the symbols for the
+ arguments. */
-#define BLOCK_SHOULD_SORT(bl) ((bl)->nsyms >= 40)
+#define BLOCK_SHOULD_SORT(bl) ((bl)->nsyms >= 40 && BLOCK_FUNCTION (bl) == NULL)
\f
/* Represent one symbol name; a variable, constant, function or typedef. */
#include "gdbcore.h"
#include "target.h"
#include "demangle.h"
+#include "language.h"
#include <errno.h>
/* 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)
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)
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
+ }
break;
case lval_reg_frame_relative:
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;
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);
+ 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, 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);
+ run_stack_dummy (name, real_pc + CALL_DUMMY_START_OFFSET, retbuf);
do_cleanups (old_chain);
{
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))