diff options
author | Randolph Chung <tausq@debian.org> | 2004-05-19 02:38:28 +0000 |
---|---|---|
committer | Randolph Chung <tausq@debian.org> | 2004-05-19 02:38:28 +0000 |
commit | 822852b9c6301724ca418fe721632a7d47665a12 (patch) | |
tree | dd64c6757c6e102f95cb04caf9442b41ce95a385 | |
parent | 5c6ab9f9c592add68b3f915d1f3ee1962e6e53d5 (diff) | |
download | gdb-822852b9c6301724ca418fe721632a7d47665a12.tar.gz |
2004-05-18 Randolph Chung <tausq@debian.org>
* hppa-tdep.c (hppa_frame_cache): If a frame pointer is available, use
it for unwinding the stack.
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/hppa-tdep.c | 34 |
2 files changed, 38 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0e5b77cf826..ccdfb141770 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,10 @@ 2004-05-18 Randolph Chung <tausq@debian.org> + * hppa-tdep.c (hppa_frame_cache): If a frame pointer is available, use + it for unwinding the stack. + +2004-05-18 Randolph Chung <tausq@debian.org> + * config/pa/tm-linux.h (IN_SOLIB_CALL_TRAMPOLINE, SKIP_TRAMPOLINE_CODE) Undefine these so we can overide them using gdbarch. diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c index 51d8385f274..37bab73e6b6 100644 --- a/gdb/hppa-tdep.c +++ b/gdb/hppa-tdep.c @@ -1725,6 +1725,7 @@ hppa_frame_cache (struct frame_info *next_frame, void **this_cache) the current function (and is thus equivalent to the "saved" stack pointer. */ CORE_ADDR this_sp = frame_unwind_register_unsigned (next_frame, HPPA_SP_REGNUM); + CORE_ADDR fp; if (hppa_debug) fprintf_unfiltered (gdb_stdlog, " (this_sp=0x%s, pc=0x%s, " @@ -1733,7 +1734,38 @@ hppa_frame_cache (struct frame_info *next_frame, void **this_cache) paddr_nz (frame_pc_unwind (next_frame)), paddr_nz (prologue_end)); - if (frame_pc_unwind (next_frame) >= prologue_end) + /* Check to see if a frame pointer is available, and use it for + frame unwinding if it is. + + There are some situations where we need to rely on the frame + pointer to do stack unwinding. For example, if a function calls + alloca (), the stack pointer can get adjusted inside the body of + the function. In this case, the ABI requires that the compiler + maintain a frame pointer for the function. + + The unwind record has a flag (alloca_frame) that indicates that + a function has a variable frame; unfortunately, gcc/binutils + does not set this flag. Instead, whenever a frame pointer is used + and saved on the stack, the Save_SP flag is set. We use this to + decide whether to use the frame pointer for unwinding. + + fp should never be zero here; checking just in case. + + TODO: For the HP compiler, maybe we should use the alloca_frame flag + instead of Save_SP. */ + + fp = frame_unwind_register_unsigned (next_frame, HPPA_FP_REGNUM); + + if (frame_pc_unwind (next_frame) >= prologue_end + && u->Save_SP && fp != 0) + { + cache->base = fp; + + if (hppa_debug) + fprintf_unfiltered (gdb_stdlog, " (base=0x%s) [frame pointer] }", + paddr_nz (cache->base)); + } + else if (frame_pc_unwind (next_frame) >= prologue_end) { if (u->Save_SP && trad_frame_addr_p (cache->saved_regs, HPPA_SP_REGNUM)) { |