Since version 4.3, gcc changed its behaviour concerning the i386/amd64

ABI and the direction flag, that is it now assumes that the direction
flag is cleared at the entry of a function and it doesn't clear once
more if needed. This new behaviour conforms to the i386/amd64 ABI.

Modify the signal handler frame setup code to clear the DF {e,r}flags
bit on the amd64/i386 for the signal handlers.

jhb@ noted that it might break old apps if they assumed DF == 1 would be
preserved in the signal handlers, but that such apps should be rare and
that older versions of gcc would not generate such apps.

Submitted by:	Aurelien Jarno <aurelien aurel32 net>
PR:	121422
Reviewed by:	jhb
MFC after:	2 weeks
This commit is contained in:
Konstantin Belousov 2008-03-13 10:54:38 +00:00
parent 53bbf5aa35
commit 22eca0bf45
7 changed files with 15 additions and 15 deletions

View file

@ -357,7 +357,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
regs->tf_rsp = (long)sfp;
regs->tf_rip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
regs->tf_rflags &= ~PSL_T;
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucodesel;
PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);

View file

@ -391,7 +391,7 @@ freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
regs->tf_rsp = (uintptr_t)sfp;
regs->tf_rip = FREEBSD32_PS_STRINGS - sz_freebsd4_ia32_sigcode;
regs->tf_rflags &= ~PSL_T;
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucode32sel;
regs->tf_ss = _udatasel;
load_ds(_udatasel);
@ -511,7 +511,7 @@ ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
regs->tf_rsp = (uintptr_t)sfp;
regs->tf_rip = FREEBSD32_PS_STRINGS - *(p->p_sysent->sv_szsigcode);
regs->tf_rflags &= ~PSL_T;
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucode32sel;
regs->tf_ss = _udatasel;
load_ds(_udatasel);

View file

@ -401,7 +401,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
regs->tf_rsp = PTROUT(fp);
regs->tf_rip = LINUX32_PS_STRINGS - *(p->p_sysent->sv_szsigcode) +
linux_sznonrtsigcode;
regs->tf_rflags &= ~PSL_T;
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucode32sel;
regs->tf_ss = _udatasel;
load_ds(_udatasel);
@ -523,7 +523,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
*/
regs->tf_rsp = PTROUT(fp);
regs->tf_rip = LINUX32_PS_STRINGS - *(p->p_sysent->sv_szsigcode);
regs->tf_rflags &= ~PSL_T;
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucode32sel;
regs->tf_ss = _udatasel;
load_ds(_udatasel);

View file

@ -417,7 +417,7 @@ osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
regs->tf_esp = (int)fp;
regs->tf_eip = PS_STRINGS - szosigcode;
regs->tf_eflags &= ~PSL_T;
regs->tf_eflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
@ -538,7 +538,7 @@ freebsd4_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
regs->tf_esp = (int)sfp;
regs->tf_eip = PS_STRINGS - szfreebsd4_sigcode;
regs->tf_eflags &= ~PSL_T;
regs->tf_eflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
@ -674,7 +674,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
regs->tf_esp = (int)sfp;
regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
regs->tf_eflags &= ~PSL_T;
regs->tf_eflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;

View file

@ -388,7 +388,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
regs->tf_esp = (int)fp;
regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode) +
linux_sznonrtsigcode;
regs->tf_eflags &= ~(PSL_T | PSL_VM);
regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D);
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
@ -507,7 +507,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
*/
regs->tf_esp = (int)fp;
regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
regs->tf_eflags &= ~(PSL_T | PSL_VM);
regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D);
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;

View file

@ -497,13 +497,13 @@ svr4_sendsig(catcher, ksi, mask)
svr4_szsigcode);
tf->tf_cs = GSEL(GUSERLDT_SEL, SEL_UPL);
tf->tf_eflags &= ~(PSL_T|PSL_VM|PSL_AC);
tf->tf_eflags &= ~(PSL_T|PSL_VM|PSL_AC|PSL_D);
tf->tf_esp = (int)fp;
tf->tf_ss = GSEL(GUSERLDT_SEL, SEL_UPL);
#else
tf->tf_esp = (int)fp;
tf->tf_eip = (int)(((char *)PS_STRINGS) - *(p->p_sysent->sv_szsigcode));
tf->tf_eflags &= ~PSL_T;
tf->tf_eflags &= ~(PSL_T | PSL_D);
tf->tf_cs = _ucodesel;
tf->tf_ds = _udatasel;
tf->tf_es = _udatasel;

View file

@ -385,7 +385,7 @@ osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
regs->tf_esp = (int)fp;
regs->tf_eip = PS_STRINGS - szosigcode;
regs->tf_eflags &= ~PSL_T;
regs->tf_eflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
@ -506,7 +506,7 @@ freebsd4_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
regs->tf_esp = (int)sfp;
regs->tf_eip = PS_STRINGS - szfreebsd4_sigcode;
regs->tf_eflags &= ~PSL_T;
regs->tf_eflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
@ -642,7 +642,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
regs->tf_esp = (int)sfp;
regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
regs->tf_eflags &= ~PSL_T;
regs->tf_eflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;