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