diff options
Diffstat (limited to 'libc/sysdeps/linux')
-rw-r--r-- | libc/sysdeps/linux/arm/Makefile | 8 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/Makefile | 26 | ||||
-rwxr-xr-x | libc/sysdeps/linux/common/str_syscalls.sh | 35 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/syscalls.c | 32 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/unified_syscall_i386.h | 41 | ||||
-rw-r--r-- | libc/sysdeps/linux/i386/Makefile | 13 | ||||
-rw-r--r-- | libc/sysdeps/linux/i386/__init_brk.c | 33 | ||||
-rw-r--r-- | libc/sysdeps/linux/i386/__uClibc_syscall.S | 39 | ||||
-rw-r--r-- | libc/sysdeps/linux/i386/brk.c | 32 | ||||
-rw-r--r-- | libc/sysdeps/linux/i386/sbrk.c | 35 |
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); +} |