Bug 7302 - PIC code in unistd.h
Summary: PIC code in unistd.h
Status: CLOSED CODE_FIX
Alias: None
Product: Platform Specific/Hardware
Classification: Unclassified
Component: i386 (show other bugs)
Hardware: i386 Linux
: P2 normal
Assignee: platform_i386
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-10-10 22:41 UTC by Robert Connolly
Modified: 2007-06-06 00:25 UTC (History)
2 users (show)

See Also:
Kernel Version: 2.6.18
Subsystem:
Regression: ---
Bisected commit-id:


Attachments

Description Robert Connolly 2006-10-10 22:41:12 UTC
Linux kernel headers are not position independent. This is only an issue in 
userland. Several distributions are using position independent executables and 
libraries, via gcc -fpic/-fpie, and there is only one kernel library in i386 
that poses an issue. I have inlined a patch which corrects the issue without 
affecting anything else. Please add it so there is one less patch against the 
Linux kernel:

diff -Naur linux-2.6.18.orig/include/asm-i386/unistd.h 
linux-2.6.18/include/asm-i386/unistd.h
--- linux-2.6.18.orig/include/asm-i386/unistd.h	2006-09-20 03:42:06.000000000 
+0000
+++ linux-2.6.18/include/asm-i386/unistd.h	2006-10-11 05:32:17.000000000 
+0000
@@ -352,6 +352,21 @@
 __syscall_return(type,__res); \
 }
 
