From: Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
Date: Wed, 12 Mar 97 10:39:16 +0100
To: linux-m68k@phil.uni-sb.de
Subject: L68K: <asm/unistd.h> broken
X-Yow: Please come home with me...  I have Tylenol!!
Sender: owner-linux-m68k@phil.uni-sb.de
Reply-To: linux-m68k@phil.uni-sb.de

There's a problem with the _syscall* macros in <asm/unistd.h>.  They all
declare the return value to be in register %d0.  When this variable is
passed to the __syscall_return macro it can be clobbered when errno
expands to a function call (as it happens in GNU libc, to get the thread
private address of errno).  The modutils are affected by this, for
example.  The solution is to copy the value to a normal, unconstrained
variable before the assignment to errno, so that is saved around the
function call.

Jes, please add this patch both to 2.0.x and 2.1.x.

Andreas.

--- linux/include/asm-m68k/unistd.h.~1~	Mon Jan 27 20:00:25 1997
+++ linux/include/asm-m68k/unistd.h	Tue Mar 11 19:51:06 1997
@@ -180,7 +180,10 @@
 #define __syscall_return(type, res) \
 do { \
 	if ((unsigned long)(res) >= (unsigned long)(-125)) { \
-		errno = -(res); \
+	/* avoid using res which is declared to be in register d0; \
+	   errno might expand to a function call and clobber it.  */ \
+		int __err = -(res); \
+		errno = __err; \
 		res = -1; \
 	} \
 	return (type) (res); \
