diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2e243b1665..44740bb8c4 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 0e1c104ee2..142d8b34d5 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 4735baa281..3addc58ed9 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; }