* tm-hppa.h (skip_trampoline_code): Add extern decl.
* hppa-tdep.c (hppa_pop_frame): Silently restart the inferior and allow it to execute any return path trampoline code. Stop the inferior and give the user control when the trampoline has finished executing. (in_solib_call_trampoline): Handle export stubs which also perform parameter relocations. (in_solib_return_trampoline): Likewise.
This commit is contained in:
parent
a84f6e1734
commit
54576db325
|
@ -1,3 +1,14 @@
|
|||
Fri Nov 25 21:26:02 1994 Jeff Law (law@snake.cs.utah.edu)
|
||||
|
||||
* tm-hppa.h (skip_trampoline_code): Add extern decl.
|
||||
* hppa-tdep.c (hppa_pop_frame): Silently restart the inferior and
|
||||
allow it to execute any return path trampoline code. Stop the
|
||||
inferior and give the user control when the trampoline has
|
||||
finished executing.
|
||||
(in_solib_call_trampoline): Handle export stubs which also perform
|
||||
parameter relocations.
|
||||
(in_solib_return_trampoline): Likewise.
|
||||
|
||||
Fri Nov 25 13:37:10 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
|
||||
|
||||
* coffread.c, symfile.h (coff_getfilename): Make it static again.
|
||||
|
|
|
@ -1153,7 +1153,7 @@ int
|
|||
hppa_pop_frame ()
|
||||
{
|
||||
register struct frame_info *frame = get_current_frame ();
|
||||
register CORE_ADDR fp;
|
||||
register CORE_ADDR fp, npc, target_pc;
|
||||
register int regnum;
|
||||
struct frame_saved_regs fsr;
|
||||
double freg_buffer;
|
||||
|
@ -1187,12 +1187,16 @@ hppa_pop_frame ()
|
|||
|
||||
/* If the PC was explicitly saved, then just restore it. */
|
||||
if (fsr.regs[PCOQ_TAIL_REGNUM])
|
||||
write_register (PCOQ_TAIL_REGNUM,
|
||||
read_memory_integer (fsr.regs[PCOQ_TAIL_REGNUM], 4));
|
||||
|
||||
{
|
||||
npc = read_memory_integer (fsr.regs[PCOQ_TAIL_REGNUM], 4);
|
||||
write_register (PCOQ_TAIL_REGNUM, npc);
|
||||
}
|
||||
/* Else use the value in %rp to set the new PC. */
|
||||
else
|
||||
target_write_pc (read_register (RP_REGNUM), 0);
|
||||
{
|
||||
npc = read_register (RP_REGNUM);
|
||||
target_write_pc (npc, 0);
|
||||
}
|
||||
|
||||
write_register (FP_REGNUM, read_memory_integer (fp, 4));
|
||||
|
||||
|
@ -1201,6 +1205,35 @@ hppa_pop_frame ()
|
|||
else
|
||||
write_register (SP_REGNUM, fp);
|
||||
|
||||
/* The PC we just restored may be inside a return trampoline. If so
|
||||
we want to restart the inferior and run it through the trampoline.
|
||||
|
||||
Do this by setting a momentary breakpoint at the location the
|
||||
trampoline returns to. */
|
||||
target_pc = SKIP_TRAMPOLINE_CODE (npc & ~0x3) & ~0x3;
|
||||
if (target_pc)
|
||||
{
|
||||
struct symtab_and_line sal;
|
||||
struct breakpoint *breakpoint;
|
||||
struct cleanup *old_chain;
|
||||
|
||||
/* Set up our breakpoint. Set it to be silent as the MI code
|
||||
for "return_command" will print the frame we returned to. */
|
||||
sal = find_pc_line (target_pc, 0);
|
||||
sal.pc = target_pc;
|
||||
breakpoint = set_momentary_breakpoint (sal, NULL, bp_finish);
|
||||
breakpoint->silent = 1;
|
||||
|
||||
/* So we can clean things up. */
|
||||
old_chain = make_cleanup (delete_breakpoint, breakpoint);
|
||||
|
||||
/* Start up the inferior. */
|
||||
proceed_to_finish = 1;
|
||||
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
|
||||
|
||||
/* Perform our cleanups. */
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
flush_cached_frames ();
|
||||
}
|
||||
|
||||
|
@ -1631,24 +1664,10 @@ in_solib_call_trampoline (pc, name)
|
|||
if (u->stub_type == IMPORT)
|
||||
return 1;
|
||||
|
||||
if (u->stub_type == EXPORT)
|
||||
{
|
||||
/* The linker may group many EXPORT stubs into one unwind entry. So
|
||||
lookup the minimal symbol and use that as the beginning of this
|
||||
particular stub. */
|
||||
minsym = lookup_minimal_symbol_by_pc (pc);
|
||||
if (minsym == NULL)
|
||||
return 0;
|
||||
|
||||
/* Export stubs have distinct call and return paths. The first
|
||||
two instructions are the call path, following four are the
|
||||
return path. */
|
||||
return (pc >= SYMBOL_VALUE (minsym) && pc < SYMBOL_VALUE (minsym) + 8);
|
||||
}
|
||||
|
||||
/* Parameter relocation stubs always have a call path and may have a
|
||||
return path. */
|
||||
if (u->stub_type == PARAMETER_RELOCATION)
|
||||
if (u->stub_type == PARAMETER_RELOCATION
|
||||
|| u->stub_type == EXPORT)
|
||||
{
|
||||
CORE_ADDR addr;
|
||||
|
||||
|
@ -1661,10 +1680,11 @@ in_solib_call_trampoline (pc, name)
|
|||
insn = read_memory_integer (addr, 4);
|
||||
|
||||
/* Does it look like a bl? If so then it's the call path, if
|
||||
we find a bv first, then we're on the return path. */
|
||||
we find a bv or be first, then we're on the return path. */
|
||||
if ((insn & 0xfc00e000) == 0xe8000000)
|
||||
return 1;
|
||||
else if ((insn & 0xfc00e001) == 0xe800c000)
|
||||
else if ((insn & 0xfc00e001) == 0xe800c000
|
||||
|| (insn & 0xfc000000) == 0xe0000000)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1706,25 +1726,10 @@ in_solib_return_trampoline (pc, name)
|
|||
if (u->stub_type == IMPORT)
|
||||
return 1;
|
||||
|
||||
if (u->stub_type == EXPORT)
|
||||
{
|
||||
/* The linker may group many EXPORT stubs into one unwind entry. So
|
||||
lookup the minimal symbol and use that as the beginning of this
|
||||
particular stub. */
|
||||
minsym = lookup_minimal_symbol_by_pc (pc);
|
||||
if (minsym == NULL)
|
||||
return 0;
|
||||
|
||||
/* Export stubs have distinct call and return paths. The first
|
||||
two instructions are the call path, following four are the
|
||||
return path. */
|
||||
return (pc >= SYMBOL_VALUE (minsym) + 8
|
||||
&& pc < SYMBOL_VALUE (minsym) + 20);
|
||||
}
|
||||
|
||||
/* Parameter relocation stubs always have a call path and may have a
|
||||
return path. */
|
||||
if (u->stub_type == PARAMETER_RELOCATION)
|
||||
if (u->stub_type == PARAMETER_RELOCATION
|
||||
|| u->stub_type == EXPORT)
|
||||
{
|
||||
CORE_ADDR addr;
|
||||
|
||||
|
@ -1737,10 +1742,11 @@ in_solib_return_trampoline (pc, name)
|
|||
insn = read_memory_integer (addr, 4);
|
||||
|
||||
/* Does it look like a bl? If so then it's the call path, if
|
||||
we find a bv first, then we're on the return path. */
|
||||
we find a bv or be first, then we're on the return path. */
|
||||
if ((insn & 0xfc00e000) == 0xe8000000)
|
||||
return 0;
|
||||
else if ((insn & 0xfc00e001) == 0xe800c000)
|
||||
else if ((insn & 0xfc00e001) == 0xe800c000
|
||||
|| (insn & 0xfc000000) == 0xe0000000)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue