* 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.
This commit is contained in:
parent
cb747ec55b
commit
5402346525
@ -1,5 +1,10 @@
|
|||||||
Wed Jul 7 14:30:00 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
|
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
|
* eval.c (evaluate_subexp): Add comment about calling a member
|
||||||
function of a variable in a register.
|
function of a variable in a register.
|
||||||
|
|
||||||
|
19
gdb/infcmd.c
19
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.
|
The dummy's frame is automatically popped whenever that break is hit.
|
||||||
If that is the first time the program stops, run_stack_dummy
|
If that is the first time the program stops, run_stack_dummy
|
||||||
returns to its caller with that frame already gone.
|
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. */
|
/* DEBUG HOOK: 4 => return instead of letting the stack dummy run. */
|
||||||
|
|
||||||
static int stack_dummy_testing = 0;
|
static int stack_dummy_testing = 0;
|
||||||
|
|
||||||
void
|
void
|
||||||
run_stack_dummy (addr, buffer)
|
run_stack_dummy (name, addr, buffer)
|
||||||
|
char *name;
|
||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
char buffer[REGISTER_BYTES];
|
char buffer[REGISTER_BYTES];
|
||||||
{
|
{
|
||||||
@ -553,10 +558,16 @@ run_stack_dummy (addr, buffer)
|
|||||||
|
|
||||||
if (!stop_stack_dummy)
|
if (!stop_stack_dummy)
|
||||||
/* This used to say
|
/* 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 ("\
|
error ("\
|
||||||
The program being debugged stopped while in a function called from GDB.\n\
|
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. */
|
/* On return, the stack dummy has been popped already. */
|
||||||
|
|
||||||
|
14
gdb/symtab.h
14
gdb/symtab.h
@ -214,6 +214,10 @@ extern int demangle; /* We reference it, so go ahead and declare it. */
|
|||||||
? SYMBOL_DEMANGLED_NAME (symbol) \
|
? SYMBOL_DEMANGLED_NAME (symbol) \
|
||||||
: SYMBOL_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.
|
/* 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
|
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
|
name if it exists. Note that whitespace is ignored while attempting to
|
||||||
@ -372,7 +376,8 @@ struct block
|
|||||||
|
|
||||||
int nsyms;
|
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];
|
struct symbol *sym[1];
|
||||||
};
|
};
|
||||||
@ -385,9 +390,12 @@ struct block
|
|||||||
#define BLOCK_SUPERBLOCK(bl) (bl)->superblock
|
#define BLOCK_SUPERBLOCK(bl) (bl)->superblock
|
||||||
#define BLOCK_GCC_COMPILED(bl) (bl)->gcc_compile_flag
|
#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. */
|
/* Represent one symbol name; a variable, constant, function or typedef. */
|
||||||
|
69
gdb/valops.c
69
gdb/valops.c
@ -26,6 +26,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
#include "gdbcore.h"
|
#include "gdbcore.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "demangle.h"
|
#include "demangle.h"
|
||||||
|
#include "language.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
@ -111,7 +112,7 @@ allocate_space_in_inferior (len)
|
|||||||
/* Cast value ARG2 to type TYPE and return as a value.
|
/* 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,
|
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. */
|
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
|
||||||
value_cast (type, arg2)
|
value_cast (type, arg2)
|
||||||
@ -132,6 +133,21 @@ value_cast (type, arg2)
|
|||||||
scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_FLT
|
scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_FLT
|
||||||
|| code2 == TYPE_CODE_ENUM);
|
|| 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)
|
if (code1 == TYPE_CODE_FLT && scalar)
|
||||||
return value_from_double (type, value_as_double (arg2));
|
return value_from_double (type, value_as_double (arg2));
|
||||||
else if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_ENUM)
|
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),
|
write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
|
||||||
raw_buffer, use_buffer);
|
raw_buffer, use_buffer);
|
||||||
else
|
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;
|
break;
|
||||||
|
|
||||||
case lval_reg_frame_relative:
|
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. */
|
they are saved on the stack in the inferior. */
|
||||||
PUSH_DUMMY_FRAME;
|
PUSH_DUMMY_FRAME;
|
||||||
|
|
||||||
old_sp = sp = read_register (SP_REGNUM);
|
old_sp = sp = read_sp ();
|
||||||
|
|
||||||
#if 1 INNER_THAN 2 /* Stack grows down */
|
#if 1 INNER_THAN 2 /* Stack grows down */
|
||||||
sp -= sizeof dummy;
|
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
|
might fool with it. On SPARC, this write also stores the register
|
||||||
window into the right place in the new stack frame, which otherwise
|
window into the right place in the new stack frame, which otherwise
|
||||||
wouldn't happen. (See write_inferior_registers in sparc-xdep.c.) */
|
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. */
|
/* Figure out the value returned by the function. */
|
||||||
{
|
{
|
||||||
char retbuf[REGISTER_BYTES];
|
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.
|
/* Execute the stack dummy routine, calling FUNCTION.
|
||||||
When it is done, discard the empty frame
|
When it is done, discard the empty frame
|
||||||
after storing the contents of all regs into retbuf. */
|
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);
|
do_cleanups (old_chain);
|
||||||
|
|
||||||
@ -1192,8 +1245,10 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
|
|||||||
{
|
{
|
||||||
value v;
|
value v;
|
||||||
/* If we are looking for baseclasses, this is what we get when we
|
/* 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
|
int found_baseclass = (looking_for_baseclass
|
||||||
|
&& TYPE_BASECLASS_NAME (type, i) != NULL
|
||||||
&& STREQ (name, TYPE_BASECLASS_NAME (type, i)));
|
&& STREQ (name, TYPE_BASECLASS_NAME (type, i)));
|
||||||
|
|
||||||
if (BASETYPE_VIA_VIRTUAL (type, i))
|
if (BASETYPE_VIA_VIRTUAL (type, i))
|
||||||
|
Loading…
Reference in New Issue
Block a user