2003-04-09 Andrew Cagney <cagney@redhat.com>

* frame.h (struct frame_id): Replace "pc" and "base" with
	"stack_addr" and "code_addr".  Update comments.
	(frame_id_build): Update parameter names and comment.
	(struct frame_info): Replace "id_p" and "id" with "this_id".
	* dummy-frame.c (dummy_frame_this_id): Update.
	* breakpoint.c (print_one_breakpoint): Update.
	* frame.c (get_frame_id): Update.
	(get_frame_base, frame_id_build): Update.
	(create_sentinel_frame, legacy_get_prev_frame): Update.
	(deprecated_update_frame_base_hack): Update.
	(frame_id_p, frame_id_eq): Rework, return 0 when an invalid ID.
	(frame_id_inner): Ditto.
This commit is contained in:
Andrew Cagney 2003-04-10 03:30:36 +00:00
parent ac16bf075e
commit d0a557723a
5 changed files with 96 additions and 47 deletions

View File

@ -1,3 +1,18 @@
2003-04-09 Andrew Cagney <cagney@redhat.com>
* frame.h (struct frame_id): Replace "pc" and "base" with
"stack_addr" and "code_addr". Update comments.
(frame_id_build): Update parameter names and comment.
(struct frame_info): Replace "id_p" and "id" with "this_id".
* dummy-frame.c (dummy_frame_this_id): Update.
* breakpoint.c (print_one_breakpoint): Update.
* frame.c (get_frame_id): Update.
(get_frame_base, frame_id_build): Update.
(create_sentinel_frame, legacy_get_prev_frame): Update.
(deprecated_update_frame_base_hack): Update.
(frame_id_p, frame_id_eq): Rework, return 0 when an invalid ID.
(frame_id_inner): Ditto.
2003-04-09 Andrew Cagney <cagney@redhat.com> 2003-04-09 Andrew Cagney <cagney@redhat.com>
* defs.h (gdb_print_host_address): Make "addr" parameter a * defs.h (gdb_print_host_address): Make "addr" parameter a

View File

@ -3418,7 +3418,7 @@ print_one_breakpoint (struct breakpoint *b,
ui_out_text (uiout, "\tstop only in stack frame at "); ui_out_text (uiout, "\tstop only in stack frame at ");
/* FIXME: cagney/2002-12-01: Shouldn't be poeking around inside /* FIXME: cagney/2002-12-01: Shouldn't be poeking around inside
the frame ID. */ the frame ID. */
ui_out_field_core_addr (uiout, "frame", b->frame_id.base); ui_out_field_core_addr (uiout, "frame", b->frame_id.stack_addr);
ui_out_text (uiout, "\n"); ui_out_text (uiout, "\n");
} }

View File

@ -397,7 +397,8 @@ dummy_frame_this_id (struct frame_info *next_frame,
(*this_id) = null_frame_id; (*this_id) = null_frame_id;
return; return;
} }
(*this_prologue_cache) = find_dummy_frame ((*this_id).pc, (*this_id).base); (*this_prologue_cache) = find_dummy_frame ((*this_id).code_addr,
(*this_id).stack_addr);
} }
static struct frame_unwind dummy_frame_unwind = static struct frame_unwind dummy_frame_unwind =

View File

