1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-12-22 19:43:42 +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:
Dave Watson 2017-08-16 15:35:38 -07:00
parent 3d9a694de8
commit 7f1aebadbf
2 changed files with 26 additions and 2 deletions

View file

@ -52,7 +52,7 @@ unw_is_signal_frame (unw_cursor_t *cursor)
__restore_rt:
0xb8 0xad 0x00 0x00 0x00 movl 0xad,%eax
0xcd 0x80 int 0x80
0x00
0x00
if SA_SIGINFO is specified.
*/
@ -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;
Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc);
sigreturn (sc);
x86_sigreturn (sc);
}
else
{
@ -305,4 +305,25 @@ x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
}
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

View file

@ -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_get_scratch_loc UNW_OBJ(get_scratch_loc)
#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 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 void *x86_r_uc_addr (ucontext_t *uc, int reg);
extern void x86_sigreturn (unw_cursor_t *cursor);
#endif /* unwind_i_h */