diff --git a/src/x86_64/Gresume.c b/src/x86_64/Gresume.c index a7822344..13c8059a 100644 --- a/src/x86_64/Gresume.c +++ b/src/x86_64/Gresume.c @@ -45,7 +45,6 @@ my_rt_sigreturn (void *new_sp) "syscall" :: "r"(new_sp), "i"(SYS_rt_sigreturn) : "memory"); - abort (); } #endif @@ -63,17 +62,20 @@ x86_64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) if (unlikely (c->sigcontext_format != X86_64_SCF_NONE)) { +#if defined __linux__ struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; Debug (8, "resuming at ip=%llx via sigreturn(%p)\n", (unsigned long long) c->dwarf.ip, sc); -#if defined __linux__ my_rt_sigreturn (sc); #elif defined __FreeBSD__ - sigreturn((char *)(c->uc) - FREEBSD_UC_MCONTEXT_OFF); + Debug (8, "resuming at ip=%llx via sigreturn(%p)\n", + (unsigned long long) c->dwarf.ip, uc); + sigreturn(uc); #else #error Port me #endif + abort(); } else { diff --git a/src/x86_64/getcontext.S b/src/x86_64/getcontext.S index b6aedbb2..ce7cbcc1 100644 --- a/src/x86_64/getcontext.S +++ b/src/x86_64/getcontext.S @@ -66,6 +66,22 @@ _Ux86_64_getcontext: fxsave UC_MCONTEXT_FPSTATE(%rdi) movq $UC_MCONTEXT_FPOWNED_FPU,UC_MCONTEXT_OWNEDFP(%rdi) movq $UC_MCONTEXT_FPFMT_XMM,UC_MCONTEXT_FPFORMAT(%rdi) + /* Save rflags and segment registers, so that sigreturn(2) + does not complain. */ + pushfq + popq UC_MCONTEXT_RFLAGS(%rdi) + movl $0, UC_MCONTEXT_FLAGS(%rdi) + movw %cs, UC_MCONTEXT_CS(%rdi) + movw %ss, UC_MCONTEXT_SS(%rdi) +#if 0 + /* Setting the flags to 0 above disables restore of segment + registers from the context */ + movw %ds, UC_MCONTEXT_DS(%rdi) + movw %es, UC_MCONTEXT_ES(%rdi) + movw %fs, UC_MCONTEXT_FS(%rdi) + movw %gs, UC_MCONTEXT_GS(%rdi) +#endif + movq $UC_MCONTEXT_MC_LEN_VAL, UC_MCONTEXT_MC_LEN(%rdi) #else #error Port me #endif diff --git a/src/x86_64/ucontext_i.h b/src/x86_64/ucontext_i.h index 82114dd2..9ce8f273 100644 --- a/src/x86_64/ucontext_i.h +++ b/src/x86_64/ucontext_i.h @@ -61,10 +61,20 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define UC_MCONTEXT_GREGS_RCX 0x30 #define UC_MCONTEXT_GREGS_RSP 0xc8 #define UC_MCONTEXT_GREGS_RIP 0xb0 +#define UC_MCONTEXT_RFLAGS 0xc0 +#define UC_MCONTEXT_FLAGS 0xa0 +#define UC_MCONTEXT_CS 0xb8 +#define UC_MCONTEXT_SS 0xd0 +#define UC_MCONTEXT_DS 0xa6 +#define UC_MCONTEXT_ES 0xa4 +#define UC_MCONTEXT_FS 0x94 +#define UC_MCONTEXT_GS 0x96 +#define UC_MCONTEXT_MC_LEN 0xd8 #define UC_MCONTEXT_FPSTATE 0xf0 #define UC_MCONTEXT_OWNEDFP 0xe8 #define UC_MCONTEXT_FPFORMAT 0xe0 #define UC_MCONTEXT_FPOWNED_FPU 0x20001 #define UC_MCONTEXT_FPFMT_XMM 0x10002 +#define UC_MCONTEXT_MC_LEN_VAL 0x320 #endif