Пример #1
0
RTStack__PrevFrame (Frame* callee, Frame* caller)
{
  PRUNTIME_FUNCTION fun;
  void *proc;
  char *file, *name;

  if (callee->lock != FrameLock) abort ();
  *caller = *callee;

  /* see if the unwind has any chance of working... */
  fun = (PRUNTIME_FUNCTION) __exc_lookup_function_entry (callee->cxt.sc_pc);
  if (fun == 0) {
    caller->pc = caller->sp = caller->unwind = 0;
    return;
  }

  __exc_virtual_unwind (fun, &(caller->cxt));
  caller->pc = caller->cxt.sc_pc;
  caller->sp = caller->cxt.sc_sp;

  RTProcedureSRC_FromPC((void *)(callee->pc), &proc, &file, &name);
  if (proc == RTHeapDep_Fault) {
    /* SIGNAL HANDLER: previous frame before signal trampoline */
    caller->unwind = 0;		/* unwind directly to handler */
  } else if (caller->unwind) {
    caller->unwind = caller->pc;
  }

  if (caller->lock != FrameLock) abort ();
}
Пример #2
0
void RTStack__PrevFrame (Frame* callee, Frame* caller)
{
  ucontext_t *link;
  struct frame *link_sp, *link_fp;
  void *proc;
  char *file, *name;

  if (callee == 0) abort();
  if (caller == 0) abort();
  if (callee->lock != FrameLock) abort();

  RTStack__Flush();

  caller->lock = FrameLock;

  RTProcedureSRC_FromPC(callee->pc, &proc, &file, &name);
  if (proc == RTHeapDep_Fault) {
    /* SIGNAL HANDLER: previous frame information can be found in third
       argument of RTHeapDep_Fault */
    link = (ucontext_t *)callee->sp->fr_arg[2];
    caller->ctxt = *link;
    caller->pc = (void *)link->uc_mcontext.gregs[REG_PC];
    caller->unwind = 0;		/* unwind directly to handler */
    if (caller->pc) {
      caller->sp = (struct frame *)link->uc_mcontext.gregs[REG_SP];
      caller->fp = caller->sp->fr_savfp;
    } else
      caller->sp = caller->fp = 0;
  } else {
    caller->pc = (void *)callee->sp->fr_savpc;
    if (caller->pc) {
      (int)caller->unwind = (int)(caller->pc) + 8; /* for return address */
      caller->fp = (caller->sp = callee->fp)->fr_savfp;
    } else
      caller->unwind = caller->sp = caller->fp = 0;
    caller->ctxt = callee->ctxt;
  }
  if (caller->lock != FrameLock) abort();
}