139358a03SJosh Poimboeuf #ifndef _ASM_X86_UNWIND_HINTS_H 239358a03SJosh Poimboeuf #define _ASM_X86_UNWIND_HINTS_H 339358a03SJosh Poimboeuf 439358a03SJosh Poimboeuf #include "orc_types.h" 539358a03SJosh Poimboeuf 639358a03SJosh Poimboeuf #ifdef __ASSEMBLY__ 739358a03SJosh Poimboeuf 839358a03SJosh Poimboeuf /* 939358a03SJosh Poimboeuf * In asm, there are two kinds of code: normal C-type callable functions and 1039358a03SJosh Poimboeuf * the rest. The normal callable functions can be called by other code, and 1139358a03SJosh Poimboeuf * don't do anything unusual with the stack. Such normal callable functions 1239358a03SJosh Poimboeuf * are annotated with the ENTRY/ENDPROC macros. Most asm code falls in this 1339358a03SJosh Poimboeuf * category. In this case, no special debugging annotations are needed because 1439358a03SJosh Poimboeuf * objtool can automatically generate the ORC data for the ORC unwinder to read 1539358a03SJosh Poimboeuf * at runtime. 1639358a03SJosh Poimboeuf * 1739358a03SJosh Poimboeuf * Anything which doesn't fall into the above category, such as syscall and 1839358a03SJosh Poimboeuf * interrupt handlers, tends to not be called directly by other functions, and 1939358a03SJosh Poimboeuf * often does unusual non-C-function-type things with the stack pointer. Such 2039358a03SJosh Poimboeuf * code needs to be annotated such that objtool can understand it. The 2139358a03SJosh Poimboeuf * following CFI hint macros are for this type of code. 2239358a03SJosh Poimboeuf * 2339358a03SJosh Poimboeuf * These macros provide hints to objtool about the state of the stack at each 2439358a03SJosh Poimboeuf * instruction. Objtool starts from the hints and follows the code flow, 2539358a03SJosh Poimboeuf * making automatic CFI adjustments when it sees pushes and pops, filling out 2639358a03SJosh Poimboeuf * the debuginfo as necessary. It will also warn if it sees any 2739358a03SJosh Poimboeuf * inconsistencies. 2839358a03SJosh Poimboeuf */ 29d31a5802SJosh Poimboeuf .macro UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=0 type=ORC_TYPE_CALL end=0 3039358a03SJosh Poimboeuf #ifdef CONFIG_STACK_VALIDATION 3139358a03SJosh Poimboeuf .Lunwind_hint_ip_\@: 3239358a03SJosh Poimboeuf .pushsection .discard.unwind_hints 3339358a03SJosh Poimboeuf /* struct unwind_hint */ 3439358a03SJosh Poimboeuf .long .Lunwind_hint_ip_\@ - . 3539358a03SJosh Poimboeuf .short \sp_offset 3639358a03SJosh Poimboeuf .byte \sp_reg 3739358a03SJosh Poimboeuf .byte \type 38d31a5802SJosh Poimboeuf .byte \end 39d31a5802SJosh Poimboeuf .balign 4 4039358a03SJosh Poimboeuf .popsection 4139358a03SJosh Poimboeuf #endif 4239358a03SJosh Poimboeuf .endm 4339358a03SJosh Poimboeuf 4439358a03SJosh Poimboeuf .macro UNWIND_HINT_EMPTY 45d31a5802SJosh Poimboeuf UNWIND_HINT sp_reg=ORC_REG_UNDEFINED end=1 4639358a03SJosh Poimboeuf .endm 4739358a03SJosh Poimboeuf 4839358a03SJosh Poimboeuf .macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 iret=0 49af79ded4SJosh Poimboeuf .if \base == %rsp 50af79ded4SJosh Poimboeuf .if \indirect 5139358a03SJosh Poimboeuf .set sp_reg, ORC_REG_SP_INDIRECT 52af79ded4SJosh Poimboeuf .else 5339358a03SJosh Poimboeuf .set sp_reg, ORC_REG_SP 54af79ded4SJosh Poimboeuf .endif 5539358a03SJosh Poimboeuf .elseif \base == %rbp 5639358a03SJosh Poimboeuf .set sp_reg, ORC_REG_BP 5739358a03SJosh Poimboeuf .elseif \base == %rdi 5839358a03SJosh Poimboeuf .set sp_reg, ORC_REG_DI 5939358a03SJosh Poimboeuf .elseif \base == %rdx 6039358a03SJosh Poimboeuf .set sp_reg, ORC_REG_DX 6139358a03SJosh Poimboeuf .elseif \base == %r10 6239358a03SJosh Poimboeuf .set sp_reg, ORC_REG_R10 6339358a03SJosh Poimboeuf .else 6439358a03SJosh Poimboeuf .error "UNWIND_HINT_REGS: bad base register" 6539358a03SJosh Poimboeuf .endif 6639358a03SJosh Poimboeuf 6739358a03SJosh Poimboeuf .set sp_offset, \offset 6839358a03SJosh Poimboeuf 6939358a03SJosh Poimboeuf .if \iret 7039358a03SJosh Poimboeuf .set type, ORC_TYPE_REGS_IRET 7139358a03SJosh Poimboeuf .elseif \extra == 0 7239358a03SJosh Poimboeuf .set type, ORC_TYPE_REGS_IRET 7339358a03SJosh Poimboeuf .set sp_offset, \offset + (16*8) 7439358a03SJosh Poimboeuf .else 7539358a03SJosh Poimboeuf .set type, ORC_TYPE_REGS 7639358a03SJosh Poimboeuf .endif 7739358a03SJosh Poimboeuf 7839358a03SJosh Poimboeuf UNWIND_HINT sp_reg=sp_reg sp_offset=sp_offset type=type 7939358a03SJosh Poimboeuf .endm 8039358a03SJosh Poimboeuf 8139358a03SJosh Poimboeuf .macro UNWIND_HINT_IRET_REGS base=%rsp offset=0 8239358a03SJosh Poimboeuf UNWIND_HINT_REGS base=\base offset=\offset iret=1 8339358a03SJosh Poimboeuf .endm 8439358a03SJosh Poimboeuf 8539358a03SJosh Poimboeuf .macro UNWIND_HINT_FUNC sp_offset=8 8639358a03SJosh Poimboeuf UNWIND_HINT sp_offset=\sp_offset 8739358a03SJosh Poimboeuf .endm 8839358a03SJosh Poimboeuf 8977ac117bSJosh Poimboeuf .macro UNWIND_HINT_SAVE 9077ac117bSJosh Poimboeuf UNWIND_HINT type=UNWIND_HINT_TYPE_SAVE 9177ac117bSJosh Poimboeuf .endm 9277ac117bSJosh Poimboeuf 9377ac117bSJosh Poimboeuf .macro UNWIND_HINT_RESTORE 9477ac117bSJosh Poimboeuf UNWIND_HINT type=UNWIND_HINT_TYPE_RESTORE 9577ac117bSJosh Poimboeuf .endm 9677ac117bSJosh Poimboeuf 97*e25eea89SPeter Zijlstra 98*e25eea89SPeter Zijlstra /* 99*e25eea89SPeter Zijlstra * RET_OFFSET: Used on instructions that terminate a function; mostly RETURN 100*e25eea89SPeter Zijlstra * and sibling calls. On these, sp_offset denotes the expected offset from 101*e25eea89SPeter Zijlstra * initial_func_cfi. 102*e25eea89SPeter Zijlstra */ 103*e25eea89SPeter Zijlstra .macro UNWIND_HINT_RET_OFFSET sp_offset=8 104*e25eea89SPeter Zijlstra UNWIND_HINT type=UNWIND_HINT_TYPE_RET_OFFSET sp_offset=\sp_offset 105*e25eea89SPeter Zijlstra .endm 106*e25eea89SPeter Zijlstra 10739358a03SJosh Poimboeuf #else /* !__ASSEMBLY__ */ 10839358a03SJosh Poimboeuf 109d31a5802SJosh Poimboeuf #define UNWIND_HINT(sp_reg, sp_offset, type, end) \ 11039358a03SJosh Poimboeuf "987: \n\t" \ 11139358a03SJosh Poimboeuf ".pushsection .discard.unwind_hints\n\t" \ 11239358a03SJosh Poimboeuf /* struct unwind_hint */ \ 11339358a03SJosh Poimboeuf ".long 987b - .\n\t" \ 11439358a03SJosh Poimboeuf ".short " __stringify(sp_offset) "\n\t" \ 11539358a03SJosh Poimboeuf ".byte " __stringify(sp_reg) "\n\t" \ 11639358a03SJosh Poimboeuf ".byte " __stringify(type) "\n\t" \ 117d31a5802SJosh Poimboeuf ".byte " __stringify(end) "\n\t" \ 118d31a5802SJosh Poimboeuf ".balign 4 \n\t" \ 11939358a03SJosh Poimboeuf ".popsection\n\t" 12039358a03SJosh Poimboeuf 121d31a5802SJosh Poimboeuf #define UNWIND_HINT_SAVE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_SAVE, 0) 12239358a03SJosh Poimboeuf 123d31a5802SJosh Poimboeuf #define UNWIND_HINT_RESTORE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_RESTORE, 0) 12439358a03SJosh Poimboeuf 12539358a03SJosh Poimboeuf #endif /* __ASSEMBLY__ */ 12639358a03SJosh Poimboeuf 12739358a03SJosh Poimboeuf #endif /* _ASM_X86_UNWIND_HINTS_H */ 128