xref: /openbmc/linux/arch/x86/include/asm/unwind_hints.h (revision ee819aedf34a8f35cd54ee3967c7beb4d1d4a635)
139358a03SJosh Poimboeuf #ifndef _ASM_X86_UNWIND_HINTS_H
239358a03SJosh Poimboeuf #define _ASM_X86_UNWIND_HINTS_H
339358a03SJosh Poimboeuf 
4*ee819aedSJulien Thierry #include <linux/objtool.h>
5*ee819aedSJulien Thierry 
639358a03SJosh Poimboeuf #include "orc_types.h"
739358a03SJosh Poimboeuf 
839358a03SJosh Poimboeuf #ifdef __ASSEMBLY__
939358a03SJosh Poimboeuf 
1039358a03SJosh Poimboeuf .macro UNWIND_HINT_EMPTY
11*ee819aedSJulien Thierry 	UNWIND_HINT sp_reg=ORC_REG_UNDEFINED type=UNWIND_HINT_TYPE_CALL end=1
1239358a03SJosh Poimboeuf .endm
1339358a03SJosh Poimboeuf 
14*ee819aedSJulien Thierry .macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0
15af79ded4SJosh Poimboeuf 	.if \base == %rsp
16af79ded4SJosh Poimboeuf 		.if \indirect
1739358a03SJosh Poimboeuf 			.set sp_reg, ORC_REG_SP_INDIRECT
18af79ded4SJosh Poimboeuf 		.else
1939358a03SJosh Poimboeuf 			.set sp_reg, ORC_REG_SP
20af79ded4SJosh Poimboeuf 		.endif
2139358a03SJosh Poimboeuf 	.elseif \base == %rbp
2239358a03SJosh Poimboeuf 		.set sp_reg, ORC_REG_BP
2339358a03SJosh Poimboeuf 	.elseif \base == %rdi
2439358a03SJosh Poimboeuf 		.set sp_reg, ORC_REG_DI
2539358a03SJosh Poimboeuf 	.elseif \base == %rdx
2639358a03SJosh Poimboeuf 		.set sp_reg, ORC_REG_DX
2739358a03SJosh Poimboeuf 	.elseif \base == %r10
2839358a03SJosh Poimboeuf 		.set sp_reg, ORC_REG_R10
2939358a03SJosh Poimboeuf 	.else
3039358a03SJosh Poimboeuf 		.error "UNWIND_HINT_REGS: bad base register"
3139358a03SJosh Poimboeuf 	.endif
3239358a03SJosh Poimboeuf 
3339358a03SJosh Poimboeuf 	.set sp_offset, \offset
3439358a03SJosh Poimboeuf 
35*ee819aedSJulien Thierry 	.if \partial
36*ee819aedSJulien Thierry 		.set type, UNWIND_HINT_TYPE_REGS_PARTIAL
3739358a03SJosh Poimboeuf 	.elseif \extra == 0
38*ee819aedSJulien Thierry 		.set type, UNWIND_HINT_TYPE_REGS_PARTIAL
3939358a03SJosh Poimboeuf 		.set sp_offset, \offset + (16*8)
4039358a03SJosh Poimboeuf 	.else
41*ee819aedSJulien Thierry 		.set type, UNWIND_HINT_TYPE_REGS
4239358a03SJosh Poimboeuf 	.endif
4339358a03SJosh Poimboeuf 
4439358a03SJosh Poimboeuf 	UNWIND_HINT sp_reg=sp_reg sp_offset=sp_offset type=type
4539358a03SJosh Poimboeuf .endm
4639358a03SJosh Poimboeuf 
4739358a03SJosh Poimboeuf .macro UNWIND_HINT_IRET_REGS base=%rsp offset=0
48*ee819aedSJulien Thierry 	UNWIND_HINT_REGS base=\base offset=\offset partial=1
4939358a03SJosh Poimboeuf .endm
5039358a03SJosh Poimboeuf 
5139358a03SJosh Poimboeuf .macro UNWIND_HINT_FUNC sp_offset=8
52*ee819aedSJulien Thierry 	UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=\sp_offset type=UNWIND_HINT_TYPE_CALL
5339358a03SJosh Poimboeuf .endm
5439358a03SJosh Poimboeuf 
55e25eea89SPeter Zijlstra /*
56e25eea89SPeter Zijlstra  * RET_OFFSET: Used on instructions that terminate a function; mostly RETURN
57e25eea89SPeter Zijlstra  * and sibling calls. On these, sp_offset denotes the expected offset from
58e25eea89SPeter Zijlstra  * initial_func_cfi.
59e25eea89SPeter Zijlstra  */
60e25eea89SPeter Zijlstra .macro UNWIND_HINT_RET_OFFSET sp_offset=8
61*ee819aedSJulien Thierry 	UNWIND_HINT sp_reg=ORC_REG_SP type=UNWIND_HINT_TYPE_RET_OFFSET sp_offset=\sp_offset
62e25eea89SPeter Zijlstra .endm
63e25eea89SPeter Zijlstra 
6439358a03SJosh Poimboeuf #endif /* __ASSEMBLY__ */
6539358a03SJosh Poimboeuf 
6639358a03SJosh Poimboeuf #endif /* _ASM_X86_UNWIND_HINTS_H */
67