From 7c5c13f43d9b3e34f5bd945eaace274a47e873da Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 20 Aug 2009 19:53:49 +0100 Subject: [PATCH] --- yaml --- r: 163488 b: refs/heads/master c: 5580e9044df9c0e87861739d8c527006ead92e52 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/sh/include/asm/dwarf.h | 3 +++ trunk/arch/sh/kernel/dwarf.c | 13 +++++++++++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 98ab27d40628..d2c6a4068270 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5480675dc60c7dda7146e506981b2b40a775cc1e +refs/heads/master: 5580e9044df9c0e87861739d8c527006ead92e52 diff --git a/trunk/arch/sh/include/asm/dwarf.h b/trunk/arch/sh/include/asm/dwarf.h index 8b0bcc087385..c367ed3373c5 100644 --- a/trunk/arch/sh/include/asm/dwarf.h +++ b/trunk/arch/sh/include/asm/dwarf.h @@ -297,6 +297,7 @@ struct dwarf_reg { unsigned long flags; #define DWARF_REG_OFFSET (1 << 0) #define DWARF_VAL_OFFSET (1 << 1) +#define DWARF_UNDEFINED (1 << 2) }; /* @@ -370,6 +371,7 @@ extern struct dwarf_frame *dwarf_unwind_stack(unsigned long, #define CFI_DEF_CFA .cfi_def_cfa #define CFI_REGISTER .cfi_register #define CFI_REL_OFFSET .cfi_rel_offset +#define CFI_UNDEFINED .cfi_undefined #else @@ -383,6 +385,7 @@ extern struct dwarf_frame *dwarf_unwind_stack(unsigned long, #define CFI_DEF_CFA CFI_IGNORE #define CFI_REGISTER CFI_IGNORE #define CFI_REL_OFFSET CFI_IGNORE +#define CFI_UNDEFINED CFI_IGNORE #ifndef __ASSEMBLY__ static inline void dwarf_unwinder_init(void) diff --git a/trunk/arch/sh/kernel/dwarf.c b/trunk/arch/sh/kernel/dwarf.c index e6f427cff5ba..577302f31e6a 100644 --- a/trunk/arch/sh/kernel/dwarf.c +++ b/trunk/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;