mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-17 13:10:12 +08:00
Prologue scanner modifications.
This commit is contained in:
parent
d469a809fa
commit
58ab00f996
@ -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.
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user