unwind.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _ASM_IA64_UNWIND_H
  3. #define _ASM_IA64_UNWIND_H
  4. /*
  5. * Copyright (C) 1999-2000, 2003 Hewlett-Packard Co
  6. * David Mosberger-Tang <davidm@hpl.hp.com>
  7. *
  8. * A simple API for unwinding kernel stacks. This is used for
  9. * debugging and error reporting purposes. The kernel doesn't need
  10. * full-blown stack unwinding with all the bells and whitles, so there
  11. * is not much point in implementing the full IA-64 unwind API (though
  12. * it would of course be possible to implement the kernel API on top
  13. * of it).
  14. */
  15. struct task_struct; /* forward declaration */
  16. struct switch_stack; /* forward declaration */
  17. enum unw_application_register {
  18. UNW_AR_BSP,
  19. UNW_AR_BSPSTORE,
  20. UNW_AR_PFS,
  21. UNW_AR_RNAT,
  22. UNW_AR_UNAT,
  23. UNW_AR_LC,
  24. UNW_AR_EC,
  25. UNW_AR_FPSR,
  26. UNW_AR_RSC,
  27. UNW_AR_CCV,
  28. UNW_AR_CSD,
  29. UNW_AR_SSD
  30. };
  31. /*
  32. * The following declarations are private to the unwind
  33. * implementation:
  34. */
  35. struct unw_stack {
  36. unsigned long limit;
  37. unsigned long top;
  38. };
  39. #define UNW_FLAG_INTERRUPT_FRAME (1UL << 0)
  40. /*
  41. * No user of this module should every access this structure directly
  42. * as it is subject to change. It is declared here solely so we can
  43. * use automatic variables.
  44. */
  45. struct unw_frame_info {
  46. struct unw_stack regstk;
  47. struct unw_stack memstk;
  48. unsigned int flags;
  49. short hint;
  50. short prev_script;
  51. /* current frame info: */
  52. unsigned long bsp; /* backing store pointer value */
  53. unsigned long sp; /* stack pointer value */
  54. unsigned long psp; /* previous sp value */
  55. unsigned long ip; /* instruction pointer value */
  56. unsigned long pr; /* current predicate values */
  57. unsigned long *cfm_loc; /* cfm save location (or NULL) */
  58. unsigned long pt; /* struct pt_regs location */
  59. struct task_struct *task;
  60. struct switch_stack *sw;
  61. /* preserved state: */
  62. unsigned long *bsp_loc; /* previous bsp save location */
  63. unsigned long *bspstore_loc;
  64. unsigned long *pfs_loc;
  65. unsigned long *rnat_loc;
  66. unsigned long *rp_loc;
  67. unsigned long *pri_unat_loc;
  68. unsigned long *unat_loc;
  69. unsigned long *pr_loc;
  70. unsigned long *lc_loc;
  71. unsigned long *fpsr_loc;
  72. struct unw_ireg {
  73. unsigned long *loc;
  74. struct unw_ireg_nat {
  75. unsigned long type : 3; /* enum unw_nat_type */
  76. signed long off : 61; /* NaT word is at loc+nat.off */
  77. } nat;
  78. } r4, r5, r6, r7;
  79. unsigned long *b1_loc, *b2_loc, *b3_loc, *b4_loc, *b5_loc;
  80. struct ia64_fpreg *f2_loc, *f3_loc, *f4_loc, *f5_loc, *fr_loc[16];
  81. };
  82. /*
  83. * The official API follows below:
  84. */
  85. struct unw_table_entry {
  86. u64 start_offset;
  87. u64 end_offset;
  88. u64 info_offset;
  89. };
  90. /*
  91. * Initialize unwind support.
  92. */
  93. extern void unw_init (void);
  94. extern void *unw_add_unwind_table (const char *name, unsigned long segment_base, unsigned long gp,
  95. const void *table_start, const void *table_end);
  96. extern void unw_remove_unwind_table (void *handle);
  97. /*
  98. * Prepare to unwind blocked task t.
  99. */
  100. extern void unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t);
  101. extern void unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t,
  102. struct switch_stack *sw);
  103. /*
  104. * Prepare to unwind the currently running thread.
  105. */
  106. extern void unw_init_running (void (*callback)(struct unw_frame_info *info, void *arg), void *arg);
  107. /*
  108. * Unwind to previous to frame. Returns 0 if successful, negative
  109. * number in case of an error.
  110. */
  111. extern int unw_unwind (struct unw_frame_info *info);
  112. /*
  113. * Unwind until the return pointer is in user-land (or until an error
  114. * occurs). Returns 0 if successful, negative number in case of
  115. * error.
  116. */
  117. extern int unw_unwind_to_user (struct unw_frame_info *info);
  118. #define unw_is_intr_frame(info) (((info)->flags & UNW_FLAG_INTERRUPT_FRAME) != 0)
  119. static inline int
  120. unw_get_ip (struct unw_frame_info *info, unsigned long *valp)
  121. {
  122. *valp = (info)->ip;
  123. return 0;
  124. }
  125. static inline int
  126. unw_get_sp (struct unw_frame_info *info, unsigned long *valp)
  127. {
  128. *valp = (info)->sp;
  129. return 0;
  130. }
  131. static inline int
  132. unw_get_psp (struct unw_frame_info *info, unsigned long *valp)
  133. {
  134. *valp = (info)->psp;
  135. return 0;
  136. }
  137. static inline int
  138. unw_get_bsp (struct unw_frame_info *info, unsigned long *valp)
  139. {
  140. *valp = (info)->bsp;
  141. return 0;
  142. }
  143. static inline int
  144. unw_get_cfm (struct unw_frame_info *info, unsigned long *valp)
  145. {
  146. *valp = *(info)->cfm_loc;
  147. return 0;
  148. }
  149. static inline int
  150. unw_set_cfm (struct unw_frame_info *info, unsigned long val)
  151. {
  152. *(info)->cfm_loc = val;
  153. return 0;
  154. }
  155. static inline int
  156. unw_get_rp (struct unw_frame_info *info, unsigned long *val)
  157. {
  158. if (!info->rp_loc)
  159. return -1;
  160. *val = *info->rp_loc;
  161. return 0;
  162. }
  163. extern int unw_access_gr (struct unw_frame_info *, int, unsigned long *, char *, int);
  164. extern int unw_access_br (struct unw_frame_info *, int, unsigned long *, int);
  165. extern int unw_access_fr (struct unw_frame_info *, int, struct ia64_fpreg *, int);
  166. extern int unw_access_ar (struct unw_frame_info *, int, unsigned long *, int);
  167. extern int unw_access_pr (struct unw_frame_info *, unsigned long *, int);
  168. static inline int
  169. unw_set_gr (struct unw_frame_info *i, int n, unsigned long v, char nat)
  170. {
  171. return unw_access_gr(i, n, &v, &nat, 1);
  172. }
  173. static inline int
  174. unw_set_br (struct unw_frame_info *i, int n, unsigned long v)
  175. {
  176. return unw_access_br(i, n, &v, 1);
  177. }
  178. static inline int
  179. unw_set_fr (struct unw_frame_info *i, int n, struct ia64_fpreg v)
  180. {
  181. return unw_access_fr(i, n, &v, 1);
  182. }
  183. static inline int
  184. unw_set_ar (struct unw_frame_info *i, int n, unsigned long v)
  185. {
  186. return unw_access_ar(i, n, &v, 1);
  187. }
  188. static inline int
  189. unw_set_pr (struct unw_frame_info *i, unsigned long v)
  190. {
  191. return unw_access_pr(i, &v, 1);
  192. }
  193. #define unw_get_gr(i,n,v,nat) unw_access_gr(i,n,v,nat,0)
  194. #define unw_get_br(i,n,v) unw_access_br(i,n,v,0)
  195. #define unw_get_fr(i,n,v) unw_access_fr(i,n,v,0)
  196. #define unw_get_ar(i,n,v) unw_access_ar(i,n,v,0)
  197. #define unw_get_pr(i,v) unw_access_pr(i,v,0)
  198. #endif /* _ASM_UNWIND_H */