diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/sparc-tdep.c | 26 |
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; } |