| .. | .. | 
|---|
| 1 | 1 |  #ifndef _ASM_X86_UNWIND_HINTS_H | 
|---|
| 2 | 2 |  #define _ASM_X86_UNWIND_HINTS_H | 
|---|
| 3 | 3 |   | 
|---|
 | 4 | +#include <linux/objtool.h>  | 
|---|
 | 5 | +  | 
|---|
| 4 | 6 |  #include "orc_types.h" | 
|---|
| 5 | 7 |   | 
|---|
| 6 | 8 |  #ifdef __ASSEMBLY__ | 
|---|
| 7 | 9 |   | 
|---|
| 8 |  | -/*  | 
|---|
| 9 |  | - * In asm, there are two kinds of code: normal C-type callable functions and  | 
|---|
| 10 |  | - * the rest.  The normal callable functions can be called by other code, and  | 
|---|
| 11 |  | - * don't do anything unusual with the stack.  Such normal callable functions  | 
|---|
| 12 |  | - * are annotated with the ENTRY/ENDPROC macros.  Most asm code falls in this  | 
|---|
| 13 |  | - * category.  In this case, no special debugging annotations are needed because  | 
|---|
| 14 |  | - * objtool can automatically generate the ORC data for the ORC unwinder to read  | 
|---|
| 15 |  | - * at runtime.  | 
|---|
| 16 |  | - *  | 
|---|
| 17 |  | - * Anything which doesn't fall into the above category, such as syscall and  | 
|---|
| 18 |  | - * interrupt handlers, tends to not be called directly by other functions, and  | 
|---|
| 19 |  | - * often does unusual non-C-function-type things with the stack pointer.  Such  | 
|---|
| 20 |  | - * code needs to be annotated such that objtool can understand it.  The  | 
|---|
| 21 |  | - * following CFI hint macros are for this type of code.  | 
|---|
| 22 |  | - *  | 
|---|
| 23 |  | - * These macros provide hints to objtool about the state of the stack at each  | 
|---|
| 24 |  | - * instruction.  Objtool starts from the hints and follows the code flow,  | 
|---|
| 25 |  | - * making automatic CFI adjustments when it sees pushes and pops, filling out  | 
|---|
| 26 |  | - * the debuginfo as necessary.  It will also warn if it sees any  | 
|---|
| 27 |  | - * inconsistencies.  | 
|---|
| 28 |  | - */  | 
|---|
| 29 |  | -.macro UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=0 type=ORC_TYPE_CALL end=0  | 
|---|
| 30 |  | -#ifdef CONFIG_STACK_VALIDATION  | 
|---|
| 31 |  | -.Lunwind_hint_ip_\@:  | 
|---|
| 32 |  | -	.pushsection .discard.unwind_hints  | 
|---|
| 33 |  | -		/* struct unwind_hint */  | 
|---|
| 34 |  | -		.long .Lunwind_hint_ip_\@ - .  | 
|---|
| 35 |  | -		.short \sp_offset  | 
|---|
| 36 |  | -		.byte \sp_reg  | 
|---|
| 37 |  | -		.byte \type  | 
|---|
| 38 |  | -		.byte \end  | 
|---|
| 39 |  | -		.balign 4  | 
|---|
| 40 |  | -	.popsection  | 
|---|
| 41 |  | -#endif  | 
|---|
| 42 |  | -.endm  | 
|---|
| 43 |  | -  | 
|---|
| 44 | 10 |  .macro UNWIND_HINT_EMPTY | 
|---|
| 45 |  | -	UNWIND_HINT sp_reg=ORC_REG_UNDEFINED end=1  | 
|---|
 | 11 | +	UNWIND_HINT type=UNWIND_HINT_TYPE_CALL end=1  | 
|---|
| 46 | 12 |  .endm | 
|---|
| 47 | 13 |   | 
|---|
| 48 |  | -.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 iret=0  | 
|---|
 | 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  | 
|---|
| 49 | 19 |  	.if \base == %rsp | 
|---|
| 50 | 20 |  		.if \indirect | 
|---|
| 51 | 21 |  			.set sp_reg, ORC_REG_SP_INDIRECT | 
|---|
| .. | .. | 
|---|
| 66 | 36 |   | 
|---|
| 67 | 37 |  	.set sp_offset, \offset | 
|---|
| 68 | 38 |   | 
|---|
| 69 |  | -	.if \iret  | 
|---|
| 70 |  | -		.set type, ORC_TYPE_REGS_IRET  | 
|---|
 | 39 | +	.if \partial  | 
