darwin-fallback.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. /* Fallback frame-state unwinder for Darwin.
  2. Copyright (C) 2004-2022 Free Software Foundation, Inc.
  3. This file is part of GCC.
  4. GCC is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3, or (at your option)
  7. any later version.
  8. GCC is distributed in the hope that it will be useful, but WITHOUT
  9. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  11. License for more details.
  12. Under Section 7 of GPL version 3, you are granted additional
  13. permissions described in the GCC Runtime Library Exception, version
  14. 3.1, as published by the Free Software Foundation.
  15. You should have received a copy of the GNU General Public License and
  16. a copy of the GCC Runtime Library Exception along with this program;
  17. see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  18. <http://www.gnu.org/licenses/>. */
  19. #ifdef __ppc__
  20. #include "tconfig.h"
  21. #include "tsystem.h"
  22. #include "coretypes.h"
  23. #include "tm.h"
  24. #include "libgcc_tm.h"
  25. #include "dwarf2.h"
  26. #include "unwind.h"
  27. #include "unwind-dw2.h"
  28. #include <stdint.h>
  29. #include <stdbool.h>
  30. #include <sys/types.h>
  31. #include <signal.h>
  32. #define R_LR 65
  33. #define R_CTR 66
  34. #define R_CR2 70
  35. #define R_XER 76
  36. #define R_VR0 77
  37. #define R_VRSAVE 109
  38. #define R_VSCR 110
  39. #define R_SPEFSCR 112
  40. typedef unsigned long reg_unit;
  41. /* Place in GPRS the parameters to the first 'sc' instruction that would
  42. have been executed if we were returning from this CONTEXT, or
  43. return false if an unexpected instruction is encountered. */
  44. static bool
  45. interpret_libc (reg_unit gprs[32], struct _Unwind_Context *context)
  46. {
  47. uint32_t *pc = (uint32_t *)_Unwind_GetIP (context);
  48. uint32_t cr;
  49. reg_unit lr = (reg_unit) pc;
  50. reg_unit ctr = 0;
  51. uint32_t *invalid_address = NULL;
  52. int i;
  53. for (i = 0; i < 13; i++)
  54. gprs[i] = 1;
  55. gprs[1] = _Unwind_GetCFA (context);
  56. for (; i < 32; i++)
  57. gprs[i] = _Unwind_GetGR (context, i);
  58. cr = _Unwind_GetGR (context, R_CR2);
  59. /* For each supported Libc, we have to track the code flow
  60. all the way back into the kernel.
  61. This code is believed to support all released Libc/Libsystem builds since
  62. Jaguar 6C115, including all the security updates. To be precise,
  63. Libc Libsystem Build(s)
  64. 262~1 60~37 6C115
  65. 262~1 60.2~4 6D52
  66. 262~1 61~3 6F21-6F22
  67. 262~1 63~24 6G30-6G37
  68. 262~1 63~32 6I34-6I35
  69. 262~1 63~64 6L29-6L60
  70. 262.4.1~1 63~84 6L123-6R172
  71. 320~1 71~101 7B85-7D28
  72. 320~1 71~266 7F54-7F56
  73. 320~1 71~288 7F112
  74. 320~1 71~289 7F113
  75. 320.1.3~1 71.1.1~29 7H60-7H105
  76. 320.1.3~1 71.1.1~30 7H110-7H113
  77. 320.1.3~1 71.1.1~31 7H114
  78. That's a big table! It would be insane to try to keep track of
  79. every little detail, so we just read the code itself and do what
  80. it would do.
  81. */
  82. for (;;)
  83. {
  84. uint32_t ins = *pc++;
  85. if ((ins & 0xFC000003) == 0x48000000) /* b instruction */
  86. {
  87. pc += ((((int32_t) ins & 0x3FFFFFC) ^ 0x2000000) - 0x2000004) / 4;
  88. continue;
  89. }
  90. if ((ins & 0xFC600000) == 0x2C000000) /* cmpwi */
  91. {
  92. int32_t val1 = (int16_t) ins;
  93. int32_t val2 = gprs[ins >> 16 & 0x1F];
  94. /* Only beq and bne instructions are supported, so we only
  95. need to set the EQ bit. */
  96. uint32_t mask = 0xF << ((ins >> 21 & 0x1C) ^ 0x1C);
  97. if (val1 == val2)
  98. cr |= mask;
  99. else
  100. cr &= ~mask;
  101. continue;
  102. }
  103. if ((ins & 0xFEC38003) == 0x40820000) /* forwards beq/bne */
  104. {
  105. if ((cr >> ((ins >> 16 & 0x1F) ^ 0x1F) & 1) == (ins >> 24 & 1))
  106. pc += (ins & 0x7FFC) / 4 - 1;
  107. continue;
  108. }
  109. if ((ins & 0xFC0007FF) == 0x7C000378) /* or, including mr */
  110. {
  111. gprs [ins >> 16 & 0x1F] = (gprs [ins >> 11 & 0x1F]
  112. | gprs [ins >> 21 & 0x1F]);
  113. continue;
  114. }
  115. if (ins >> 26 == 0x0E) /* addi, including li */
  116. {
  117. reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
  118. gprs [ins >> 21 & 0x1F] = src + (int16_t) ins;
  119. continue;
  120. }
  121. if (ins >> 26 == 0x0F) /* addis, including lis */
  122. {
  123. reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
  124. gprs [ins >> 21 & 0x1F] = src + ((int16_t) ins << 16);
  125. continue;
  126. }
  127. if (ins >> 26 == 0x20) /* lwz */
  128. {
  129. reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
  130. uint32_t *p = (uint32_t *)(src + (int16_t) ins);
  131. if (p == invalid_address)
  132. return false;
  133. gprs [ins >> 21 & 0x1F] = *p;
  134. continue;
  135. }
  136. if (ins >> 26 == 0x21) /* lwzu */
  137. {
  138. uint32_t *p = (uint32_t *)(gprs [ins >> 16 & 0x1F] += (int16_t) ins);
  139. if (p == invalid_address)
  140. return false;
  141. gprs [ins >> 21 & 0x1F] = *p;
  142. continue;
  143. }
  144. if (ins >> 26 == 0x24) /* stw */
  145. /* What we hope this is doing is '--in_sigtramp'. We don't want
  146. to actually store to memory, so just make a note of the
  147. address and refuse to load from it. */
  148. {
  149. reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
  150. uint32_t *p = (uint32_t *)(src + (int16_t) ins);
  151. if (p == NULL || invalid_address != NULL)
  152. return false;
  153. invalid_address = p;
  154. continue;
  155. }
  156. if (ins >> 26 == 0x2E) /* lmw */
  157. {
  158. reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F];
  159. uint32_t *p = (uint32_t *)(src + (int16_t) ins);
  160. int i;
  161. for (i = (ins >> 21 & 0x1F); i < 32; i++)
  162. {
  163. if (p == invalid_address)
  164. return false;
  165. gprs[i] = *p++;
  166. }
  167. continue;
  168. }
  169. if ((ins & 0xFC1FFFFF) == 0x7c0803a6) /* mtlr */
  170. {
  171. lr = gprs [ins >> 21 & 0x1F];
  172. continue;
  173. }
  174. if ((ins & 0xFC1FFFFF) == 0x7c0802a6) /* mflr */
  175. {
  176. gprs [ins >> 21 & 0x1F] = lr;
  177. continue;
  178. }
  179. if ((ins & 0xFC1FFFFF) == 0x7c0903a6) /* mtctr */
  180. {
  181. ctr = gprs [ins >> 21 & 0x1F];
  182. continue;
  183. }
  184. /* The PowerPC User's Manual says that bit 11 of the mtcrf
  185. instruction is reserved and should be set to zero, but it
  186. looks like the Darwin assembler doesn't do that... */
  187. if ((ins & 0xFC000FFF) == 0x7c000120) /* mtcrf */
  188. {
  189. int i;
  190. uint32_t mask = 0;
  191. for (i = 0; i < 8; i++)
  192. mask |= ((-(ins >> (12 + i) & 1)) & 0xF) << 4 * i;
  193. cr = (cr & ~mask) | (gprs [ins >> 21 & 0x1F] & mask);
  194. continue;
  195. }
  196. if (ins == 0x429f0005) /* bcl- 20,4*cr7+so,.+4, loads pc into LR */
  197. {
  198. lr = (reg_unit) pc;
  199. continue;
  200. }
  201. if (ins == 0x4e800420) /* bctr */
  202. {
  203. pc = (uint32_t *) ctr;
  204. continue;
  205. }
  206. if (ins == 0x44000002) /* sc */
  207. return true;
  208. return false;
  209. }
  210. }
  211. /* We used to include <ucontext.h> and <mach/thread_status.h>,
  212. but they change so much between different Darwin system versions
  213. that it's much easier to just write the structures involved here
  214. directly. */
  215. /* These defines are from the kernel's bsd/dev/ppc/unix_signal.c. */
  216. #define UC_TRAD 1
  217. #define UC_TRAD_VEC 6
  218. #define UC_TRAD64 20
  219. #define UC_TRAD64_VEC 25
  220. #define UC_FLAVOR 30
  221. #define UC_FLAVOR_VEC 35
  222. #define UC_FLAVOR64 40
  223. #define UC_FLAVOR64_VEC 45
  224. #define UC_DUAL 50
  225. #define UC_DUAL_VEC 55
  226. struct gcc_ucontext
  227. {
  228. int onstack;
  229. sigset_t sigmask;
  230. void * stack_sp;
  231. size_t stack_sz;
  232. int stack_flags;
  233. struct gcc_ucontext *link;
  234. size_t mcsize;
  235. struct gcc_mcontext32 *mcontext;
  236. };
  237. struct gcc_float_vector_state
  238. {
  239. double fpregs[32];
  240. uint32_t fpscr_pad;
  241. uint32_t fpscr;
  242. uint32_t save_vr[32][4];
  243. uint32_t save_vscr[4];
  244. };
  245. struct gcc_mcontext32 {
  246. uint32_t dar;
  247. uint32_t dsisr;
  248. uint32_t exception;
  249. uint32_t padding1[5];
  250. uint32_t srr0;
  251. uint32_t srr1;
  252. uint32_t gpr[32];
  253. uint32_t cr;
  254. uint32_t xer;
  255. uint32_t lr;
  256. uint32_t ctr;
  257. uint32_t mq;
  258. uint32_t vrsave;
  259. struct gcc_float_vector_state fvs;
  260. };
  261. /* These are based on /usr/include/ppc/ucontext.h and
  262. /usr/include/mach/ppc/thread_status.h, but rewritten to be more
  263. convenient, to compile on Jaguar, and to work around Radar 3712064
  264. on Panther, which is that the 'es' field of 'struct mcontext64' has
  265. the wrong type (doh!). */
  266. struct gcc_mcontext64 {
  267. uint64_t dar;
  268. uint32_t dsisr;
  269. uint32_t exception;
  270. uint32_t padding1[4];
  271. uint64_t srr0;
  272. uint64_t srr1;
  273. uint32_t gpr[32][2];
  274. uint32_t cr;
  275. uint32_t xer[2]; /* These are arrays because the original structure has them misaligned. */
  276. uint32_t lr[2];
  277. uint32_t ctr[2];
  278. uint32_t vrsave;
  279. struct gcc_float_vector_state fvs;
  280. };
  281. #define UC_FLAVOR_SIZE \
  282. (sizeof (struct gcc_mcontext32) - 33*16)
  283. #define UC_FLAVOR_VEC_SIZE (sizeof (struct gcc_mcontext32))
  284. #define UC_FLAVOR64_SIZE \
  285. (sizeof (struct gcc_mcontext64) - 33*16)
  286. #define UC_FLAVOR64_VEC_SIZE (sizeof (struct gcc_mcontext64))
  287. /* Given GPRS as input to a 'sc' instruction, and OLD_CFA, update FS
  288. to represent the execution of a signal return; or, if not a signal
  289. return, return false. */
  290. static bool
  291. handle_syscall (_Unwind_FrameState *fs, const reg_unit gprs[32],
  292. _Unwind_Ptr old_cfa)
  293. {
  294. struct gcc_ucontext *uctx;
  295. bool is_64, is_vector;
  296. struct gcc_float_vector_state * float_vector_state;
  297. _Unwind_Ptr new_cfa;
  298. int i;
  299. static _Unwind_Ptr return_addr;
  300. /* Yay! We're in a Libc that we understand, and it's made a
  301. system call. In Jaguar, this is a direct system call with value 103;
  302. in Panther and Tiger it is a SYS_syscall call for system call number 184,
  303. and in Leopard it is a direct syscall with number 184. */
  304. if (gprs[0] == 0x67 /* SYS_SIGRETURN */)
  305. {
  306. uctx = (struct gcc_ucontext *) gprs[3];
  307. is_vector = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE
  308. || uctx->mcsize == UC_FLAVOR_VEC_SIZE);
  309. is_64 = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE
  310. || uctx->mcsize == UC_FLAVOR64_SIZE);
  311. }
  312. else if (gprs[0] == 0 /* SYS_syscall */ && gprs[3] == 184)
  313. {
  314. int ctxstyle = gprs[5];
  315. uctx = (struct gcc_ucontext *) gprs[4];
  316. is_vector = (ctxstyle == UC_FLAVOR_VEC || ctxstyle == UC_FLAVOR64_VEC
  317. || ctxstyle == UC_TRAD_VEC || ctxstyle == UC_TRAD64_VEC);
  318. is_64 = (ctxstyle == UC_FLAVOR64_VEC || ctxstyle == UC_TRAD64_VEC
  319. || ctxstyle == UC_FLAVOR64 || ctxstyle == UC_TRAD64);
  320. }
  321. else if (gprs[0] == 184 /* SYS_sigreturn */)
  322. {
  323. int ctxstyle = gprs[4];
  324. uctx = (struct gcc_ucontext *) gprs[3];
  325. is_vector = (ctxstyle == UC_FLAVOR_VEC || ctxstyle == UC_FLAVOR64_VEC
  326. || ctxstyle == UC_TRAD_VEC || ctxstyle == UC_TRAD64_VEC);
  327. is_64 = (ctxstyle == UC_FLAVOR64_VEC || ctxstyle == UC_TRAD64_VEC
  328. || ctxstyle == UC_FLAVOR64 || ctxstyle == UC_TRAD64);
  329. }
  330. else
  331. return false;
  332. #define set_offset(r, addr) \
  333. (fs->regs.reg[r].how = REG_SAVED_OFFSET, \
  334. fs->regs.reg[r].loc.offset = (_Unwind_Ptr)(addr) - new_cfa)
  335. /* Restore even the registers that are not call-saved, since they
  336. might be being used in the prologue to save other registers,
  337. for instance GPR0 is sometimes used to save LR. */
  338. /* Handle the GPRs, and produce the information needed to do the rest. */
  339. if (is_64)
  340. {
  341. /* The context is 64-bit, but it doesn't carry any extra information
  342. for us because only the low 32 bits of the registers are
  343. call-saved. */
  344. struct gcc_mcontext64 *m64 = (struct gcc_mcontext64 *)uctx->mcontext;
  345. int i;
  346. float_vector_state = &m64->fvs;
  347. new_cfa = m64->gpr[1][1];
  348. set_offset (R_CR2, &m64->cr);
  349. for (i = 0; i < 32; i++)
  350. set_offset (i, m64->gpr[i] + 1);
  351. set_offset (R_XER, m64->xer + 1);
  352. set_offset (R_LR, m64->lr + 1);
  353. set_offset (R_CTR, m64->ctr + 1);
  354. if (is_vector)
  355. set_offset (R_VRSAVE, &m64->vrsave);
  356. /* Sometimes, srr0 points to the instruction that caused the exception,
  357. and sometimes to the next instruction to be executed; we want
  358. the latter. */
  359. if (m64->exception == 3 || m64->exception == 4
  360. || m64->exception == 6
  361. || (m64->exception == 7 && !(m64->srr1 & 0x10000)))
  362. return_addr = m64->srr0 + 4;
  363. else
  364. return_addr = m64->srr0;
  365. }
  366. else
  367. {
  368. struct gcc_mcontext32 *m = uctx->mcontext;
  369. int i;
  370. float_vector_state = &m->fvs;
  371. new_cfa = m->gpr[1];
  372. set_offset (R_CR2, &m->cr);
  373. for (i = 0; i < 32; i++)
  374. set_offset (i, m->gpr + i);
  375. set_offset (R_XER, &m->xer);
  376. set_offset (R_LR, &m->lr);
  377. set_offset (R_CTR, &m->ctr);
  378. if (is_vector)
  379. set_offset (R_VRSAVE, &m->vrsave);
  380. /* Sometimes, srr0 points to the instruction that caused the exception,
  381. and sometimes to the next instruction to be executed; we want
  382. the latter. */
  383. if (m->exception == 3 || m->exception == 4
  384. || m->exception == 6
  385. || (m->exception == 7 && !(m->srr1 & 0x10000)))
  386. return_addr = m->srr0 + 4;
  387. else
  388. return_addr = m->srr0;
  389. }
  390. fs->regs.cfa_how = CFA_REG_OFFSET;
  391. fs->regs.cfa_reg = __LIBGCC_STACK_POINTER_REGNUM__;
  392. fs->regs.cfa_offset = new_cfa - old_cfa;;
  393. /* The choice of column for the return address is somewhat tricky.
  394. Fortunately, the actual choice is private to this file, and
  395. the space it's reserved from is the GCC register space, not the
  396. DWARF2 numbering. So any free element of the right size is an OK
  397. choice. Thus: */
  398. fs->retaddr_column = ARG_POINTER_REGNUM;
  399. /* FIXME: this should really be done using a DWARF2 location expression,
  400. not using a static variable. In fact, this entire file should
  401. be implemented in DWARF2 expressions. */
  402. set_offset (ARG_POINTER_REGNUM, &return_addr);
  403. for (i = 0; i < 32; i++)
  404. set_offset (32 + i, float_vector_state->fpregs + i);
  405. set_offset (R_SPEFSCR, &float_vector_state->fpscr);
  406. if (is_vector)
  407. {
  408. for (i = 0; i < 32; i++)
  409. set_offset (R_VR0 + i, float_vector_state->save_vr + i);
  410. set_offset (R_VSCR, float_vector_state->save_vscr);
  411. }
  412. return true;
  413. }
  414. /* This is also prototyped in rs6000/darwin.h, inside the
  415. MD_FALLBACK_FRAME_STATE_FOR macro. */
  416. extern bool _Unwind_fallback_frame_state_for (struct _Unwind_Context *context,
  417. _Unwind_FrameState *fs);
  418. /* Implement the MD_FALLBACK_FRAME_STATE_FOR macro,
  419. returning true iff the frame was a sigreturn() frame that we
  420. can understand. */
  421. bool
  422. _Unwind_fallback_frame_state_for (struct _Unwind_Context *context,
  423. _Unwind_FrameState *fs)
  424. {
  425. reg_unit gprs[32];
  426. if (!interpret_libc (gprs, context))
  427. return false;
  428. return handle_syscall (fs, gprs, _Unwind_GetCFA (context));
  429. }
  430. #endif