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>
This commit is contained in:
parent
5480675dc6
commit
5580e9044d
@ -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,
|
|||||||
#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,
|
|||||||
#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,
|
|||||||
case DW_CFA_undefined:
|
case DW_CFA_undefined:
|
||||||
count = dwarf_read_uleb128(current_insn, ®);
|
count = dwarf_read_uleb128(current_insn, ®);
|
||||||
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,
|
|||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user