@ -58,53 +58,74 @@ get_frame_id (struct frame_info *fi)
{ {
return null_frame_id; return null_frame_id;
} }
if (!fi->id_p) if (!fi->this_id.p)
{ {
gdb_assert (!legacy_frame_p (current_gdbarch)); gdb_assert (!legacy_frame_p (current_gdbarch));
/* Find THIS frame's ID. */ /* Find THIS frame's ID. */
fi->unwind->this_id (fi->next, &fi->prologue_cache, &fi->id); fi->unwind->this_id (fi->next, &fi->prologue_cache, &fi->this_id.value);
fi->id_p = 1; fi->this_id.p = 1;
} }
return frame_id_build (fi->id.base, get_frame_pc (fi)); return frame_id_build (fi->this_id.value.stack_addr, get_frame_pc (fi));
} }
const struct frame_id null_frame_id; /* All zeros. */ const struct frame_id null_frame_id; /* All zeros. */
struct frame_id struct frame_id
frame_id_build (CORE_ADDR base, CORE_ADDR func_or_pc) frame_id_build (CORE_ADDR stack_addr, CORE_ADDR code_addr)
{ {
struct frame_id id; struct frame_id id;
id.base = base; id.stack_addr = stack_addr;
id.pc = func_or_pc; id.code_addr = code_addr;
return id; return id;
} }
int int
frame_id_p (struct frame_id l) frame_id_p (struct frame_id l)
{ {
/* The .func can be NULL but the .base cannot. */ int p;
return (l.base != 0); /* The .code can be NULL but the .stack cannot. */
p = (l.stack_addr != 0);
return p;
} }
int int
frame_id_eq (struct frame_id l, struct frame_id r) frame_id_eq (struct frame_id l, struct frame_id r)
{ {
/* If .base is different, the frames are different. */ int eq;
if (l.base != r.base) if (l.stack_addr == 0 || r.stack_addr == 0)
return 0; /* Like a NaN, if either ID is invalid, the result is false. */
/* Add a test to check that the frame ID's are for the same function eq = 0;
here. */ else if (l.stack_addr != r.stack_addr)
return 1; /* If .stack addresses are different, the frames are different. */
eq = 0;
else if (l.code_addr == 0 || r.code_addr == 0)
/* A zero code addr is a wild card, always succeed. */
eq = 1;
else if (l.code_addr == r.code_addr)
/* The .stack and .code are identical, the ID's are identical. */
eq = 1;
else
/* FIXME: cagney/2003-04-06: This should be zero. Can't yet do
this because most frame ID's are not being initialized
correctly. */
eq = 1;
return eq;
} }
int int
frame_id_inner (struct frame_id l, struct frame_id r) frame_id_inner (struct frame_id l, struct frame_id r)
{ {
/* Only return non-zero when strictly inner than. Note that, per int inner;
comment in "frame.h", there is some fuzz here. Frameless if (l.stack_addr == 0 || r.stack_addr == 0)
functions are not strictly inner than (same .base but different /* Like NaN, any operation involving an invalid ID always fails. */
.func). */ inner = 0;
return INNER_THAN (l.base, r.base); else
/* 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 .stack but
different .code). */
inner = INNER_THAN (l.stack_addr, r.stack_addr);
return inner;
} }
struct frame_info * struct frame_info *
@ -520,8 +541,8 @@ create_sentinel_frame (struct regcache *regcache)
frame->next = frame; frame->next = frame;
/* Make the sentinel frame's ID valid, but invalid. That way all /* Make the sentinel frame's ID valid, but invalid. That way all
comparisons with it should fail. */ comparisons with it should fail. */
frame->id_p = 1; frame->this_id.p = 1;
frame->id = null_frame_id; frame->this_id.value = null_frame_id;
return frame; return frame;
} }
@ -1069,7 +1090,7 @@ legacy_get_prev_frame (struct frame_info *this_frame)
prev->type = UNKNOWN_FRAME; prev->type = UNKNOWN_FRAME;
/* A legacy frame's ID is always computed here. Mark it as valid. */ /* A legacy frame's ID is always computed here. Mark it as valid. */
prev->id_p = 1; prev->this_id.p = 1;
/* Handle sentinel frame unwind as a special case. */ /* Handle sentinel frame unwind as a special case. */
if (this_frame->level < 0) if (this_frame->level < 0)
@ -1132,7 +1153,8 @@ legacy_get_prev_frame (struct frame_info *this_frame)
dummy ID from the next frame. Note that this method uses dummy ID from the next frame. Note that this method uses
frame_register_unwind to obtain the register values frame_register_unwind to obtain the register values
needed to determine the dummy frame's ID. */ needed to determine the dummy frame's ID. */
prev->id = gdbarch_unwind_dummy_id (current_gdbarch, this_frame); prev->this_id.value = gdbarch_unwind_dummy_id (current_gdbarch,
this_frame);
} }
else else
{ {
@ -1141,11 +1163,11 @@ legacy_get_prev_frame (struct frame_info *this_frame)
using the same sequence as is found a traditional using the same sequence as is found a traditional
unwinder. Once all architectures supply the unwinder. Once all architectures supply the
unwind_dummy_id method, this code can go away. */ unwind_dummy_id method, this code can go away. */
prev->id = frame_id_build (read_fp (), read_pc ()); prev->this_id.value = frame_id_build (read_fp (), read_pc ());
} }
/* Check that the unwound ID is valid. */ /* Check that the unwound ID is valid. */
if (!frame_id_p (prev->id)) if (!frame_id_p (prev->this_id.value))
{ {
if (frame_debug) if (frame_debug)
fprintf_unfiltered (gdb_stdlog, fprintf_unfiltered (gdb_stdlog,
@ -1664,7 +1686,7 @@ find_frame_sal (struct frame_info *frame, struct symtab_and_line *sal)
CORE_ADDR CORE_ADDR
get_frame_base (struct frame_info *fi) get_frame_base (struct frame_info *fi)
{ {
return get_frame_id (fi).base; return get_frame_id (fi).stack_addr;
} }
/* High-level offsets into the frame. Used by the debug info. */ /* High-level offsets into the frame. Used by the debug info. */
@ -1786,7 +1808,7 @@ void
deprecated_update_frame_base_hack (struct frame_info *frame, CORE_ADDR base) deprecated_update_frame_base_hack (struct frame_info *frame, CORE_ADDR base)
{ {
/* See comment in "frame.h". */ /* See comment in "frame.h". */
frame->id.base = base; frame->this_id.value.stack_addr = base;
} }
void void

View File

@ -44,15 +44,24 @@ struct frame_info;
struct frame_id struct frame_id
{ {
/* The frame's address. This should be constant through out the /* The frame's stack address. This shall be constant through out
lifetime of a frame. */ the lifetime of a frame. Note that this requirement applies to
not just the function body, but also the prologue and (in theory
at least) the epilogue. Since that value needs to fall either on
the boundary, or within the frame's address range, the frame's
outer-most address (the inner-most address of the previous frame)
is used. Watch out for all the legacy targets that still use the
function pointer register or stack pointer register. They are
wrong. */
/* NOTE: cagney/2002-11-16: The ia64 has two stacks and hence two /* NOTE: cagney/2002-11-16: The ia64 has two stacks and hence two
frame bases. This will need to be expanded to accomodate that. */ frame bases. This will need to be expanded to accomodate that. */
CORE_ADDR base; CORE_ADDR stack_addr;
/* The frame's current PC. While the PC within the function may /* The frame's code address. This shall be constant through out the
change, the function that contains the PC does not. Should this lifetime of the frame. While the PC (a.k.a. resume address)
instead be the frame's function? */ changes as the function is executed, this code address cannot.
CORE_ADDR pc; Typically, it is set to the address of the entry point of the
frame's function (as returned by frame_func_unwind(). */
CORE_ADDR code_addr;
}; };
/* Methods for constructing and comparing Frame IDs. /* Methods for constructing and comparing Frame IDs.
@ -66,12 +75,12 @@ struct frame_id
/* For convenience. All fields are zero. */ /* For convenience. All fields are zero. */
extern const struct frame_id null_frame_id; extern const struct frame_id null_frame_id;
/* Construct a frame ID. The second parameter isn't yet well defined. /* Construct a frame ID. The first parameter is the frame's constant
It might be the containing function, or the resume PC (see comment stack address (typically the outer-bound), and the second the
above in `struct frame_id')? A func/pc of zero indicates a frame's constant code address (typically the entry point) (or zero,
wildcard (i.e., do not use func in frame ID comparisons). */ to indicate a wild card). */
extern struct frame_id frame_id_build (CORE_ADDR base, extern struct frame_id frame_id_build (CORE_ADDR stack_addr,
CORE_ADDR func_or_pc); CORE_ADDR code_addr);
/* Returns non-zero when L is a valid frame (a valid frame has a /* Returns non-zero when L is a valid frame (a valid frame has a
non-zero .base). */ non-zero .base). */
@ -397,10 +406,12 @@ struct frame_info
int p; int p;
} prev_func; } prev_func;
/* This frame's ID. Note that the frame's ID, base and PC contain /* This frame's ID. */
redundant information. */ struct
int id_p; {
struct frame_id id; int p;
struct frame_id value;
} this_id;
/* The frame's high-level base methods, and corresponding cache. /* The frame's high-level base methods, and corresponding cache.
The high level base methods are selected based on the frame's The high level base methods are selected based on the frame's