* sparc-tdep.c (sparc_is_unimp_insn): New function.
authorJoel Brobecker <brobecker@gnat.com>
Tue, 23 Nov 2004 18:59:14 +0000 (18:59 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Tue, 23 Nov 2004 18:59:14 +0000 (18:59 +0000)
        (sparc32_frame_cache): For functions where there is no debugging
        information to help us determine whether it's a struct-return
        function or not, fallback on checking whether the instruction
        at the return address is an "unimp" instruction or not.

gdb/ChangeLog
gdb/sparc-tdep.c

index f270f548a30874863ab43d26699dd405f9838042..64b52691f7dd1956ea4e93538d550ce4b0fc308b 100644 (file)
@@ -1,3 +1,11 @@
+2004-11-23  Joel Brobecker  <brobecker@gnat.com>
+
+       * sparc-tdep.c (sparc_is_unimp_insn): New function.
+       (sparc32_frame_cache): For functions where there is no debugging
+       information to help us determine whether it's a struct-return
+       function or not, fallback on checking whether the instruction
+       at the return address is an "unimp" instruction or not.
+
 2004-11-22  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
        * MAINTAINERS: Add myself to write after approval section.
index 8f39baa738a9c62efb9b6ebd7b17311674304314..9facbadcad37bbedb821d9a373ce090c4117cee3 100644 (file)
@@ -106,6 +106,17 @@ sparc_fetch_instruction (CORE_ADDR pc)
 }
 \f
 
+/* Return non-zero if the instruction corresponding to PC is an "unimp"
+   instruction.  */
+
+static int
+sparc_is_unimp_insn (CORE_ADDR pc)
+{
+  const unsigned long insn = sparc_fetch_instruction (pc);
+  
+  return ((insn & 0xc1c00000) == 0);
+}
+
 /* OpenBSD/sparc includes StackGhost, which according to the author's
    website http://stackghost.cerias.purdue.edu "... transparently and
    automatically protects applications' stack frames; more
@@ -665,6 +676,21 @@ sparc32_frame_cache (struct frame_info *next_frame, void **this_cache)
            cache->struct_return_p = 1;
        }
     }
+  else
+    {
+      /* There is no debugging information for this function to
+         help us determine whether this function returns a struct
+         or not.  So we rely on another heuristic which is to check
+         the instruction at the return address and see if this is
+         an "unimp" instruction.  If it is, then it is a struct-return
+         function.  */
+      CORE_ADDR pc;
+      int regnum = cache->frameless_p ? SPARC_O7_REGNUM : SPARC_I7_REGNUM;
+
+      pc = frame_unwind_register_unsigned (next_frame, regnum) + 8;
+      if (sparc_is_unimp_insn (pc))
+        cache->struct_return_p = 1;
+    }
 
   return cache;
 }