#include "unwind_i.h"
#include "offsets.h"
int
unw_step (unw_cursor_t *cursor)
{
struct cursor *c = (struct cursor *) cursor;
int ret, i;
int validate = c->validate;
c->validate = 1;
Debug (1, "(cursor=%p, ip=0x%08x)\n", c, (unsigned) c->dwarf.ip);
if (unw_is_signal_frame (cursor) > 0)
{
ret = x86_handle_signal_frame(cursor);
return 1;
}
ret = dwarf_step (&c->dwarf);
c->validate = validate;
if (ret < 0 && ret != -UNW_ENOINFO)
{
Debug (2, "returning %d\n", ret);
return ret;
}
if (unlikely (ret < 0))
{
struct dwarf_loc ebp_loc, eip_loc, esp_loc;
Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret);
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);
esp_loc = DWARF_VAL_LOC (c, c->dwarf.cfa + 8);
eip_loc = DWARF_LOC (c->dwarf.cfa + 4, 0);
c->dwarf.cfa += 8;
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[ESP] = esp_loc;
c->dwarf.loc[EIP] = eip_loc;
c->dwarf.use_prev_instr = 1;
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;
}