summaryrefslogtreecommitdiff
path: root/gdb/hppa-hpux-tdep.c
diff options
context:
space:
mode:
authorRandolph Chung <tausq@debian.org>2004-12-08 01:48:03 +0000
committerRandolph Chung <tausq@debian.org>2004-12-08 01:48:03 +0000
commite2e153369755e622003659e548d6fd0ce47c9250 (patch)
tree1145903374024f052de8d76a08168f1bf3cde9d0 /gdb/hppa-hpux-tdep.c
parent1c76144205064fc9c4ac99ef90ed0d899fb8be9a (diff)
downloadgdb-e2e153369755e622003659e548d6fd0ce47c9250.tar.gz
2004-12-07 Randolph Chung <tausq@debian.org>
* hppa-tdep.h (gdbarch_tdep): Add unwind_adjust_stub method. * hppa-hpux-tdep.c (hppa_hpux_unwind_adjust_stub): New function. (hppa_hpux_init_abi) Set unwind_adjust_stub method. * hppa-tdep.c (hppa_frame_cache): Call unwind_adjust_stub method if defined.
Diffstat (limited to 'gdb/hppa-hpux-tdep.c')
-rw-r--r--gdb/hppa-hpux-tdep.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/gdb/hppa-hpux-tdep.c b/gdb/hppa-hpux-tdep.c
index cd5c0163522..9aebb041ca3 100644
--- a/gdb/hppa-hpux-tdep.c
+++ b/gdb/hppa-hpux-tdep.c
@@ -1471,6 +1471,44 @@ hppa_hpux_inferior_created (struct target_ops *objfile, int from_tty)
hp_cxx_exception_support_initialized = 0;
}
+/* Given the current value of the pc, check to see if it is inside a stub, and
+ if so, change the value of the pc to point to the caller of the stub.
+ NEXT_FRAME is the next frame in the current list of frames.
+ BASE contains to stack frame base of the current frame.
+ SAVE_REGS is the register file stored in the frame cache. */
+static void
+hppa_hpux_unwind_adjust_stub (struct frame_info *next_frame, CORE_ADDR base,
+ struct trad_frame_saved_reg *saved_regs)
+{
+ int optimized, realreg;
+ enum lval_type lval;
+ CORE_ADDR addr;
+ char buffer[sizeof(ULONGEST)];
+ ULONGEST val;
+ CORE_ADDR stubpc;
+ struct unwind_table_entry *u;
+
+ trad_frame_get_prev_register (next_frame, saved_regs,
+ HPPA_PCOQ_HEAD_REGNUM,
+ &optimized, &lval, &addr, &realreg, buffer);
+ val = extract_unsigned_integer (buffer,
+ register_size (get_frame_arch (next_frame),
+ HPPA_PCOQ_HEAD_REGNUM));
+
+ u = find_unwind_entry (val);
+ if (u && u->stub_unwind.stub_type == EXPORT)
+ {
+ stubpc = read_memory_integer (base - 24, TARGET_PTR_BIT / 8);
+ trad_frame_set_value (saved_regs, HPPA_PCOQ_HEAD_REGNUM, stubpc);
+ }
+ else if (hppa_symbol_address ("__gcc_plt_call")
+ == get_pc_function_start (val))
+ {
+ stubpc = read_memory_integer (base - 8, TARGET_PTR_BIT / 8);
+ trad_frame_set_value (saved_regs, HPPA_PCOQ_HEAD_REGNUM, stubpc);
+ }
+}
+
static void
hppa_hpux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
@@ -1481,6 +1519,8 @@ hppa_hpux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
else
tdep->in_solib_call_trampoline = hppa64_hpux_in_solib_call_trampoline;
+ tdep->unwind_adjust_stub = hppa_hpux_unwind_adjust_stub;
+
set_gdbarch_in_solib_return_trampoline (gdbarch,
hppa_hpux_in_solib_return_trampoline);
set_gdbarch_skip_trampoline_code (gdbarch, hppa_hpux_skip_trampoline_code);