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:
Andrew Cagney 2002-11-15 22:16:25 +00:00
parent d9285969ae
commit f18c5a7303
7 changed files with 109 additions and 18 deletions

View file

@ -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.

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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);

View file

@ -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. */

View file

@ -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");
{ {