mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-21 01:12:32 +08:00
* blockframe.c (block_innermost_frame): Uncomment.
Return NULL if passed NULL. * frame.h: Declare it. * expression.h (union exp_element): Add field block. * parse.c (write_exp_elt_block): New function. * expression.h (OP_VAR_VALUE): Now takes additional struct block *. * *-exp.y: Write block for OP_VAR_VALUE. * eval.c, expprint.c, parse.c: Deal with block for OP_VAR_VALUE. * valops.c, value.h (value_of_variable), callers: Add second argument, for block.
This commit is contained in:
parent
e56ac0ba86
commit
479fdd26ee
@ -1,5 +1,16 @@
|
||||
Wed Aug 18 12:03:00 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
|
||||
|
||||
* blockframe.c (block_innermost_frame): Uncomment.
|
||||
Return NULL if passed NULL.
|
||||
* frame.h: Declare it.
|
||||
* expression.h (union exp_element): Add field block.
|
||||
* parse.c (write_exp_elt_block): New function.
|
||||
* expression.h (OP_VAR_VALUE): Now takes additional struct block *.
|
||||
* *-exp.y: Write block for OP_VAR_VALUE.
|
||||
* eval.c, expprint.c, parse.c: Deal with block for OP_VAR_VALUE.
|
||||
* valops.c, value.h (value_of_variable), callers:
|
||||
Add second argument, for block.
|
||||
|
||||
* main.c (gdb_readline): If we read some characters followed by EOF,
|
||||
return them rather than returning NULL.
|
||||
|
||||
|
@ -724,10 +724,8 @@ find_pc_partial_function (pc, name, address, endaddr)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return the innermost stack frame executing inside of the specified block,
|
||||
or zero if there is no such frame. */
|
||||
|
||||
#if 0 /* Currently unused */
|
||||
/* Return the innermost stack frame executing inside of BLOCK,
|
||||
or zero if there is no such frame. If BLOCK is NULL, just return NULL. */
|
||||
|
||||
FRAME
|
||||
block_innermost_frame (block)
|
||||
@ -738,6 +736,9 @@ block_innermost_frame (block)
|
||||
register CORE_ADDR start = BLOCK_START (block);
|
||||
register CORE_ADDR end = BLOCK_END (block);
|
||||
|
||||
if (block == NULL)
|
||||
return NULL;
|
||||
|
||||
frame = 0;
|
||||
while (1)
|
||||
{
|
||||
@ -750,8 +751,6 @@ block_innermost_frame (block)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
#ifdef SIGCONTEXT_PC_OFFSET
|
||||
/* Get saved user PC for sigtramp from sigcontext for BSD style sigtramp. */
|
||||
|
||||
|
@ -564,6 +564,8 @@ variable: block COLONCOLON name
|
||||
copy_name ($3));
|
||||
|
||||
write_exp_elt_opcode (OP_VAR_VALUE);
|
||||
/* block_found is set by lookup_symbol. */
|
||||
write_exp_elt_block (block_found);
|
||||
write_exp_elt_sym (sym);
|
||||
write_exp_elt_opcode (OP_VAR_VALUE); }
|
||||
;
|
||||
@ -620,6 +622,7 @@ variable: qualified_name
|
||||
if (sym)
|
||||
{
|
||||
write_exp_elt_opcode (OP_VAR_VALUE);
|
||||
write_exp_elt_block (NULL);
|
||||
write_exp_elt_sym (sym);
|
||||
write_exp_elt_opcode (OP_VAR_VALUE);
|
||||
break;
|
||||
@ -689,6 +692,10 @@ variable: name_not_typename
|
||||
break;
|
||||
}
|
||||
write_exp_elt_opcode (OP_VAR_VALUE);
|
||||
/* We want to use the selected frame, not
|
||||
another more inner frame which happens to
|
||||
be in the same block. */
|
||||
write_exp_elt_block (NULL);
|
||||
write_exp_elt_sym (sym);
|
||||
write_exp_elt_opcode (OP_VAR_VALUE);
|
||||
}
|
||||
|
@ -346,6 +346,7 @@ location : access_name
|
||||
access_name : LOCATION_NAME
|
||||
{
|
||||
write_exp_elt_opcode (OP_VAR_VALUE);
|
||||
write_exp_elt_block (NULL);
|
||||
write_exp_elt_sym ($1.sym);
|
||||
write_exp_elt_opcode (OP_VAR_VALUE);
|
||||
}
|
||||
@ -477,6 +478,7 @@ value_name : synonym_name
|
||||
| GENERAL_PROCEDURE_NAME
|
||||
{
|
||||
write_exp_elt_opcode (OP_VAR_VALUE);
|
||||
write_exp_elt_block (NULL);
|
||||
write_exp_elt_sym ($1.sym);
|
||||
write_exp_elt_opcode (OP_VAR_VALUE);
|
||||
}
|
||||
|
49
gdb/eval.c
49
gdb/eval.c
@ -197,7 +197,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
|
||||
exp->elts[pc + 2].doubleconst);
|
||||
|
||||
case OP_VAR_VALUE:
|
||||
(*pos) += 2;
|
||||
(*pos) += 3;
|
||||
if (noside == EVAL_SKIP)
|
||||
goto nosideret;
|
||||
if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
||||
@ -226,7 +226,8 @@ evaluate_subexp (expect_type, exp, pos, noside)
|
||||
return value_zero (SYMBOL_TYPE (sym), lv);
|
||||
}
|
||||
else
|
||||
return value_of_variable (exp->elts[pc + 1].symbol);
|
||||
return value_of_variable (exp->elts[pc + 2].symbol,
|
||||
exp->elts[pc + 1].block);
|
||||
|
||||
case OP_LAST:
|
||||
(*pos) += 2;
|
||||
@ -373,6 +374,20 @@ evaluate_subexp (expect_type, exp, pos, noside)
|
||||
|
||||
if (op == STRUCTOP_STRUCT)
|
||||
{
|
||||
/* If v is a variable in a register, and the user types
|
||||
v.method (), this will produce an error, because v has
|
||||
no address.
|
||||
|
||||
A possible way around this would be to allocate a
|
||||
copy of the variable on the stack, copy in the
|
||||
contents, call the function, and copy out the
|
||||
contents. I.e. convert this from call by reference
|
||||
to call by copy-return (or whatever it's called).
|
||||
However, this does not work because it is not the
|
||||
same: the method being called could stash a copy of
|
||||
the address, and then future uses through that address
|
||||
(after the method returns) would be expected to
|
||||
use the variable itself, not some copy of it. */
|
||||
arg2 = evaluate_subexp_for_address (exp, pos, noside);
|
||||
}
|
||||
else
|
||||
@ -1041,14 +1056,14 @@ evaluate_subexp_for_address (exp, pos, noside)
|
||||
evaluate_subexp (NULL_TYPE, exp, pos, noside));
|
||||
|
||||
case OP_VAR_VALUE:
|
||||
var = exp->elts[pc + 1].symbol;
|
||||
var = exp->elts[pc + 2].symbol;
|
||||
|
||||
/* C++: The "address" of a reference should yield the address
|
||||
* of the object pointed to. Let value_addr() deal with it. */
|
||||
if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_REF)
|
||||
goto default_case;
|
||||
|
||||
(*pos) += 3;
|
||||
(*pos) += 4;
|
||||
if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
||||
{
|
||||
struct type *type =
|
||||
@ -1065,7 +1080,10 @@ evaluate_subexp_for_address (exp, pos, noside)
|
||||
value_zero (type, not_lval);
|
||||
}
|
||||
else
|
||||
return locate_var_value (var, (FRAME) 0);
|
||||
return
|
||||
locate_var_value
|
||||
(var,
|
||||
block_innermost_frame (exp->elts[pc + 1].block));
|
||||
|
||||
default:
|
||||
default_case:
|
||||
@ -1085,7 +1103,8 @@ evaluate_subexp_for_address (exp, pos, noside)
|
||||
/* Evaluate like `evaluate_subexp' except coercing arrays to pointers.
|
||||
When used in contexts where arrays will be coerced anyway, this is
|
||||
equivalent to `evaluate_subexp' but much faster because it avoids
|
||||
actually fetching array contents.
|
||||
actually fetching array contents (perhaps obsolete now that we have
|
||||
VALUE_LAZY).
|
||||
|
||||
Note that we currently only do the coercion for C expressions, where
|
||||
arrays are zero based and the coercion is correct. For other languages,
|
||||
@ -1111,15 +1130,19 @@ evaluate_subexp_with_coercion (exp, pos, noside)
|
||||
switch (op)
|
||||
{
|
||||
case OP_VAR_VALUE:
|
||||
var = exp->elts[pc + 1].symbol;
|
||||
var = exp->elts[pc + 2].symbol;
|
||||
if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_ARRAY
|
||||
&& CAST_IS_CONVERSION)
|
||||
{
|
||||
(*pos) += 3;
|
||||
val = locate_var_value (var, (FRAME) 0);
|
||||
(*pos) += 4;
|
||||
val =
|
||||
locate_var_value
|
||||
(var, block_innermost_frame (exp->elts[pc + 1].block));
|
||||
return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (SYMBOL_TYPE (var))),
|
||||
val);
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
default:
|
||||
return evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
||||
}
|
||||
@ -1159,9 +1182,11 @@ evaluate_subexp_for_sizeof (exp, pos)
|
||||
(LONGEST) TYPE_LENGTH (exp->elts[pc + 1].type));
|
||||
|
||||
case OP_VAR_VALUE:
|
||||
(*pos) += 3;
|
||||
return value_from_longest (builtin_type_int,
|
||||
(LONGEST) TYPE_LENGTH (SYMBOL_TYPE (exp->elts[pc + 1].symbol)));
|
||||
(*pos) += 4;
|
||||
return
|
||||
value_from_longest
|
||||
(builtin_type_int,
|
||||
(LONGEST) TYPE_LENGTH (SYMBOL_TYPE (exp->elts[pc + 2].symbol)));
|
||||
|
||||
default:
|
||||
val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
|
||||
|
33
gdb/frame.h
33
gdb/frame.h
@ -223,34 +223,27 @@ get_frame_pc PARAMS ((FRAME));
|
||||
extern CORE_ADDR
|
||||
get_pc_function_start PARAMS ((CORE_ADDR));
|
||||
|
||||
extern struct block *
|
||||
block_for_pc PARAMS ((CORE_ADDR));
|
||||
extern struct block * block_for_pc PARAMS ((CORE_ADDR));
|
||||
|
||||
extern int
|
||||
frameless_look_for_prologue PARAMS ((FRAME));
|
||||
extern int frameless_look_for_prologue PARAMS ((FRAME));
|
||||
|
||||
extern void
|
||||
print_frame_args PARAMS ((struct symbol *, struct frame_info *, int, FILE *));
|
||||
extern void print_frame_args PARAMS ((struct symbol *, struct frame_info *,
|
||||
int, FILE *));
|
||||
|
||||
extern FRAME
|
||||
find_relative_frame PARAMS ((FRAME, int*));
|
||||
extern FRAME find_relative_frame PARAMS ((FRAME, int*));
|
||||
|
||||
extern void
|
||||
print_stack_frame PARAMS ((FRAME, int, int));
|
||||
extern void print_stack_frame PARAMS ((FRAME, int, int));
|
||||
|
||||
extern void
|
||||
select_frame PARAMS ((FRAME, int));
|
||||
extern void select_frame PARAMS ((FRAME, int));
|
||||
|
||||
extern void
|
||||
record_selected_frame PARAMS ((FRAME_ADDR *, int *));
|
||||
extern void record_selected_frame PARAMS ((FRAME_ADDR *, int *));
|
||||
|
||||
extern void
|
||||
print_frame_info PARAMS ((struct frame_info *, int, int, int));
|
||||
extern void print_frame_info PARAMS ((struct frame_info *, int, int, int));
|
||||
|
||||
extern CORE_ADDR
|
||||
find_saved_register PARAMS ((FRAME, int));
|
||||
extern CORE_ADDR find_saved_register PARAMS ((FRAME, int));
|
||||
|
||||
extern CORE_ADDR
|
||||
sigtramp_saved_pc PARAMS ((FRAME));
|
||||
extern FRAME block_innermost_frame PARAMS ((struct block *));
|
||||
|
||||
extern CORE_ADDR sigtramp_saved_pc PARAMS ((FRAME));
|
||||
|
||||
#endif /* !defined (FRAME_H) */
|
||||
|
@ -559,6 +559,7 @@ fblock : block COLONCOLON BLOCKNAME
|
||||
/* Useful for assigning to PROCEDURE variables */
|
||||
variable: fblock
|
||||
{ write_exp_elt_opcode(OP_VAR_VALUE);
|
||||
write_exp_elt_block (NULL);
|
||||
write_exp_elt_sym ($1);
|
||||
write_exp_elt_opcode (OP_VAR_VALUE); }
|
||||
;
|
||||
@ -580,6 +581,8 @@ variable: block COLONCOLON NAME
|
||||
copy_name ($3));
|
||||
|
||||
write_exp_elt_opcode (OP_VAR_VALUE);
|
||||
/* block_found is set by lookup_symbol. */
|
||||
write_exp_elt_block (block_found);
|
||||
write_exp_elt_sym (sym);
|
||||
write_exp_elt_opcode (OP_VAR_VALUE); }
|
||||
;
|
||||
@ -623,6 +626,10 @@ variable: NAME
|
||||
break;
|
||||
}
|
||||
write_exp_elt_opcode (OP_VAR_VALUE);
|
||||
/* We want to use the selected frame, not
|
||||
another more inner frame which happens to
|
||||
be in the same block. */
|
||||
write_exp_elt_block (NULL);
|
||||
write_exp_elt_sym (sym);
|
||||
write_exp_elt_opcode (OP_VAR_VALUE);
|
||||
}
|
||||
|
13
gdb/parse.c
13
gdb/parse.c
@ -178,6 +178,15 @@ write_exp_elt_sym (expelt)
|
||||
write_exp_elt (tmp);
|
||||
}
|
||||
|
||||
void
|
||||
write_exp_elt_block (b)
|
||||
struct block *b;
|
||||
{
|
||||
union exp_element tmp;
|
||||
tmp.block = b;
|
||||
write_exp_elt (tmp);
|
||||
}
|
||||
|
||||
void
|
||||
write_exp_elt_longcst (expelt)
|
||||
LONGEST expelt;
|
||||
@ -389,12 +398,12 @@ length_of_subexp (expr, endpos)
|
||||
|
||||
case OP_LONG:
|
||||
case OP_DOUBLE:
|
||||
case OP_VAR_VALUE:
|
||||
oplen = 4;
|
||||
break;
|
||||
|
||||
case OP_TYPE:
|
||||
case OP_BOOL:
|
||||
case OP_VAR_VALUE:
|
||||
case OP_LAST:
|
||||
case OP_REGISTER:
|
||||
case OP_INTERNALVAR:
|
||||
@ -518,12 +527,12 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
|
||||
|
||||
case OP_LONG:
|
||||
case OP_DOUBLE:
|
||||
case OP_VAR_VALUE:
|
||||
oplen = 4;
|
||||
break;
|
||||
|
||||
case OP_TYPE:
|
||||
case OP_BOOL:
|
||||
case OP_VAR_VALUE:
|
||||
case OP_LAST:
|
||||
case OP_REGISTER:
|
||||
case OP_INTERNALVAR:
|
||||
|
71
gdb/valops.c
71
gdb/valops.c
@ -81,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
|
||||
{
|
||||
@ -332,7 +332,7 @@ value_assign (toval, fromval)
|
||||
int v; /* FIXME, this won't work for large bitfields */
|
||||
read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
|
||||
(char *) &v, sizeof v);
|
||||
modify_field ((char *) &v, (int) value_as_long (fromval),
|
||||
modify_field ((char *) &v, value_as_long (fromval),
|
||||
VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
|
||||
write_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
|
||||
(char *)&v, sizeof v);
|
||||
@ -352,7 +352,7 @@ value_assign (toval, fromval)
|
||||
|
||||
read_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
|
||||
(char *) &v, sizeof v);
|
||||
modify_field ((char *) &v, (int) value_as_long (fromval),
|
||||
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);
|
||||
@ -415,7 +415,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);
|
||||
@ -498,12 +498,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)
|
||||
{
|
||||
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;
|
||||
@ -632,14 +650,14 @@ push_word (sp, word)
|
||||
REGISTER_TYPE word;
|
||||
{
|
||||
register int len = sizeof (REGISTER_TYPE);
|
||||
REGISTER_TYPE buffer;
|
||||
char buffer[MAX_REGISTER_RAW_SIZE];
|
||||
|
||||
store_unsigned_integer (&buffer, len, word);
|
||||
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 */
|
||||
|
||||
@ -694,7 +712,15 @@ 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)
|
||||
@ -1153,8 +1179,11 @@ value_string (ptr, len)
|
||||
return (val);
|
||||
}
|
||||
|
||||
/* 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.
|
||||
@ -1186,8 +1215,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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user