コード例 #1
0
ファイル: Gos-freebsd.c プロジェクト: JeoYaoxiao/libunwind
PROTECTED int
unw_handle_signal_frame (unw_cursor_t *cursor)
{
  struct cursor *c = (struct cursor *) cursor;
  unw_word_t ucontext;
  int ret;

  if (c->sigcontext_format == X86_64_SCF_FREEBSD_SIGFRAME)
   {
    ucontext = c->dwarf.cfa + offsetof(struct sigframe, sf_uc);
    c->sigcontext_addr = c->dwarf.cfa;
    Debug(1, "signal frame, skip over trampoline\n");

    struct dwarf_loc rsp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0);
    ret = dwarf_get (&c->dwarf, rsp_loc, &c->dwarf.cfa);
    if (ret < 0)
     {
       Debug (2, "returning %d\n", ret);
       return ret;
     }

    c->dwarf.loc[RAX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RAX, 0);
    c->dwarf.loc[RDX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDX, 0);
    c->dwarf.loc[RCX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RCX, 0);
    c->dwarf.loc[RBX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBX, 0);
    c->dwarf.loc[RSI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSI, 0);
    c->dwarf.loc[RDI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDI, 0);
    c->dwarf.loc[RBP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBP, 0);
    c->dwarf.loc[RSP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0);
    c->dwarf.loc[ R8] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0);
    c->dwarf.loc[ R9] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0);
    c->dwarf.loc[R10] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0);
    c->dwarf.loc[R11] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0);
    c->dwarf.loc[R12] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0);
    c->dwarf.loc[R13] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0);
    c->dwarf.loc[R14] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0);
    c->dwarf.loc[R15] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0);
    c->dwarf.loc[RIP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RIP, 0);

    return 0;
   }
コード例 #2
0
ファイル: Gstep.c プロジェクト: 0-T-0/linux-sgx
PROTECTED int
unw_step (unw_cursor_t *cursor)
{
  struct cursor *c = (struct cursor *) cursor;
  int ret = -UNW_EUNSPEC;

  Debug (1, "(cursor=%p)\n", c);

  /* Check if this is a signal frame. */
  if (unw_is_signal_frame (cursor))
     return unw_handle_signal_frame (cursor);

#ifdef CONFIG_DEBUG_FRAME
  /* First, try DWARF-based unwinding. */
  if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF))
    {
      ret = dwarf_step (&c->dwarf);
      Debug(1, "dwarf_step()=%d\n", ret);

      if (likely (ret > 0))
	return 1;
      else if (unlikely (ret == -UNW_ESTOPUNWIND))
	return ret;

    if (ret < 0 && ret != -UNW_ENOINFO)
      {
        Debug (2, "returning %d\n", ret);
        return ret;
      }
    }
