summaryrefslogtreecommitdiff
path: root/libc/gnu_i386/mksyscall
diff options
context:
space:
mode:
Diffstat (limited to 'libc/gnu_i386/mksyscall')
-rw-r--r--libc/gnu_i386/mksyscall123
1 files changed, 123 insertions, 0 deletions
diff --git a/libc/gnu_i386/mksyscall b/libc/gnu_i386/mksyscall
new file mode 100644
index 0000000..b655e9e
--- /dev/null
+++ b/libc/gnu_i386/mksyscall
@@ -0,0 +1,123 @@
+# Copyright (C) 1995-1997 Robert de Bath <rdebath@cix.compulink.co.uk>
+# This file is part of the Linux-8086 C library and is distributed
+# under the GNU Library General Public License.
+#
+# This script generates the 'simple' system calls for the 386
+#
+# Each call is put into it's own object file, if the semantics of the
+# call are not correct UNIX then the 4th field in the dat file has a
+# marker and the function is generated with a __ prefix.
+#
+#
+# Different levels of squeeze
+# 0 = each is complete
+# 1 = Short codes calling common function
+
+rm -f syscall.c syscall.mak
+
+tr '[A-Z]' '[a-z]' < syscall.dat | \
+awk 'BEGIN{
+ print "# Copyright (C) 1995-1997 Robert de Bath <rdebath@cix.compulink.co.uk>" > "syscall.mak";
+ print "# This file is part of the Linux-8086 C library and is distributed" > "syscall.mak";
+ print "# under the GNU Library General Public License." > "syscall.mak";
+ print "# " > "syscall.mak";
+ print "# This file is automatically generated\n" > "syscall.mak"
+
+ print "# Copyright (C) 1995-1997 Robert de Bath <rdebath@cix.compulink.co.uk>";
+ print "# This file is part of the Linux-8086 C library and is distributed";
+ print "# under the GNU Library General Public License.";
+ print "# ";
+ print "# This file is automatically generated */\n"
+ obj="OBJ=";
+
+ print "# Standard start\n\n"
+ printf("#ifndef __MSDOS__\n");
+ printf("#ifdef __AS386_32__\n");
+ printf(" .text\n");
+ printf(" .align 16\n");
+
+ COMPACT=0;
+}
+/^[ ]*#/ { next; }
+/^[ ]*$/ { next; }
+{
+ if( $2 > max_call ) max_call = $2;
+
+ if( $3 == "x" || $3 == "" ) next;
+ else if( $4 == "-" ) next;
+ else if( $4 == "*" ) funcname="__" $1;
+ else funcname=$1;
+
+ if( length(obj) > 60 )
+ {
+ printf("%s\t\\\n", obj) > "syscall.mak";
+ obj=" ";
+ }
+ obj=obj funcname ".o ";
+
+ printf "# CALL %s\n\n", $0;
+
+ printf(".ifdef L_%s\n", funcname);
+ printf(".globl %s\n", funcname);
+ printf(".type %s,@function\n", funcname);
+ printf("%s:\n", funcname);
+
+ # Inline assembler max to 5 args (20 bytes)
+ if( $3 != 4 && $3 != 5 && ( COMPACT || $3 > 5 ))
+ {
+ printf(" mov %%eax,#%d\n", $2);
+ printf(" br sys_call%d\n", $3);
+ }
+ else
+ {
+ printf(" pushl %%ebp\n");
+ printf(" movl %%esp,%%ebp\n");
+ printf(" pushl %%ebx\n");
+ if( $3 >= 1 ) printf(" mov 8(%%ebp),%%ebx\n");
+ if( $3 >= 2 ) printf(" mov 12(%%ebp),%%ecx\n");
+ if( $3 >= 3 ) printf(" mov 16(%%ebp),%%edx\n");
+ if( $3 >= 4 ) printf(" push %%esi\n");
+ if( $3 >= 4 ) printf(" mov 20(%%ebp),%%esi\n");
+ if( $3 >= 5 ) printf(" push %%edi\n");
+ if( $3 >= 5 ) printf(" mov 24(%%ebp),%%edi\n");
+ printf(" mov $%d,%%eax\n", $2);
+ printf(" int $0x80\n");
+
+ if( $3 >= 5 ) printf(" pop %%edi\n");
+ if( $3 >= 4 ) printf(" pop %%esi\n");
+ printf(" pop %%ebx\n");
+
+ printf(" test %%eax,%%eax\n");
+ printf(" jge syscall_ok\n");
+ printf(" neg %%eax\n");
+ printf(" mov %%eax,errno\n");
+ printf(" mov $-1,%%eax\n");
+ printf("syscall_ok:\n");
+ printf(" movl %%ebp,%%esp\n");
+ printf(" popl %%ebp\n");
+ printf(" ret\n");
+ }
+ printf(".endif\n\n");
+}
+END{
+
+ printf("#endif /* __AS386_32__ */\n\n");
+ printf("#endif /* __MSDOS__ */\n\n");
+ printf("%s\n", obj) > "syscall.mak";
+ printf "\n" > "syscall.mak";
+
+}' > syscall.s
+
+cat >> syscall.mak <<\!
+
+CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS)
+
+all: $(LIBC)($(OBJ))
+ @$(RM) $(OBJ)
+
+$(LIBC)($(OBJ)): syscall.dat mksyscall
+ $(AS) --defsym L_$*=0 syscall.s -o $*.o
+ $(AR) $(ARFLAGS) $@ $*.o
+!
+
+exit $?