* hppa-tdep.c (pc_in_linker_stub): New function.

(find_proc_framesize): Return 0 for linker stubs.
	(rp_saved): Tell the caller where rp is saved.
	(frame_chain_valid): Return 1 for linker stubs.
	(frame_saved_pc): Use return value from rp_saved.
This commit is contained in:
Jim Kingdon
1993-07-15 17:38:59 +00:00
parent 0568df2acf
commit 5ac7f56ee8
2 changed files with 104 additions and 11 deletions

View File

@ -1,5 +1,11 @@
Thu Jul 15 08:34:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com) Thu Jul 15 08:34:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
* hppa-tdep.c (pc_in_linker_stub): New function.
(find_proc_framesize): Return 0 for linker stubs.
(rp_saved): Tell the caller where rp is saved.
(frame_chain_valid): Return 1 for linker stubs.
(frame_saved_pc): Use return value from rp_saved.
* stack.c (print_frame_info): When checking PC_IN_CALL_DUMMY, * stack.c (print_frame_info): When checking PC_IN_CALL_DUMMY,
pass the sp relative to the frame in question, not the sp in the pass the sp relative to the frame in question, not the sp in the
innermost frame. innermost frame.

View File

@ -296,6 +296,62 @@ find_unwind_entry(pc)
return NULL; return NULL;
} }
/* Called when no unwind descriptor was found for PC. Returns 1 if it
appears that PC is in a linker stub. */
static int pc_in_linker_stub PARAMS ((CORE_ADDR));
static int
pc_in_linker_stub (pc)
CORE_ADDR pc;
{
int found_magic_instruction = 0;
int i;
/* Maximum known linker stub size is 4 instructions. Search forward
from the given PC, then backward. */
for (i = 0; i < 4; i++)
{
/* If we hit something with an unwind, stop searching this direction.
if (find_unwind_entry (pc + i * 4) != 0)
break;
/* Check for ldsid (rp),r1 which is the magic instruction for a
return from a cross-space function call. */
if (read_memory_integer (pc + i * 4, 4) == 0x004010a1)
{
found_magic_instruction = 1;
break;
}
/* Add code to handle long call/branch and argument relocation stubs
here. */
}
if (found_magic_instruction != 0)
return 1;
/* Now look backward. */
for (i = 0; i < 4; i++)
{
/* If we hit something with an unwind, stop searching this direction.
if (find_unwind_entry (pc - i * 4) != 0)
break;
/* Check for ldsid (rp),r1 which is the magic instruction for a
return from a cross-space function call. */
if (read_memory_integer (pc - i * 4, 4) == 0x004010a1)
{
found_magic_instruction = 1;
break;
}
/* Add code to handle long call/branch and argument relocation stubs
here. */
}
return found_magic_instruction;
}
static int static int
find_return_regnum(pc) find_return_regnum(pc)
CORE_ADDR pc; CORE_ADDR pc;
@ -313,6 +369,7 @@ find_return_regnum(pc)
return RP_REGNUM; return RP_REGNUM;
} }
/* Return size of frame, or -1 if we should use a frame pointer. */
int int
find_proc_framesize(pc) find_proc_framesize(pc)
CORE_ADDR pc; CORE_ADDR pc;
@ -325,7 +382,13 @@ find_proc_framesize(pc)
u = find_unwind_entry (pc); u = find_unwind_entry (pc);
if (!u) if (!u)
return -1; {
if (pc_in_linker_stub (pc))
/* Linker stubs have a zero size frame. */
return 0;
else
return -1;
}
if (u->Save_SP) if (u->Save_SP)
/* If this bit is set, it means there is a frame pointer and we should /* If this bit is set, it means there is a frame pointer and we should
@ -335,18 +398,28 @@ find_proc_framesize(pc)
return u->Total_frame_size << 3; return u->Total_frame_size << 3;
} }
int /* Return offset from sp at which rp is saved, or 0 if not saved. */
rp_saved(pc) static int rp_saved PARAMS ((CORE_ADDR));
static int
rp_saved (pc)
CORE_ADDR pc;
{ {
struct unwind_table_entry *u; struct unwind_table_entry *u;
u = find_unwind_entry (pc); u = find_unwind_entry (pc);
if (!u) if (!u)
return 0; {
if (pc_in_linker_stub (pc))
/* This is the so-called RP'. */
return -24;
else
return 0;
}
if (u->Save_RP) if (u->Save_RP)
return 1; return -20;
else else
return 0; return 0;
} }
@ -396,10 +469,15 @@ frame_saved_pc (frame)
return read_register (ret_regnum) & ~0x3; return read_register (ret_regnum) & ~0x3;
} }
else if (rp_saved (pc))
return read_memory_integer (frame->frame - 20, 4) & ~0x3;
else else
return read_register (RP_REGNUM) & ~0x3; {
int rp_offset = rp_saved (pc);
if (rp_offset == 0)
return read_register (RP_REGNUM) & ~0x3;
else
return read_memory_integer (frame->frame - rp_offset, 4) & ~0x3;
}
} }
/* We need to correct the PC and the FP for the outermost frame when we are /* We need to correct the PC and the FP for the outermost frame when we are
@ -470,10 +548,19 @@ frame_chain_valid (chain, thisframe)
u = find_unwind_entry (thisframe->pc); u = find_unwind_entry (thisframe->pc);
if (u && (u->Save_SP || u->Total_frame_size)) if (u == NULL)
return 1; /* FIXME, we should probably fall back to some other technique,
else if we want to deal gracefully with stripped executables or others
without unwind info. */
return 0; return 0;
if (u->Save_SP || u->Total_frame_size)
return 1;
if (pc_in_linker_stub (thisframe->pc))
return 1;
return 0;
} }
else else
{ {