#endif /* CONFIG_DEBUG_FRAME */

  /* Next, try extbl-based unwinding. */
  if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX))
    {
      ret = arm_exidx_step (c);
      if (ret > 0)
	return 1;
      if (ret == -UNW_ESTOPUNWIND || ret == 0)
	return ret;
    }

  /* Fall back on APCS frame parsing.
     Note: This won't work in case the ARM EABI is used. */
  if (unlikely (ret < 0))
    {
      if (UNW_TRY_METHOD(UNW_ARM_METHOD_FRAME))
        {
          ret = UNW_ESUCCESS;
          /* DWARF unwinding failed, try to follow APCS/optimized APCS frame chain */
          unw_word_t instr, i;
          Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret);
          dwarf_loc_t ip_loc, fp_loc;
          unw_word_t frame;
          /* Mark all registers unsaved, since we don't know where
             they are saved (if at all), except for the EBP and
             EIP.  */
          if (dwarf_get(&c->dwarf, c->dwarf.loc[UNW_ARM_R11], &frame) < 0)
            {
              return 0;
            }
          for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) {
            c->dwarf.loc[i] = DWARF_NULL_LOC;
          }
          if (frame)
            {
              if (dwarf_get(&c->dwarf, DWARF_LOC(frame, 0), &instr) < 0)
                {
                  return 0;
                }
              instr -= 8;
              if (dwarf_get(&c->dwarf, DWARF_LOC(instr, 0), &instr) < 0)
                {
                  return 0;
                }
              if ((instr & 0xFFFFD800) == 0xE92DD800)
                {
                  /* Standard APCS frame. */
                  ip_loc = DWARF_LOC(frame - 4, 0);
                  fp_loc = DWARF_LOC(frame - 12, 0);
                }
              else
                {
                  /* Codesourcery optimized normal frame. */
                  ip_loc = DWARF_LOC(frame, 0);
                  fp_loc = DWARF_LOC(frame - 4, 0);
                }
              if (dwarf_get(&c->dwarf, ip_loc, &c->dwarf.ip) < 0)
                {
                  return 0;
                }
              c->dwarf.loc[UNW_ARM_R12] = ip_loc;
              c->dwarf.loc[UNW_ARM_R11] = fp_loc;
              Debug(15, "ip=%lx\n", c->dwarf.ip);
            }
          else
            {
              ret = -UNW_ENOINFO;
            }
        }
    }
  return ret == -UNW_ENOINFO ? 0 : 1;
}
コード例 #3
0
ファイル: Gstep.c プロジェクト: 0-T-0/linux-sgx
PROTECTED int
unw_handle_signal_frame (unw_cursor_t *cursor)
{
  struct cursor *c = (struct cursor *) cursor;
  int ret;
  unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa;
  struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0);

  if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0)
    return -UNW_EUNSPEC;

  /* Obtain signal frame type (non-RT or RT). */
  ret = unw_is_signal_frame (cursor);

  /* Save the SP and PC to be able to return execution at this point
     later in time (unw_resume).  */
  c->sigcontext_sp = c->dwarf.cfa;
  c->sigcontext_pc = c->dwarf.ip;

  /* Since kernel version 2.6.18 the non-RT signal frame starts with a
     ucontext while the RT signal frame starts with a siginfo, followed
     by a sigframe whose first element is an ucontext.
     Prior 2.6.18 the non-RT signal frame starts with a sigcontext while
     the RT signal frame starts with two pointers followed by a siginfo
     and an ucontext. The first pointer points to the start of the siginfo
     structure and the second one to the ucontext structure.  */

  if (ret == 1)
    {
      /* Handle non-RT signal frames. Check if the first word on the stack
	 is the magic number.  */
      if (sp == 0x5ac3c35a)
	{
	  c->sigcontext_format = ARM_SCF_LINUX_SIGFRAME;
	  sc_addr = sp_addr + LINUX_UC_MCONTEXT_OFF;
	}
      else
	{
	  c->sigcontext_format = ARM_SCF_LINUX_OLD_SIGFRAME;
	  sc_addr = sp_addr;
	}
      c->sigcontext_addr = sp_addr;
    }
  else if (ret == 2)
    {
      /* Handle RT signal frames. Check if the first word on the stack is a
	 pointer to the siginfo structure.  */
      if (sp == sp_addr + 8)
	{
	  c->sigcontext_format = ARM_SCF_LINUX_OLD_RT_SIGFRAME;
	  c->sigcontext_addr = sp_addr + 8 + sizeof (siginfo_t); 
	}
      else
	{
	  c->sigcontext_format = ARM_SCF_LINUX_RT_SIGFRAME;
	  c->sigcontext_addr = sp_addr + sizeof (siginfo_t);
	}
      sc_addr = c->sigcontext_addr + LINUX_UC_MCONTEXT_OFF;
    }
  else
    return -UNW_EUNSPEC;

  /* Update the dwarf cursor.
     Set the location of the registers to the corresponding addresses of the
     uc_mcontext / sigcontext structure contents.  */
  c->dwarf.loc[UNW_ARM_R0] = DWARF_LOC (sc_addr + LINUX_SC_R0_OFF, 0);
  c->dwarf.loc[UNW_ARM_R1] = DWARF_LOC (sc_addr + LINUX_SC_R1_OFF, 0);
  c->dwarf.loc[UNW_ARM_R2] = DWARF_LOC (sc_addr + LINUX_SC_R2_OFF, 0);
  c->dwarf.loc[UNW_ARM_R3] = DWARF_LOC (sc_addr + LINUX_SC_R3_OFF, 0);
  c->dwarf.loc[UNW_ARM_R4] = DWARF_LOC (sc_addr + LINUX_SC_R4_OFF, 0);
  c->dwarf.loc[UNW_ARM_R5] = DWARF_LOC (sc_addr + LINUX_SC_R5_OFF, 0);
  c->dwarf.loc[UNW_ARM_R6] = DWARF_LOC (sc_addr + LINUX_SC_R6_OFF, 0);
  c->dwarf.loc[UNW_ARM_R7] = DWARF_LOC (sc_addr + LINUX_SC_R7_OFF, 0);
  c->dwarf.loc[UNW_ARM_R8] = DWARF_LOC (sc_addr + LINUX_SC_R8_OFF, 0);
  c->dwarf.loc[UNW_ARM_R9] = DWARF_LOC (sc_addr + LINUX_SC_R9_OFF, 0);
  c->dwarf.loc[UNW_ARM_R10] = DWARF_LOC (sc_addr + LINUX_SC_R10_OFF, 0);
  c->dwarf.loc[UNW_ARM_R11] = DWARF_LOC (sc_addr + LINUX_SC_FP_OFF, 0);
  c->dwarf.loc[UNW_ARM_R12] = DWARF_LOC (sc_addr + LINUX_SC_IP_OFF, 0);
  c->dwarf.loc[UNW_ARM_R13] = DWARF_LOC (sc_addr + LINUX_SC_SP_OFF, 0);
  c->dwarf.loc[UNW_ARM_R14] = DWARF_LOC (sc_addr + LINUX_SC_LR_OFF, 0);
  c->dwarf.loc[UNW_ARM_R15] = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0);

  /* Set SP/CFA and PC/IP.  */
  dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R13], &c->dwarf.cfa);
  dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R15], &c->dwarf.ip);

  return 1;
}
コード例 #4
0
ファイル: Gstep.c プロジェクト: chenqiangzhishen/linux-sgx
PROTECTED int
unw_step (unw_cursor_t * cursor)
{
    struct cursor *c = (struct cursor *) cursor;
    stack_frame_t dummy;
    unw_word_t back_chain_offset, lr_save_offset, v_regs_ptr;
    struct dwarf_loc back_chain_loc, lr_save_loc, sp_loc, ip_loc, v_regs_loc;
    int ret;

    Debug (1, "(cursor=%p, ip=0x%016lx)\n", c, (unsigned long) c->dwarf.ip);

    if (c->dwarf.ip == 0)
    {
        /* Unless the cursor or stack is corrupt or uninitialized,
           we've most likely hit the top of the stack */
        return 0;
    }

    /* Try DWARF-based unwinding... */

    ret = dwarf_step (&c->dwarf);

    if (ret < 0 && ret != -UNW_ENOINFO)
    {
        Debug (2, "returning %d\n", ret);
        return ret;
    }

    if (unlikely (ret < 0))
    {
        if (likely (!unw_is_signal_frame (cursor)))
        {
            /* DWARF unwinding failed.  As of 09/26/2006, gcc in 64-bit mode
               produces the mandatory level of traceback record in the code, but
               I get the impression that this is transitory, that eventually gcc
               will not produce any traceback records at all.  So, for now, we
               won't bother to try to find and use these records.

               We can, however, attempt to unwind the frame by using the callback
               chain.  This is very crude, however, and won't be able to unwind
               any registers besides the IP, SP, and LR . */

            back_chain_offset = ((void *) &dummy.back_chain - (void *) &dummy);
            lr_save_offset = ((void *) &dummy.lr_save - (void *) &dummy);

            back_chain_loc = DWARF_LOC (c->dwarf.cfa + back_chain_offset, 0);

            if ((ret =
                        dwarf_get (&c->dwarf, back_chain_loc, &c->dwarf.cfa)) < 0)
            {
                Debug
                ("Unable to retrieve CFA from back chain in stack frame - %d\n",
                 ret);
                return ret;
            }
            if (c->dwarf.cfa == 0)
                /* Unless the cursor or stack is corrupt or uninitialized we've most
                   likely hit the top of the stack */
                return 0;

            lr_save_loc = DWARF_LOC (c->dwarf.cfa + lr_save_offset, 0);

            if ((ret = dwarf_get (&c->dwarf, lr_save_loc, &c->dwarf.ip)) < 0)
            {
                Debug
                ("Unable to retrieve IP from lr save in stack frame - %d\n",
                 ret);
                return ret;
            }
            ret = 1;
        }
        else
        {
            /* Find the sigcontext record by taking the CFA and adjusting by
               the dummy signal frame size.

               Note that there isn't any way to determined if SA_SIGINFO was
               set in the sa_flags parameter to sigaction when the signal
               handler was established.  If it was not set, the ucontext
               record is not required to be on the stack, in which case the
               following code will likely cause a seg fault or other crash
               condition.  */

            unw_word_t ucontext = c->dwarf.cfa + __SIGNAL_FRAMESIZE;

            Debug (1, "signal frame, skip over trampoline\n");

            c->sigcontext_format = PPC_SCF_LINUX_RT_SIGFRAME;
            c->sigcontext_addr = ucontext;

            sp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0);
            ip_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_NIP, 0);

            ret = dwarf_get (&c->dwarf, sp_loc, &c->dwarf.cfa);
            if (ret < 0)
            {
                Debug (2, "returning %d\n", ret);
                return ret;
            }
            ret = dwarf_get (&c->dwarf, ip_loc, &c->dwarf.ip);
            if (ret < 0)
            {
                Debug (2, "returning %d\n", ret);
                return ret;
            }

            /* Instead of just restoring the non-volatile registers, do all
               of the registers for now.  This will incur a performance hit,
               but it's rare enough not to cause too much of a problem, and
               might be useful in some cases.  */
            c->dwarf.loc[UNW_PPC64_R0] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R0, 0);
            c->dwarf.loc[UNW_PPC64_R1] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R1, 0);
            c->dwarf.loc[UNW_PPC64_R2] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R2, 0);
            c->dwarf.loc[UNW_PPC64_R3] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R3, 0);
            c->dwarf.loc[UNW_PPC64_R4] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R4, 0);
            c->dwarf.loc[UNW_PPC64_R5] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R5, 0);
            c->dwarf.loc[UNW_PPC64_R6] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R6, 0);
            c->dwarf.loc[UNW_PPC64_R7] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R7, 0);
            c->dwarf.loc[UNW_PPC64_R8] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0);
            c->dwarf.loc[UNW_PPC64_R9] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0);
            c->dwarf.loc[UNW_PPC64_R10] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0);
            c->dwarf.loc[UNW_PPC64_R11] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0);
            c->dwarf.loc[UNW_PPC64_R12] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0);
            c->dwarf.loc[UNW_PPC64_R13] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0);
            c->dwarf.loc[UNW_PPC64_R14] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0);
            c->dwarf.loc[UNW_PPC64_R15] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0);
            c->dwarf.loc[UNW_PPC64_R16] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R16, 0);
            c->dwarf.loc[UNW_PPC64_R17] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R17, 0);
            c->dwarf.loc[UNW_PPC64_R18] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R18, 0);
            c->dwarf.loc[UNW_PPC64_R19] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R19, 0);
            c->dwarf.loc[UNW_PPC64_R20] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R20, 0);
            c->dwarf.loc[UNW_PPC64_R21] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R21, 0);
            c->dwarf.loc[UNW_PPC64_R22] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R22, 0);
            c->dwarf.loc[UNW_PPC64_R23] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R23, 0);
            c->dwarf.loc[UNW_PPC64_R24] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R24, 0);
            c->dwarf.loc[UNW_PPC64_R25] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R25, 0);
            c->dwarf.loc[UNW_PPC64_R26] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R26, 0);
            c->dwarf.loc[UNW_PPC64_R27] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R27, 0);
            c->dwarf.loc[UNW_PPC64_R28] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R28, 0);
            c->dwarf.loc[UNW_PPC64_R29] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R29, 0);
            c->dwarf.loc[UNW_PPC64_R30] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R30, 0);
            c->dwarf.loc[UNW_PPC64_R31] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R31, 0);

            c->dwarf.loc[UNW_PPC64_LR] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_LINK, 0);
            c->dwarf.loc[UNW_PPC64_CTR] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CTR, 0);
            /* This CR0 assignment is probably wrong.  There are 8 dwarf columns
               assigned to the CR registers, but only one CR register in the
               mcontext structure */
            c->dwarf.loc[UNW_PPC64_CR0] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_CCR, 0);
            c->dwarf.loc[UNW_PPC64_XER] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_XER, 0);
            c->dwarf.loc[UNW_PPC64_NIP] =
                DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_NIP, 0);

            /* TODO: Is there a way of obtaining the value of the
               pseudo frame pointer (which is sp + some fixed offset, I
               assume), based on the contents of the ucontext record
               structure?  For now, set this loc to null. */
            c->dwarf.loc[UNW_PPC64_FRAME_POINTER] = DWARF_NULL_LOC;

            c->dwarf.loc[UNW_PPC64_F0] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R0, 0);
            c->dwarf.loc[UNW_PPC64_F1] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R1, 0);
            c->dwarf.loc[UNW_PPC64_F2] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R2, 0);
            c->dwarf.loc[UNW_PPC64_F3] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R3, 0);
            c->dwarf.loc[UNW_PPC64_F4] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R4, 0);
            c->dwarf.loc[UNW_PPC64_F5] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R5, 0);
            c->dwarf.loc[UNW_PPC64_F6] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R6, 0);
            c->dwarf.loc[UNW_PPC64_F7] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R7, 0);
            c->dwarf.loc[UNW_PPC64_F8] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R8, 0);
            c->dwarf.loc[UNW_PPC64_F9] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R9, 0);
            c->dwarf.loc[UNW_PPC64_F10] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R10, 0);
            c->dwarf.loc[UNW_PPC64_F11] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R11, 0);
            c->dwarf.loc[UNW_PPC64_F12] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R12, 0);
            c->dwarf.loc[UNW_PPC64_F13] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R13, 0);
            c->dwarf.loc[UNW_PPC64_F14] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R14, 0);
            c->dwarf.loc[UNW_PPC64_F15] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R15, 0);
            c->dwarf.loc[UNW_PPC64_F16] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R16, 0);
            c->dwarf.loc[UNW_PPC64_F17] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R17, 0);
            c->dwarf.loc[UNW_PPC64_F18] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R18, 0);
            c->dwarf.loc[UNW_PPC64_F19] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R19, 0);
            c->dwarf.loc[UNW_PPC64_F20] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R20, 0);
            c->dwarf.loc[UNW_PPC64_F21] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R21, 0);
            c->dwarf.loc[UNW_PPC64_F22] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R22, 0);
            c->dwarf.loc[UNW_PPC64_F23] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R23, 0);
            c->dwarf.loc[UNW_PPC64_F24] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R24, 0);
            c->dwarf.loc[UNW_PPC64_F25] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R25, 0);
            c->dwarf.loc[UNW_PPC64_F26] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R26, 0);
            c->dwarf.loc[UNW_PPC64_F27] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R27, 0);
            c->dwarf.loc[UNW_PPC64_F28] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R28, 0);
            c->dwarf.loc[UNW_PPC64_F29] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R29, 0);
            c->dwarf.loc[UNW_PPC64_F30] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R30, 0);
            c->dwarf.loc[UNW_PPC64_F31] =
                DWARF_LOC (ucontext + UC_MCONTEXT_FREGS_R31, 0);
            /* Note that there is no .eh_section register column for the
               FPSCR register.  I don't know why this is.  */

            v_regs_loc = DWARF_LOC (ucontext + UC_MCONTEXT_V_REGS, 0);
            ret = dwarf_get (&c->dwarf, v_regs_loc, &v_regs_ptr);
            if (ret < 0)
            {
                Debug (2, "returning %d\n", ret);
                return ret;
            }
            if (v_regs_ptr != 0)
            {
                /* The v_regs_ptr is not null.  Set all of the AltiVec locs */

                c->dwarf.loc[UNW_PPC64_V0] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R0, 0);
                c->dwarf.loc[UNW_PPC64_V1] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R1, 0);
                c->dwarf.loc[UNW_PPC64_V2] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R2, 0);
                c->dwarf.loc[UNW_PPC64_V3] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R3, 0);
                c->dwarf.loc[UNW_PPC64_V4] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R4, 0);
                c->dwarf.loc[UNW_PPC64_V5] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R5, 0);
                c->dwarf.loc[UNW_PPC64_V6] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R6, 0);
                c->dwarf.loc[UNW_PPC64_V7] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R7, 0);
                c->dwarf.loc[UNW_PPC64_V8] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R8, 0);
                c->dwarf.loc[UNW_PPC64_V9] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R9, 0);
                c->dwarf.loc[UNW_PPC64_V10] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R10, 0);
                c->dwarf.loc[UNW_PPC64_V11] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R11, 0);
                c->dwarf.loc[UNW_PPC64_V12] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R12, 0);
                c->dwarf.loc[UNW_PPC64_V13] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R13, 0);
                c->dwarf.loc[UNW_PPC64_V14] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R14, 0);
                c->dwarf.loc[UNW_PPC64_V15] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R15, 0);
                c->dwarf.loc[UNW_PPC64_V16] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R16, 0);
                c->dwarf.loc[UNW_PPC64_V17] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R17, 0);
                c->dwarf.loc[UNW_PPC64_V18] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R18, 0);
                c->dwarf.loc[UNW_PPC64_V19] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R19, 0);
                c->dwarf.loc[UNW_PPC64_V20] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R20, 0);
                c->dwarf.loc[UNW_PPC64_V21] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R21, 0);
                c->dwarf.loc[UNW_PPC64_V22] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R22, 0);
                c->dwarf.loc[UNW_PPC64_V23] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R23, 0);
                c->dwarf.loc[UNW_PPC64_V24] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R24, 0);
                c->dwarf.loc[UNW_PPC64_V25] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R25, 0);
                c->dwarf.loc[UNW_PPC64_V26] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R26, 0);
                c->dwarf.loc[UNW_PPC64_V27] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R27, 0);
                c->dwarf.loc[UNW_PPC64_V28] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R28, 0);
                c->dwarf.loc[UNW_PPC64_V29] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R29, 0);
                c->dwarf.loc[UNW_PPC64_V30] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R30, 0);
                c->dwarf.loc[UNW_PPC64_V31] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_R31, 0);
                c->dwarf.loc[UNW_PPC64_VRSAVE] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_VRSAVE, 0);
                c->dwarf.loc[UNW_PPC64_VSCR] =
                    DWARF_LOC (v_regs_ptr + UC_MCONTEXT_VREGS_VSCR, 0);
            }
            else
            {
                c->dwarf.loc[UNW_PPC64_V0] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V1] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V2] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V3] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V4] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V5] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V6] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V7] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V8] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V9] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V10] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V11] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V12] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V13] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V14] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V15] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V16] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V17] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V18] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V19] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V20] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V21] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V22] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V23] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V24] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V25] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V26] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V27] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V28] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V29] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V30] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_V31] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_VRSAVE] = DWARF_NULL_LOC;
                c->dwarf.loc[UNW_PPC64_VSCR] = DWARF_NULL_LOC;
            }
            ret = 1;
        }
    }
    return ret;
}
コード例 #5
0
ファイル: Gstep.c プロジェクト: Daft-Freak/vogl
PROTECTED int
unw_handle_signal_frame (unw_cursor_t *cursor)
{
  struct cursor *c = (struct cursor *) cursor;
  int ret;
  unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa;
  struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0);

  if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0)
    return -UNW_EUNSPEC;

  ret = unw_is_signal_frame (cursor);
  Debug(1, "unw_is_signal_frame()=%d\n", ret);

  /* Save the SP and PC to be able to return execution at this point
     later in time (unw_resume).  */
  c->sigcontext_sp = c->dwarf.cfa;
  c->sigcontext_pc = c->dwarf.ip;

  if (ret)
    {
      c->sigcontext_format = AARCH64_SCF_LINUX_RT_SIGFRAME;
      sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF;
    }
  else
    return -UNW_EUNSPEC;

  c->sigcontext_addr = sc_addr;

  /* Update the dwarf cursor.
     Set the location of the registers to the corresponding addresses of the
     uc_mcontext / sigcontext structure contents.  */
  c->dwarf.loc[UNW_AARCH64_X0]  = DWARF_LOC (sc_addr + LINUX_SC_X0_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X1]  = DWARF_LOC (sc_addr + LINUX_SC_X1_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X2]  = DWARF_LOC (sc_addr + LINUX_SC_X2_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X3]  = DWARF_LOC (sc_addr + LINUX_SC_X3_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X4]  = DWARF_LOC (sc_addr + LINUX_SC_X4_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X5]  = DWARF_LOC (sc_addr + LINUX_SC_X5_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X6]  = DWARF_LOC (sc_addr + LINUX_SC_X6_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X7]  = DWARF_LOC (sc_addr + LINUX_SC_X7_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X8]  = DWARF_LOC (sc_addr + LINUX_SC_X8_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X9]  = DWARF_LOC (sc_addr + LINUX_SC_X9_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X10] = DWARF_LOC (sc_addr + LINUX_SC_X10_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X11] = DWARF_LOC (sc_addr + LINUX_SC_X11_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X12] = DWARF_LOC (sc_addr + LINUX_SC_X12_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X13] = DWARF_LOC (sc_addr + LINUX_SC_X13_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X14] = DWARF_LOC (sc_addr + LINUX_SC_X14_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X15] = DWARF_LOC (sc_addr + LINUX_SC_X15_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X16] = DWARF_LOC (sc_addr + LINUX_SC_X16_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X17] = DWARF_LOC (sc_addr + LINUX_SC_X17_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X18] = DWARF_LOC (sc_addr + LINUX_SC_X18_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X19] = DWARF_LOC (sc_addr + LINUX_SC_X19_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X20] = DWARF_LOC (sc_addr + LINUX_SC_X20_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X21] = DWARF_LOC (sc_addr + LINUX_SC_X21_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X22] = DWARF_LOC (sc_addr + LINUX_SC_X22_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X23] = DWARF_LOC (sc_addr + LINUX_SC_X23_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X24] = DWARF_LOC (sc_addr + LINUX_SC_X24_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X25] = DWARF_LOC (sc_addr + LINUX_SC_X25_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X26] = DWARF_LOC (sc_addr + LINUX_SC_X26_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X27] = DWARF_LOC (sc_addr + LINUX_SC_X27_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X28] = DWARF_LOC (sc_addr + LINUX_SC_X28_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X29] = DWARF_LOC (sc_addr + LINUX_SC_X29_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_X30] = DWARF_LOC (sc_addr + LINUX_SC_X30_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_SP]  = DWARF_LOC (sc_addr + LINUX_SC_SP_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_PC]  = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0);
  c->dwarf.loc[UNW_AARCH64_PSTATE]  = DWARF_LOC (sc_addr + LINUX_SC_PSTATE_OFF, 0);

  /* Set SP/CFA and PC/IP.  */
  dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_SP], &c->dwarf.cfa);
  dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_PC], &c->dwarf.ip);

  c->dwarf.pi_valid = 0;

  return 1;
}
コード例 #6
0
ファイル: Gstep.c プロジェクト: 0-T-0/linux-sgx
PROTECTED int
unw_step (unw_cursor_t *cursor)
{
  struct cursor *c = (struct cursor *) cursor;
  int ret, i;

  Debug (1, "(cursor=%p, ip=0x%08x)\n", c, (unsigned) c->dwarf.ip);

  /* Try DWARF-based unwinding... */
  ret = dwarf_step (&c->dwarf);

  if (ret < 0 && ret != -UNW_ENOINFO)
    {
      Debug (2, "returning %d\n", ret);
      return ret;
    }

  if (unlikely (ret < 0))
    {
      /* DWARF failed, let's see if we can follow the frame-chain
	 or skip over the signal trampoline.  */
      struct dwarf_loc ebp_loc, eip_loc;

      /* We could get here because of missing/bad unwind information.
         Validate all addresses before dereferencing. */
      c->validate = 1;

      Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret);

      if (unw_is_signal_frame (cursor))
        {
          ret = unw_handle_signal_frame(cursor);
	  if (ret < 0)
	    {
	      Debug (2, "returning 0\n");
	      return 0;
	    }
        }
      else
	{
	  ret = dwarf_get (&c->dwarf, c->dwarf.loc[EBP], &c->dwarf.cfa);
	  if (ret < 0)
	    {
	      Debug (2, "returning %d\n", ret);
	      return ret;
	    }

	  Debug (13, "[EBP=0x%x] = 0x%x\n", DWARF_GET_LOC (c->dwarf.loc[EBP]),
		 c->dwarf.cfa);

	  ebp_loc = DWARF_LOC (c->dwarf.cfa, 0);
	  eip_loc = DWARF_LOC (c->dwarf.cfa + 4, 0);
	  c->dwarf.cfa += 8;

	  /* Mark all registers unsaved, since we don't know where
	     they are saved (if at all), except for the EBP and
	     EIP.  */
	  for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
	    c->dwarf.loc[i] = DWARF_NULL_LOC;

          c->dwarf.loc[EBP] = ebp_loc;
          c->dwarf.loc[EIP] = eip_loc;
	}
      c->dwarf.ret_addr_column = EIP;

      if (!DWARF_IS_NULL_LOC (c->dwarf.loc[EBP]))
	{
	  ret = dwarf_get (&c->dwarf, c->dwarf.loc[EIP], &c->dwarf.ip);
	  if (ret < 0)
	    {
	      Debug (13, "dwarf_get([EIP=0x%x]) failed\n", DWARF_GET_LOC (c->dwarf.loc[EIP]));
	      Debug (2, "returning %d\n", ret);
	      return ret;
	    }
	  else
	    {
	      Debug (13, "[EIP=0x%x] = 0x%x\n", DWARF_GET_LOC (c->dwarf.loc[EIP]),
		c->dwarf.ip);
	    }
	}
      else
	c->dwarf.ip = 0;
    }
  ret = (c->dwarf.ip == 0) ? 0 : 1;
  Debug (2, "returning %d\n", ret);
  return ret;
}
PROTECTED int
unw_step (unw_cursor_t *cursor)
{
  struct cursor *c = (struct cursor *) cursor;
  int ret, i;

  Debug (1, "(cursor=%p, ip=0x%08x)\n", c, (unsigned) c->dwarf.ip);

  /* ANDROID support update. */
  /* Save the current ip/cfa to prevent looping if the decode yields
     the same ip/cfa as before. */
  unw_word_t old_ip = c->dwarf.ip;
  unw_word_t old_cfa = c->dwarf.cfa;
  /* End of ANDROID update. */

  /* Try DWARF-based unwinding... */
  ret = dwarf_step (&c->dwarf);

#if !defined(UNW_LOCAL_ONLY)
  /* Do not use this method on a local unwind. There is a very high
   * probability this method will try to access unmapped memory, which
   * will crash the process. Since this almost never actually works,
   * it should be okay to skip.
   */
  if (ret < 0)
    {
      /* DWARF failed, let's see if we can follow the frame-chain
	 or skip over the signal trampoline.  */
      struct dwarf_loc ebp_loc, eip_loc;

      /* We could get here because of missing/bad unwind information.
         Validate all addresses before dereferencing. */
      c->validate = 1;

      Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret);

      if (unw_is_signal_frame (cursor))
        {
          ret = unw_handle_signal_frame(cursor);
	  if (ret < 0)
	    {
	      Debug (2, "returning 0\n");
	      return 0;
	    }
        }
      else
	{
	  ret = dwarf_get (&c->dwarf, c->dwarf.loc[EBP], &c->dwarf.cfa);
	  if (ret < 0)
	    {
	      Debug (2, "returning %d\n", ret);
	      return ret;
	    }

	  Debug (13, "[EBP=0x%x] = 0x%x\n", DWARF_GET_LOC (c->dwarf.loc[EBP]),
		 c->dwarf.cfa);

	  ebp_loc = DWARF_LOC (c->dwarf.cfa, 0);
	  eip_loc = DWARF_LOC (c->dwarf.cfa + 4, 0);
	  c->dwarf.cfa += 8;

	  /* Mark all registers unsaved, since we don't know where
	     they are saved (if at all), except for the EBP and
	     EIP.  */
	  for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
	    c->dwarf.loc[i] = DWARF_NULL_LOC;

          c->dwarf.loc[EBP] = ebp_loc;
          c->dwarf.loc[EIP] = eip_loc;
	}
      c->dwarf.ret_addr_column = EIP;

      if (!DWARF_IS_NULL_LOC (c->dwarf.loc[EBP]))
	{
	  ret = dwarf_get (&c->dwarf, c->dwarf.loc[EIP], &c->dwarf.ip);
	  if (ret < 0)
	    {
	      Debug (13, "dwarf_get([EIP=0x%x]) failed\n", DWARF_GET_LOC (c->dwarf.loc[EIP]));
	      Debug (2, "returning %d\n", ret);
	      return ret;
	    }
	  else
	    {
	      Debug (13, "[EIP=0x%x] = 0x%x\n", DWARF_GET_LOC (c->dwarf.loc[EIP]),
		c->dwarf.ip);
	    }
	}
      else
	c->dwarf.ip = 0;
    }
