提交 5580e904 编写于 作者: M Matt Fleming

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: NMatt Fleming <matt@console-pimps.org>
上级 5480675d
...@@ -297,6 +297,7 @@ struct dwarf_reg { ...@@ -297,6 +297,7 @@ struct dwarf_reg {
unsigned long flags; unsigned long flags;
#define DWARF_REG_OFFSET (1 << 0) #define DWARF_REG_OFFSET (1 << 0)
#define DWARF_VAL_OFFSET (1 << 1) #define DWARF_VAL_OFFSET (1 << 1)
#define DWARF_UNDEFINED (1 << 2)
}; };
/* /*
...@@ -370,6 +371,7 @@ extern struct dwarf_frame *dwarf_unwind_stack(unsigned long, ...@@ -370,6 +371,7 @@ extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
#define CFI_DEF_CFA .cfi_def_cfa #define CFI_DEF_CFA .cfi_def_cfa
#define CFI_REGISTER .cfi_register #define CFI_REGISTER .cfi_register
#define CFI_REL_OFFSET .cfi_rel_offset #define CFI_REL_OFFSET .cfi_rel_offset
#define CFI_UNDEFINED .cfi_undefined
#else #else
...@@ -383,6 +385,7 @@ extern struct dwarf_frame *dwarf_unwind_stack(unsigned long, ...@@ -383,6 +385,7 @@ extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
#define CFI_DEF_CFA CFI_IGNORE #define CFI_DEF_CFA CFI_IGNORE
#define CFI_REGISTER CFI_IGNORE #define CFI_REGISTER CFI_IGNORE
#define CFI_REL_OFFSET CFI_IGNORE #define CFI_REL_OFFSET CFI_IGNORE
#define CFI_UNDEFINED CFI_IGNORE
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
static inline void dwarf_unwinder_init(void) static inline void dwarf_unwinder_init(void)
......
...@@ -452,6 +452,8 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start, ...@@ -452,6 +452,8 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start,
case DW_CFA_undefined: case DW_CFA_undefined:
count = dwarf_read_uleb128(current_insn, &reg); count = dwarf_read_uleb128(current_insn, &reg);
current_insn += count; current_insn += count;
regp = dwarf_frame_alloc_reg(frame, reg);
regp->flags |= DWARF_UNDEFINED;
break; break;
case DW_CFA_def_cfa: case DW_CFA_def_cfa:
count = dwarf_read_uleb128(current_insn, count = dwarf_read_uleb128(current_insn,
...@@ -629,9 +631,16 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc, ...@@ -629,9 +631,16 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
UNWINDER_BUG(); UNWINDER_BUG();
} }
/* If we haven't seen the return address reg, we're screwed. */
reg = dwarf_frame_reg(frame, DWARF_ARCH_RA_REG); 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); UNWINDER_BUG_ON(reg->flags != DWARF_REG_OFFSET);
addr = frame->cfa + reg->addr; addr = frame->cfa + reg->addr;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册