From 54023465250e1fb98fdb5bad7f8ebb0d95b55556 Mon Sep 17 00:00:00 2001 From: Jim Kingdon Date: Thu, 8 Jul 1993 03:32:00 +0000 Subject: * infcmd.c (run_stack_dummy): New argument name. Change error message in (another) attempt to make it comprehensible. * valops.c (call_function_by_hand): Pass name to run_stack_dummy. * symtab.h: Declare demangle and asm_demangle since macros use them. --- gdb/ChangeLog | 5 +++++ gdb/infcmd.c | 19 ++++++++++++---- gdb/symtab.h | 14 +++++++++--- gdb/valops.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 93 insertions(+), 14 deletions(-) (limited to 'gdb') diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 76fa0b4..8452275 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,10 @@ Wed Jul 7 14:30:00 1993 Jim Kingdon (kingdon@lioth.cygnus.com) + * infcmd.c (run_stack_dummy): New argument name. + Change error message in (another) attempt to make it comprehensible. + * valops.c (call_function_by_hand): Pass name to run_stack_dummy. + * symtab.h: Declare demangle and asm_demangle since macros use them. + * eval.c (evaluate_subexp): Add comment about calling a member function of a variable in a register. diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 389ed17..4aaa791 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -530,14 +530,19 @@ signal_command (signum_exp, from_tty) 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]; { @@ -553,10 +558,16 @@ run_stack_dummy (addr, buffer) 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. */ diff --git a/gdb/symtab.h b/gdb/symtab.h index de0d110..489e4d9 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -214,6 +214,10 @@ extern int demangle; /* We reference it, so go ahead and declare it. */ ? 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 @@ -372,7 +376,8 @@ struct block 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]; }; @@ -385,9 +390,12 @@ struct block #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) /* Represent one symbol name; a variable, constant, function or typedef. */ diff --git a/gdb/valops.c b/gdb/valops.c index 2180c03..59e228d 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -26,6 +26,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "gdbcore.h" #include "target.h" #include "demangle.h" +#include "language.h" #include @@ -111,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) @@ -132,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) @@ -345,8 +361,19 @@ value_assign (toval, fromval) 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: @@ -801,7 +828,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; @@ -974,16 +1001,42 @@ call_function_by_hand (function, nargs, args) 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); @@ -1192,8 +1245,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)) -- cgit v1.1