unwind.h 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #ifndef _ASM_X86_UNWIND_H
  2. #define _ASM_X86_UNWIND_H
  3. #include <linux/sched.h>
  4. #include <linux/ftrace.h>
  5. #include <asm/ptrace.h>
  6. #include <asm/stacktrace.h>
  7. struct unwind_state {
  8. struct stack_info stack_info;
  9. unsigned long stack_mask;
  10. struct task_struct *task;
  11. int graph_idx;
  12. #ifdef CONFIG_FRAME_POINTER
  13. unsigned long *bp;
  14. #else
  15. unsigned long *sp;
  16. #endif
  17. };
  18. void __unwind_start(struct unwind_state *state, struct task_struct *task,
  19. struct pt_regs *regs, unsigned long *first_frame);
  20. bool unwind_next_frame(struct unwind_state *state);
  21. static inline bool unwind_done(struct unwind_state *state)
  22. {
  23. return state->stack_info.type == STACK_TYPE_UNKNOWN;
  24. }
  25. static inline
  26. void unwind_start(struct unwind_state *state, struct task_struct *task,
  27. struct pt_regs *regs, unsigned long *first_frame)
  28. {
  29. first_frame = first_frame ? : get_stack_pointer(task, regs);
  30. __unwind_start(state, task, regs, first_frame);
  31. }
  32. #ifdef CONFIG_FRAME_POINTER
  33. static inline
  34. unsigned long *unwind_get_return_address_ptr(struct unwind_state *state)
  35. {
  36. if (unwind_done(state))
  37. return NULL;
  38. return state->bp + 1;
  39. }
  40. unsigned long unwind_get_return_address(struct unwind_state *state);
  41. #else /* !CONFIG_FRAME_POINTER */
  42. static inline
  43. unsigned long *unwind_get_return_address_ptr(struct unwind_state *state)
  44. {
  45. return NULL;
  46. }
  47. static inline
  48. unsigned long unwind_get_return_address(struct unwind_state *state)
  49. {
  50. if (unwind_done(state))
  51. return 0;
  52. return ftrace_graph_ret_addr(state->task, &state->graph_idx,
  53. *state->sp, state->sp);
  54. }
  55. #endif /* CONFIG_FRAME_POINTER */
  56. #endif /* _ASM_X86_UNWIND_H */