aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/config/pa/tm-hppa.h7
-rw-r--r--gdb/hppa-tdep.c25
3 files changed, 32 insertions, 8 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 2e243b1..44740bb 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+Tue Aug 22 02:00:47 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * 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.
+
Mon Aug 21 23:39:56 1995 Jeff Law (law@snake.cs.utah.edu)
* hppa-tdep.c (frame_chain_valid): Handle systems where "$START$"
diff --git a/gdb/config/pa/tm-hppa.h b/gdb/config/pa/tm-hppa.h
index 0e1c104..142d8b3 100644
--- a/gdb/config/pa/tm-hppa.h
+++ b/gdb/config/pa/tm-hppa.h
@@ -620,10 +620,3 @@ extern CORE_ADDR skip_trampoline_code PARAMS ((CORE_ADDR, char *));
#define HPREAD_ADJUST_STACK_ADDRESS(ADDR) hpread_adjust_stack_address(ADDR)
extern int hpread_adjust_stack_address PARAMS ((CORE_ADDR));
-
-/* When prologues are scheduled, the first line of the function may
- overlap with prologue instructions. We want to avoid "skipping"
- to the start of the next source line in such situations (might
- skip over a conditional branch when trying to set a breakpoint at
- the start of a function. */
-#define PROLOGUE_FIRSTLINE_OVERLAP
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;
}