#ifndef inhibit_libc
#include <signal.h>
typedef struct _sig_ucontext {
unsigned long uc_flags;
struct _sig_ucontext *uc_link;
stack_t uc_stack;
struct sigcontext uc_mcontext;
sigset_t uc_sigmask;
} _sig_ucontext_t;
#define MD_FALLBACK_FRAME_STATE_FOR mips_fallback_frame_state
static _Unwind_Reason_Code
mips_fallback_frame_state (struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
u_int32_t *pc = (u_int32_t *) context->ra;
struct sigcontext *sc;
_Unwind_Ptr new_cfa;
int i;
if (*(pc + 1) != 0x0000000c)
return _URC_END_OF_STACK;
if (*(pc + 0) == 0x24021017)
{
struct sigframe {
u_int32_t trampoline[2];
struct sigcontext sigctx;
} *rt_ = context->ra;
sc = &rt_->sigctx;
}
else if (*(pc + 0) == 0x24021061)
{
struct rt_sigframe {
u_int32_t trampoline[2];
struct siginfo info;
_sig_ucontext_t uc;
} *rt_ = context->ra;
sc = &rt_->uc.uc_mcontext;
}
else
return _URC_END_OF_STACK;
new_cfa = (_Unwind_Ptr)sc;
fs->cfa_how = CFA_REG_OFFSET;
fs->cfa_reg = STACK_POINTER_REGNUM;
fs->cfa_offset = new_cfa - (_Unwind_Ptr) context->cfa;
for (i = 0; i < 32; i++) {
fs->regs.reg[i].how = REG_SAVED_OFFSET;
fs->regs.reg[i].loc.offset
= (_Unwind_Ptr)&(sc->sc_regs[i]) - new_cfa;
}
fs->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].how = REG_SAVED_OFFSET;
fs->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].loc.offset
= (_Unwind_Ptr)&(sc->sc_pc) - new_cfa;
fs->retaddr_column = SIGNAL_UNWIND_RETURN_COLUMN;
return _URC_NO_REASON;
}
#endif