2002-12-03 Andrew Cagney <ac131313@redhat.com>

* frame.h (get_frame_id): Convert to a function.
	(null_frame_id, frame_id_p): Declare.
	(frame_id_eq, frame_id_inner): Declare.
	(frame_id_build): New function.
	* frame.c (get_frame_id): Update.  Use null_frame_id.
	(frame_find_by_id): Rewrite using frame_id_p, frame_id_eq and
	frame_id_inner.
	(null_frame_id, frame_id_p): Define.
	(frame_id_eq, frame_id_inner): Define.
	(frame_id_build): New function.
	* varobj.c (varobj_create): Update.
	(varobj_update): Update.
	* valops.c (value_assign): Update.
	(new_root_variable): Update.
	* infrun.c (save_inferior_status): Update.
	* breakpoint.c (watch_command_1): Update.
This commit is contained in:
Andrew Cagney 2002-12-04 00:05:54 +00:00
parent 179f9f7a5a
commit 7a424e9969
7 changed files with 120 additions and 34 deletions

View File

@ -1,3 +1,22 @@
2002-12-03 Andrew Cagney <ac131313@redhat.com>
* frame.h (get_frame_id): Convert to a function.
(null_frame_id, frame_id_p): Declare.
(frame_id_eq, frame_id_inner): Declare.
(frame_id_build): New function.
* frame.c (get_frame_id): Update. Use null_frame_id.
(frame_find_by_id): Rewrite using frame_id_p, frame_id_eq and
frame_id_inner.
(null_frame_id, frame_id_p): Define.
(frame_id_eq, frame_id_inner): Define.
(frame_id_build): New function.
* varobj.c (varobj_create): Update.
(varobj_update): Update.
* valops.c (value_assign): Update.
(new_root_variable): Update.
* infrun.c (save_inferior_status): Update.
* breakpoint.c (watch_command_1): Update.
2002-12-03 J. Brobecker <brobecker@gnat.com>
* config/pa/tm-hppah.h (SNAP1): Remove unused macro.

View File

