aboutsummaryrefslogtreecommitdiff
path: root/gdb/sparc-tdep.c
diff options
context:
space:
mode:
authorJoel Brobecker <brobecker@gnat.com>2004-11-23 18:59:14 +0000
committerJoel Brobecker <brobecker@gnat.com>2004-11-23 18:59:14 +0000
commit5465445a4b3784355989bda41c890fb3c7bcd1e1 (patch)
tree784f6f54dda6f3bc964a20eb4274925389e90c14 /gdb/sparc-tdep.c
parentdae1b34eabf9669f84490afb384c0281485b67ef (diff)
downloadgdb-5465445a4b3784355989bda41c890fb3c7bcd1e1.zip
gdb-5465445a4b3784355989bda41c890fb3c7bcd1e1.tar.gz
gdb-5465445a4b3784355989bda41c890fb3c7bcd1e1.tar.bz2
* 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.
Diffstat (limited to 'gdb/sparc-tdep.c')
-rw-r--r--gdb/sparc-tdep.c26
1 files changed, 26 insertions, 0 deletions
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;
}