Prologue scanner modifications.

This commit is contained in:
Kevin Buettner 2001-06-01 02:39:51 +00:00
parent d469a809fa
commit 58ab00f996
2 changed files with 78 additions and 1 deletions

View File

@ -4,6 +4,13 @@
match the location at which the kernel is placing the sigcontext
struct.
* ia64-tdep.c (max_skip_non_prologue_insns): New static global.
(refine_prologue_limit): New function.
(examine_prologue): Further limit number of instructions
scanned by calling refine_prologue_limit(). Revise way in
which the end of prologue address is computed for frameless
functions.
2001-05-29 Christopher Faylor <cgf@redhat.com>
* partial-stab.h: Revert previous patch.

View File

@ -717,6 +717,69 @@ ia64_frame_saved_pc (struct frame_info *frame)
}
}
/* Limit the number of skipped non-prologue instructions since examining
of the prologue is expensive. */
static int max_skip_non_prologue_insns = 10;
/* Given PC representing the starting address of a function, and
LIM_PC which is the (sloppy) limit to which to scan when looking
for a prologue, attempt to further refine this limit by using
the line data in the symbol table. If successful, a better guess
on where the prologue ends is returned, otherwise the previous
value of lim_pc is returned. TRUST_LIMIT is a pointer to a flag
which will be set to indicate whether the returned limit may be
used with no further scanning in the event that the function is
frameless. */
static CORE_ADDR
refine_prologue_limit (CORE_ADDR pc, CORE_ADDR lim_pc, int *trust_limit)
{
struct symtab_and_line prologue_sal;
CORE_ADDR start_pc = pc;
/* Start off not trusting the limit. */
*trust_limit = 0;
prologue_sal = find_pc_line (pc, 0);
if (prologue_sal.line != 0)
{
int i;
CORE_ADDR addr = prologue_sal.end;
/* Handle the case in which compiler's optimizer/scheduler
has moved instructions into the prologue. We scan ahead
in the function looking for address ranges whose corresponding
line number is less than or equal to the first one that we
found for the function. (It can be less than when the
scheduler puts a body instruction before the first prologue
instruction.) */
for (i = 2 * max_skip_non_prologue_insns;
i > 0 && (lim_pc == 0 || addr < lim_pc);
i--)
{
struct symtab_and_line sal;
sal = find_pc_line (addr, 0);
if (sal.line == 0)
break;
if (sal.line <= prologue_sal.line
&& sal.symtab == prologue_sal.symtab)
{
prologue_sal = sal;
}
addr = sal.end;
}
if (lim_pc == 0 || prologue_sal.end < lim_pc)
{
lim_pc = prologue_sal.end;
if (start_pc == get_pc_function_start (lim_pc))
*trust_limit = 1;
}
}
return lim_pc;
}
#define isScratch(_regnum_) ((_regnum_) == 2 || (_regnum_) == 3 \
|| (8 <= (_regnum_) && (_regnum_) <= 11) \
|| (14 <= (_regnum_) && (_regnum_) <= 31))
@ -744,6 +807,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
CORE_ADDR spill_addr = 0;
char instores[8];
char infpstores[8];
int trust_limit;
memset (instores, 0, sizeof instores);
memset (infpstores, 0, sizeof infpstores);
@ -760,6 +824,8 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
&& frame->extra_info->after_prologue <= lim_pc)
return frame->extra_info->after_prologue;
lim_pc = refine_prologue_limit (pc, lim_pc, &trust_limit);
/* Must start with an alloc instruction */
next_pc = fetch_instruction (pc, &it, &instr);
if (pc < lim_pc && next_pc
@ -779,7 +845,11 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
pc = next_pc;
}
else
pc = lim_pc; /* We're done early */
{
pc = lim_pc; /* Frameless: We're done early. */
if (trust_limit)
last_prologue_pc = lim_pc;
}
/* Loop, looking for prologue instructions, keeping track of
where preserved registers were spilled. */