summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux')
-rw-r--r--libc/sysdeps/linux/arm/Makefile8
-rw-r--r--libc/sysdeps/linux/common/Makefile26
-rwxr-xr-xlibc/sysdeps/linux/common/str_syscalls.sh35
-rw-r--r--libc/sysdeps/linux/common/syscalls.c32
-rw-r--r--libc/sysdeps/linux/common/unified_syscall_i386.h41
-rw-r--r--libc/sysdeps/linux/i386/Makefile13
-rw-r--r--libc/sysdeps/linux/i386/__init_brk.c33
-rw-r--r--libc/sysdeps/linux/i386/__uClibc_syscall.S39
-rw-r--r--libc/sysdeps/linux/i386/brk.c32
-rw-r--r--libc/sysdeps/linux/i386/sbrk.c35
10 files changed, 279 insertions, 15 deletions
diff --git a/libc/sysdeps/linux/arm/Makefile b/libc/sysdeps/linux/arm/Makefile
index db3cf1966..7d901b769 100644
--- a/libc/sysdeps/linux/arm/Makefile
+++ b/libc/sysdeps/linux/arm/Makefile
@@ -41,12 +41,12 @@ $(LIBC): ar-target
ar-target: $(OBJS)
$(AR) $(ARFLAGS) $(LIBC) $(OBJS)
-$(SOBJS):
- $(CC) $(CFLAGS) $< -c $*.S -o $*.o
+$(SOBJS): %.o : %.S
+ $(CC) $(CFLAGS) -c $< -o $@
$(STRIPTOOL) -x -R .note -R .comment $*.o
-$(COBJS):
- $(CC) $(CFLAGS) $< -c $*.c -o $*.o
+$(COBJS): %.o : %.c
+ $(CC) $(CFLAGS) -c $< -o $@
$(STRIPTOOL) -x -R .note -R .comment $*.o
clean:
diff --git a/libc/sysdeps/linux/common/Makefile b/libc/sysdeps/linux/common/Makefile
index 73190ac9c..3a66e4c2e 100644
--- a/libc/sysdeps/linux/common/Makefile
+++ b/libc/sysdeps/linux/common/Makefile
@@ -25,7 +25,6 @@ TOPDIR=../../../
include $(TOPDIR)Rules.mak
LIBC=$(TOPDIR)libc.a
-
CSRC =closedir.c dirfd.c getdents.c getdnnm.c gethstnm.c getpagesize.c \
isatty.c kernel_version.c mkfifo.c opendir.c readdir.c rewinddir.c \
seekdir.c setegid.c seteuid.c setpgrp.c statfix.c tell.c telldir.c \
@@ -40,7 +39,16 @@ MOBJ=$(shell ./list_syscalls.sh)
OBJ=$(COBJS) $(NIOBJS) $(MOBJ)
-all: $(OBJ) $(LIBC)
+UNIFIED_SYSCALL_HEADER = /dev/null
+STR_SYSCALLS =
+ifeq ($(UNIFIED_SYSCALL),true)
+ ifeq ($(TARGET_ARCH), i386)
+ UNIFIED_SYSCALL_HEADER = unified_syscall_i386.h
+ STR_SYSCALLS = str_syscalls
+ endif
+endif
+
+all: $(STR_SYSCALLS) unified_syscall.h $(OBJ) $(LIBC)
$(LIBC): ar-target
@@ -51,14 +59,22 @@ $(MOBJ): $(MSRC)
$(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
$(STRIPTOOL) -x -R .note -R .comment $*.o
-$(COBJS):
- $(CC) $(CFLAGS) $< -c $*.c -o $*.o
+$(COBJS): %.o : %.c
+ $(CC) $(CFLAGS) -c $< -o $@
$(STRIPTOOL) -x -R .note -R .comment $*.o
$(NIOBJS):
$(CC) $(CFLAGS) $< -c $*.c -o $*.o -fno-inline
$(STRIPTOOL) -x -R .note -R .comment $*.o
+str_syscalls:
+ ./str_syscalls.sh > str_syscalls.c
+ gcc str_syscalls.c -o str_syscalls
+ ./str_syscalls > str_syscalls.h
+
+unified_syscall.h:
+ cat $(UNIFIED_SYSCALL_HEADER) > unified_syscall.h
+
clean:
- rm -f *.[oa] *~ core
+ rm -f *.[oa] *~ core unified_syscall.h str_syscalls.[ch] str_syscalls
diff --git a/libc/sysdeps/linux/common/str_syscalls.sh b/libc/sysdeps/linux/common/str_syscalls.sh
new file mode 100755
index 000000000..66ef6824d
--- /dev/null
+++ b/libc/sysdeps/linux/common/str_syscalls.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+echo "#include <stdio.h>"
+echo "#include <stdlib.h>"
+echo "#include \"../include/asm/unistd.h\""
+echo
+echo "int main(void) {"
+echo
+echo "#define __NR__exit __NR_exit"
+echo "#define __NR___open __NR_open"
+echo "#define __NR__ioctl __NR_ioctl"
+echo "#define __NR__fcntl __NR_fcntl"
+echo "#define __NR__reboot __NR_reboot"
+echo "#define __NR__mmap __NR_mmap"
+echo "#define __NR__syslog __NR_syslog"
+echo "#define __NR__stat __NR_stat"
+echo "#define __NR__lstat __NR_lstat"
+echo "#define __NR__fstat __NR_fstat"
+echo "#define __NR__getdents __NR_getdents"
+echo
+sed -ne 's/^.*_syscall[0-9].*([^,]*, *\([^,)]*\).*/printf("#define __STR_NR_\1 \\\"%d\\\"\\n", __NR_\1);/gp' syscalls.c
+echo
+echo "printf(\"#define __STR_NR_exit __STR_NR__exit\n\");"
+echo "printf(\"#define __STR_NR_open __STR_NR___open\n\");"
+echo "printf(\"#define __STR_NR_ioctl __STR_NR__ioctl\n\");"
+echo "printf(\"#define __STR_NR_fcntl __STR_NR__fcntl\n\");"
+echo "printf(\"#define __STR_NR_reboot __STR_NR__reboot\n\");"
+echo "printf(\"#define __STR_NR_mmap __STR_NR__mmap\n\");"
+echo "printf(\"#define __STR_NR_syslog __STR_NR__syslog\n\");"
+echo "printf(\"#define __STR_NR_stat __STR_NR__stat\n\");"
+echo "printf(\"#define __STR_NR_lstat __STR_NR__lstat\n\");"
+echo "printf(\"#define __STR_NR_fstat __STR_NR__fstat\n\");"
+echo "printf(\"#define __STR_NR_getdents __STR_NR__getdents\n\");"
+echo
+echo "return EXIT_SUCCESS; }"
diff --git a/libc/sysdeps/linux/common/syscalls.c b/libc/sysdeps/linux/common/syscalls.c
index 2f9fb723d..e726ba7fc 100644
--- a/libc/sysdeps/linux/common/syscalls.c
+++ b/libc/sysdeps/linux/common/syscalls.c
@@ -26,13 +26,18 @@
#include <sys/types.h>
#include <sys/syscall.h>
+#define uClibc_syscall_exit(void, _exit, int, status) \
+_syscall1(void, _exit, int, status)
+
+
+#include "unified_syscall.h"
//#define __NR_exit 1
#ifdef L__exit
/* Do not include unistd.h, so gcc doesn't whine about
* _exit returning. It really doesn't return... */
#define __NR__exit __NR_exit
-_syscall1(void, _exit, int, status);
+uClibc_syscall_exit(void, _exit, int, status);
#endif
//#define __NR_fork 2
@@ -347,6 +352,9 @@ _syscall2(int, umount2, const char *, special_file, int, flags);
#include <stdarg.h>
#include <sys/ioctl.h>
#define __NR__ioctl __NR_ioctl
+
+extern int _ioctl(int fd, int request, void *arg);
+
_syscall3(int, _ioctl, int, fd, int, request, void *, arg);
int ioctl(int fd, unsigned long int request, ...)
@@ -368,6 +376,9 @@ int ioctl(int fd, unsigned long int request, ...)
#include <stdarg.h>
#include <fcntl.h>
#define __NR__fcntl __NR_fcntl
+
+extern int _fcntl(int fd, int cmd, long arg);
+
_syscall3(int, _fcntl, int, fd, int, cmd, long, arg);
int fcntl(int fd, int command, ...)
@@ -558,6 +569,9 @@ _syscall2(int, swapon, const char *, path, int, swapflags);
//#define __NR_reboot 88
#ifdef L__reboot
#define __NR__reboot __NR_reboot
+
+extern int _reboot(int magic, int magic2, int flag);
+
_syscall3(int, _reboot, int, magic, int, magic2, int, flag);
int reboot(int flag)
@@ -574,6 +588,8 @@ int reboot(int flag)
#include <unistd.h>
#include <sys/mman.h>
+extern __ptr_t _mmap(unsigned long *buffer);
+
_syscall1(__ptr_t, _mmap, unsigned long *, buffer);
__ptr_t mmap(__ptr_t addr, size_t len, int prot,
@@ -667,6 +683,9 @@ _syscall2(int, socketcall, int, call, unsigned long *, args);
#ifdef L__syslog
#include <unistd.h>
#define __NR__syslog __NR_syslog
+
+extern int _syslog(int type, char *buf, int len);
+
_syscall3(int, _syslog, int, type, char *, buf, int, len);
int klogctl(int type, char *buf, int len)
@@ -694,6 +713,8 @@ _syscall2(int, getitimer, enum __itimer_which, which, struct itimerval *, value)
#define __NR__stat __NR_stat
#include <unistd.h>
#include "statfix.h"
+extern int _stat(const char *file_name, struct kernel_stat *buf);
+
_syscall2(int, _stat, const char *, file_name, struct kernel_stat *, buf);
int stat(const char * file_name, struct libc_stat * cstat)
@@ -713,6 +734,8 @@ int stat(const char * file_name, struct libc_stat * cstat)
#define __NR__lstat __NR_lstat
#include <unistd.h>
#include "statfix.h"
+extern int _lstat(const char *file_name, struct kernel_stat *buf);
+
_syscall2(int, _lstat, const char *, file_name, struct kernel_stat *, buf);
int lstat(const char * file_name, struct libc_stat * cstat)
@@ -732,6 +755,8 @@ int lstat(const char * file_name, struct libc_stat * cstat)
#define __NR__fstat __NR_fstat
#include <unistd.h>
#include "statfix.h"
+extern int _fstat(int filedes, struct kernel_stat *buf);
+
_syscall2(int, _fstat, int, filedes, struct kernel_stat *, buf);
int fstat(int fd, struct libc_stat *cstat)
@@ -878,6 +903,8 @@ SYSCALL__(setfsuid, 1)
#endif
//#define __NR__llseek 140
#ifdef L__llseek
+extern int _llseek(int fd, off_t hoff, off_t loff, loff_t *res, int whence);
+
_syscall5(int, _llseek, int, fd, off_t, hoff, off_t, loff, loff_t *, res,
int, whence);
@@ -904,6 +931,9 @@ _syscall3(int, _getdents, int, fd, char *, dirp, size_t, count);
//#define __NR__newselect 142
#ifdef L__newselect
#include <unistd.h>
+extern int _newselect(int n, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds, struct timeval *timeout);
+
_syscall5(int, _newselect, int, n, fd_set *, readfds, fd_set *, writefds,
fd_set *, exceptfds, struct timeval *, timeout);
diff --git a/libc/sysdeps/linux/common/unified_syscall_i386.h b/libc/sysdeps/linux/common/unified_syscall_i386.h
new file mode 100644
index 000000000..793337af7
--- /dev/null
+++ b/libc/sysdeps/linux/common/unified_syscall_i386.h
@@ -0,0 +1,41 @@
+#undef _syscall0
+#undef _syscall1
+#undef _syscall2
+#undef _syscall3
+#undef _syscall4
+#undef _syscall5
+
+#include "str_syscalls.h"
+
+#undef uClibc_syscall_exit
+#define uClibc_syscall_exit(type,name,type1,arg1) \
+__asm__ ( \
+".text\n.align 4\n.global "###name"\n"#name":;\npushl %ebp;\n" \
+"movl %esp,%ebp;\nsubl $4,%esp;\npushl %ebx;\nmovl 8(%ebp),%ebx;\n" \
+"jmp _start_exit" \
+)
+
+#define unified_syscall_body(name) \
+__asm__ ( \
+".text\n.align 4\n.global "###name"\n"#name":\nmovb $"__STR_NR_##name \
+",%al;\n jmp __uClibc_syscall" \
+)
+
+#define _syscall0(type,name) \
+unified_syscall_body(name)
+
+#define _syscall1(type,name,type1,arg1) \
+unified_syscall_body(name)
+
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+unified_syscall_body(name)
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+unified_syscall_body(name)
+
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+unified_syscall_body(name)
+
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
+unified_syscall_body(name)
+
diff --git a/libc/sysdeps/linux/i386/Makefile b/libc/sysdeps/linux/i386/Makefile
index f4520b4ac..9c487bfd1 100644
--- a/libc/sysdeps/linux/i386/Makefile
+++ b/libc/sysdeps/linux/i386/Makefile
@@ -26,9 +26,12 @@ LIBC=$(TOPDIR)libc.a
ASFLAGS=$(CFLAGS)
SSRC=_start.S longjmp.S setjmp.S #_start.S #clone.S
+ifeq ($(UNIFIED_SYSCALL),true)
+ SSRC += __uClibc_syscall.S
+endif
SOBJS=$(patsubst %.S,%.o, $(SSRC))
-CSRC=fork.c vfork.c
+CSRC=fork.c vfork.c __init_brk.c brk.c sbrk.c
COBJS=$(patsubst %.c,%.o, $(CSRC))
OBJS=$(SOBJS) $(COBJS)
@@ -41,12 +44,12 @@ $(LIBC): ar-target
ar-target: $(OBJS)
$(AR) $(ARFLAGS) $(LIBC) $(OBJS)
-$(SOBJS):
- $(CC) $(CFLAGS) $< -c $*.S -o $*.o
+$(SOBJS): %.o : %.S
+ $(CC) $(CFLAGS) -c $< -o $@
$(STRIPTOOL) -x -R .note -R .comment $*.o
-$(COBJS):
- $(CC) $(CFLAGS) $< -c $*.c -o $*.o
+$(COBJS): %.o : %.c
+ $(CC) $(CFLAGS) -c $< -o $@
$(STRIPTOOL) -x -R .note -R .comment $*.o
clean:
diff --git a/libc/sysdeps/linux/i386/__init_brk.c b/libc/sysdeps/linux/i386/__init_brk.c
new file mode 100644
index 000000000..c2ae482dd
--- /dev/null
+++ b/libc/sysdeps/linux/i386/__init_brk.c
@@ -0,0 +1,33 @@
+/* From libc-5.3.12 */
+
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <errno.h>
+
+void * ___brk_addr = 0;
+
+int
+__init_brk ()
+{
+ if (___brk_addr == 0)
+ {
+#if defined(__PIC__) || defined (__pic__)
+ __asm__ volatile ("pushl %%ebx\n\t"
+ "movl $0,%%ebx\n\t"
+ "int $0x80\n\t"
+ "popl %%ebx"
+ :"=a" (___brk_addr)
+ :"0" (SYS_brk));
+#else
+ __asm__ volatile ("int $0x80"
+ :"=a" (___brk_addr)
+ :"0" (SYS_brk),"b" (0));
+#endif
+ if (___brk_addr == 0)
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+ }
+ return 0;
+}
diff --git a/libc/sysdeps/linux/i386/__uClibc_syscall.S b/libc/sysdeps/linux/i386/__uClibc_syscall.S
new file mode 100644
index 000000000..ecf2d6350
--- /dev/null
+++ b/libc/sysdeps/linux/i386/__uClibc_syscall.S
@@ -0,0 +1,39 @@
+.globl __uClibc_syscall
+
+.text
+ .align 4
+__uClibc_syscall:
+ pushl %ebp
+ movl %esp,%ebp
+ subl $8,%esp
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ /* movl $21,%eax */
+ and $0xff,%eax
+ movl 8(%ebp),%ebx
+ movl 12(%ebp),%ecx
+ movl 16(%ebp),%edx
+ movl 20(%ebp),%esi
+ movl 24(%ebp),%edi
+#APP
+ int $0x80
+#NO_APP
+ movl %eax,-4(%ebp)
+ .p2align 4,,7
+ cmpl $-126,-4(%ebp)
+ jbe .L5
+ movl -4(%ebp),%eax
+ negl %eax
+ movl %eax,errno
+ movl $-1,-4(%ebp)
+.L5:
+ movl -4(%ebp),%edx
+ movl %edx,-8(%ebp)
+ movl -8(%ebp),%eax
+ leal -20(%ebp),%esp
+ popl %ebx
+ popl %esi
+ popl %edi
+ leave
+ ret
diff --git a/libc/sysdeps/linux/i386/brk.c b/libc/sysdeps/linux/i386/brk.c
new file mode 100644
index 000000000..2a776bac1
--- /dev/null
+++ b/libc/sysdeps/linux/i386/brk.c
@@ -0,0 +1,32 @@
+/* From libc-5.3.12 */
+
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <errno.h>
+
+extern void * ___brk_addr;
+
+extern int __init_brk ();
+
+int brk(void * end_data_seg)
+{
+ if (__init_brk () == 0)
+ {
+#if defined(__PIC__) || defined (__pic__)
+ __asm__ volatile ("pushl %%ebx\n\t"
+ "movl %%ecx,%%ebx\n\t"
+ "int $0x80\n\t"
+ "popl %%ebx"
+ :"=a" (___brk_addr)
+ :"0" (SYS_brk),"c" (end_data_seg));
+#else
+ __asm__ volatile ("int $0x80"
+ :"=a" (___brk_addr)
+ :"0" (SYS_brk),"b" (end_data_seg));
+#endif
+ if (___brk_addr == end_data_seg)
+ return 0;
+ errno = ENOMEM;
+ }
+ return -1;
+}
diff --git a/libc/sysdeps/linux/i386/sbrk.c b/libc/sysdeps/linux/i386/sbrk.c
new file mode 100644
index 000000000..f5099d7e8
--- /dev/null
+++ b/libc/sysdeps/linux/i386/sbrk.c
@@ -0,0 +1,35 @@
+/* From libc-5.3.12 */
+
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <errno.h>
+
+extern void * ___brk_addr;
+
+extern int __init_brk (void);
+
+void *
+sbrk(ptrdiff_t increment)
+{
+ if (__init_brk () == 0)
+ {
+ void * tmp = ___brk_addr+increment;
+#if defined(__PIC__) || defined (__pic__)
+ __asm__ volatile ("pushl %%ebx\n\t"
+ "movl %%ecx,%%ebx\n\t"
+ "int $0x80\n\t"
+ "popl %%ebx"
+ :"=a" (___brk_addr)
+ :"0" (SYS_brk),"c" (tmp));
+#else
+ __asm__ volatile ("int $0x80"
+ :"=a" (___brk_addr)
+ :"0" (SYS_brk),"b" (tmp));
+#endif
+ if (___brk_addr == tmp)
+ return tmp-increment;
+ errno = ENOMEM;
+ return ((void *) -1);
+ }
+ return ((void *) -1);
+}