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>
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
index e6f427c..577302f 100644
--- a/arch/sh/kernel/dwarf.c
+++ b/arch/sh/kernel/dwarf.c
@@ -452,6 +452,8 @@
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 @@
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;