+/* 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;
+
+ /* We are looking for something like
+
+ ; $$dyncall jams RP into this special spot in the frame (RP')
+ ; before calling the "call stub"
+ ldw -18(sp),rp
+
+ ldsid (rp),r1 ; Get space associated with RP into r1
+ mtsp r1,sp ; Move it into space register 0
+ be,n 0(sr0),rp) ; back to your regularly scheduled program
+ */
+
+ /* 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;
+}
+