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.
This commit is contained in:
Randolph Chung 2004-12-08 01:48:03 +00:00
parent f1b38a5791
commit f77a2124d6
4 changed files with 70 additions and 0 deletions

View File

@ -1,3 +1,11 @@
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.
2004-12-07 Randolph Chung <tausq@debian.org>
* hppa-tdep.c (hppa_stub_Frame_unwind_cache): Stop unwinding if

View File

@ -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);

View File

@ -1905,6 +1905,19 @@ hppa_frame_cache (struct frame_info *next_frame, void **this_cache)
}
}
{
struct gdbarch *gdbarch;
struct gdbarch_tdep *tdep;
gdbarch = get_frame_arch (next_frame);
tdep = gdbarch_tdep (gdbarch);
if (tdep->unwind_adjust_stub)
{
tdep->unwind_adjust_stub (next_frame, cache->base, cache->saved_regs);
}
}
if (hppa_debug)
fprintf_unfiltered (gdb_stdlog, "base=0x%s }",
paddr_nz (((struct hppa_frame_cache *)*this_cache)->base));

View File

@ -88,6 +88,15 @@ struct gdbarch_tdep
IN_SOLIB_CALL_TRAMPOLINE evaluates to nonzero if we are currently
stopped in one of these. */
int (*in_solib_call_trampoline) (CORE_ADDR pc, char *name);
/* For targets that support multiple spaces, we may have additional stubs
in the return path. These stubs are internal to the ABI, and users are
not interested in them. If we detect that we are returning to a stub,
adjust the pc to the real caller. This improves the behavior of commands
that traverse frames such as "up" and "finish". */
void (*unwind_adjust_stub) (struct frame_info *next_frame, CORE_ADDR base,
struct trad_frame_saved_reg *saved_regs);
};
/*