aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandolph Chung <tausq@debian.org>2004-11-12 00:51:23 +0000
committerRandolph Chung <tausq@debian.org>2004-11-12 00:51:23 +0000
commita71f8c301ed74646c78414ae45f551848443db5c (patch)
treeab19ce19c5e70c2d093d5c6aaa061becdaebf425
parent50b2f48ac1fea9b0ae40e2e66b883802fa647193 (diff)
downloadgdb-a71f8c301ed74646c78414ae45f551848443db5c.zip
gdb-a71f8c301ed74646c78414ae45f551848443db5c.tar.gz
gdb-a71f8c301ed74646c78414ae45f551848443db5c.tar.bz2
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.
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/hppa-tdep.c43
2 files changed, 38 insertions, 13 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 986318a..dcd83bf 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,13 @@
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>
+
* hppa-tdep.c (hppa_frame_cache): Properly handle the frame pointer
register so that it can be unwound from anywhere in the prologue.
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index c48ca86..8e86367 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -1247,14 +1247,15 @@ inst_saves_fr (unsigned long inst)
be in the prologue. */
-CORE_ADDR
-skip_prologue_hard_way (CORE_ADDR pc)
+static CORE_ADDR
+skip_prologue_hard_way (CORE_ADDR pc, int stop_before_branch)
{
char buf[4];
CORE_ADDR orig_pc = pc;
unsigned long inst, stack_remaining, save_gr, save_fr, save_rp, save_sp;
unsigned long args_stored, status, i, restart_gr, restart_fr;
struct unwind_table_entry *u;
+ int final_iteration;
restart_gr = 0;
restart_fr = 0;
@@ -1298,6 +1299,8 @@ restart:
save_fr |= (1 << i);
save_fr &= ~restart_fr;
+ final_iteration = 0;
+
/* 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
@@ -1434,7 +1437,7 @@ restart:
/* 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. */
- if (is_branch (inst))
+ if (is_branch (inst) && stop_before_branch)
break;
/* What a crock. The HP compilers set args_stored even if no
@@ -1455,6 +1458,13 @@ restart:
/* Bump the PC. */
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
@@ -1513,12 +1523,13 @@ after_prologue (CORE_ADDR pc)
/* To skip prologues, I use this predicate. Returns either PC itself
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
- 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
- anything which might clobber the registers which are being saved.
- Currently we must not skip more on the alpha, but we might the lenient
- stuff some day. */
+ returns an address that (if we're lucky) follows the prologue.
+
+ hppa_skip_prologue is called by gdb to place a breakpoint in a function.
+ It doesn't necessarily skips all the insns in the prologue. In fact
+ we might not want to skip all the insns because a prologue insn may
+ 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
hppa_skip_prologue (CORE_ADDR pc)
@@ -1543,7 +1554,7 @@ hppa_skip_prologue (CORE_ADDR pc)
if (post_prologue_pc != 0)
return max (pc, post_prologue_pc);
else
- return (skip_prologue_hard_way (pc));
+ return (skip_prologue_hard_way (pc, 1));
}
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 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
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
- 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
function to pass to skip_prologue (). However, when objects are
compiled without debug symbols, frame_func_unwind can return the wrong
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);
if (prologue_end != 0 && end_pc > prologue_end)