Gstep.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /* libunwind - a platform-independent unwind library
  2. Copyright (C) 2006-2007 IBM
  3. Contributed by
  4. Corey Ashford <cjashfor@us.ibm.com>
  5. Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
  6. This file is part of libunwind.
  7. Permission is hereby granted, free of charge, to any person obtaining
  8. a copy of this software and associated documentation files (the
  9. "Software"), to deal in the Software without restriction, including
  10. without limitation the rights to use, copy, modify, merge, publish,
  11. distribute, sublicense, and/or sell copies of the Software, and to
  12. permit persons to whom the Software is furnished to do so, subject to
  13. the following conditions:
  14. The above copyright notice and this permission notice shall be
  15. included in all copies or substantial portions of the Software.
  16. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  20. LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  21. OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  22. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  23. #include "unwind_i.h"
  24. #include "ucontext_i.h"
  25. #include <signal.h>
  26. /* This definition originates in /usr/include/asm-ppc64/ptrace.h, but is
  27. defined there only when __KERNEL__ is defined. We reproduce it here for
  28. our use at the user level in order to locate the ucontext record, which
  29. appears to be at this offset relative to the stack pointer when in the
  30. context of the signal handler return trampoline code -
  31. __kernel_sigtramp_rt64. */
  32. #define __SIGNAL_FRAMESIZE 128
  33. /* This definition comes from the document "64-bit PowerPC ELF Application
  34. Binary Interface Supplement 1.9", section 3.2.2.
  35. http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK */
  36. typedef struct
  37. {
  38. long unsigned back_chain;
  39. long unsigned lr_save;
  40. /* many more fields here, but they are unused by this code */
  41. } stack_frame_t;
  42. PROTECTED int
  43. unw_step (unw_cursor_t * cursor)
  44. {
  45. struct cursor *c = (struct cursor *) cursor;
  46. stack_frame_t dummy;
  47. unw_word_t back_chain_offset, lr_save_offset;
  48. struct dwarf_loc back_chain_loc, lr_save_loc, sp_loc, ip_loc;
  49. int ret;
  50. Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->dwarf.ip);
  51. if (c->dwarf.ip == 0)
  52. {
  53. /* Unless the cursor or stack is corrupt or uninitialized,
  54. we've most likely hit the top of the stack */
  55. return 0;
  56. }
  57. /* Try DWARF-based unwinding... */
  58. ret = dwarf_step (&c->dwarf);
  59. if (ret < 0 && ret != -UNW_ENOINFO)
  60. {
  61. Debug (2, "returning %d\n", ret);
  62. return ret;
  63. }
  64. if (unlikely (ret < 0))
  65. {
  66. if (likely (!unw_is_signal_frame (cursor)))
  67. {
  68. /* DWARF unwinding failed. As of 09/26/2006, gcc in 64-bit mode
  69. produces the mandatory level of traceback record in the code, but
  70. I get the impression that this is transitory, that eventually gcc
  71. will not produce any traceback records at all. So, for now, we
  72. won't bother to try to find and use these records.
  73. We can, however, attempt to unwind the frame by using the callback
  74. chain. This is very crude, however, and won't be able to unwind
  75. any registers besides the IP, SP, and LR . */
  76. back_chain_offset = ((void *) &dummy.back_chain - (void *) &dummy);
  77. lr_save_offset = ((void *) &dummy.lr_save - (void *) &dummy);
  78. back_chain_loc = DWARF_LOC (c->dwarf.cfa + back_chain_offset, 0);
  79. if ((ret =
  80. dwarf_get (&c->dwarf, back_chain_loc, &c->dwarf.cfa)) < 0)
  81. {
  82. Debug
  83. ("Unable to retrieve CFA from back chain in stack frame - %d\n",
  84. ret);
  85. return ret;
  86. }
  87. if (c->dwarf.cfa == 0)
  88. /* Unless the cursor or stack is corrupt or uninitialized we've most
  89. likely hit the top of the stack */
  90. return 0;
  91. lr_save_loc = DWARF_LOC (c->dwarf.cfa + lr_save_offset, 0);
  92. if ((ret = dwarf_get (&c->dwarf, lr_save_loc, &c->dwarf.ip)) < 0)
  93. {
  94. Debug
  95. ("Unable to retrieve IP from lr save in stack frame - %d\n",
  96. ret);
  97. return ret;
  98. }
  99. ret = 1;
  100. }
  101. else
  102. {
  103. /* Find the sigcontext record by taking the CFA and adjusting by
  104. the dummy signal frame size.
  105. Note that there isn't any way to determined if SA_SIGINFO was
  106. set in the sa_flags parameter to sigaction when the signal
  107. handler was established. If it was not set, the ucontext
  108. record is not required to be on the stack, in which case the
  109. following code will likely cause a seg fault or other crash
  110. condition. */
  111. unw_word_t ucontext = c->dwarf.cfa + __SIGNAL_FRAMESIZE;
  112. Debug (1, "signal frame, skip over trampoline\n");
  113. c->sigcontext_format = PPC_SCF_LINUX_RT_SIGFRAME;
  114. c->sigcontext_addr = ucontext;
  115. sp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0);
  116. ip_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0);
  117. ret = dwarf_get (&c->dwarf, sp_loc, &c->dwarf.cfa);
  118. if (ret < 0)
  119. {
  120. Debug (2, "returning %d\n", ret);
  121. return ret;
  122. }
  123. ret = dwarf_get (&c->dwarf, ip_loc, &c->dwarf.ip);
  124. if (ret < 0)
  125. {
  126. Debug (2, "returning %d\n", ret);
  127. return ret;
  128. }
  129. /* Instead of just restoring the non-volatile registers, do all
  130. of the registers for now. This will incur a performance hit,
  131. but it's rare enough not to cause too much of a problem, and
  132. might be useful in some cases. */
  133. c->dwarf.loc[UNW_PPC32_R0] =
  134. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R0, 0);
  135. c->dwarf.loc[UNW_PPC32_R1] =
  136. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0);
  137. c->dwarf.loc[UNW_PPC32_R2] =
  138. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R2, 0);
  139. c->dwarf.loc[UNW_PPC32_R3] =
  140. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R3, 0);
  141. c->dwarf.loc[UNW_PPC32_R4] =
  142. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R4, 0);
  143. c->dwarf.loc[UNW_PPC32_R5] =
  144. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R5, 0);
  145. c->dwarf.loc[UNW_PPC32_R6] =
  146. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R6, 0);
  147. c->dwarf.loc[UNW_PPC32_R7] =
  148. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R7, 0);
  149. c->dwarf.loc[UNW_PPC32_R8] =
  150. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0);
  151. c->dwarf.loc[UNW_PPC32_R9] =
  152. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0);
  153. c->dwarf.loc[UNW_PPC32_R10] =
  154. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0);
  155. c->dwarf.loc[UNW_PPC32_R11] =
  156. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0);
  157. c->dwarf.loc[UNW_PPC32_R12] =
  158. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0);
  159. c->dwarf.loc[UNW_PPC32_R13] =
  160. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0);
  161. c->dwarf.loc[UNW_PPC32_R14] =
  162. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0);
  163. c->dwarf.loc[UNW_PPC32_R15] =
  164. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0);
  165. c->dwarf.loc[UNW_PPC32_R16] =
  166. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R16, 0);
  167. c->dwarf.loc[UNW_PPC32_R17] =
  168. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R17, 0);
  169. c->dwarf.loc[UNW_PPC32_R18] =
  170. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R18, 0);
  171. c->dwarf.loc[UNW_PPC32_R19] =
  172. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R19, 0);
  173. c->dwarf.loc[UNW_PPC32_R20] =
  174. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R20, 0);
  175. c->dwarf.loc[UNW_PPC32_R21] =
  176. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R21, 0);
  177. c->dwarf.loc[UNW_PPC32_R22] =
  178. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R22, 0);
  179. c->dwarf.loc[UNW_PPC32_R23] =
  180. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R23, 0);
  181. c->dwarf.loc[UNW_PPC32_R24] =
  182. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R24, 0);
  183. c->dwarf.loc[UNW_PPC32_R25] =
  184. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R25, 0);
  185. c->dwarf.loc[UNW_PPC32_R26] =
  186. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R26, 0);
  187. c->dwarf.loc[UNW_PPC32_R27] =
  188. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R27, 0);
  189. c->dwarf.loc[UNW_PPC32_R28] =
  190. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R28, 0);
  191. c->dwarf.loc[UNW_PPC32_R29] =
  192. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R29, 0);
  193. c->dwarf.loc[UNW_PPC32_R30] =
  194. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R30, 0);
  195. c->dwarf.loc[UNW_PPC32_R31] =
  196. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R31, 0);
  197. c->dwarf.loc[UNW_PPC32_LR] =
  198. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0);
  199. c->dwarf.loc[UNW_PPC32_CTR] =
  200. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CTR, 0);
  201. /* This CR0 assignment is probably wrong. There are 8 dwarf columns
  202. assigned to the CR registers, but only one CR register in the
  203. mcontext structure */
  204. c->dwarf.loc[UNW_PPC32_CCR] =
  205. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CCR, 0);
  206. c->dwarf.loc[UNW_PPC32_XER] =
  207. DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_XER, 0);
  208. c->dwarf.loc[UNW_PPC32_F0] =
  209. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R0, 0);
  210. c->dwarf.loc[UNW_PPC32_F1] =
  211. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R1, 0);
  212. c->dwarf.loc[UNW_PPC32_F2] =
  213. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R2, 0);
  214. c->dwarf.loc[UNW_PPC32_F3] =
  215. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R3, 0);
  216. c->dwarf.loc[UNW_PPC32_F4] =
  217. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R4, 0);
  218. c->dwarf.loc[UNW_PPC32_F5] =
  219. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R5, 0);
  220. c->dwarf.loc[UNW_PPC32_F6] =
  221. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R6, 0);
  222. c->dwarf.loc[UNW_PPC32_F7] =
  223. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R7, 0);
  224. c->dwarf.loc[UNW_PPC32_F8] =
  225. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R8, 0);
  226. c->dwarf.loc[UNW_PPC32_F9] =
  227. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R9, 0);
  228. c->dwarf.loc[UNW_PPC32_F10] =
  229. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R10, 0);
  230. c->dwarf.loc[UNW_PPC32_F11] =
  231. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R11, 0);
  232. c->dwarf.loc[UNW_PPC32_F12] =
  233. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R12, 0);
  234. c->dwarf.loc[UNW_PPC32_F13] =
  235. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R13, 0);
  236. c->dwarf.loc[UNW_PPC32_F14] =
  237. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R14, 0);
  238. c->dwarf.loc[UNW_PPC32_F15] =
  239. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R15, 0);
  240. c->dwarf.loc[UNW_PPC32_F16] =
  241. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R16, 0);
  242. c->dwarf.loc[UNW_PPC32_F17] =
  243. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R17, 0);
  244. c->dwarf.loc[UNW_PPC32_F18] =
  245. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R18, 0);
  246. c->dwarf.loc[UNW_PPC32_F19] =
  247. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R19, 0);
  248. c->dwarf.loc[UNW_PPC32_F20] =
  249. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R20, 0);
  250. c->dwarf.loc[UNW_PPC32_F21] =
  251. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R21, 0);
  252. c->dwarf.loc[UNW_PPC32_F22] =
  253. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R22, 0);
  254. c->dwarf.loc[UNW_PPC32_F23] =
  255. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R23, 0);
  256. c->dwarf.loc[UNW_PPC32_F24] =
  257. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R24, 0);
  258. c->dwarf.loc[UNW_PPC32_F25] =
  259. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R25, 0);
  260. c->dwarf.loc[UNW_PPC32_F26] =
  261. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R26, 0);
  262. c->dwarf.loc[UNW_PPC32_F27] =
  263. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R27, 0);
  264. c->dwarf.loc[UNW_PPC32_F28] =
  265. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R28, 0);
  266. c->dwarf.loc[UNW_PPC32_F29] =
  267. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R29, 0);
  268. c->dwarf.loc[UNW_PPC32_F30] =
  269. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R30, 0);
  270. c->dwarf.loc[UNW_PPC32_F31] =
  271. DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R31, 0);
  272. ret = 1;
  273. }
  274. }
  275. return ret;
  276. }