aboutsummaryrefslogtreecommitdiff
path: root/gdb/hppa-tdep.c
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>1995-08-22 08:04:15 +0000
committerJeff Law <law@redhat.com>1995-08-22 08:04:15 +0000
commit7e72b115ada54faef45a03f47e3053f96786b7b8 (patch)
treeeded183ab8dbab6883d7e465d47f5364b536e893 /gdb/hppa-tdep.c
parent06997b9a10be1d3b2ccc2104d2bb2898019d4fe4 (diff)
downloadgdb-7e72b115ada54faef45a03f47e3053f96786b7b8.zip
gdb-7e72b115ada54faef45a03f47e3053f96786b7b8.tar.gz
gdb-7e72b115ada54faef45a03f47e3053f96786b7b8.tar.bz2
* tm-hppa.h (PROLOGUE_FIRSTLINE_OVERLAP): Delete. Causes more
problems than it fixes. * hppa-tdep.c (skip_prologue): If we exit the main loop without finding all the register saves, retry again without looking for the registers we could not find the first time. Better fix for 7768.
Diffstat (limited to 'gdb/hppa-tdep.c')
-rw-r--r--gdb/hppa-tdep.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index 4735baa..3addc58 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -2288,10 +2288,15 @@ skip_prologue (pc)
CORE_ADDR pc;
{
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;
+ unsigned long args_stored, status, i, restart_gr, restart_fr;
struct unwind_table_entry *u;
+ restart_gr = 0;
+ restart_fr = 0;
+
+restart:
u = find_unwind_entry (pc);
if (!u)
return pc;
@@ -2322,11 +2327,13 @@ skip_prologue (pc)
save_gr |= (1 << i);
}
+ save_gr &= ~restart_gr;
/* Turn the Entry_FR field into a bitmask too. */
save_fr = 0;
for (i = 12; i < u->Entry_FR + 12; i++)
save_fr |= (1 << i);
+ save_fr &= ~restart_fr;
/* Loop until we find everything of interest or hit a branch.
@@ -2476,6 +2483,22 @@ skip_prologue (pc)
pc += 4;
}
+ /* We've got a tenative location for the end of the prologue. However
+ because of limitations in the unwind descriptor mechanism we may
+ have went too far into user code looking for the save of a register
+ that does not exist. So, if there registers we expected to be saved
+ but never were, mask them out and restart.
+
+ This should only happen in optimized code, and should be very rare. */
+ if (save_gr || save_fr
+ && ! (restart_fr || restart_gr))
+ {
+ pc = orig_pc;
+ restart_gr = save_gr;
+ restart_fr = save_fr;
+ goto restart;
+ }
+
return pc;
}