linux-unwind.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /* DWARF2 EH unwinding support for MIPS Linux.
  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
  5. it 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,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public 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. #ifndef inhibit_libc
  20. /* Do code reading to identify a signal frame, and set the frame
  21. state data appropriately. See unwind-dw2.c for the structs. */
  22. #include <signal.h>
  23. #include <sys/syscall.h>
  24. /* The third parameter to the signal handler points to something with
  25. * this structure defined in asm/ucontext.h, but the name clashes with
  26. * struct ucontext from sys/ucontext.h so this private copy is used. */
  27. typedef struct _sig_ucontext {
  28. unsigned long uc_flags;
  29. struct _sig_ucontext *uc_link;
  30. stack_t uc_stack;
  31. struct sigcontext uc_mcontext;
  32. sigset_t uc_sigmask;
  33. } _sig_ucontext_t;
  34. #define MD_FALLBACK_FRAME_STATE_FOR mips_fallback_frame_state
  35. static _Unwind_Reason_Code
  36. mips_fallback_frame_state (struct _Unwind_Context *context,
  37. _Unwind_FrameState *fs)
  38. {
  39. u_int32_t *pc = (u_int32_t *) context->ra;
  40. struct sigcontext *sc;
  41. _Unwind_Ptr new_cfa, reg_offset;
  42. int i;
  43. /* A MIPS16 or microMIPS frame. Signal frames always use the standard
  44. ISA encoding. */
  45. if ((_Unwind_Ptr) pc & 3)
  46. return _URC_END_OF_STACK;
  47. /* 24021061 li v0, 0x1061 (rt_sigreturn)*/
  48. /* 0000000c syscall */
  49. /* or */
  50. /* 24021017 li v0, 0x1017 (sigreturn) */
  51. /* 0000000c syscall */
  52. if (pc[1] != 0x0000000c)
  53. return _URC_END_OF_STACK;
  54. #if _MIPS_SIM == _ABIO32
  55. if (pc[0] == (0x24020000 | __NR_sigreturn))
  56. {
  57. struct sigframe {
  58. u_int32_t ass[4]; /* Argument save space for o32. */
  59. u_int32_t trampoline[2];
  60. struct sigcontext sigctx;
  61. } *rt_ = context->cfa;
  62. sc = &rt_->sigctx;
  63. }
  64. else
  65. #endif
  66. if (pc[0] == (0x24020000 | __NR_rt_sigreturn))
  67. {
  68. struct rt_sigframe {
  69. u_int32_t ass[4]; /* Argument save space for o32. */
  70. u_int32_t trampoline[2];
  71. siginfo_t info;
  72. _sig_ucontext_t uc;
  73. } *rt_ = context->cfa;
  74. sc = &rt_->uc.uc_mcontext;
  75. }
  76. else
  77. return _URC_END_OF_STACK;
  78. new_cfa = (_Unwind_Ptr) sc;
  79. fs->regs.cfa_how = CFA_REG_OFFSET;
  80. fs->regs.cfa_reg = __LIBGCC_STACK_POINTER_REGNUM__;
  81. fs->regs.cfa_offset = new_cfa - (_Unwind_Ptr) context->cfa;
  82. /* On o32 Linux, the register save slots in the sigcontext are
  83. eight bytes. We need the lower half of each register slot,
  84. so slide our view of the structure back four bytes. */
  85. #if _MIPS_SIM == _ABIO32 && defined __MIPSEB__
  86. reg_offset = 4;
  87. #else
  88. reg_offset = 0;
  89. #endif
  90. for (i = 0; i < 32; i++) {
  91. fs->regs.reg[i].how = REG_SAVED_OFFSET;
  92. fs->regs.reg[i].loc.offset
  93. = (_Unwind_Ptr)&(sc->sc_regs[i]) + reg_offset - new_cfa;
  94. }
  95. /* "PC & -2" points to the faulting instruction, but the unwind code
  96. searches for "(ADDR & -2) - 1". (See MASK_RETURN_ADDR for the source
  97. of the -2 mask.) Adding 2 here ensures that "(ADDR & -2) - 1" is the
  98. address of the second byte of the faulting instruction.
  99. Note that setting fs->signal_frame would not work. As the comment
  100. above MASK_RETURN_ADDR explains, MIPS unwinders must earch for an
  101. odd-valued address. */
  102. fs->regs.reg[__LIBGCC_DWARF_ALT_FRAME_RETURN_COLUMN__].how
  103. = REG_SAVED_VAL_OFFSET;
  104. fs->regs.reg[__LIBGCC_DWARF_ALT_FRAME_RETURN_COLUMN__].loc.offset
  105. = (_Unwind_Ptr)(sc->sc_pc) + 2 - new_cfa;
  106. fs->retaddr_column = __LIBGCC_DWARF_ALT_FRAME_RETURN_COLUMN__;
  107. return _URC_NO_REASON;
  108. }
  109. #endif