Commit b735bd3e authored by Josh Poimboeuf's avatar Josh Poimboeuf
Browse files

objtool: Combine UNWIND_HINT_RET_OFFSET and UNWIND_HINT_FUNC



The ORC metadata generated for UNWIND_HINT_FUNC isn't actually very
func-like.  With certain usages it can cause stack state mismatches
because it doesn't set the return address (CFI_RA).

Also, users of UNWIND_HINT_RET_OFFSET no longer need to set a custom
return stack offset.  Instead they just need to specify a func-like
situation, so the current ret_offset code is hacky for no good reason.

Solve both problems by simplifying the RET_OFFSET handling and
converting it into a more useful UNWIND_HINT_FUNC.

If we end up needing the old 'ret_offset' functionality again in the
future, we should be able to support it pretty easily with the addition
of a custom 'sp_offset' in UNWIND_HINT_FUNC.

Signed-off-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/r/db9d1f5d79dddfbb3725ef6d8ec3477ad199948d.1611263462.git.jpoimboe@redhat.com
parent 081df943
Loading
Loading
Loading
Loading
+2 −11
Original line number Diff line number Diff line
@@ -48,17 +48,8 @@
	UNWIND_HINT_REGS base=\base offset=\offset partial=1
.endm

.macro UNWIND_HINT_FUNC sp_offset=8
	UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=\sp_offset type=UNWIND_HINT_TYPE_CALL
.endm

/*
 * RET_OFFSET: Used on instructions that terminate a function; mostly RETURN
 * and sibling calls. On these, sp_offset denotes the expected offset from
 * initial_func_cfi.
 */
.macro UNWIND_HINT_RET_OFFSET sp_offset=8
	UNWIND_HINT sp_reg=ORC_REG_SP type=UNWIND_HINT_TYPE_RET_OFFSET sp_offset=\sp_offset
.macro UNWIND_HINT_FUNC
	UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=8 type=UNWIND_HINT_TYPE_FUNC
.endm

#endif /* __ASSEMBLY__ */
+1 −1
Original line number Diff line number Diff line
@@ -277,7 +277,7 @@ SYM_INNER_LABEL(ftrace_regs_caller_end, SYM_L_GLOBAL)
	restore_mcount_regs 8
	/* Restore flags */
	popfq
	UNWIND_HINT_RET_OFFSET
	UNWIND_HINT_FUNC
	jmp	ftrace_epilogue

SYM_FUNC_END(ftrace_regs_caller)
+1 −1
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ SYM_FUNC_START_NOALIGN(__x86_retpoline_\reg)
	jmp	.Lspec_trap_\@
.Ldo_rop_\@:
	mov	%\reg, (%_ASM_SP)
	UNWIND_HINT_RET_OFFSET
	UNWIND_HINT_FUNC
	ret
SYM_FUNC_END(__x86_retpoline_\reg)

+4 −1
Original line number Diff line number Diff line
@@ -29,11 +29,14 @@ struct unwind_hint {
 *
 * UNWIND_HINT_TYPE_REGS_PARTIAL: Used in entry code to indicate that
 * sp_reg+sp_offset points to the iret return frame.
 *
 * UNWIND_HINT_FUNC: Generate the unwind metadata of a callable function.
 * Useful for code which doesn't have an ELF function annotation.
 */
#define UNWIND_HINT_TYPE_CALL		0
#define UNWIND_HINT_TYPE_REGS		1
#define UNWIND_HINT_TYPE_REGS_PARTIAL	2
#define UNWIND_HINT_TYPE_RET_OFFSET	3
#define UNWIND_HINT_TYPE_FUNC		3

#ifdef CONFIG_STACK_VALIDATION

+4 −1
Original line number Diff line number Diff line
@@ -29,11 +29,14 @@ struct unwind_hint {
 *
 * UNWIND_HINT_TYPE_REGS_PARTIAL: Used in entry code to indicate that
 * sp_reg+sp_offset points to the iret return frame.
 *
 * UNWIND_HINT_FUNC: Generate the unwind metadata of a callable function.
 * Useful for code which doesn't have an ELF function annotation.
 */
#define UNWIND_HINT_TYPE_CALL		0
#define UNWIND_HINT_TYPE_REGS		1
#define UNWIND_HINT_TYPE_REGS_PARTIAL	2
#define UNWIND_HINT_TYPE_RET_OFFSET	3
#define UNWIND_HINT_TYPE_FUNC		3

#ifdef CONFIG_STACK_VALIDATION

Loading