|---|
 | 40 | +		.set type, UNWIND_HINT_TYPE_REGS_PARTIAL  | 
|---|
| 71 | 41 |  	.elseif \extra == 0 | 
|---|
| 72 |  | -		.set type, ORC_TYPE_REGS_IRET  | 
|---|
 | 42 | +		.set type, UNWIND_HINT_TYPE_REGS_PARTIAL  | 
|---|
| 73 | 43 |  		.set sp_offset, \offset + (16*8) | 
|---|
| 74 | 44 |  	.else | 
|---|
| 75 |  | -		.set type, ORC_TYPE_REGS  | 
|---|
 | 45 | +		.set type, UNWIND_HINT_TYPE_REGS  | 
|---|
| 76 | 46 |  	.endif | 
|---|
| 77 | 47 |   | 
|---|
| 78 | 48 |  	UNWIND_HINT sp_reg=sp_reg sp_offset=sp_offset type=type | 
|---|
| 79 | 49 |  .endm | 
|---|
| 80 | 50 |   | 
|---|
| 81 | 51 |  .macro UNWIND_HINT_IRET_REGS base=%rsp offset=0 | 
|---|
| 82 |  | -	UNWIND_HINT_REGS base=\base offset=\offset iret=1  | 
|---|
 | 52 | +	UNWIND_HINT_REGS base=\base offset=\offset partial=1  | 
|---|
| 83 | 53 |  .endm | 
|---|
| 84 | 54 |   | 
|---|
| 85 |  | -.macro UNWIND_HINT_FUNC sp_offset=8  | 
|---|
| 86 |  | -	UNWIND_HINT sp_offset=\sp_offset  | 
|---|
 | 55 | +.macro UNWIND_HINT_FUNC  | 
|---|
 | 56 | +	UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=8 type=UNWIND_HINT_TYPE_FUNC  | 
|---|
| 87 | 57 |  .endm | 
|---|
| 88 | 58 |   | 
|---|
| 89 |  | -#else /* !__ASSEMBLY__ */  | 
|---|
 | 59 | +.macro UNWIND_HINT_SAVE  | 
|---|
 | 60 | +	UNWIND_HINT type=UNWIND_HINT_TYPE_SAVE  | 
|---|
 | 61 | +.endm  | 
|---|
| 90 | 62 |   | 
|---|
| 91 |  | -#define UNWIND_HINT(sp_reg, sp_offset, type, end)		\  | 
|---|
| 92 |  | -	"987: \n\t"						\  | 
|---|
| 93 |  | -	".pushsection .discard.unwind_hints\n\t"		\  | 
|---|
| 94 |  | -	/* struct unwind_hint */				\  | 
|---|
| 95 |  | -	".long 987b - .\n\t"					\  | 
|---|
| 96 |  | -	".short " __stringify(sp_offset) "\n\t"			\  | 
|---|
| 97 |  | -	".byte " __stringify(sp_reg) "\n\t"			\  | 
|---|
| 98 |  | -	".byte " __stringify(type) "\n\t"			\  | 
|---|
| 99 |  | -	".byte " __stringify(end) "\n\t"			\  | 
|---|
| 100 |  | -	".balign 4 \n\t"					\  | 
|---|
| 101 |  | -	".popsection\n\t"  | 
|---|
| 102 |  | -  | 
|---|
| 103 |  | -#define UNWIND_HINT_SAVE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_SAVE, 0)  | 
|---|
| 104 |  | -  | 
|---|
| 105 |  | -#define UNWIND_HINT_RESTORE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_RESTORE, 0)  | 
|---|
 | 63 | +.macro UNWIND_HINT_RESTORE  | 
|---|
 | 64 | +	UNWIND_HINT type=UNWIND_HINT_TYPE_RESTORE  | 
|---|
 | 65 | +.endm  | 
|---|
| 106 | 66 |   | 
|---|
| 107 | 67 |  #endif /* __ASSEMBLY__ */ | 
|---|
| 108 | 68 |   | 
|---|