#endif

  /* ANDROID support update. */
  if (ret >= 0)
    {
      if (c->dwarf.ip)
        {
          /* Adjust the pc to the instruction before. */
          c->dwarf.ip--;
        }
      /* If the decode yields the exact same ip/cfa as before, then indicate
         the unwind is complete. */
      if (old_ip == c->dwarf.ip && old_cfa == c->dwarf.cfa)
        {
          Dprintf ("%s: ip and cfa unchanged; stopping here (ip=0x%lx)\n",
                   __FUNCTION__, (long) c->dwarf.ip);
          return -UNW_EBADFRAME;
        }
      c->dwarf.frame++;
    }
  /* End of ANDROID update. */
  if (unlikely (ret <= 0))
    return 0;

  return (c->dwarf.ip == 0) ? 0 : 1;
}
コード例 #8
0
ファイル: Gos-freebsd.c プロジェクト: AmirAbrams/haiku
PROTECTED int
unw_handle_signal_frame (unw_cursor_t *cursor)
{
  struct cursor *c = (struct cursor *) cursor;
  int ret;

  if (c->sigcontext_format == X86_SCF_FREEBSD_SIGFRAME) {
    struct sigframe *sf;
    uintptr_t uc_addr;
    struct dwarf_loc esp_loc;

    sf = (struct sigframe *)c->dwarf.cfa;
    uc_addr = (uintptr_t)&(sf->sf_uc);
    c->sigcontext_addr = c->dwarf.cfa;

    esp_loc = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ESP_OFF, 0);
    ret = dwarf_get (&c->dwarf, esp_loc, &c->dwarf.cfa);
    if (ret < 0)
    {
            Debug (2, "returning 0\n");
            return 0;
    }

    c->dwarf.loc[EIP] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EIP_OFF, 0);
    c->dwarf.loc[ESP] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ESP_OFF, 0);
    c->dwarf.loc[EAX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EAX_OFF, 0);
    c->dwarf.loc[ECX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ECX_OFF, 0);
    c->dwarf.loc[EDX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EDX_OFF, 0);
    c->dwarf.loc[EBX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EBX_OFF, 0);
    c->dwarf.loc[EBP] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EBP_OFF, 0);
    c->dwarf.loc[ESI] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ESI_OFF, 0);
    c->dwarf.loc[EDI] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EDI_OFF, 0);
    c->dwarf.loc[EFLAGS] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EFLAGS_OFF, 0);
    c->dwarf.loc[TRAPNO] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_TRAPNO_OFF, 0);
    c->dwarf.loc[ST0] = DWARF_NULL_LOC;
  } else if (c->sigcontext_format == X86_SCF_FREEBSD_SYSCALL) {
    c->dwarf.loc[EIP] = DWARF_LOC (c->dwarf.cfa, 0);
    c->dwarf.loc[EAX] = DWARF_NULL_LOC;
    c->dwarf.cfa += 4;
    c->dwarf.use_prev_instr = 1;
  } else {
    Debug (8, "Gstep: not handling frame format %d\n", c->sigcontext_format);
    abort();
  }
  return 0;
}
コード例 #9
0
ファイル: Gstep.c プロジェクト: A-And/coreclr
static int
mips_handle_signal_frame (unw_cursor_t *cursor)
{
  struct cursor *c = (struct cursor *) cursor;
  unw_word_t sc_addr, sp_addr = c->dwarf.cfa;
  unw_word_t ra, fp;
  int ret;

  switch (unw_is_signal_frame (cursor)) {
  case 1:
    sc_addr = sp_addr + LINUX_SF_TRAMP_SIZE + sizeof (siginfo_t) +
              LINUX_UC_MCONTEXT_OFF;
    break;
  case 2:
    sc_addr = sp_addr + LINUX_UC_MCONTEXT_OFF;
    break;
  default:
    return -UNW_EUNSPEC;
  }

  if (tdep_big_endian(c->dwarf.as))
    sc_addr += 4;

  c->sigcontext_addr = sc_addr;

  /* Update the dwarf cursor. */
  c->dwarf.loc[UNW_MIPS_R0]  = DWARF_LOC (sc_addr + LINUX_SC_R0_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R1]  = DWARF_LOC (sc_addr + LINUX_SC_R1_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R2]  = DWARF_LOC (sc_addr + LINUX_SC_R2_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R3]  = DWARF_LOC (sc_addr + LINUX_SC_R3_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R4]  = DWARF_LOC (sc_addr + LINUX_SC_R4_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R5]  = DWARF_LOC (sc_addr + LINUX_SC_R5_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R6]  = DWARF_LOC (sc_addr + LINUX_SC_R6_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R7]  = DWARF_LOC (sc_addr + LINUX_SC_R7_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R8]  = DWARF_LOC (sc_addr + LINUX_SC_R8_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R9]  = DWARF_LOC (sc_addr + LINUX_SC_R9_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R10] = DWARF_LOC (sc_addr + LINUX_SC_R10_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R11] = DWARF_LOC (sc_addr + LINUX_SC_R11_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R12] = DWARF_LOC (sc_addr + LINUX_SC_R12_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R13] = DWARF_LOC (sc_addr + LINUX_SC_R13_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R14] = DWARF_LOC (sc_addr + LINUX_SC_R14_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R15] = DWARF_LOC (sc_addr + LINUX_SC_R15_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R16] = DWARF_LOC (sc_addr + LINUX_SC_R16_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R17] = DWARF_LOC (sc_addr + LINUX_SC_R17_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R18] = DWARF_LOC (sc_addr + LINUX_SC_R18_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R19] = DWARF_LOC (sc_addr + LINUX_SC_R19_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R20] = DWARF_LOC (sc_addr + LINUX_SC_R20_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R21] = DWARF_LOC (sc_addr + LINUX_SC_R21_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R22] = DWARF_LOC (sc_addr + LINUX_SC_R22_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R23] = DWARF_LOC (sc_addr + LINUX_SC_R23_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R24] = DWARF_LOC (sc_addr + LINUX_SC_R24_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R25] = DWARF_LOC (sc_addr + LINUX_SC_R25_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R26] = DWARF_LOC (sc_addr + LINUX_SC_R26_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R27] = DWARF_LOC (sc_addr + LINUX_SC_R27_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R28] = DWARF_LOC (sc_addr + LINUX_SC_R28_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R29] = DWARF_LOC (sc_addr + LINUX_SC_R29_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R30] = DWARF_LOC (sc_addr + LINUX_SC_R30_OFF, 0);
  c->dwarf.loc[UNW_MIPS_R31] = DWARF_LOC (sc_addr + LINUX_SC_R31_OFF, 0);
  c->dwarf.loc[UNW_MIPS_PC] = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0);

  /* Set SP/CFA and PC/IP. */
  dwarf_get (&c->dwarf, c->dwarf.loc[UNW_MIPS_R29], &c->dwarf.cfa);

  if ((ret = dwarf_get(&c->dwarf, DWARF_LOC(sc_addr + LINUX_SC_PC_OFF, 0),
                       &c->dwarf.ip)) < 0)
    return ret;

  if ((ret = dwarf_get(&c->dwarf, DWARF_LOC(sc_addr + LINUX_SC_R31_OFF, 0),
                       &ra)) < 0)
    return ret;
  if ((ret = dwarf_get(&c->dwarf, DWARF_LOC(sc_addr + LINUX_SC_R30_OFF, 0),
                       &fp)) < 0)
    return ret;

  Debug (2, "SH (ip=0x%016llx, ra=0x%016llx, sp=0x%016llx, fp=0x%016llx)\n",
         (unsigned long long)c->dwarf.ip, (unsigned long long)ra,
         (unsigned long long)c->dwarf.cfa, (unsigned long long)fp);

  c->dwarf.pi_valid = 0;
  c->dwarf.use_prev_instr = 0;

  return 1;
}
コード例 #10
0
ファイル: Gstep.c プロジェクト: JeoYaoxiao/libunwind
PROTECTED int
unw_step (unw_cursor_t *cursor)
{
  struct cursor *c = (struct cursor *) cursor;
  int ret = -UNW_EUNSPEC;

  Debug (1, "(cursor=%p)\n", c);

  /* Try DWARF-based unwinding...  this is the only method likely to work for
     ARM.  */
  if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF))
    {
      ret = dwarf_step (&c->dwarf);
      Debug(1, "dwarf_step()=%d\n", ret);

      if (unlikely (ret == -UNW_ESTOPUNWIND))
        return ret;

    if (ret < 0 && ret != -UNW_ENOINFO)
      {
        Debug (2, "returning %d\n", ret);
        return ret;
      }
    }

  if (unlikely (ret < 0))
    {
      if (UNW_TRY_METHOD(UNW_ARM_METHOD_FRAME))
        {
          ret = UNW_ESUCCESS;
          /* DWARF unwinding failed, try to follow APCS/optimized APCS frame chain */
          unw_word_t instr, i;
          Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret);
          dwarf_loc_t ip_loc, fp_loc;
          unw_word_t frame;
          /* Mark all registers unsaved, since we don't know where
             they are saved (if at all), except for the EBP and
             EIP.  */
          if (dwarf_get(&c->dwarf, c->dwarf.loc[UNW_ARM_R11], &frame) < 0)
            {
              return 0;
            }
          for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) {
            c->dwarf.loc[i] = DWARF_NULL_LOC;
          }
          if (frame)
            {
              if (dwarf_get(&c->dwarf, DWARF_LOC(frame, 0), &instr) < 0)
                {
                  return 0;
                }
              instr -= 8;
              if (dwarf_get(&c->dwarf, DWARF_LOC(instr, 0), &instr) < 0)
                {
                  return 0;
                }
              if ((instr & 0xFFFFD800) == 0xE92DD800)
                {
                  /* Standard APCS frame. */
                  ip_loc = DWARF_LOC(frame - 4, 0);
                  fp_loc = DWARF_LOC(frame - 12, 0);
                }
              else
                {
                  /* Codesourcery optimized normal frame. */
                  ip_loc = DWARF_LOC(frame, 0);
                  fp_loc = DWARF_LOC(frame - 4, 0);
                }
              if (dwarf_get(&c->dwarf, ip_loc, &c->dwarf.ip) < 0)
                {
                  return 0;
                }
              c->dwarf.loc[UNW_ARM_R12] = ip_loc;
              c->dwarf.loc[UNW_ARM_R11] = fp_loc;
              Debug(15, "ip=%lx\n", c->dwarf.ip);
            }
          else
            {
              ret = -UNW_ENOINFO;
            }
        }
    }
  return ret == -UNW_ENOINFO ? 0 : 1;
}
コード例 #11
0
ファイル: Gstep.c プロジェクト: 0-T-0/linux-sgx
PROTECTED int
unw_step (unw_cursor_t *cursor)
{
  struct cursor *c = (struct cursor *) cursor;
  int ret, i;

  Debug (1, "(cursor=%p, ip=0x%08x)\n", c, (unsigned) c->dwarf.ip);

  /* Try DWARF-based unwinding... */
  ret = dwarf_step (&c->dwarf);

  if (ret < 0 && ret != -UNW_ENOINFO)
    {
      Debug (2, "returning %d\n", ret);
      return ret;
    }

  if (unlikely (ret < 0))
    {
      /* DWARF failed, let's see if we can follow the frame-chain
	 or skip over the signal trampoline.  */

      Debug (13, "dwarf_step() failed (ret=%d), trying fallback\n", ret);

      if (unw_is_signal_frame (cursor))
	{
#ifdef __linux__
	  /* Assume that the trampoline is at the beginning of the
	     sigframe.  */
	  unw_word_t ip, sc_addr = c->dwarf.ip + LINUX_RT_SIGFRAME_UC_OFF;
	  dwarf_loc_t iaoq_loc = DWARF_LOC (sc_addr + LINUX_SC_IAOQ_OFF, 0);

	  c->sigcontext_format = HPPA_SCF_LINUX_RT_SIGFRAME;
	  c->sigcontext_addr = sc_addr;
	  c->dwarf.ret_addr_column = UNW_HPPA_RP;

	  if ((ret = dwarf_get (&c->dwarf, iaoq_loc, &ip)) , 0)
	    {
	      Debug (2, "failed to read IAOQ[1] (ret=%d)\n", ret);
	      return ret;
	    }
	  c->dwarf.ip = ip & ~0x3;	/* mask out the privilege level */

	  for (i = 0; i < 32; ++i)
	    {
	      c->dwarf.loc[UNW_HPPA_GR + i]
		= DWARF_LOC (sc_addr + LINUX_SC_GR_OFF + 4*i, 0);
	      c->dwarf.loc[UNW_HPPA_FR + i]
		= DWARF_LOC (sc_addr + LINUX_SC_FR_OFF + 4*i, 0);
	    }

	  if ((ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_HPPA_SP],
				&c->dwarf.cfa)) < 0)
	    {
	      Debug (2, "failed to read SP (ret=%d)\n", ret);
	      return ret;
	    }
#else
# error Implement me!
#endif
	}
      else
	c->dwarf.ip = 0;
    }
  ret = (c->dwarf.ip == 0) ? 0 : 1;
  Debug (2, "returning %d\n", ret);
  return ret;
}
コード例 #12
0
ファイル: Gos-linux.c プロジェクト: 0-T-0/linux-sgx
PROTECTED int
unw_handle_signal_frame (unw_cursor_t *cursor)
{
  struct cursor *c = (struct cursor *) cursor;
  int ret;

  /* c->esp points at the arguments to the handler.  Without
     SA_SIGINFO, the arguments consist of a signal number
     followed by a struct sigcontext.  With SA_SIGINFO, the
     arguments consist a signal number, a siginfo *, and a
     ucontext *. */
  unw_word_t sc_addr;
  unw_word_t siginfo_ptr_addr = c->dwarf.cfa + 4;
  unw_word_t sigcontext_ptr_addr = c->dwarf.cfa + 8;
  unw_word_t siginfo_ptr, sigcontext_ptr;
  struct dwarf_loc esp_loc, siginfo_ptr_loc, sigcontext_ptr_loc;

  siginfo_ptr_loc = DWARF_LOC (siginfo_ptr_addr, 0);
  sigcontext_ptr_loc = DWARF_LOC (sigcontext_ptr_addr, 0);
  ret = (dwarf_get (&c->dwarf, siginfo_ptr_loc, &siginfo_ptr)
	 | dwarf_get (&c->dwarf, sigcontext_ptr_loc, &sigcontext_ptr));
  if (ret < 0)
    {
      Debug (2, "returning 0\n");
      return 0;
    }
  if (siginfo_ptr < c->dwarf.cfa
      || siginfo_ptr > c->dwarf.cfa + 256
      || sigcontext_ptr < c->dwarf.cfa
      || sigcontext_ptr > c->dwarf.cfa + 256)
    {
      /* Not plausible for SA_SIGINFO signal */
      c->sigcontext_format = X86_SCF_LINUX_SIGFRAME;
      c->sigcontext_addr = sc_addr = c->dwarf.cfa + 4;
    }
  else
    {
      /* If SA_SIGINFO were not specified, we actually read
	 various segment pointers instead.  We believe that at
	 least fs and _fsh are always zero for linux, so it is
	 not just unlikely, but impossible that we would end
	 up here. */
      c->sigcontext_format = X86_SCF_LINUX_RT_SIGFRAME;
      c->sigcontext_addr = sigcontext_ptr;
      sc_addr = sigcontext_ptr + LINUX_UC_MCONTEXT_OFF;
    }
  esp_loc = DWARF_LOC (sc_addr + LINUX_SC_ESP_OFF, 0);
  ret = dwarf_get (&c->dwarf, esp_loc, &c->dwarf.cfa);
  if (ret < 0)
    {
      Debug (2, "returning 0\n");
      return 0;
    }

  c->dwarf.loc[EAX] = DWARF_LOC (sc_addr + LINUX_SC_EAX_OFF, 0);
  c->dwarf.loc[ECX] = DWARF_LOC (sc_addr + LINUX_SC_ECX_OFF, 0);
  c->dwarf.loc[EDX] = DWARF_LOC (sc_addr + LINUX_SC_EDX_OFF, 0);
  c->dwarf.loc[EBX] = DWARF_LOC (sc_addr + LINUX_SC_EBX_OFF, 0);
  c->dwarf.loc[EBP] = DWARF_LOC (sc_addr + LINUX_SC_EBP_OFF, 0);
  c->dwarf.loc[ESI] = DWARF_LOC (sc_addr + LINUX_SC_ESI_OFF, 0);
  c->dwarf.loc[EDI] = DWARF_LOC (sc_addr + LINUX_SC_EDI_OFF, 0);
  c->dwarf.loc[EFLAGS] = DWARF_NULL_LOC;
  c->dwarf.loc[TRAPNO] = DWARF_NULL_LOC;
  c->dwarf.loc[ST0] = DWARF_NULL_LOC;
  c->dwarf.loc[EIP] = DWARF_LOC (sc_addr + LINUX_SC_EIP_OFF, 0);
  c->dwarf.loc[ESP] = DWARF_LOC (sc_addr + LINUX_SC_ESP_OFF, 0);

  return 0;
}