mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:54:41 +08:00
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:
parent
f1b38a5791
commit
f77a2124d6
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user