Contents of /trunk/mkinitrd-magellan/klibc/usr/klibc/syscalls.pl
Parent Directory | Revision Log
Revision 532 -
(show annotations)
(download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 6587 byte(s)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 6587 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd
1 | #!/usr/bin/perl |
2 | # |
3 | # Script to parse the SYSCALLS file and generate appropriate |
4 | # stubs. |
5 | # |
6 | # Pass 1: generate the C array of sizes |
7 | # Pass 2: generate the syscall stubs and other output |
8 | # |
9 | |
10 | # |
11 | # Convert a string to a C array of characters, |
12 | # e.g. foo -> 'f','o','o','\0', |
13 | # |
14 | sub chararray($) { |
15 | use bytes; |
16 | |
17 | my($s) = @_; |
18 | my($i, $c); |
19 | my($a) = ''; |
20 | |
21 | for ($i = 0; $i < length($s); $i++) { |
22 | $c = substr($s, $i, 1); |
23 | if (ord($c) < 32 || ord($c) > 126) { |
24 | $a .= sprintf("0x%02x,", ord($c)); |
25 | } elsif ($c eq "\\" || $c eq "\'") { |
26 | $a .= "\'\\$c\',"; |
27 | } else { |
28 | $a .= "\'$c\',"; |
29 | } |
30 | } |
31 | |
32 | return $a; |
33 | } |
34 | |
35 | # |
36 | # This extracts an ASCIIZ string for the type and the additional |
37 | # information. This is open-coded, because unpack("Z*") apparently |
38 | # is broken in Perl 5.6.1. |
39 | # |
40 | sub get_one_type($) { |
41 | use bytes; |
42 | |
43 | my($typestr) = @_; |
44 | my $i, $c; |
45 | my $l = length($typestr); |
46 | |
47 | for ($i = 0; $i < $l-3; $i++) { |
48 | $c = substr($typestr, $i, 1); |
49 | if ($c eq "\0") { |
50 | return (substr($typestr, 0, $i), |
51 | unpack("CC", substr($typestr, $i+1, 2)), |
52 | substr($typestr, $i+3)); |
53 | } |
54 | } |
55 | |
56 | return (undef, undef, undef, undef); |
57 | } |
58 | |
59 | $v = $ENV{'KBUILD_VERBOSE'}; |
60 | $quiet = defined($v) && ($v == 0) ? 1 : undef; |
61 | |
62 | @args = (); |
63 | undef $pass; |
64 | for $arg ( @ARGV ) { |
65 | if ( $arg =~ /^-/ ) { |
66 | if ( $arg eq '-q' ) { |
67 | $quiet = 1; |
68 | } elsif ( $arg eq '-v' ) { |
69 | $quiet = 0; |
70 | } elsif ( $arg =~ /\-([0-9]+)$/ ) { |
71 | $pass = $1+0; |
72 | } else { |
73 | die "$0: Unknown option: $arg\n"; |
74 | } |
75 | } else { |
76 | push(@args, $arg); |
77 | } |
78 | } |
79 | ($file, $sysstub, $arch, $bits, $unistd, $outputdir, |
80 | $havesyscall, $typesize) = @args; |
81 | |
82 | if (!$pass) { |
83 | die "$0: Need to specify pass\n"; |
84 | } |
85 | |
86 | $quiet = ($pass != 2) unless defined($quiet); |
87 | |
88 | require "$sysstub"; |
89 | |
90 | if (!open(UNISTD, "< $unistd\0")) { |
91 | die "$0: $unistd: $!\n"; |
92 | } |
93 | |
94 | while ( defined($line = <UNISTD>) ) { |
95 | chomp $line; |
96 | |
97 | if ( $line =~ /^\#\s*define\s+__NR_([A-Za-z0-9_]+)\s+(.*\S)\s*$/ ) { |
98 | $syscalls{$1} = $2; |
99 | print STDERR "SYSCALL FOUND: $1\n" unless ( $quiet ); |
100 | } |
101 | } |
102 | close(UNISTD); |
103 | |
104 | if ($pass == 2) { |
105 | use bytes; |
106 | |
107 | if (!open(TYPESIZE, "< $typesize\0")) { |
108 | die "$0: $typesize: $!\n"; |
109 | } |
110 | |
111 | binmode TYPESIZE; |
112 | |
113 | $len = -s TYPESIZE; |
114 | if (read(TYPESIZE, $typebin, $len) != $len) { |
115 | die "$0: $typesize: short read: $!\n"; |
116 | } |
117 | close(TYPESIZE); |
118 | |
119 | $ix = index($typebin, "\x7a\xc8\xdb\x4e\x97\xb4\x9c\x19"); |
120 | if ($ix < 0) { |
121 | die "$0: $typesize: magic number not found\n"; |
122 | } |
123 | |
124 | # Remove magic number and bytes before it |
125 | $typebin = substr($typebin, $ix+8); |
126 | |
127 | # Expand the types until a terminating null |
128 | %typesize = (); |
129 | while (1) { |
130 | my $n, $sz, $si; |
131 | ($n, $sz, $si, $typebin) = get_one_type($typebin); |
132 | last if (length($n) == 0); |
133 | $typesize{$n} = $sz; |
134 | $typesign{$n} = $si; |
135 | print STDERR "TYPE $n: size $sz, sign $si\n" unless ($quiet); |
136 | } |
137 | } else { |
138 | # List here any types which should be sized even if they never occur |
139 | # in any system calls at all. |
140 | %type_list = ('int' => 1, 'long' => 1, 'long long' => 1, |
141 | 'void *' => 1, |
142 | 'intptr_t' => 1, 'uintptr_t' => 1, |
143 | 'intmax_t' => 1, 'uintmax_t' => 1); |
144 | } |
145 | |
146 | if ($pass == 2) { |
147 | if (!open(HAVESYS, "> $havesyscall\0")) { |
148 | die "$0: $havesyscall: $!\n"; |
149 | } |
150 | |
151 | print HAVESYS "#ifndef _KLIBC_HAVESYSCALL_H\n"; |
152 | print HAVESYS "#define _KLIBC_HAVESYSCALL_H 1\n\n"; |
153 | } |
154 | |
155 | if (!open(FILE, "< $file\0")) { |
156 | die "$0: $file: $!\n"; |
157 | } |
158 | |
159 | |
160 | if ($pass == 2) { |
161 | print "syscall-objs := "; |
162 | } |
163 | |
164 | |
165 | while ( defined($line = <FILE>) ) { |
166 | chomp $line; |
167 | $line =~ s/\s*(|\#.*|\/\/.*)$//; # Strip comments and trailing blanks |
168 | next unless $line; |
169 | |
170 | if ( $line =~ /^\s*(\<[^\>]+\>\s+|)([A-Za-z0-9_\*\s]+)\s+([A-Za-z0-9_,]+)(|\@[A-Za-z0-9_]+)(|\:\:[A-Za-z0-9_]+)\s*\(([^\:\)]*)\)\s*\;$/ ) { |
171 | $archs = $1; |
172 | $type = $2; |
173 | $snames = $3; |
174 | $stype = $4; |
175 | $fname = $5; |
176 | $argv = $6; |
177 | |
178 | $doit = 1; |
179 | $maybe = 0; |
180 | if ( $archs ne '' ) { |
181 | die "$file:$.: Invalid architecture spec: <$archs>\n" |
182 | unless ( $archs =~ /^\<(|\?)(|\!)([^\>\!\?]*)\>/ ); |
183 | $maybe = $1 ne ''; |
184 | $not = $2 ne ''; |
185 | $list = $3; |
186 | |
187 | $doit = $not || ($list eq ''); |
188 | |
189 | @list = split(/,/, $list); |
190 | foreach $a ( @list ) { |
191 | if ( $a eq $arch || $a eq $bits ) { |
192 | $doit = !$not; |
193 | last; |
194 | } |
195 | } |
196 | } |
197 | next if ( ! $doit ); |
198 | |
199 | undef $sname; |
200 | foreach $sn ( split(/,/, $snames) ) { |
201 | if ( defined $syscalls{$sn} ) { |
202 | $sname = $sn; |
203 | last; |
204 | } |
205 | } |
206 | if ( !defined($sname) ) { |
207 | next if ( $maybe ); |
208 | die "$file:$.: Undefined system call: $snames\n"; |
209 | } |
210 | |
211 | $type =~ s/\s*$//; |
212 | $stype =~ s/^\@//; |
213 | |
214 | if ( $fname eq '' ) { |
215 | $fname = $sname; |
216 | } else { |
217 | $fname =~ s/^\:\://; |
218 | } |
219 | |
220 | $argv =~ s/^\s+//; |
221 | $argv =~ s/\s+$//; |
222 | |
223 | if ($argv eq 'void') { |
224 | @args = (); |
225 | } else { |
226 | @args = split(/\s*\,\s*/, $argv); |
227 | } |
228 | |
229 | if ($pass == 1) { |
230 | # Pass 1: Add the types to the type list |
231 | foreach $a (@args) { |
232 | $type_list{$a}++; |
233 | } |
234 | } else { |
235 | # Pass 2: make sure all types defined, and actually generate stubs |
236 | |
237 | foreach $a (@args) { |
238 | if (!defined($typesize{$a})) { |
239 | die "$0: $typesize: type name missing: $a\n"; |
240 | } |
241 | } |
242 | |
243 | print HAVESYS "#define _KLIBC_HAVE_SYSCALL_${fname} ${sname}\n"; |
244 | print " \\\n\t${fname}.o"; |
245 | make_sysstub($outputdir, $fname, $type, $sname, $stype, @args); |
246 | } |
247 | } else { |
248 | die "$file:$.: Could not parse input: \"$line\"\n"; |
249 | } |
250 | } |
251 | |
252 | if ($pass == 1) { |
253 | # Pass 1: generate typesize.c |
254 | if (!open(TYPESIZE, "> $typesize")) { |
255 | die "$0: cannot create file: $typesize: $!\n"; |
256 | } |
257 | |
258 | print TYPESIZE "#include \"syscommon.h\"\n"; |
259 | |
260 | # This compares -2 < 1 in the appropriate type, which is true for |
261 | # signed types and false for unsigned types. We use -2 and 1 since |
262 | # gcc complains about comparing unsigned types with zero, and might |
263 | # complain equally about -1 in the future. |
264 | # |
265 | # This test is valid (as in, doesn't cause the compiler to barf) |
266 | # for pointers as well as for integral types; if we ever add system |
267 | # calls which take any other kinds of types than that then this needs |
268 | # to be smarter. |
269 | print TYPESIZE "#define SIGNED(X) ((X)-2 < (X)1)\n"; |
270 | |
271 | print TYPESIZE "\n"; |
272 | print TYPESIZE "const unsigned char type_sizes[] = {\n"; |
273 | print TYPESIZE "\t0x7a,0xc8,0xdb,0x4e,0x97,0xb4,0x9c,0x19, /* magic */\n"; |
274 | foreach $t (sort(keys(%type_list))) { |
275 | print TYPESIZE "\t", chararray($t), "0, sizeof($t), SIGNED($t),\n"; |
276 | } |
277 | print TYPESIZE "\t0, 0,\n"; # End sentinel |
278 | print TYPESIZE "};\n"; |
279 | close(TYPESIZE); |
280 | } else { |
281 | # Pass 2: finalize output files |
282 | print "\n"; |
283 | |
284 | print HAVESYS "\n#endif\n"; |
285 | close(HAVESYS); |
286 | } |