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. 32*b735bd3eSJosh Poimboeuf * 33*b735bd3eSJosh Poimboeuf * UNWIND_HINT_FUNC: Generate the unwind metadata of a callable function. 34*b735bd3eSJosh 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 39*b735bd3eSJosh 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 695567c6c3SJulien Thierry #else /* __ASSEMBLY__ */ 705567c6c3SJulien Thierry 7100089c04SJulien Thierry /* 7200089c04SJulien Thierry * This macro indicates that the following intra-function call is valid. 7300089c04SJulien Thierry * Any non-annotated intra-function call will cause objtool to issue a warning. 7400089c04SJulien Thierry */ 7500089c04SJulien Thierry #define ANNOTATE_INTRA_FUNCTION_CALL \ 7600089c04SJulien Thierry 999: \ 7700089c04SJulien Thierry .pushsection .discard.intra_function_calls; \ 7800089c04SJulien Thierry .long 999b; \ 7900089c04SJulien Thierry .popsection; 8000089c04SJulien Thierry 81ee819aedSJulien Thierry /* 82ee819aedSJulien Thierry * In asm, there are two kinds of code: normal C-type callable functions and 83ee819aedSJulien Thierry * the rest. The normal callable functions can be called by other code, and 84ee819aedSJulien Thierry * don't do anything unusual with the stack. Such normal callable functions 85ee819aedSJulien Thierry * are annotated with the ENTRY/ENDPROC macros. Most asm code falls in this 86ee819aedSJulien Thierry * category. In this case, no special debugging annotations are needed because 87ee819aedSJulien Thierry * objtool can automatically generate the ORC data for the ORC unwinder to read 88ee819aedSJulien Thierry * at runtime. 89ee819aedSJulien Thierry * 90ee819aedSJulien Thierry * Anything which doesn't fall into the above category, such as syscall and 91ee819aedSJulien Thierry * interrupt handlers, tends to not be called directly by other functions, and 92ee819aedSJulien Thierry * often does unusual non-C-function-type things with the stack pointer. Such 93ee819aedSJulien Thierry * code needs to be annotated such that objtool can understand it. The 94ee819aedSJulien Thierry * following CFI hint macros are for this type of code. 95ee819aedSJulien Thierry * 96ee819aedSJulien Thierry * These macros provide hints to objtool about the state of the stack at each 97ee819aedSJulien Thierry * instruction. Objtool starts from the hints and follows the code flow, 98ee819aedSJulien Thierry * making automatic CFI adjustments when it sees pushes and pops, filling out 99ee819aedSJulien Thierry * the debuginfo as necessary. It will also warn if it sees any 100ee819aedSJulien Thierry * inconsistencies. 101ee819aedSJulien Thierry */ 102ee819aedSJulien Thierry .macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0 103ee819aedSJulien Thierry .Lunwind_hint_ip_\@: 104ee819aedSJulien Thierry .pushsection .discard.unwind_hints 105ee819aedSJulien Thierry /* struct unwind_hint */ 106ee819aedSJulien Thierry .long .Lunwind_hint_ip_\@ - . 107ee819aedSJulien Thierry .short \sp_offset 108ee819aedSJulien Thierry .byte \sp_reg 109ee819aedSJulien Thierry .byte \type 110ee819aedSJulien Thierry .byte \end 111ee819aedSJulien Thierry .balign 4 112ee819aedSJulien Thierry .popsection 113ee819aedSJulien Thierry .endm 114ee819aedSJulien Thierry 115081df943SJosh Poimboeuf .macro STACK_FRAME_NON_STANDARD func:req 116081df943SJosh Poimboeuf .pushsection .discard.func_stack_frame_non_standard, "aw" 117081df943SJosh Poimboeuf .long \func - . 118081df943SJosh Poimboeuf .popsection 119081df943SJosh Poimboeuf .endm 120081df943SJosh Poimboeuf 1215567c6c3SJulien Thierry #endif /* __ASSEMBLY__ */ 1225567c6c3SJulien Thierry 12300089c04SJulien Thierry #else /* !CONFIG_STACK_VALIDATION */ 12400089c04SJulien Thierry 125ee819aedSJulien Thierry #ifndef __ASSEMBLY__ 126ee819aedSJulien Thierry 127ee819aedSJulien Thierry #define UNWIND_HINT(sp_reg, sp_offset, type, end) \ 128ee819aedSJulien Thierry "\n\t" 12900089c04SJulien Thierry #define STACK_FRAME_NON_STANDARD(func) 130ee819aedSJulien Thierry #else 13100089c04SJulien Thierry #define ANNOTATE_INTRA_FUNCTION_CALL 132ee819aedSJulien Thierry .macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0 133ee819aedSJulien Thierry .endm 134081df943SJosh Poimboeuf .macro STACK_FRAME_NON_STANDARD func:req 135081df943SJosh Poimboeuf .endm 136ee819aedSJulien Thierry #endif 13700089c04SJulien Thierry 13800089c04SJulien Thierry #endif /* CONFIG_STACK_VALIDATION */ 13900089c04SJulien Thierry 14000089c04SJulien Thierry #endif /* _LINUX_OBJTOOL_H */ 141