aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/sparc-tdep.c26
2 files changed, 34 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index f270f54..64b5269 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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.
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 8f39baa..9facbad 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -106,6 +106,17 @@ sparc_fetch_instruction (CORE_ADDR pc)
}
+/* 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;
}