2002-11-15 Andrew Cagney <ac131313@redhat.com>
* frame.c (frame_pc_unwind): New function. (frame_saved_regs_pc_unwind): New function. (frame_register_unwind): Pass unwind_cache instead of register_unwind_cache. (set_unwind_by_pc): Add unwind_pc parameter, set. (create_new_frame): Pass frame->pc_unwind to set_unwind_by_pc. (get_prev_frame): Ditto. * frame.h (frame_pc_unwind_ftype): Declare. (struct frame_info): Add pc_unwind, pc_unwind_cache_p and pc_unwind_cache. Rename register_unwind_cache to unwind_cache. (frame_pc_unwind): Declare. * dummy-frame.c (dummy_frame_pc_unwind): New function. (struct dummy_frame): Add comment mentioning that values are for previous frame. * dummy-frame.h (dummy_frame_pc_unwind): Declare. * blockframe.c (file_frame_chain_valid): Use frame_pc_unwind. (generic_file_frame_chain_valid): Ditto. * stack.c (frame_info): Ditto.
This commit is contained in:
parent
d9285969ae
commit
f18c5a7303
7 changed files with 109 additions and 18 deletions
|
@ -1,3 +1,24 @@
|
||||||
|
2002-11-15 Andrew Cagney <ac131313@redhat.com>
|
||||||
|
|
||||||
|
* frame.c (frame_pc_unwind): New function.
|
||||||
|
(frame_saved_regs_pc_unwind): New function.
|
||||||
|
(frame_register_unwind): Pass unwind_cache instead of
|
||||||
|
register_unwind_cache.
|
||||||
|
(set_unwind_by_pc): Add unwind_pc parameter, set.
|
||||||
|
(create_new_frame): Pass frame->pc_unwind to set_unwind_by_pc.
|
||||||
|
(get_prev_frame): Ditto.
|
||||||
|
* frame.h (frame_pc_unwind_ftype): Declare.
|
||||||
|
(struct frame_info): Add pc_unwind, pc_unwind_cache_p and
|
||||||
|
pc_unwind_cache. Rename register_unwind_cache to unwind_cache.
|
||||||
|
(frame_pc_unwind): Declare.
|
||||||
|
* dummy-frame.c (dummy_frame_pc_unwind): New function.
|
||||||
|
(struct dummy_frame): Add comment mentioning that values are for
|
||||||
|
previous frame.
|
||||||
|
* dummy-frame.h (dummy_frame_pc_unwind): Declare.
|
||||||
|
* blockframe.c (file_frame_chain_valid): Use frame_pc_unwind.
|
||||||
|
(generic_file_frame_chain_valid): Ditto.
|
||||||
|
* stack.c (frame_info): Ditto.
|
||||||
|
|
||||||
2002-11-15 David Carlton <carlton@math.stanford.edu>
|
2002-11-15 David Carlton <carlton@math.stanford.edu>
|
||||||
|
|
||||||
* linespec.c (locate_first_half): New function.
|
* linespec.c (locate_first_half): New function.
|
||||||
|
|
|
@ -49,7 +49,7 @@ int
|
||||||
file_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
|
file_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
|
||||||
{
|
{
|
||||||
return ((chain) != 0
|
return ((chain) != 0
|
||||||
&& !inside_entry_file (FRAME_SAVED_PC (thisframe)));
|
&& !inside_entry_file (frame_pc_unwind (thisframe)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use the alternate method of avoiding running up off the end of the
|
/* Use the alternate method of avoiding running up off the end of the
|
||||||
|
@ -753,12 +753,12 @@ pc_in_call_dummy_at_entry_point (CORE_ADDR pc, CORE_ADDR sp,
|
||||||
int
|
int
|
||||||
generic_file_frame_chain_valid (CORE_ADDR fp, struct frame_info *fi)
|
generic_file_frame_chain_valid (CORE_ADDR fp, struct frame_info *fi)
|
||||||
{
|
{
|
||||||
if (PC_IN_CALL_DUMMY (FRAME_SAVED_PC (fi), fp, fp))
|
if (PC_IN_CALL_DUMMY (frame_pc_unwind (fi), fp, fp))
|
||||||
return 1; /* don't prune CALL_DUMMY frames */
|
return 1; /* don't prune CALL_DUMMY frames */
|
||||||
else /* fall back to default algorithm (see frame.h) */
|
else /* fall back to default algorithm (see frame.h) */
|
||||||
return (fp != 0
|
return (fp != 0
|
||||||
&& (INNER_THAN (fi->frame, fp) || fi->frame == fp)
|
&& (INNER_THAN (fi->frame, fp) || fi->frame == fp)
|
||||||
&& !inside_entry_file (FRAME_SAVED_PC (fi)));
|
&& !inside_entry_file (frame_pc_unwind (fi)));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -37,6 +37,8 @@ struct dummy_frame
|
||||||
{
|
{
|
||||||
struct dummy_frame *next;
|
struct dummy_frame *next;
|
||||||
|
|
||||||
|
/* These values belong to the caller (the previous frame, the frame
|
||||||
|
that this unwinds back to). */
|
||||||
CORE_ADDR pc;
|
CORE_ADDR pc;
|
||||||
CORE_ADDR fp;
|
CORE_ADDR fp;
|
||||||
CORE_ADDR sp;
|
CORE_ADDR sp;
|
||||||
|
@ -308,3 +310,16 @@ dummy_frame_register_unwind (struct frame_info *frame, void **cache,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CORE_ADDR
|
||||||
|
dummy_frame_pc_unwind (struct frame_info *frame,
|
||||||
|
void **cache)
|
||||||
|
{
|
||||||
|
struct dummy_frame *dummy = cached_find_dummy_frame (frame, cache);
|
||||||
|
/* Oops! In a dummy-frame but can't find the stack dummy. Pretend
|
||||||
|
that the frame doesn't unwind. Should this function instead
|
||||||
|
return a has-no-caller indication? */
|
||||||
|
if (dummy == NULL)
|
||||||
|
return 0;
|
||||||
|
return dummy->pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,12 @@ extern void dummy_frame_register_unwind (struct frame_info *frame,
|
||||||
int *realnump,
|
int *realnump,
|
||||||
void *valuep);
|
void *valuep);
|
||||||
|
|
||||||
|
/* Assuming that FRAME is a dummy, return the resume address for the
|
||||||
|
previous frame. */
|
||||||
|
|
||||||
|
extern CORE_ADDR dummy_frame_pc_unwind (struct frame_info *frame,
|
||||||
|
void **unwind_cache);
|
||||||
|
|
||||||
/* Return the regcache that belongs to the dummy-frame identifed by PC
|
/* Return the regcache that belongs to the dummy-frame identifed by PC
|
||||||
and FP, or NULL if no such frame exists. */
|
and FP, or NULL if no such frame exists. */
|
||||||
/* FIXME: cagney/2002-11-08: The function only exists because of
|
/* FIXME: cagney/2002-11-08: The function only exists because of
|
||||||
|
|
51
gdb/frame.c
51
gdb/frame.c
|
@ -84,6 +84,17 @@ frame_find_by_id (struct frame_id id)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CORE_ADDR
|
||||||
|
frame_pc_unwind (struct frame_info *frame)
|
||||||
|
{
|
||||||
|
if (!frame->pc_unwind_cache_p)
|
||||||
|
{
|
||||||
|
frame->pc_unwind_cache = frame->pc_unwind (frame, &frame->unwind_cache);
|
||||||
|
frame->pc_unwind_cache_p = 1;
|
||||||
|
}
|
||||||
|
return frame->pc_unwind_cache;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
frame_register_unwind (struct frame_info *frame, int regnum,
|
frame_register_unwind (struct frame_info *frame, int regnum,
|
||||||
int *optimizedp, enum lval_type *lvalp,
|
int *optimizedp, enum lval_type *lvalp,
|
||||||
|
@ -124,7 +135,7 @@ frame_register_unwind (struct frame_info *frame, int regnum,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ask this frame to unwind its register. */
|
/* Ask this frame to unwind its register. */
|
||||||
frame->register_unwind (frame, &frame->register_unwind_cache, regnum,
|
frame->register_unwind (frame, &frame->unwind_cache, regnum,
|
||||||
optimizedp, lvalp, addrp, realnump, bufferp);
|
optimizedp, lvalp, addrp, realnump, bufferp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,6 +535,12 @@ frame_saved_regs_register_unwind (struct frame_info *frame, void **cache,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CORE_ADDR
|
||||||
|
frame_saved_regs_pc_unwind (struct frame_info *frame, void **cache)
|
||||||
|
{
|
||||||
|
return FRAME_SAVED_PC (frame);
|
||||||
|
}
|
||||||
|
|
||||||
/* Function: get_saved_register
|
/* Function: get_saved_register
|
||||||
Find register number REGNUM relative to FRAME and put its (raw,
|
Find register number REGNUM relative to FRAME and put its (raw,
|
||||||
target format) contents in *RAW_BUFFER.
|
target format) contents in *RAW_BUFFER.
|
||||||
|
@ -627,18 +644,28 @@ deprecated_generic_get_saved_register (char *raw_buffer, int *optimized,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_unwind_by_pc (CORE_ADDR pc, CORE_ADDR fp,
|
set_unwind_by_pc (CORE_ADDR pc, CORE_ADDR fp,
|
||||||
frame_register_unwind_ftype **unwind)
|
frame_register_unwind_ftype **unwind_register,
|
||||||
|
frame_pc_unwind_ftype **unwind_pc)
|
||||||
{
|
{
|
||||||
if (!USE_GENERIC_DUMMY_FRAMES)
|
if (!USE_GENERIC_DUMMY_FRAMES)
|
||||||
/* Still need to set this to something. The ``info frame'' code
|
{
|
||||||
calls this function to find out where the saved registers are.
|
/* Still need to set this to something. The ``info frame'' code
|
||||||
Hopefully this is robust enough to stop any core dumps and
|
calls this function to find out where the saved registers are.
|
||||||
return vaguely correct values.. */
|
Hopefully this is robust enough to stop any core dumps and
|
||||||
*unwind = frame_saved_regs_register_unwind;
|
return vaguely correct values.. */
|
||||||
|
*unwind_register = frame_saved_regs_register_unwind;
|
||||||
|
*unwind_pc = frame_saved_regs_pc_unwind;
|
||||||
|
}
|
||||||
else if (PC_IN_CALL_DUMMY (pc, fp, fp))
|
else if (PC_IN_CALL_DUMMY (pc, fp, fp))
|
||||||
*unwind = dummy_frame_register_unwind;
|
{
|
||||||
|
*unwind_register = dummy_frame_register_unwind;
|
||||||
|
*unwind_pc = dummy_frame_pc_unwind;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
*unwind = frame_saved_regs_register_unwind;
|
{
|
||||||
|
*unwind_register = frame_saved_regs_register_unwind;
|
||||||
|
*unwind_pc = frame_saved_regs_pc_unwind;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create an arbitrary (i.e. address specified by user) or innermost frame.
|
/* Create an arbitrary (i.e. address specified by user) or innermost frame.
|
||||||
|
@ -666,7 +693,8 @@ create_new_frame (CORE_ADDR addr, CORE_ADDR pc)
|
||||||
INIT_EXTRA_FRAME_INFO (0, fi);
|
INIT_EXTRA_FRAME_INFO (0, fi);
|
||||||
|
|
||||||
/* Select/initialize an unwind function. */
|
/* Select/initialize an unwind function. */
|
||||||
set_unwind_by_pc (fi->pc, fi->frame, &fi->register_unwind);
|
set_unwind_by_pc (fi->pc, fi->frame, &fi->register_unwind,
|
||||||
|
&fi->pc_unwind);
|
||||||
|
|
||||||
return fi;
|
return fi;
|
||||||
}
|
}
|
||||||
|
@ -913,7 +941,8 @@ get_prev_frame (struct frame_info *next_frame)
|
||||||
(and probably other architectural information). The PC lets you
|
(and probably other architectural information). The PC lets you
|
||||||
check things like the debug info at that point (dwarf2cfi?) and
|
check things like the debug info at that point (dwarf2cfi?) and
|
||||||
use that to decide how the frame should be unwound. */
|
use that to decide how the frame should be unwound. */
|
||||||
set_unwind_by_pc (prev->pc, prev->frame, &prev->register_unwind);
|
set_unwind_by_pc (prev->pc, prev->frame, &prev->register_unwind,
|
||||||
|
&prev->pc_unwind);
|
||||||
|
|
||||||
find_pc_partial_function (prev->pc, &name,
|
find_pc_partial_function (prev->pc, &name,
|
||||||
(CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
|
(CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
|
||||||
|
|
26
gdb/frame.h
26
gdb/frame.h
|
@ -139,6 +139,12 @@ extern void frame_read_unsigned_register (struct frame_info *frame,
|
||||||
extern int frame_map_name_to_regnum (const char *name, int strlen);
|
extern int frame_map_name_to_regnum (const char *name, int strlen);
|
||||||
extern const char *frame_map_regnum_to_name (int regnum);
|
extern const char *frame_map_regnum_to_name (int regnum);
|
||||||
|
|
||||||
|
/* Unwind the PC. Strictly speaking return the resume address of the
|
||||||
|
calling frame. For GDB, `pc' is the resume address and not a
|
||||||
|
specific register. */
|
||||||
|
|
||||||
|
extern CORE_ADDR frame_pc_unwind (struct frame_info *frame);
|
||||||
|
|
||||||
|
|
||||||
/* Return the location (and possibly value) of REGNUM for the previous
|
/* Return the location (and possibly value) of REGNUM for the previous
|
||||||
(older, up) frame. All parameters except VALUEP can be assumed to
|
(older, up) frame. All parameters except VALUEP can be assumed to
|
||||||
|
@ -163,6 +169,12 @@ typedef void (frame_register_unwind_ftype) (struct frame_info *frame,
|
||||||
int *realnump,
|
int *realnump,
|
||||||
void *valuep);
|
void *valuep);
|
||||||
|
|
||||||
|
/* Same as for registers above, but return the address at which the
|
||||||
|
calling frame would resume. */
|
||||||
|
|
||||||
|
typedef CORE_ADDR (frame_pc_unwind_ftype) (struct frame_info *frame,
|
||||||
|
void **unwind_cache);
|
||||||
|
|
||||||
/* Describe the saved registers of a frame. */
|
/* Describe the saved registers of a frame. */
|
||||||
|
|
||||||
#if defined (EXTRA_FRAME_INFO) || defined (FRAME_FIND_SAVED_REGS)
|
#if defined (EXTRA_FRAME_INFO) || defined (FRAME_FIND_SAVED_REGS)
|
||||||
|
@ -252,10 +264,18 @@ struct frame_info
|
||||||
related unwind data. */
|
related unwind data. */
|
||||||
struct context *context;
|
struct context *context;
|
||||||
|
|
||||||
/* See description above. Return the register value for the
|
/* Unwind cache shared between the unwind functions - they had
|
||||||
previous frame. */
|
better all agree as to the contents. */
|
||||||
|
void *unwind_cache;
|
||||||
|
|
||||||
|
/* See description above. The previous frame's registers. */
|
||||||
frame_register_unwind_ftype *register_unwind;
|
frame_register_unwind_ftype *register_unwind;
|
||||||
void *register_unwind_cache;
|
|
||||||
|
/* See description above. The previous frame's resume address.
|
||||||
|
Save the previous PC in a local cache. */
|
||||||
|
frame_pc_unwind_ftype *pc_unwind;
|
||||||
|
int pc_unwind_cache_p;
|
||||||
|
CORE_ADDR pc_unwind_cache;
|
||||||
|
|
||||||
/* Pointers to the next (down, inner, younger) and previous (up,
|
/* Pointers to the next (down, inner, younger) and previous (up,
|
||||||
outer, older) frame_info's in the frame cache. */
|
outer, older) frame_info's in the frame cache. */
|
||||||
|
|
|
@ -866,7 +866,7 @@ frame_info (char *addr_exp, int from_tty)
|
||||||
puts_filtered ("; ");
|
puts_filtered ("; ");
|
||||||
wrap_here (" ");
|
wrap_here (" ");
|
||||||
printf_filtered ("saved %s ", REGISTER_NAME (PC_REGNUM));
|
printf_filtered ("saved %s ", REGISTER_NAME (PC_REGNUM));
|
||||||
print_address_numeric (FRAME_SAVED_PC (fi), 1, gdb_stdout);
|
print_address_numeric (frame_pc_unwind (fi), 1, gdb_stdout);
|
||||||
printf_filtered ("\n");
|
printf_filtered ("\n");
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue