100089c04SJulien Thierry /* SPDX-License-Identifier: GPL-2.0 */ 200089c04SJulien Thierry #ifndef _LINUX_OBJTOOL_H 300089c04SJulien Thierry #define _LINUX_OBJTOOL_H 400089c04SJulien Thierry 5f7515d9fSJosh Poimboeuf #include <linux/objtool_types.h> 6ee819aedSJulien Thierry 703f16cd0SJosh Poimboeuf #ifdef CONFIG_OBJTOOL 85567c6c3SJulien Thierry 9e2ef1158SPeter Zijlstra #include <asm/asm.h> 10e2ef1158SPeter Zijlstra 115567c6c3SJulien Thierry #ifndef __ASSEMBLY__ 12ee819aedSJulien Thierry 13fb799447SJosh Poimboeuf #define UNWIND_HINT(type, sp_reg, sp_offset, signal) \ 14ee819aedSJulien Thierry "987: \n\t" \ 15ee819aedSJulien Thierry ".pushsection .discard.unwind_hints\n\t" \ 16ee819aedSJulien Thierry /* struct unwind_hint */ \ 17ee819aedSJulien Thierry ".long 987b - .\n\t" \ 18ee819aedSJulien Thierry ".short " __stringify(sp_offset) "\n\t" \ 19ee819aedSJulien Thierry ".byte " __stringify(sp_reg) "\n\t" \ 20ee819aedSJulien Thierry ".byte " __stringify(type) "\n\t" \ 21ffb1b4a4SJosh Poimboeuf ".byte " __stringify(signal) "\n\t" \ 22ee819aedSJulien Thierry ".balign 4 \n\t" \ 23ee819aedSJulien Thierry ".popsection\n\t" 24ee819aedSJulien Thierry 2500089c04SJulien Thierry /* 2600089c04SJulien Thierry * This macro marks the given function's stack frame as "non-standard", which 2700089c04SJulien Thierry * tells objtool to ignore the function when doing stack metadata validation. 2800089c04SJulien Thierry * It should only be used in special cases where you're 100% sure it won't 2900089c04SJulien Thierry * affect the reliability of frame pointers and kernel stack traces. 3000089c04SJulien Thierry * 31d6a21f2dSMauro Carvalho Chehab * For more information, see tools/objtool/Documentation/objtool.txt. 3200089c04SJulien Thierry */ 3300089c04SJulien Thierry #define STACK_FRAME_NON_STANDARD(func) \ 3433def849SJoe Perches static void __used __section(".discard.func_stack_frame_non_standard") \ 3500089c04SJulien Thierry *__func_stack_frame_non_standard_##func = func 3600089c04SJulien Thierry 37e028c4f7SJosh Poimboeuf /* 38e028c4f7SJosh Poimboeuf * STACK_FRAME_NON_STANDARD_FP() is a frame-pointer-specific function ignore 39e028c4f7SJosh Poimboeuf * for the case where a function is intentionally missing frame pointer setup, 40e028c4f7SJosh Poimboeuf * but otherwise needs objtool/ORC coverage when frame pointers are disabled. 41e028c4f7SJosh Poimboeuf */ 42e028c4f7SJosh Poimboeuf #ifdef CONFIG_FRAME_POINTER 43e028c4f7SJosh Poimboeuf #define STACK_FRAME_NON_STANDARD_FP(func) STACK_FRAME_NON_STANDARD(func) 44e028c4f7SJosh Poimboeuf #else 45e028c4f7SJosh Poimboeuf #define STACK_FRAME_NON_STANDARD_FP(func) 46e028c4f7SJosh Poimboeuf #endif 47e028c4f7SJosh Poimboeuf 48dca5da2aSPeter Zijlstra #define ASM_REACHABLE \ 49dca5da2aSPeter Zijlstra "998:\n\t" \ 50dca5da2aSPeter Zijlstra ".pushsection .discard.reachable\n\t" \ 51b8ec60e1SFangrui Song ".long 998b\n\t" \ 52dca5da2aSPeter Zijlstra ".popsection\n\t" 53dca5da2aSPeter Zijlstra 54317f2a64SPeter Zijlstra #define __ASM_BREF(label) label ## b 55317f2a64SPeter Zijlstra 56317f2a64SPeter Zijlstra #define __ASM_ANNOTATE(label, type) \ 572116b349SPeter Zijlstra ".pushsection .discard.annotate_insn,\"M\",@progbits,8\n\t" \ 58317f2a64SPeter Zijlstra ".long " __stringify(label) " - .\n\t" \ 592116b349SPeter Zijlstra ".long " __stringify(type) "\n\t" \ 602116b349SPeter Zijlstra ".popsection\n\t" 612116b349SPeter Zijlstra 62317f2a64SPeter Zijlstra #define ASM_ANNOTATE(type) \ 63317f2a64SPeter Zijlstra "911:\n\t" \ 64317f2a64SPeter Zijlstra __ASM_ANNOTATE(911b, type) 65317f2a64SPeter Zijlstra 665567c6c3SJulien Thierry #else /* __ASSEMBLY__ */ 675567c6c3SJulien Thierry 6800089c04SJulien Thierry /* 69ee819aedSJulien Thierry * In asm, there are two kinds of code: normal C-type callable functions and 70ee819aedSJulien Thierry * the rest. The normal callable functions can be called by other code, and 71ee819aedSJulien Thierry * don't do anything unusual with the stack. Such normal callable functions 72ee819aedSJulien Thierry * are annotated with the ENTRY/ENDPROC macros. Most asm code falls in this 73ee819aedSJulien Thierry * category. In this case, no special debugging annotations are needed because 74ee819aedSJulien Thierry * objtool can automatically generate the ORC data for the ORC unwinder to read 75ee819aedSJulien Thierry * at runtime. 76ee819aedSJulien Thierry * 77ee819aedSJulien Thierry * Anything which doesn't fall into the above category, such as syscall and 78ee819aedSJulien Thierry * interrupt handlers, tends to not be called directly by other functions, and 79ee819aedSJulien Thierry * often does unusual non-C-function-type things with the stack pointer. Such 80ee819aedSJulien Thierry * code needs to be annotated such that objtool can understand it. The 81ee819aedSJulien Thierry * following CFI hint macros are for this type of code. 82ee819aedSJulien Thierry * 83ee819aedSJulien Thierry * These macros provide hints to objtool about the state of the stack at each 84ee819aedSJulien Thierry * instruction. Objtool starts from the hints and follows the code flow, 85ee819aedSJulien Thierry * making automatic CFI adjustments when it sees pushes and pops, filling out 86ee819aedSJulien Thierry * the debuginfo as necessary. It will also warn if it sees any 87ee819aedSJulien Thierry * inconsistencies. 88ee819aedSJulien Thierry */ 89fb799447SJosh Poimboeuf .macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0 901c0c1fafSJosh Poimboeuf .Lhere_\@: 91ee819aedSJulien Thierry .pushsection .discard.unwind_hints 92ee819aedSJulien Thierry /* struct unwind_hint */ 931c0c1fafSJosh Poimboeuf .long .Lhere_\@ - . 94ee819aedSJulien Thierry .short \sp_offset 95ee819aedSJulien Thierry .byte \sp_reg 96ee819aedSJulien Thierry .byte \type 97ffb1b4a4SJosh Poimboeuf .byte \signal 98ee819aedSJulien Thierry .balign 4 99ee819aedSJulien Thierry .popsection 100ee819aedSJulien Thierry .endm 101ee819aedSJulien Thierry 102081df943SJosh Poimboeuf .macro STACK_FRAME_NON_STANDARD func:req 103081df943SJosh Poimboeuf .pushsection .discard.func_stack_frame_non_standard, "aw" 1041c0c1fafSJosh Poimboeuf .long \func - . 105081df943SJosh Poimboeuf .popsection 106081df943SJosh Poimboeuf .endm 107081df943SJosh Poimboeuf 1087b6c7a87SJosh Poimboeuf .macro STACK_FRAME_NON_STANDARD_FP func:req 1097b6c7a87SJosh Poimboeuf #ifdef CONFIG_FRAME_POINTER 1107b6c7a87SJosh Poimboeuf STACK_FRAME_NON_STANDARD \func 1117b6c7a87SJosh Poimboeuf #endif 1127b6c7a87SJosh Poimboeuf .endm 1137b6c7a87SJosh Poimboeuf 1144708ea14SJosh Poimboeuf 115dca5da2aSPeter Zijlstra .macro REACHABLE 116dca5da2aSPeter Zijlstra .Lhere_\@: 117dca5da2aSPeter Zijlstra .pushsection .discard.reachable 118b8ec60e1SFangrui Song .long .Lhere_\@ 119dca5da2aSPeter Zijlstra .popsection 120dca5da2aSPeter Zijlstra .endm 121dca5da2aSPeter Zijlstra 1222116b349SPeter Zijlstra .macro ANNOTATE type:req 1232116b349SPeter Zijlstra .Lhere_\@: 1242116b349SPeter Zijlstra .pushsection .discard.annotate_insn,"M",@progbits,8 1252116b349SPeter Zijlstra .long .Lhere_\@ - . 1262116b349SPeter Zijlstra .long \type 1272116b349SPeter Zijlstra .popsection 1282116b349SPeter Zijlstra .endm 1292116b349SPeter Zijlstra 1305567c6c3SJulien Thierry #endif /* __ASSEMBLY__ */ 1315567c6c3SJulien Thierry 13203f16cd0SJosh Poimboeuf #else /* !CONFIG_OBJTOOL */ 13300089c04SJulien Thierry 134ee819aedSJulien Thierry #ifndef __ASSEMBLY__ 135ee819aedSJulien Thierry 136fb799447SJosh Poimboeuf #define UNWIND_HINT(type, sp_reg, sp_offset, signal) "\n\t" 13700089c04SJulien Thierry #define STACK_FRAME_NON_STANDARD(func) 138e028c4f7SJosh Poimboeuf #define STACK_FRAME_NON_STANDARD_FP(func) 139317f2a64SPeter Zijlstra #define __ASM_ANNOTATE(label, type) 1402116b349SPeter Zijlstra #define ASM_ANNOTATE(type) 141dca5da2aSPeter Zijlstra #define ASM_REACHABLE 142ee819aedSJulien Thierry #else 143fb799447SJosh Poimboeuf .macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0 144ee819aedSJulien Thierry .endm 145081df943SJosh Poimboeuf .macro STACK_FRAME_NON_STANDARD func:req 146081df943SJosh Poimboeuf .endm 147dca5da2aSPeter Zijlstra .macro REACHABLE 148dca5da2aSPeter Zijlstra .endm 1492116b349SPeter Zijlstra .macro ANNOTATE type:req 1502116b349SPeter Zijlstra .endm 151ee819aedSJulien Thierry #endif 15200089c04SJulien Thierry 15303f16cd0SJosh Poimboeuf #endif /* CONFIG_OBJTOOL */ 15400089c04SJulien Thierry 155*bb817006SPeter Zijlstra #ifndef __ASSEMBLY__ 156*bb817006SPeter Zijlstra /* 157*bb817006SPeter Zijlstra * Annotate away the various 'relocation to !ENDBR` complaints; knowing that 158*bb817006SPeter Zijlstra * these relocations will never be used for indirect calls. 159*bb817006SPeter Zijlstra */ 160*bb817006SPeter Zijlstra #define ANNOTATE_NOENDBR ASM_ANNOTATE(ANNOTYPE_NOENDBR) 161*bb817006SPeter Zijlstra /* 162*bb817006SPeter Zijlstra * This should be used immediately before an indirect jump/call. It tells 163*bb817006SPeter Zijlstra * objtool the subsequent indirect jump/call is vouched safe for retpoline 164*bb817006SPeter Zijlstra * builds. 165*bb817006SPeter Zijlstra */ 166*bb817006SPeter Zijlstra #define ANNOTATE_RETPOLINE_SAFE ASM_ANNOTATE(ANNOTYPE_RETPOLINE_SAFE) 167*bb817006SPeter Zijlstra /* 168*bb817006SPeter Zijlstra * See linux/instrumentation.h 169*bb817006SPeter Zijlstra */ 170*bb817006SPeter Zijlstra #define ANNOTATE_INSTR_BEGIN(label) __ASM_ANNOTATE(label, ANNOTYPE_INSTR_BEGIN) 171*bb817006SPeter Zijlstra #define ANNOTATE_INSTR_END(label) __ASM_ANNOTATE(label, ANNOTYPE_INSTR_END) 172*bb817006SPeter Zijlstra /* 173*bb817006SPeter Zijlstra * objtool annotation to ignore the alternatives and only consider the original 174*bb817006SPeter Zijlstra * instruction(s). 175*bb817006SPeter Zijlstra */ 176*bb817006SPeter Zijlstra #define ANNOTATE_IGNORE_ALTERNATIVE ASM_ANNOTATE(ANNOTYPE_IGNORE_ALTS) 177*bb817006SPeter Zijlstra /* 178*bb817006SPeter Zijlstra * This macro indicates that the following intra-function call is valid. 179*bb817006SPeter Zijlstra * Any non-annotated intra-function call will cause objtool to issue a warning. 180*bb817006SPeter Zijlstra */ 181*bb817006SPeter Zijlstra #define ANNOTATE_INTRA_FUNCTION_CALL ASM_ANNOTATE(ANNOTYPE_INTRA_FUNCTION_CALL) 182*bb817006SPeter Zijlstra /* 183*bb817006SPeter Zijlstra * Use objtool to validate the entry requirement that all code paths do 184*bb817006SPeter Zijlstra * VALIDATE_UNRET_END before RET. 185*bb817006SPeter Zijlstra * 186*bb817006SPeter Zijlstra * NOTE: The macro must be used at the beginning of a global symbol, otherwise 187*bb817006SPeter Zijlstra * it will be ignored. 188*bb817006SPeter Zijlstra */ 189*bb817006SPeter Zijlstra #define ANNOTATE_UNRET_BEGIN ASM_ANNOTATE(ANNOTYPE_UNRET_BEGIN) 190*bb817006SPeter Zijlstra 191*bb817006SPeter Zijlstra #else 192*bb817006SPeter Zijlstra #define ANNOTATE_NOENDBR ANNOTATE type=ANNOTYPE_NOENDBR 193*bb817006SPeter Zijlstra #define ANNOTATE_RETPOLINE_SAFE ANNOTATE type=ANNOTYPE_RETPOLINE_SAFE 194*bb817006SPeter Zijlstra /* ANNOTATE_INSTR_BEGIN ANNOTATE type=ANNOTYPE_INSTR_BEGIN */ 195*bb817006SPeter Zijlstra /* ANNOTATE_INSTR_END ANNOTATE type=ANNOTYPE_INSTR_END */ 196*bb817006SPeter Zijlstra #define ANNOTATE_IGNORE_ALTERNATIVE ANNOTATE type=ANNOTYPE_IGNORE_ALTS 197*bb817006SPeter Zijlstra #define ANNOTATE_INTRA_FUNCTION_CALL ANNOTATE type=ANNOTYPE_INTRA_FUNCTION_CALL 198*bb817006SPeter Zijlstra #define ANNOTATE_UNRET_BEGIN ANNOTATE type=ANNOTYPE_UNRET_BEGIN 199*bb817006SPeter Zijlstra #endif 200*bb817006SPeter Zijlstra 201*bb817006SPeter Zijlstra #if defined(CONFIG_NOINSTR_VALIDATION) && \ 202*bb817006SPeter Zijlstra (defined(CONFIG_MITIGATION_UNRET_ENTRY) || defined(CONFIG_MITIGATION_SRSO)) 203*bb817006SPeter Zijlstra #define VALIDATE_UNRET_BEGIN ANNOTATE_UNRET_BEGIN 204*bb817006SPeter Zijlstra #else 205*bb817006SPeter Zijlstra #define VALIDATE_UNRET_BEGIN 206*bb817006SPeter Zijlstra #endif 207*bb817006SPeter Zijlstra 20800089c04SJulien Thierry #endif /* _LINUX_OBJTOOL_H */ 209