Browse Source

This adds in support for PIC on x86. Unfortunately, this will break
all arches till they add in an libc/sysdeps/linux/<arch>/bits/syscalls.h
file. Sorry about there, there was no other way...
-Erik

Eric Andersen 23 years ago
parent
commit
f0d383b45b
3 changed files with 87 additions and 5 deletions
  1. 1 1
      Rules.mak
  2. 5 4
      include/sys/syscall.h
  3. 81 0
      libc/sysdeps/linux/i386/bits/syscalls.h

+ 1 - 1
Rules.mak

@@ -45,7 +45,7 @@ endif
 
 ARFLAGS=r
 
-CCFLAGS=$(WARNINGS) $(OPTIMIZATION) -fno-builtin -nostdinc $(CPUFLAGS) -I$(TOPDIR)include -I$(GCCINCDIR) -I. -D_LIBC
+CCFLAGS=$(WARNINGS) $(OPTIMIZATION) -fPIC -fno-builtin -nostdinc $(CPUFLAGS) -I$(TOPDIR)include -I$(GCCINCDIR) -I. -D_LIBC
 TARGET_CCFLAGS=--uclibc-use-build-dir $(WARNINGS) $(OPTIMIZATION) $(CPUFLAGS)
 
 CFLAGS=$(ARCH_CFLAGS) $(CCFLAGS) $(DEFS) $(ARCH_CFLAGS2)

+ 5 - 4
include/sys/syscall.h

@@ -19,10 +19,11 @@
 #ifndef _SYSCALL_H
 #define _SYSCALL_H	1
 
-/* This file should list the numbers of the system the system knows.
-   But instead of duplicating this we use the information available
-   from the kernel sources.  */
-#include <asm/unistd.h>
+/* This file includes the kernel's syscall list, and then includes our own
+ * private copy of the _syscall macros.  This is important, since on
+ * some arches (such as i386), the kernel _syscall[0-5] macros don't
+ * handle things like PIC code, so we can't use them. */
+#include <bits/syscalls.h>
 
 #ifndef _LIBC
 /* The Linux kernel header file defines macros `__NR_<name>', but some

+ 81 - 0
libc/sysdeps/linux/i386/bits/syscalls.h

@@ -0,0 +1,81 @@
+#include <asm/unistd.h>
+
+#undef __syscall_return
+#define __syscall_return(type, res) \
+do { \
+	if ((unsigned long)(res) >= (unsigned long)(-125)) { \
+		errno = -(res); \
+		res = -1; \
+	} \
+	return (type) (res); \
+} while (0)
+
+
+#if defined(__PIC__)
+
+/*
+ * PIC uses %ebx, so we need to save it during system calls
+ */
+
+#undef _syscall1
+#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),"r" ((long)(arg1))); \
+__syscall_return(type,__res); \
+}
+
+#undef _syscall2
+#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),"r" ((long)(arg1)),"c" ((long)(arg2))); \
+__syscall_return(type,__res); \
+}
+
+#undef _syscall3
+#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),"r" ((long)(arg1)),"c" ((long)(arg2)), \
+		"d" ((long)(arg3))); \
+__syscall_return(type,__res); \
+}
+
+#undef _syscall4
+#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),"r" ((long)(arg1)),"c" ((long)(arg2)), \
+	  "d" ((long)(arg3)),"S" ((long)(arg4))); \
+__syscall_return(type,__res); \
+}
+
+#undef _syscall5
+#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; int $0x80; pop %%ebx" \
+	: "=a" (__res) \
+	: "0" (__NR_##name),"m" ((long)(arg1)),"c" ((long)(arg2)), \
+	  "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \
+__syscall_return(type,__res); \
+}
+
+#endif /* __PIC__ */
+
+