100089c04SJulien Thierry /* SPDX-License-Identifier: GPL-2.0 */ 200089c04SJulien Thierry #ifndef _LINUX_OBJTOOL_H 300089c04SJulien Thierry #define _LINUX_OBJTOOL_H 400089c04SJulien Thierry 5ee819aedSJulien Thierry #ifndef __ASSEMBLY__ 6ee819aedSJulien Thierry 7ee819aedSJulien Thierry #include <linux/types.h> 8ee819aedSJulien Thierry 9ee819aedSJulien Thierry /* 10ee819aedSJulien Thierry * This struct is used by asm and inline asm code to manually annotate the 11ee819aedSJulien Thierry * location of registers on the stack. 12ee819aedSJulien Thierry */ 13ee819aedSJulien Thierry struct unwind_hint { 14ee819aedSJulien Thierry u32 ip; 15ee819aedSJulien Thierry s16 sp_offset; 16ee819aedSJulien Thierry u8 sp_reg; 17ee819aedSJulien Thierry u8 type; 18ee819aedSJulien Thierry u8 end; 19ee819aedSJulien Thierry }; 20ee819aedSJulien Thierry #endif 21ee819aedSJulien Thierry 22ee819aedSJulien Thierry /* 23ee819aedSJulien Thierry * UNWIND_HINT_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP 24ee819aedSJulien Thierry * (the caller's SP right before it made the call). Used for all callable 25ee819aedSJulien Thierry * functions, i.e. all C code and all callable asm functions. 26ee819aedSJulien Thierry * 27ee819aedSJulien Thierry * UNWIND_HINT_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset 28ee819aedSJulien Thierry * points to a fully populated pt_regs from a syscall, interrupt, or exception. 29ee819aedSJulien Thierry * 30ee819aedSJulien Thierry * UNWIND_HINT_TYPE_REGS_PARTIAL: Used in entry code to indicate that 31ee819aedSJulien Thierry * sp_reg+sp_offset points to the iret return frame. 32b735bd3eSJosh Poimboeuf * 33b735bd3eSJosh Poimboeuf * UNWIND_HINT_FUNC: Generate the unwind metadata of a callable function. 34b735bd3eSJosh Poimboeuf * Useful for code which doesn't have an ELF function annotation. 35ee819aedSJulien Thierry */ 36ee819aedSJulien Thierry #define UNWIND_HINT_TYPE_CALL 0 37ee819aedSJulien Thierry #define UNWIND_HINT_TYPE_REGS 1 38ee819aedSJulien Thierry #define UNWIND_HINT_TYPE_REGS_PARTIAL 2 39b735bd3eSJosh Poimboeuf #define UNWIND_HINT_TYPE_FUNC 3 40ee819aedSJulien Thierry 4100089c04SJulien Thierry #ifdef CONFIG_STACK_VALIDATION 425567c6c3SJulien Thierry 435567c6c3SJulien Thierry #ifndef __ASSEMBLY__ 44ee819aedSJulien Thierry 45ee819aedSJulien Thierry #define UNWIND_HINT(sp_reg, sp_offset, type, end) \ 46ee819aedSJulien Thierry "987: \n\t" \ 47ee819aedSJulien Thierry ".pushsection .discard.unwind_hints\n\t" \ 48ee819aedSJulien Thierry /* struct unwind_hint */ \ 49ee819aedSJulien Thierry ".long 987b - .\n\t" \ 50ee819aedSJulien Thierry ".short " __stringify(sp_offset) "\n\t" \ 51ee819aedSJulien Thierry ".byte " __stringify(sp_reg) "\n\t" \ 52ee819aedSJulien Thierry ".byte " __stringify(type) "\n\t" \ 53ee819aedSJulien Thierry ".byte " __stringify(end) "\n\t" \ 54ee819aedSJulien Thierry ".balign 4 \n\t" \ 55ee819aedSJulien Thierry ".popsection\n\t" 56ee819aedSJulien Thierry 5700089c04SJulien Thierry /* 5800089c04SJulien Thierry * This macro marks the given function's stack frame as "non-standard", which 5900089c04SJulien Thierry * tells objtool to ignore the function when doing stack metadata validation. 6000089c04SJulien Thierry * It should only be used in special cases where you're 100% sure it won't 6100089c04SJulien Thierry * affect the reliability of frame pointers and kernel stack traces. 6200089c04SJulien Thierry * 6300089c04SJulien Thierry * For more information, see tools/objtool/Documentation/stack-validation.txt. 6400089c04SJulien Thierry */ 6500089c04SJulien Thierry #define STACK_FRAME_NON_STANDARD(func) \ 6633def849SJoe Perches static void __used __section(".discard.func_stack_frame_non_standard") \ 6700089c04SJulien Thierry *__func_stack_frame_non_standard_##func = func 6800089c04SJulien Thierry 69e028c4f7SJosh Poimboeuf /* 70e028c4f7SJosh Poimboeuf * STACK_FRAME_NON_STANDARD_FP() is a frame-pointer-specific function ignore 71e028c4f7SJosh Poimboeuf * for the case where a function is intentionally missing frame pointer setup, 72e028c4f7SJosh Poimboeuf * but otherwise needs objtool/ORC coverage when frame pointers are disabled. 73e028c4f7SJosh Poimboeuf */ 74e028c4f7SJosh Poimboeuf #ifdef CONFIG_FRAME_POINTER 75e028c4f7SJosh Poimboeuf #define STACK_FRAME_NON_STANDARD_FP(func) STACK_FRAME_NON_STANDARD(func) 76e028c4f7SJosh Poimboeuf #else 77e028c4f7SJosh Poimboeuf #define STACK_FRAME_NON_STANDARD_FP(func) 78e028c4f7SJosh Poimboeuf #endif 79e028c4f7SJosh Poimboeuf 80c8c301abSPeter Zijlstra #define ANNOTATE_NOENDBR \ 81c8c301abSPeter Zijlstra "986: \n\t" \ 82c8c301abSPeter Zijlstra ".pushsection .discard.noendbr\n\t" \ 83c8c301abSPeter Zijlstra _ASM_PTR " 986b\n\t" \ 84c8c301abSPeter Zijlstra ".popsection\n\t" 85c8c301abSPeter Zijlstra 86*dca5da2aSPeter Zijlstra #define ASM_REACHABLE \ 87*dca5da2aSPeter Zijlstra "998:\n\t" \ 88*dca5da2aSPeter Zijlstra ".pushsection .discard.reachable\n\t" \ 89*dca5da2aSPeter Zijlstra ".long 998b - .\n\t" \ 90*dca5da2aSPeter Zijlstra ".popsection\n\t" 91*dca5da2aSPeter Zijlstra 925567c6c3SJulien Thierry #else /* __ASSEMBLY__ */ 935567c6c3SJulien Thierry 9400089c04SJulien Thierry /* 9500089c04SJulien Thierry * This macro indicates that the following intra-function call is valid. 9600089c04SJulien Thierry * Any non-annotated intra-function call will cause objtool to issue a warning. 9700089c04SJulien Thierry */ 9800089c04SJulien Thierry #define ANNOTATE_INTRA_FUNCTION_CALL \ 9900089c04SJulien Thierry 999: \ 10000089c04SJulien Thierry .pushsection .discard.intra_function_calls; \ 10100089c04SJulien Thierry .long 999b; \ 10200089c04SJulien Thierry .popsection; 10300089c04SJulien Thierry 104ee819aedSJulien Thierry /* 105ee819aedSJulien Thierry * In asm, there are two kinds of code: normal C-type callable functions and 106ee819aedSJulien Thierry * the rest. The normal callable functions can be called by other code, and 107ee819aedSJulien Thierry * don't do anything unusual with the stack. Such normal callable functions 108ee819aedSJulien Thierry * are annotated with the ENTRY/ENDPROC macros. Most asm code falls in this 109ee819aedSJulien Thierry * category. In this case, no special debugging annotations are needed because 110ee819aedSJulien Thierry * objtool can automatically generate the ORC data for the ORC unwinder to read 111ee819aedSJulien Thierry * at runtime. 112ee819aedSJulien Thierry * 113ee819aedSJulien Thierry * Anything which doesn't fall into the above category, such as syscall and 114ee819aedSJulien Thierry * interrupt handlers, tends to not be called directly by other functions, and 115ee819aedSJulien Thierry * often does unusual non-C-function-type things with the stack pointer. Such 116ee819aedSJulien Thierry * code needs to be annotated such that objtool can understand it. The 117ee819aedSJulien Thierry * following CFI hint macros are for this type of code. 118ee819aedSJulien Thierry * 119ee819aedSJulien Thierry * These macros provide hints to objtool about the state of the stack at each 120ee819aedSJulien Thierry * instruction. Objtool starts from the hints and follows the code flow, 121ee819aedSJulien Thierry * making automatic CFI adjustments when it sees pushes and pops, filling out 122ee819aedSJulien Thierry * the debuginfo as necessary. It will also warn if it sees any 123ee819aedSJulien Thierry * inconsistencies. 124ee819aedSJulien Thierry */ 125ee819aedSJulien Thierry .macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0 126ee819aedSJulien Thierry .Lunwind_hint_ip_\@: 127ee819aedSJulien Thierry .pushsection .discard.unwind_hints 128ee819aedSJulien Thierry /* struct unwind_hint */ 129ee819aedSJulien Thierry .long .Lunwind_hint_ip_\@ - . 130ee819aedSJulien Thierry .short \sp_offset 131ee819aedSJulien Thierry .byte \sp_reg 132ee819aedSJulien Thierry .byte \type 133ee819aedSJulien Thierry .byte \end 134ee819aedSJulien Thierry .balign 4 135ee819aedSJulien Thierry .popsection 136ee819aedSJulien Thierry .endm 137ee819aedSJulien Thierry 138081df943SJosh Poimboeuf .macro STACK_FRAME_NON_STANDARD func:req 139081df943SJosh Poimboeuf .pushsection .discard.func_stack_frame_non_standard, "aw" 140081df943SJosh Poimboeuf .long \func - . 141081df943SJosh Poimboeuf .popsection 142081df943SJosh Poimboeuf .endm 143081df943SJosh Poimboeuf 144c8c301abSPeter Zijlstra .macro ANNOTATE_NOENDBR 145c8c301abSPeter Zijlstra .Lhere_\@: 146c8c301abSPeter Zijlstra .pushsection .discard.noendbr 147c8c301abSPeter Zijlstra .quad .Lhere_\@ 148c8c301abSPeter Zijlstra .popsection 149c8c301abSPeter Zijlstra .endm 150c8c301abSPeter Zijlstra 151*dca5da2aSPeter Zijlstra .macro REACHABLE 152*dca5da2aSPeter Zijlstra .Lhere_\@: 153*dca5da2aSPeter Zijlstra .pushsection .discard.reachable 154*dca5da2aSPeter Zijlstra .long .Lhere_\@ - . 155*dca5da2aSPeter Zijlstra .popsection 156*dca5da2aSPeter Zijlstra .endm 157*dca5da2aSPeter Zijlstra 1585567c6c3SJulien Thierry #endif /* __ASSEMBLY__ */ 1595567c6c3SJulien Thierry 16000089c04SJulien Thierry #else /* !CONFIG_STACK_VALIDATION */ 16100089c04SJulien Thierry 162ee819aedSJulien Thierry #ifndef __ASSEMBLY__ 163ee819aedSJulien Thierry 164ee819aedSJulien Thierry #define UNWIND_HINT(sp_reg, sp_offset, type, end) \ 165ee819aedSJulien Thierry "\n\t" 16600089c04SJulien Thierry #define STACK_FRAME_NON_STANDARD(func) 167e028c4f7SJosh Poimboeuf #define STACK_FRAME_NON_STANDARD_FP(func) 168c8c301abSPeter Zijlstra #define ANNOTATE_NOENDBR 169*dca5da2aSPeter Zijlstra #define ASM_REACHABLE 170ee819aedSJulien Thierry #else 17100089c04SJulien Thierry #define ANNOTATE_INTRA_FUNCTION_CALL 172ee819aedSJulien Thierry .macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0 173ee819aedSJulien Thierry .endm 174081df943SJosh Poimboeuf .macro STACK_FRAME_NON_STANDARD func:req 175081df943SJosh Poimboeuf .endm 176c8c301abSPeter Zijlstra .macro ANNOTATE_NOENDBR 177c8c301abSPeter Zijlstra .endm 178*dca5da2aSPeter Zijlstra .macro REACHABLE 179*dca5da2aSPeter Zijlstra .endm 180ee819aedSJulien Thierry #endif 18100089c04SJulien Thierry 18200089c04SJulien Thierry #endif /* CONFIG_STACK_VALIDATION */ 18300089c04SJulien Thierry 18400089c04SJulien Thierry #endif /* _LINUX_OBJTOOL_H */ 185