2004-11-11 Randolph Chung <tausq@debian.org>

* hppa-tdep.c (skip_prologue_hard_way): Make static, add
	stop_after_branch parameter and use it to determine if we should look
	at the delay slot of the first branch insn to find prologue insns.
	(hppa_skip_prologue): Update comment and call to skip_prologue_hard_way.
	(hppa_frame_cache): Likewise.
This commit is contained in:
Randolph Chung 2004-11-12 00:51:23 +00:00
parent 50b2f48ac1
commit a71f8c301e
2 changed files with 38 additions and 13 deletions

View file

@ -1,3 +1,11 @@
2004-11-11 Randolph Chung <tausq@debian.org>
* hppa-tdep.c (skip_prologue_hard_way): Make static, add
stop_after_branch parameter and use it to determine if we should look
at the delay slot of the first branch insn to find prologue insns.
(hppa_skip_prologue): Update comment and call to skip_prologue_hard_way.
(hppa_frame_cache): Likewise.
2004-11-11 Randolph Chung <tausq@debian.org> 2004-11-11 Randolph Chung <tausq@debian.org>
* hppa-tdep.c (hppa_frame_cache): Properly handle the frame pointer * hppa-tdep.c (hppa_frame_cache): Properly handle the frame pointer

View file

@ -1247,14 +1247,15 @@ inst_saves_fr (unsigned long inst)
be in the prologue. */ be in the prologue. */
CORE_ADDR static CORE_ADDR
skip_prologue_hard_way (CORE_ADDR pc) skip_prologue_hard_way (CORE_ADDR pc, int stop_before_branch)
{ {
char buf[4]; char buf[4];
CORE_ADDR orig_pc = pc; CORE_ADDR orig_pc = pc;
unsigned long inst, stack_remaining, save_gr, save_fr, save_rp, save_sp; unsigned long inst, stack_remaining, save_gr, save_fr, save_rp, save_sp;
unsigned long args_stored, status, i, restart_gr, restart_fr; unsigned long args_stored, status, i, restart_gr, restart_fr;
struct unwind_table_entry *u; struct unwind_table_entry *u;
int final_iteration;
restart_gr = 0; restart_gr = 0;
restart_fr = 0; restart_fr = 0;
@ -1298,6 +1299,8 @@ restart:
save_fr |= (1 << i); save_fr |= (1 << i);
save_fr &= ~restart_fr; save_fr &= ~restart_fr;
final_iteration = 0;
/* Loop until we find everything of interest or hit a branch. /* Loop until we find everything of interest or hit a branch.
For unoptimized GCC code and for any HP CC code this will never ever For unoptimized GCC code and for any HP CC code this will never ever
@ -1434,7 +1437,7 @@ restart:
/* Quit if we hit any kind of branch. This can happen if a prologue /* Quit if we hit any kind of branch. This can happen if a prologue
instruction is in the delay slot of the first call/branch. */ instruction is in the delay slot of the first call/branch. */
if (is_branch (inst)) if (is_branch (inst) && stop_before_branch)
break; break;
/* What a crock. The HP compilers set args_stored even if no /* What a crock. The HP compilers set args_stored even if no
@ -1455,6 +1458,13 @@ restart:
/* Bump the PC. */ /* Bump the PC. */
pc += 4; pc += 4;
/* !stop_before_branch, so also look at the insn in the delay slot
of the branch. */
if (final_iteration)
break;
if (is_branch (inst))
final_iteration = 1;
} }
/* We've got a tenative location for the end of the prologue. However /* We've got a tenative location for the end of the prologue. However
@ -1513,12 +1523,13 @@ after_prologue (CORE_ADDR pc)
/* To skip prologues, I use this predicate. Returns either PC itself /* To skip prologues, I use this predicate. Returns either PC itself
if the code at PC does not look like a function prologue; otherwise if the code at PC does not look like a function prologue; otherwise
returns an address that (if we're lucky) follows the prologue. If returns an address that (if we're lucky) follows the prologue.
LENIENT, then we must skip everything which is involved in setting
up the frame (it's OK to skip more, just so long as we don't skip hppa_skip_prologue is called by gdb to place a breakpoint in a function.
anything which might clobber the registers which are being saved. It doesn't necessarily skips all the insns in the prologue. In fact
Currently we must not skip more on the alpha, but we might the lenient we might not want to skip all the insns because a prologue insn may
stuff some day. */ appear in the delay slot of the first branch, and we don't want to
skip over the branch in that case. */
static CORE_ADDR static CORE_ADDR
hppa_skip_prologue (CORE_ADDR pc) hppa_skip_prologue (CORE_ADDR pc)
@ -1543,7 +1554,7 @@ hppa_skip_prologue (CORE_ADDR pc)
if (post_prologue_pc != 0) if (post_prologue_pc != 0)
return max (pc, post_prologue_pc); return max (pc, post_prologue_pc);
else else
return (skip_prologue_hard_way (pc)); return (skip_prologue_hard_way (pc, 1));
} }
struct hppa_frame_cache struct hppa_frame_cache
@ -1626,18 +1637,24 @@ hppa_frame_cache (struct frame_info *next_frame, void **this_cache)
int looking_for_rp = u->Save_RP; int looking_for_rp = u->Save_RP;
int fp_loc = -1; int fp_loc = -1;
/* We have to use hppa_skip_prologue instead of just /* We have to use skip_prologue_hard_way instead of just
skip_prologue_using_sal, in case we stepped into a function without skip_prologue_using_sal, in case we stepped into a function without
symbol information. hppa_skip_prologue also bounds the returned symbol information. hppa_skip_prologue also bounds the returned
pc by the passed in pc, so it will not return a pc in the next pc by the passed in pc, so it will not return a pc in the next
function. */ function.
We used to call hppa_skip_prologue to find the end of the prologue,
but if some non-prologue instructions get scheduled into the prologue,
and the program is compiled with debug information, the "easy" way
in hppa_skip_prologue will return a prologue end that is too early
for us to notice any potential frame adjustments. */
/* We used to use frame_func_unwind () to locate the beginning of the /* We used to use frame_func_unwind () to locate the beginning of the
function to pass to skip_prologue (). However, when objects are function to pass to skip_prologue (). However, when objects are
compiled without debug symbols, frame_func_unwind can return the wrong compiled without debug symbols, frame_func_unwind can return the wrong
function (or 0). We can do better than that by using unwind records. */ function (or 0). We can do better than that by using unwind records. */
prologue_end = hppa_skip_prologue (u->region_start); prologue_end = skip_prologue_hard_way (u->region_start, 0);
end_pc = frame_pc_unwind (next_frame); end_pc = frame_pc_unwind (next_frame);
if (prologue_end != 0 && end_pc > prologue_end) if (prologue_end != 0 && end_pc > prologue_end)