@ -5400,7 +5400,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
if (frame)
{
prev_frame = get_prev_frame (frame);
get_frame_id (frame, &b->watchpoint_frame);
b->watchpoint_frame = get_frame_id (frame);
}
else
{

View File

@ -35,24 +35,64 @@
#include "annotate.h"
#include "language.h"
/* Return a frame uniq ID that can be used to, later re-find the
/* Return a frame uniq ID that can be used to, later, re-find the
frame. */
void
get_frame_id (struct frame_info *fi, struct frame_id *id)
struct frame_id
get_frame_id (struct frame_info *fi)
{
if (fi == NULL)
{
id->base = 0;
id->pc = 0;
return null_frame_id;
}
else
{
id->base = fi->frame;
id->pc = fi->pc;
struct frame_id id;
id.base = fi->frame;
id.pc = fi->pc;
return id;
}
}
const struct frame_id null_frame_id; /* All zeros. */
struct frame_id
frame_id_build (CORE_ADDR base, CORE_ADDR func_or_pc)
{
struct frame_id id;
id.base = base;
id.pc = func_or_pc;
return id;
}
int
frame_id_p (struct frame_id l)
{
/* The .func can be NULL but the .base cannot. */
return (l.base != 0);
}
int
frame_id_eq (struct frame_id l, struct frame_id r)
{
/* If .base is different, the frames are different. */
if (l.base != r.base)
return 0;
/* Add a test to check that the frame ID's are for the same function
here. */
return 1;
}
int
frame_id_inner (struct frame_id l, struct frame_id r)
{
/* Only return non-zero when strictly inner than. Note that, per
comment in "frame.h", there is some fuzz here. Frameless
functions are not strictly inner than (same .base but different
.func). */
return INNER_THAN (l.base, r.base);
}
struct frame_info *
frame_find_by_id (struct frame_id id)
{
@ -60,29 +100,24 @@ frame_find_by_id (struct frame_id id)
/* ZERO denotes the null frame, let the caller decide what to do
about it. Should it instead return get_current_frame()? */
if (id.base == 0 && id.pc == 0)
if (!frame_id_p (id))
return NULL;
for (frame = get_current_frame ();
frame != NULL;
frame = get_prev_frame (frame))
{
struct frame_id this;
get_frame_id (frame, &this);
if (INNER_THAN (this.base, id.base))
/* ``inner/current < frame < id.base''. Keep looking along
the frame chain. */
continue;
if (INNER_THAN (id.base, this.base))
/* ``inner/current < id.base < frame''. Oops, gone past it.
Just give up. */
struct frame_id this = get_frame_id (frame);
if (frame_id_eq (id, this))
/* An exact match. */
return frame;
if (frame_id_inner (id, this))
/* Gone to far. */
return NULL;
/* FIXME: cagney/2002-04-21: This isn't sufficient. It should
use id.pc / this.pc to check that the two frames belong to
the same function. Otherwise we'll do things like match
dummy frames or mis-match frameless functions. However,
until someone notices, stick with the existing behavour. */
return frame;
/* Either, we're not yet gone far enough out along the frame
chain (inner(this,id), or we're comparing frameless functions
(same .base, different .func, no test available). Struggle
on until we've definitly gone to far. */
}
return NULL;
}

View File

@ -31,8 +31,8 @@ struct frame_info;
/* The frame object's ID. This provides a per-frame unique identifier
that can be used to relocate a `struct frame_info' after a target
resume or a frame cache destruct (assuming the target hasn't
unwound the stack past that frame - a problem handled elsewhere). */
resume or a frame cache destruct. It of course assumes that the
inferior hasn't unwound the stack past that frame. */
struct frame_id
{
@ -47,6 +47,38 @@ struct frame_id
CORE_ADDR pc;
};
/* Methods for constructing and comparing Frame IDs.
NOTE: Given frameless functions A and B, where A calls B (and hence
B is inner-to A). The relationships: !eq(A,B); !eq(B,A);
!inner(A,B); !inner(B,A); all hold. This is because, while B is
inner to A, B is not strictly inner to A (being frameless, they
have the same .base value). */
/* For convenience. All fields are zero. */
extern const struct frame_id null_frame_id;
/* Construct a frame ID. The second parameter isn't yet well defined.
It might be the containing function, or the resume PC (see comment
above in `struct frame_id')? A func/pc of zero indicates a
wildcard (i.e., do not use func in frame ID comparisons). */
extern struct frame_id frame_id_build (CORE_ADDR base,
CORE_ADDR func_or_pc);
/* Returns non-zero when L is a valid frame (a valid frame has a
non-zero .base). */
extern int frame_id_p (struct frame_id l);
/* Returns non-zero when L and R identify the same frame, or, if
either L or R have a zero .func, then the same frame base. */
extern int frame_id_eq (struct frame_id l, struct frame_id r);
/* Returns non-zero when L is strictly inner-than R (they have
different frame .bases). Neither L, nor R can be `null'. See note
above about frameless functions. */
extern int frame_id_inner (struct frame_id l, struct frame_id r);
/* For every stopped thread, GDB tracks two frames: current and
selected. Current frame is the inner most frame of the selected
thread. Selected frame is the one being examined by the the GDB
@ -176,8 +208,9 @@ extern void find_frame_sal (struct frame_info *frame,
extern CORE_ADDR get_frame_base (struct frame_info *);
/* Return the per-frame unique identifer. Can be used to relocate a
frame after a frame cache flush (and other similar operations). */
extern void get_frame_id (struct frame_info *fi, struct frame_id *id);
frame after a frame cache flush (and other similar operations). If
FI is NULL, return the null_frame_id. */
extern struct frame_id get_frame_id (struct frame_info *fi);
/* The frame's level: 0 for innermost, 1 for its caller, ...; or -1
for an invalid frame). */

View File

@ -3856,7 +3856,7 @@ save_inferior_status (int restore_stack_info)
inf_status->registers = regcache_dup (current_regcache);
get_frame_id (deprecated_selected_frame, &inf_status->selected_frame_id);
inf_status->selected_frame_id = get_frame_id (deprecated_selected_frame);
return inf_status;
}

View File

@ -649,7 +649,7 @@ value_assign (struct value *toval, struct value *fromval)
/* Since modifying a register can trash the frame chain, we
save the old frame and then restore the new frame
afterwards. */
get_frame_id (deprecated_selected_frame, &old_frame);
old_frame = get_frame_id (deprecated_selected_frame);
/* Figure out which frame this is in currently. */
if (VALUE_LVAL (toval) == lval_register)

View File

@ -487,7 +487,7 @@ varobj_create (char *objname,
Since select_frame is so benign, just call it for all cases. */
if (fi != NULL)
{
get_frame_id (fi, &var->root->frame);
var->root->frame = get_frame_id (fi);
old_fi = deprecated_selected_frame;
select_frame (fi);
}
@ -898,7 +898,7 @@ varobj_update (struct varobj **varp, struct varobj ***changelist)
/* Save the selected stack frame, since we will need to change it
in order to evaluate expressions. */
get_frame_id (deprecated_selected_frame, &old_fid);
old_fid = get_frame_id (deprecated_selected_frame);
/* Update the root variable. value_of_root can return NULL
if the variable is no longer around, i.e. we stepped out of
@ -1344,8 +1344,7 @@ new_root_variable (void)
var->root->lang = NULL;
var->root->exp = NULL;
var->root->valid_block = NULL;
var->root->frame.base = 0;
var->root->frame.pc = 0;
var->root->frame = null_frame_id;
var->root->use_selected_frame = 0;
var->root->rootvar = NULL;