mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-11-16 21:27:38 +01:00
x86: Add sigreturn asm stub
glibc no longer defines sigreturn, but we want to use it when unwinding through signal stacks to resture the signal mask, without forcing all uses of getcontext/setcontext to save and restore the signal mask
This commit is contained in:
parent
3d9a694de8
commit
7f1aebadbf
2 changed files with 26 additions and 2 deletions
|
@ -296,7 +296,7 @@ x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
|
||||||
struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
|
struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
|
||||||
|
|
||||||
Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc);
|
Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc);
|
||||||
sigreturn (sc);
|
x86_sigreturn (sc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -305,4 +305,25 @@ x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
|
||||||
}
|
}
|
||||||
return -UNW_EINVAL;
|
return -UNW_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* sigreturn() is a no-op on x86 glibc. */
|
||||||
|
HIDDEN void
|
||||||
|
x86_sigreturn (unw_cursor_t *cursor)
|
||||||
|
{
|
||||||
|
struct cursor *c = (struct cursor *) cursor;
|
||||||
|
struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
|
||||||
|
mcontext_t *sc_mcontext = &((struct ucontext*)sc)->uc_mcontext;
|
||||||
|
/* Copy in saved uc - all preserved regs are at the start of sigcontext */
|
||||||
|
memcpy(sc_mcontext, &c->uc->uc_mcontext,
|
||||||
|
DWARF_NUM_PRESERVED_REGS * sizeof(unw_word_t));
|
||||||
|
|
||||||
|
Debug (8, "resuming at ip=%llx via sigreturn(%p)\n",
|
||||||
|
(unsigned long long) c->dwarf.ip, sc);
|
||||||
|
__asm__ __volatile__ ("mov %0, %%esp;"
|
||||||
|
"mov %1, %%eax;"
|
||||||
|
"syscall"
|
||||||
|
:: "r"(sc), "i"(SYS_rt_sigreturn)
|
||||||
|
: "memory");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -52,6 +52,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
#define x86_scratch_loc UNW_OBJ(scratch_loc)
|
#define x86_scratch_loc UNW_OBJ(scratch_loc)
|
||||||
#define x86_get_scratch_loc UNW_OBJ(get_scratch_loc)
|
#define x86_get_scratch_loc UNW_OBJ(get_scratch_loc)
|
||||||
#define x86_r_uc_addr UNW_OBJ(r_uc_addr)
|
#define x86_r_uc_addr UNW_OBJ(r_uc_addr)
|
||||||
|
#define x86_sigreturn UNW_OBJ(sigreturn)
|
||||||
|
|
||||||
extern void x86_local_addr_space_init (void);
|
extern void x86_local_addr_space_init (void);
|
||||||
extern int x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
|
extern int x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
|
||||||
|
@ -60,4 +61,6 @@ extern dwarf_loc_t x86_scratch_loc (struct cursor *c, unw_regnum_t reg);
|
||||||
extern dwarf_loc_t x86_get_scratch_loc (struct cursor *c, unw_regnum_t reg);
|
extern dwarf_loc_t x86_get_scratch_loc (struct cursor *c, unw_regnum_t reg);
|
||||||
extern void *x86_r_uc_addr (ucontext_t *uc, int reg);
|
extern void *x86_r_uc_addr (ucontext_t *uc, int reg);
|
||||||
|
|
||||||
|
extern void x86_sigreturn (unw_cursor_t *cursor);
|
||||||
|
|
||||||
#endif /* unwind_i_h */
|
#endif /* unwind_i_h */
|
||||||
|
|
Loading…
Reference in a new issue