1 #ifndef _ASM_X86_UNWIND_HINTS_H
2 #define _ASM_X86_UNWIND_HINTS_H
3 
4 #include <linux/objtool.h>
5 
6 #include "orc_types.h"
7 
8 #ifdef __ASSEMBLY__
9 
10 .macro UNWIND_HINT_EMPTY
11 	UNWIND_HINT sp_reg=ORC_REG_UNDEFINED type=UNWIND_HINT_TYPE_CALL end=1
12 .endm
13 
14 .macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0
15 	.if \base == %rsp
16 		.if \indirect
17 			.set sp_reg, ORC_REG_SP_INDIRECT
18 		.else
19 			.set sp_reg, ORC_REG_SP
20 		.endif
21 	.elseif \base == %rbp
22 		.set sp_reg, ORC_REG_BP
23 	.elseif \base == %rdi
24 		.set sp_reg, ORC_REG_DI
25 	.elseif \base == %rdx
26 		.set sp_reg, ORC_REG_DX
27 	.elseif \base == %r10
28 		.set sp_reg, ORC_REG_R10
29 	.else
30 		.error "UNWIND_HINT_REGS: bad base register"
31 	.endif
32 
33 	.set sp_offset, \offset
34 
35 	.if \partial
36 		.set type, UNWIND_HINT_TYPE_REGS_PARTIAL
37 	.elseif \extra == 0
38 		.set type, UNWIND_HINT_TYPE_REGS_PARTIAL
39 		.set sp_offset, \offset + (16*8)
40 	.else
41 		.set type, UNWIND_HINT_TYPE_REGS
42 	.endif
43 
44 	UNWIND_HINT sp_reg=sp_reg sp_offset=sp_offset type=type
45 .endm
46 
47 .macro UNWIND_HINT_IRET_REGS base=%rsp offset=0
48 	UNWIND_HINT_REGS base=\base offset=\offset partial=1
49 .endm
50 
51 .macro UNWIND_HINT_FUNC sp_offset=8
52 	UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=\sp_offset type=UNWIND_HINT_TYPE_CALL
53 .endm
54 
55 /*
56  * RET_OFFSET: Used on instructions that terminate a function; mostly RETURN
57  * and sibling calls. On these, sp_offset denotes the expected offset from
58  * initial_func_cfi.
59  */
60 .macro UNWIND_HINT_RET_OFFSET sp_offset=8
61 	UNWIND_HINT sp_reg=ORC_REG_SP type=UNWIND_HINT_TYPE_RET_OFFSET sp_offset=\sp_offset
62 .endm
63 
64 #endif /* __ASSEMBLY__ */
65 
66 #endif /* _ASM_X86_UNWIND_HINTS_H */
67