xref: /linux/arch/x86/include/asm/unwind_hints.h (revision 4359a011e259a4608afc7fb3635370c9d4ba5943)
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 type=UNWIND_HINT_TYPE_CALL end=1
12 .endm
13 
14 .macro UNWIND_HINT_ENTRY
15 	UNWIND_HINT type=UNWIND_HINT_TYPE_ENTRY end=1
16 .endm
17 
18 .macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0
19 	.if \base == %rsp
20 		.if \indirect
21 			.set sp_reg, ORC_REG_SP_INDIRECT
22 		.else
23 			.set sp_reg, ORC_REG_SP
24 		.endif
25 	.elseif \base == %rbp
26 		.set sp_reg, ORC_REG_BP
27 	.elseif \base == %rdi
28 		.set sp_reg, ORC_REG_DI
29 	.elseif \base == %rdx
30 		.set sp_reg, ORC_REG_DX
31 	.elseif \base == %r10
32 		.set sp_reg, ORC_REG_R10
33 	.else
34 		.error "UNWIND_HINT_REGS: bad base register"
35 	.endif
36 
37 	.set sp_offset, \offset
38 
39 	.if \partial
40 		.set type, UNWIND_HINT_TYPE_REGS_PARTIAL
41 	.elseif \extra == 0
42 		.set type, UNWIND_HINT_TYPE_REGS_PARTIAL
43 		.set sp_offset, \offset + (16*8)
44 	.else
45 		.set type, UNWIND_HINT_TYPE_REGS
46 	.endif
47 
48 	UNWIND_HINT sp_reg=sp_reg sp_offset=sp_offset type=type
49 .endm
50 
51 .macro UNWIND_HINT_IRET_REGS base=%rsp offset=0
52 	UNWIND_HINT_REGS base=\base offset=\offset partial=1
53 .endm
54 
55 .macro UNWIND_HINT_FUNC
56 	UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=8 type=UNWIND_HINT_TYPE_FUNC
57 .endm
58 
59 .macro UNWIND_HINT_SAVE
60 	UNWIND_HINT type=UNWIND_HINT_TYPE_SAVE
61 .endm
62 
63 .macro UNWIND_HINT_RESTORE
64 	UNWIND_HINT type=UNWIND_HINT_TYPE_RESTORE
65 .endm
66 
67 #else
68 
69 #define UNWIND_HINT_FUNC \
70 	UNWIND_HINT(ORC_REG_SP, 8, UNWIND_HINT_TYPE_FUNC, 0)
71 
72 #endif /* __ASSEMBLY__ */
73 
74 #endif /* _ASM_X86_UNWIND_HINTS_H */
75