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