1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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 $?
|