[patch] clear direction flag for signal handlers

Aggelos Economopoulos aoiko at cc.ece.ntua.gr
Fri Mar 14 10:18:49 PDT 2008


On Sunday 09 March 2008, Aggelos Economopoulos wrote:
> On Saturday 08 March 2008, Simon 'corecode' Schubert wrote:
> > Aggelos Economopoulos wrote:
> > > gcc-4.3 assumes the direction flag is clear on function entry as
> > > specified by the i386 abi. Ensure that is the case when running
> > > a signal handler.
> > > 
> > > Linux-kernel discussion with gcc people starts here:
> > > http://article.gmane.org/gmane.linux.kernel/650279
> > > 
> > > Index: platform/pc32/i386/machdep.c
> > 
> > You might want to pull this up to vkernel as well.
> 
> And to amd64 as well, otherwise this might stay unnoticed for a long time.
> Wait. Did I even fix regular i386? Wouldn't be surprised if I've sent an
> empty patch...

swildner@ pointed out that there's yet another path that ends up running
a signal handler (for linux binaries). Updated patch follows.

gcc-4.3 assumes the direction flag is clear on function entry as
specified by the i386 abi. Ensure that is the case when running
a signal handler.

Linux-kernel discussion with gcc people starts here:
http://article.gmane.org/gmane.linux.kernel/650279

Index: platform/pc32/i386/machdep.c
===================================================================
retrieving revision 1.129
diff -u -r1.129 machdep.c
--- platform/pc32/i386/machdep.c
+++ platform/pc32/i386/machdep.c
@@ -515,7 +515,13 @@
 
 	regs->tf_esp = (int)sfp;
 	regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
-	regs->tf_eflags &= ~PSL_T;
+
+	/*
+	 * i386 abi specifies that the direction flag must be cleared
+	 * on function entry
+	 */
+	regs->tf_eflags &= ~(PSL_T|PSL_D);
+
 	regs->tf_cs = _ucodesel;
 	regs->tf_ds = _udatasel;
 	regs->tf_es = _udatasel;
Index: platform/vkernel/i386/cpu_regs.c
===================================================================
retrieving revision 1.24
diff -u -r1.24 cpu_regs.c
--- platform/vkernel/i386/cpu_regs.c
+++ platform/vkernel/i386/cpu_regs.c
@@ -325,7 +325,13 @@
 
 	regs->tf_esp = (int)sfp;
 	regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
-	regs->tf_eflags &= ~PSL_T;
+
+	/*
+	 * i386 abi specifies that the direction flag must be cleared
+	 * on function entry
+	 */
+	regs->tf_eflags &= ~(PSL_T|PSL_D);
+
 	regs->tf_cs = _ucodesel;
 	regs->tf_ds = _udatasel;
 	regs->tf_es = _udatasel;
Index: platform/pc64/amd64/cpu_regs.c
===================================================================
retrieving revision 1.4
diff -u -r1.4 cpu_regs.c
--- platform/pc64/amd64/cpu_regs.c
+++ platform/pc64/amd64/cpu_regs.c
@@ -327,7 +327,13 @@
 
 	regs->tf_rsp = (int)sfp;
 	regs->tf_rip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
-	regs->tf_rflags &= ~PSL_T;
+
+	/*
+	 * amd64 abi specifies that the direction flag must be cleared
+	 * on function entry
+	 */
+	regs->tf_rflags &= ~(PSL_T|PSL_D);
+
 	regs->tf_cs = _ucodesel;
 	/* regs->tf_ds = _udatasel;
 	regs->tf_es = _udatasel; */
Index: emulation/linux/i386/linux_sysvec.c
===================================================================
retrieving revision 1.29
diff -u -r1.29 linux_sysvec.c
--- emulation/linux/i386/linux_sysvec.c
+++ emulation/linux/i386/linux_sysvec.c
@@ -369,7 +369,13 @@
 	regs->tf_esp = (int)fp;
 	regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode) + 
 	    linux_sznonrtsigcode;
-	regs->tf_eflags &= ~(PSL_T | PSL_VM);
+
+	/*
+	 * i386 abi specifies that the direction flag must be cleared
+	 * on function entry
+	 */
+	regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D);
+
 	regs->tf_cs = _ucodesel;
 	regs->tf_ds = _udatasel;
 	regs->tf_es = _udatasel;
@@ -503,7 +509,13 @@
 	 */
 	regs->tf_esp = (int)fp;
 	regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
-	regs->tf_eflags &= ~(PSL_T | PSL_VM);
+
+	/*
+	 * i386 abi specifies that the direction flag must be cleared
+	 * on function entry
+	 */
+	regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D);
+
 	regs->tf_cs = _ucodesel;
 	regs->tf_ds = _udatasel;
 	regs->tf_es = _udatasel;





More information about the Submit mailing list