+#ifdef __PIC__
+#define _syscall1(type,name,type1,arg1) \
+type name(type1 arg1) \
+{ \
+long __res; \
+__asm__ volatile (\
+	"pushl %%ebx\n\t" \
+	"movl %2,%%ebx\n\t" \
+	"int $0x80\n\t" \
+	"popl %%ebx\n\t" \
+	: "=a" (__res) \
+	: "0" (__NR_##name),"r" ((long)(arg1))); \
+__syscall_return(type,__res); \
+}
+#else
 #define _syscall1(type,name,type1,arg1) \
 type name(type1 arg1) \
 { \
@@ -361,7 +376,23 @@
 	: "0" (__NR_##name),"ri" ((long)(arg1)) : "memory"); \
 __syscall_return(type,__res); \
 }
+#endif
 
+#ifdef __PIC__
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+type name(type1 arg1,type2 arg2) \
+{ \
+long __res; \
+__asm__ volatile (\
+	"pushl %%ebx\n\t" \
+	"movl %2,%%ebx\n\t" \
+	"int $0x80\n\t" \
+	"popl %%ebx\n\t" \
+	: "=a" (__res) \
+	: "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2))); \
+__syscall_return(type,__res); \
+}
+#else
 #define _syscall2(type,name,type1,arg1,type2,arg2) \
 type name(type1 arg1,type2 arg2) \
 { \
@@ -372,7 +403,24 @@
 	: "memory"); \
 __syscall_return(type,__res); \
 }
+#endif
 
+#ifdef __PIC__
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type name(type1 arg1,type2 arg2,type3 arg3) \
+{ \
+long __res; \
+__asm__ volatile (\
+	"pushl %%ebx\n\t" \
+	"movl %2,%%ebx\n\t" \
+	"int $0x80\n\t" \
+	"popl %%ebx\n\t" \
+	: "=a" (__res) \
+	: "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2)), \
+		  "d" ((long)(arg3))); \
+__syscall_return(type,__res); \
+}
+#else
 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
 type name(type1 arg1,type2 arg2,type3 arg3) \
 { \
@@ -383,7 +431,24 @@
 		  "d" ((long)(arg3)) : "memory"); \
 __syscall_return(type,__res); \
 }
+#endif
 
+#ifdef __PIC__
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+{ \
+long __res; \
+__asm__ volatile (\
+	"pushl %%ebx\n\t" \
+	"movl %2,%%ebx\n\t" \
+	"int $0x80\n\t" \
+	"popl %%ebx\n\t" \
+	: "=a" (__res) \
+	: "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2)), \
+	  "d" ((long)(arg3)),"S" ((long)(arg4))); \
+__syscall_return(type,__res); \
+} 
+#else
 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
 type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
 { \
@@ -394,7 +459,25 @@
 	  "d" ((long)(arg3)),"S" ((long)(arg4)) : "memory"); \
 __syscall_return(type,__res); \
 } 
+#endif
 
+#ifdef __PIC__
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+	  type5,arg5) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+{ \
+long __res; \
+__asm__ volatile (\
+	"pushl %%ebx\n\t" \
+	"movl %2,%%ebx\n\t" \
+	"int $0x80\n\t" \
+	"popl %%ebx\n\t" \
+	: "=a" (__res) \
+	: "0" (__NR_##name),"m" ((long)(arg1)),"c" ((long)(arg2)), \
+	  "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \
+__syscall_return(type,__res); \
+}
+#else
 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
 	  type5,arg5) \
 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
@@ -408,7 +491,30 @@
 	: "memory"); \
 __syscall_return(type,__res); \
 }
+#endif
 
+#ifdef __PIC__
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+	  type5,arg5,type6,arg6) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) 
\
+{ \
+long __res; \
+__asm__ volatile (\
+	"pushl %%ebp\n\t" \
+	"movl %%eax,%%ebp\n\t" \
+	"movl %1,%%eax\n\t" \
+	"pushl %%ebx\n\t" \
+	"movl %2,%%ebx\n\t" \
+	"int $0x80\n\t" \
+	"popl %%ebx\n\t" \
+	"popl %%ebp\n\t" \
+	: "=a" (__res) \
+	: "i" (__NR_##name),"m" ((long)(arg1)),"c" ((long)(arg2)), \
+	  "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)), \
+	  "0" ((long)(arg6))); \
+__syscall_return(type,__res); \
+}
+#else
 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
 	  type5,arg5,type6,arg6) \
 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) 
\
@@ -424,6 +530,7 @@
 	: "memory"); \
 __syscall_return(type,__res); \
 }
+#endif
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
Comment 1 Andrew Morton 2006-10-10 23:16:31 UTC
The medium-term plan is to remove all that syscall code from unistd.h
altogether.

So please create your own private version of this stuff - the kernel's copy
is going away.

In fact the 2.6.19-rc1 kernel builds OK without it there.  Arnd, what's the
story?  Can we nuke it all?


From: Andrew Morton <akpm@osdl.org>

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 include/asm-i386/unistd.h |   97 ------------------------------------
 1 file changed, 97 deletions(-)

diff -puN include/asm-i386/unistd.h~a include/asm-i386/unistd.h
--- a/include/asm-i386/unistd.h~a
+++ a/include/asm-i386/unistd.h
@@ -330,103 +330,6 @@
 #define NR_syscalls 319
 #include <linux/err.h>
 
-/*
- * user-visible error numbers are in the range -1 - -MAX_ERRNO: see
- * <asm-i386/errno.h>
- */
-#define __syscall_return(type, res) \
-do { \
-	if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \
-		errno = -(res); \
-		res = -1; \
-	} \
-	return (type) (res); \
-} while (0)
-
-/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
-#define _syscall0(type,name) \
-type name(void) \
-{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
-	: "=a" (__res) \
-	: "0" (__NR_##name)); \
-__syscall_return(type,__res); \
-}
-
-#define _syscall1(type,name,type1,arg1) \
-type name(type1 arg1) \
-{ \
-long __res; \
-__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
-	: "=a" (__res) \
-	: "0" (__NR_##name),"ri" ((long)(arg1)) : "memory"); \
-__syscall_return(type,__res); \
-}
-
-#define _syscall2(type,name,type1,arg1,type2,arg2) \
-type name(type1 arg1,type2 arg2) \
-{ \
-long __res; \
-__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
-	: "=a" (__res) \
-	: "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)) \
-	: "memory"); \
-__syscall_return(type,__res); \
-}
-
-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
-type name(type1 arg1,type2 arg2,type3 arg3) \
-{ \
-long __res; \
-__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
-	: "=a" (__res) \
-	: "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \
-		  "d" ((long)(arg3)) : "memory"); \
-__syscall_return(type,__res); \
-}
-
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-{ \
-long __res; \
-__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
-	: "=a" (__res) \
-	: "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \
-	  "d" ((long)(arg3)),"S" ((long)(arg4)) : "memory"); \
-__syscall_return(type,__res); \
-} 
-
-#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
-	  type5,arg5) \
-type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
-{ \
-long __res; \
-__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; movl %1,%%eax ; " \
-                  "int $0x80 ; pop %%ebx" \
-	: "=a" (__res) \
-	: "i" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \
-	  "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)) \
-	: "memory"); \
-__syscall_return(type,__res); \
-}
-
-#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
-	  type5,arg5,type6,arg6) \
-type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
-{ \
-long __res; \
-  struct { long __a1; long __a6; } __s = { (long)arg1, (long)arg6 }; \
-__asm__ volatile ("push %%ebp ; push %%ebx ; movl 4(%2),%%ebp ; " \
-                  "movl 0(%2),%%ebx ; movl %1,%%eax ; int $0x80 ; " \
-                  "pop %%ebx ;  pop %%ebp" \
-	: "=a" (__res) \
-	: "i" (__NR_##name),"0" ((long)(&__s)),"c" ((long)(arg2)), \
-	  "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)) \
-	: "memory"); \
-__syscall_return(type,__res); \
-}
-
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_OLD_STAT
_

Comment 2 Anonymous Emailer 2006-10-11 02:34:49 UTC
Reply-To: arnd@arndb.de

On Wednesday 11 October 2006 08:28, Andrew Morton wrote:
> The medium-term plan is to remove all that syscall code from unistd.h
> altogether.
> 
> So please create your own private version of this stuff - the kernel's copy
> is going away.
> 
> In fact the 2.6.19-rc1 kernel builds OK without it there. 
Comment 3 David Woodhouse 2006-10-11 02:55:42 UTC
On Wed, 2006-10-11 at 11:46 +0200, Arnd Bergmann wrote:
> On Wednesday 11 October 2006 08:28, Andrew Morton wrote:
> > The medium-term plan is to remove all that syscall code from unistd.h
> > altogether.
> > 
> > So please create your own private version of this stuff - the kernel's copy
> > is going away.
> > 
> > In fact the 2.6.19-rc1 kernel builds OK without it there.  Arnd, what's the
> > story?  Can we nuke it all?
> 
> The kernel does not need it at all and we try to make sure no new users
> are introduced.
> 
> The only person that has repeatedly expressed the wish to keep them
> is Andi Kleen, arguing that we should not break existing source code
> that still uses them.

By that logic, we shouldn't make _any_ attempt to clean up the kernel
headers. A large part of that cleanup is removing stuff which just
shouldn't be exposed.

> The current kernel has them inside of '#ifdef __KERNEL__' on most
> architectures, which is completely broken. The three options we have
> are:
> 
> 1. Ignore Andi and remove them from all architectures.
> 2. Change the '#ifdef __KERNEL__' to '#ifndef __KERNEL__' to make
>    Andi happy while preventing kernel users.
> 3. Replace the existing definitions of these macros with generic
>    ones in asm-generic/unistd.h, inside '#ifndef __KERNEL__'.
> 
> I'd prefer the third solution and can do a patch if we get agreement
> on that. I believe David still advocates the first option, based on
> the assumption that all code we care about has stopped using the
> macros already.

They should definitely be removed from all architectures, which is
involved in both #1 and #3.

I don't think we want to set a precedent of adding hacks into _kernel_
header files which are solely for userspace -- especially where where
the C libraries provide a perfectly acceptable alternative -- but if
that's the only way we can move forward without Andi sabotaging it again
by undoing the fixes in private patches which aren't Cc'd to use or the
appropriate mailing lists, then so be it.

Comment 4 Andrew Morton 2006-10-11 08:59:20 UTC
On Wed, 11 Oct 2006 11:07:11 +0100
David Woodhouse <dwmw2@infradead.org> wrote:

> > The current kernel has them inside of '#ifdef __KERNEL__' on most
> > architectures, which is completely broken. The three options we have
> > are:
> > 
> > 1. Ignore Andi and remove them from all architectures.
> > 2. Change the '#ifdef __KERNEL__' to '#ifndef __KERNEL__' to make
> >    Andi happy while preventing kernel users.
> > 3. Replace the existing definitions of these macros with generic
> >    ones in asm-generic/unistd.h, inside '#ifndef __KERNEL__'.
> > 
> > I'd prefer the third solution and can do a patch if we get agreement
> > on that. I believe David still advocates the first option, based on
> > the assumption that all code we care about has stopped using the
> > macros already.
> 
> They should definitely be removed from all architectures, which is
> involved in both #1 and #3.

How about we tidy things up a bit and stick a bit fat

#ifndef __KERNEL__
#warning this is going away in 2.6.20
#endif

in there for 2.6.19, then zap them in 2.6.20?

Comment 5 David Woodhouse 2006-10-11 09:02:48 UTC
On Wed, 2006-10-11 at 09:10 -0700, Andrew Morton wrote:
> 
> How about we tidy things up a bit and stick a bit fat
> 
> #ifndef __KERNEL__
> #warning this is going away in 2.6.20
> #endif
> 
> in there for 2.6.19, then zap them in 2.6.20?

The header file itself isn't -- it's reasonable enough for apps to use
<asm/unistd.h>. It's just the _syscallX() stuff which is gone.

It's already gone in 2.6.18, and the whole of Fedora is built without
using those _syscallX() macros. I really don't think we need to worry
unduly about backward compatibility.

Comment 6 Andrew Morton 2006-10-11 11:00:04 UTC
On Wed, 11 Oct 2006 17:14:18 +0100
David Woodhouse <dwmw2@infradead.org> wrote:

> On Wed, 2006-10-11 at 09:10 -0700, Andrew Morton wrote:
> > 
> > How about we tidy things up a bit and stick a bit fat
> > 
> > #ifndef __KERNEL__
> > #warning this is going away in 2.6.20
> > #endif
> > 
> > in there for 2.6.19, then zap them in 2.6.20?
> 
> The header file itself isn't -- it's reasonable enough for apps to use
> <asm/unistd.h>. It's just the _syscallX() stuff which is gone.

That's what I meant.

#warning the _syscallX macros will be removed in 2.6.20

Plus we put the macros themselves inside `#ifndef __KERNEL__' immediately
so no kernel code henceforth uses them.

Comment 7 David Woodhouse 2006-10-11 13:36:59 UTC
On Wed, 2006-10-11 at 11:11 -0700, Andrew Morton wrote:
> That's what I meant.
> 
> #warning the _syscallX macros will be removed in 2.6.20

Except that as far as userspace is concerned they were _already_
removed, in 2.6.18. We've built an entire distribution without them
present.

And an unconditional warning whenever you #include <asm/unistd.h> would
be a bad thing.

Comment 8 Andrew Morton 2006-10-11 14:49:20 UTC
On Wed, 11 Oct 2006 21:48:28 +0100
David Woodhouse <dwmw2@infradead.org> wrote:

> On Wed, 2006-10-11 at 11:11 -0700, Andrew Morton wrote:
> > That's what I meant.
> > 
> > #warning the _syscallX macros will be removed in 2.6.20
> 
> Except that as far as userspace is concerned they were _already_
> removed, in 2.6.18. We've built an entire distribution without them
> present.
> 
> And an unconditional warning whenever you #include <asm/unistd.h> would
> be a bad thing.

OK, let's just zap it all.

Comment 9 Dave Jones 2007-06-06 00:25:05 UTC
these macros are now removed.

Note You need to log in before you can comment on or make changes to this bug.