Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5580e904 authored by Matt Fleming's avatar Matt Fleming
Browse files

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: default avatarMatt Fleming <matt@console-pimps.org>
parent 5480675d
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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)
+11 −2
Original line number Diff line number Diff line
@@ -452,6 +452,8 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start,
		case DW_CFA_undefined:
			count = dwarf_read_uleb128(current_insn, &reg);
			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;