unwind_hints.h 3.0 KB

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