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 72*24fe172bSJosh Poimboeuf * are annotated with SYM_FUNC_{START,END}. 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 1142116b349SPeter Zijlstra .macro ANNOTATE type:req 1152116b349SPeter Zijlstra .Lhere_\@: 1162116b349SPeter Zijlstra .pushsection .discard.annotate_insn,"M",@progbits,8 1172116b349SPeter Zijlstra .long .Lhere_\@ - . 1182116b349SPeter Zijlstra .long \type 1192116b349SPeter Zijlstra .popsection 1202116b349SPeter Zijlstra .endm 1212116b349SPeter Zijlstra 1225567c6c3SJulien Thierry #endif /* __ASSEMBLY__ */ 1235567c6c3SJulien Thierry 12403f16cd0SJosh Poimboeuf #else /* !CONFIG_OBJTOOL */ 12500089c04SJulien Thierry 126ee819aedSJulien Thierry #ifndef __ASSEMBLY__ 127ee819aedSJulien Thierry 128fb799447SJosh Poimboeuf #define UNWIND_HINT(type, sp_reg, sp_offset, signal) "\n\t" 12900089c04SJulien Thierry #define STACK_FRAME_NON_STANDARD(func) 130e028c4f7SJosh Poimboeuf #define STACK_FRAME_NON_STANDARD_FP(func) 13193f16a1aSPeter Zijlstra #define __ASM_ANNOTATE(label, type) "" 1322116b349SPeter Zijlstra #define ASM_ANNOTATE(type) 133ee819aedSJulien Thierry #else 134fb799447SJosh Poimboeuf .macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0 135ee819aedSJulien Thierry .endm 136081df943SJosh Poimboeuf .macro STACK_FRAME_NON_STANDARD func:req 137081df943SJosh Poimboeuf .endm 1382116b349SPeter Zijlstra .macro ANNOTATE type:req 1392116b349SPeter Zijlstra .endm 140ee819aedSJulien Thierry #endif 14100089c04SJulien Thierry 14203f16cd0SJosh Poimboeuf #endif /* CONFIG_OBJTOOL */ 14300089c04SJulien Thierry 144bb817006SPeter Zijlstra #ifndef __ASSEMBLY__ 145bb817006SPeter Zijlstra /* 146bb817006SPeter Zijlstra * Annotate away the various 'relocation to !ENDBR` complaints; knowing that 147bb817006SPeter Zijlstra * these relocations will never be used for indirect calls. 148bb817006SPeter Zijlstra */ 149bb817006SPeter Zijlstra #define ANNOTATE_NOENDBR ASM_ANNOTATE(ANNOTYPE_NOENDBR) 15093f16a1aSPeter Zijlstra #define ANNOTATE_NOENDBR_SYM(sym) asm(__ASM_ANNOTATE(sym, ANNOTYPE_NOENDBR)) 15193f16a1aSPeter Zijlstra 152bb817006SPeter Zijlstra /* 153bb817006SPeter Zijlstra * This should be used immediately before an indirect jump/call. It tells 154bb817006SPeter Zijlstra * objtool the subsequent indirect jump/call is vouched safe for retpoline 155bb817006SPeter Zijlstra * builds. 156bb817006SPeter Zijlstra */ 157bb817006SPeter Zijlstra #define ANNOTATE_RETPOLINE_SAFE ASM_ANNOTATE(ANNOTYPE_RETPOLINE_SAFE) 158bb817006SPeter Zijlstra /* 159bb817006SPeter Zijlstra * See linux/instrumentation.h 160bb817006SPeter Zijlstra */ 161bb817006SPeter Zijlstra #define ANNOTATE_INSTR_BEGIN(label) __ASM_ANNOTATE(label, ANNOTYPE_INSTR_BEGIN) 162bb817006SPeter Zijlstra #define ANNOTATE_INSTR_END(label) __ASM_ANNOTATE(label, ANNOTYPE_INSTR_END) 163bb817006SPeter Zijlstra /* 164bb817006SPeter Zijlstra * objtool annotation to ignore the alternatives and only consider the original 165bb817006SPeter Zijlstra * instruction(s). 166bb817006SPeter Zijlstra */ 167bb817006SPeter Zijlstra #define ANNOTATE_IGNORE_ALTERNATIVE ASM_ANNOTATE(ANNOTYPE_IGNORE_ALTS) 168bb817006SPeter Zijlstra /* 169bb817006SPeter Zijlstra * This macro indicates that the following intra-function call is valid. 170bb817006SPeter Zijlstra * Any non-annotated intra-function call will cause objtool to issue a warning. 171bb817006SPeter Zijlstra */ 172bb817006SPeter Zijlstra #define ANNOTATE_INTRA_FUNCTION_CALL ASM_ANNOTATE(ANNOTYPE_INTRA_FUNCTION_CALL) 173bb817006SPeter Zijlstra /* 174bb817006SPeter Zijlstra * Use objtool to validate the entry requirement that all code paths do 175bb817006SPeter Zijlstra * VALIDATE_UNRET_END before RET. 176bb817006SPeter Zijlstra * 177bb817006SPeter Zijlstra * NOTE: The macro must be used at the beginning of a global symbol, otherwise 178bb817006SPeter Zijlstra * it will be ignored. 179bb817006SPeter Zijlstra */ 180bb817006SPeter Zijlstra #define ANNOTATE_UNRET_BEGIN ASM_ANNOTATE(ANNOTYPE_UNRET_BEGIN) 181e7a174fbSPeter Zijlstra /* 18287116ae6SPeter Zijlstra * This should be used to refer to an instruction that is considered 183e7a174fbSPeter Zijlstra * terminating, like a noreturn CALL or UD2 when we know they are not -- eg 184e7a174fbSPeter Zijlstra * WARN using UD2. 185e7a174fbSPeter Zijlstra */ 18687116ae6SPeter Zijlstra #define ANNOTATE_REACHABLE(label) __ASM_ANNOTATE(label, ANNOTYPE_REACHABLE) 187bb817006SPeter Zijlstra 188bb817006SPeter Zijlstra #else 189bb817006SPeter Zijlstra #define ANNOTATE_NOENDBR ANNOTATE type=ANNOTYPE_NOENDBR 190bb817006SPeter Zijlstra #define ANNOTATE_RETPOLINE_SAFE ANNOTATE type=ANNOTYPE_RETPOLINE_SAFE 191bb817006SPeter Zijlstra /* ANNOTATE_INSTR_BEGIN ANNOTATE type=ANNOTYPE_INSTR_BEGIN */ 192bb817006SPeter Zijlstra /* ANNOTATE_INSTR_END ANNOTATE type=ANNOTYPE_INSTR_END */ 193bb817006SPeter Zijlstra #define ANNOTATE_IGNORE_ALTERNATIVE ANNOTATE type=ANNOTYPE_IGNORE_ALTS 194bb817006SPeter Zijlstra #define ANNOTATE_INTRA_FUNCTION_CALL ANNOTATE type=ANNOTYPE_INTRA_FUNCTION_CALL 195bb817006SPeter Zijlstra #define ANNOTATE_UNRET_BEGIN ANNOTATE type=ANNOTYPE_UNRET_BEGIN 196e7a174fbSPeter Zijlstra #define ANNOTATE_REACHABLE ANNOTATE type=ANNOTYPE_REACHABLE 197bb817006SPeter Zijlstra #endif 198bb817006SPeter Zijlstra 199bb817006SPeter Zijlstra #if defined(CONFIG_NOINSTR_VALIDATION) && \ 200bb817006SPeter Zijlstra (defined(CONFIG_MITIGATION_UNRET_ENTRY) || defined(CONFIG_MITIGATION_SRSO)) 201bb817006SPeter Zijlstra #define VALIDATE_UNRET_BEGIN ANNOTATE_UNRET_BEGIN 202bb817006SPeter Zijlstra #else 203bb817006SPeter Zijlstra #define VALIDATE_UNRET_BEGIN 204bb817006SPeter Zijlstra #endif 205bb817006SPeter Zijlstra 20600089c04SJulien Thierry #endif /* _LINUX_OBJTOOL_H */ 207