diff options
author | Matt Fleming <matt@console-pimps.org> | 2009-08-20 19:53:49 +0100 |
---|---|---|
committer | Matt Fleming <matt@console-pimps.org> | 2009-08-21 13:04:11 +0100 |
commit | 5580e9044df9c0e87861739d8c527006ead92e52 (patch) | |
tree | ef7c280cbc9e5b9f22170485cf05e7ebbe6c01f5 /arch/sh/kernel | |
parent | 5480675dc60c7dda7146e506981b2b40a775cc1e (diff) | |
download | blackbird-op-linux-5580e9044df9c0e87861739d8c527006ead92e52.tar.gz blackbird-op-linux-5580e9044df9c0e87861739d8c527006ead92e52.zip |
sh: Handle the DWARF op, DW_CFA_undefined
Allow a DWARF register to have an undefined value. When applied to the
DWARF return address register this lets lets us label a function as
having no direct caller, e.g. kernel_thread_helper().
Signed-off-by: Matt Fleming <matt@console-pimps.org>
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r-- | arch/sh/kernel/dwarf.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c index e6f427cff5ba..577302f31e6a 100644 --- a/arch/sh/kernel/dwarf.c +++ b/arch/sh/kernel/dwarf.c @@ -452,6 +452,8 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start, case DW_CFA_undefined: count = dwarf_read_uleb128(current_insn, ®); current_insn += count; + regp = dwarf_frame_alloc_reg(frame, reg); + regp->flags |= DWARF_UNDEFINED; break; case DW_CFA_def_cfa: count = dwarf_read_uleb128(current_insn, @@ -629,9 +631,16 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc, UNWINDER_BUG(); } - /* If we haven't seen the return address reg, we're screwed. */ reg = dwarf_frame_reg(frame, DWARF_ARCH_RA_REG); - UNWINDER_BUG_ON(!reg); + + /* + * If we haven't seen the return address register or the return + * address column is undefined then we must assume that this is + * the end of the callstack. + */ + if (!reg || reg->flags == DWARF_UNDEFINED) + goto bail; + UNWINDER_BUG_ON(reg->flags != DWARF_REG_OFFSET); addr = frame->cfa + reg->addr; |