1855239e5SApple OSS Distributions#!/usr/bin/perl
2855239e5SApple OSS Distributions#
3a3bb9fccSApple OSS Distributions# Copyright (c) 2006-2014 Apple Inc. All rights reserved.
4855239e5SApple OSS Distributions#
5855239e5SApple OSS Distributions# @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6855239e5SApple OSS Distributions#
7855239e5SApple OSS Distributions# This file contains Original Code and/or Modifications of Original Code
8855239e5SApple OSS Distributions# as defined in and that are subject to the Apple Public Source License
9855239e5SApple OSS Distributions# Version 2.0 (the 'License'). You may not use this file except in
10855239e5SApple OSS Distributions# compliance with the License. Please obtain a copy of the License at
11855239e5SApple OSS Distributions# http://www.opensource.apple.com/apsl/ and read it before using this
12855239e5SApple OSS Distributions# file.
13855239e5SApple OSS Distributions#
14855239e5SApple OSS Distributions# The Original Code and all software distributed under the License are
15855239e5SApple OSS Distributions# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16855239e5SApple OSS Distributions# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17855239e5SApple OSS Distributions# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18855239e5SApple OSS Distributions# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19855239e5SApple OSS Distributions# Please see the License for the specific language governing rights and
20855239e5SApple OSS Distributions# limitations under the License.
21855239e5SApple OSS Distributions#
22855239e5SApple OSS Distributions# @APPLE_OSREFERENCE_LICENSE_HEADER_END@
23855239e5SApple OSS Distributions#
24855239e5SApple OSS Distributions##########################################################################
25855239e5SApple OSS Distributions#
26186b8fceSApple OSS Distributions# % create-syscalls.pl syscalls.master custom-directory platforms-directory platform-name out-directory
27855239e5SApple OSS Distributions#
28855239e5SApple OSS Distributions# This script fills the the out-directory with a Makefile.inc and *.s
29855239e5SApple OSS Distributions# files to create the double-underbar syscall stubs.  It reads the
30855239e5SApple OSS Distributions# syscall.master file to get the symbol names and number of arguments,
31855239e5SApple OSS Distributions# and whether Libsystem should automatically create the (non-double-underbar)
32855239e5SApple OSS Distributions# stubs if Libc doesn't provide a wrapper.  Which system calls will get
33855239e5SApple OSS Distributions# the automatic treatment is writen to the libsyscall.list file, also
34855239e5SApple OSS Distributions# written to the out-directory.
35855239e5SApple OSS Distributions#
36855239e5SApple OSS Distributions# The custom-directory contains:
37855239e5SApple OSS Distributions# 1. SYS.h - used by the automatically created *.s and custom files
38855239e5SApple OSS Distributions# 2. custom.s - contains architecture specific additional system calls and
39855239e5SApple OSS Distributions#    auxilliary routines (like cerror)
40855239e5SApple OSS Distributions# 3. special case double-underbar stub files - which are copied into
41855239e5SApple OSS Distributions#    the out-directory
42855239e5SApple OSS Distributions#
43855239e5SApple OSS Distributions##########################################################################
44855239e5SApple OSS Distributions
45855239e5SApple OSS Distributionsuse strict;
46855239e5SApple OSS Distributionsuse File::Basename ();
47855239e5SApple OSS Distributionsuse File::Copy ();
48855239e5SApple OSS Distributionsuse File::Spec;
49855239e5SApple OSS Distributionsuse IO::File;
50855239e5SApple OSS Distributions
51855239e5SApple OSS Distributionsmy $MyName = File::Basename::basename($0);
52855239e5SApple OSS Distributions
53855239e5SApple OSS Distributionsmy @CustomSrc = qw(custom.s);
54855239e5SApple OSS Distributions
55855239e5SApple OSS Distributionsmy @Architectures = split /\s/, $ENV{"ARCHS"};
56855239e5SApple OSS Distributionsmy @Copy = (qw(SYS.h), @CustomSrc);
57855239e5SApple OSS Distributionsmy $CustomDir;
58855239e5SApple OSS Distributionsmy $PlatformsDir;
59855239e5SApple OSS Distributionsmy $PlatformName;
60855239e5SApple OSS Distributionsmy $OutDir;
61855239e5SApple OSS Distributions# size in bytes of known types (only used for i386)
62855239e5SApple OSS Distributionsmy %TypeBytes = (
63855239e5SApple OSS Distributions    'au_asid_t'		=> 4,
640f3703acSApple OSS Distributions    'sae_associd_t'	=> 4,
65855239e5SApple OSS Distributions    'caddr_t'		=> 4,
66*8d741a5dSApple OSS Distributions    'caddr_ut'	=> 4,
670f3703acSApple OSS Distributions    'sae_connid_t'	=> 4,
68855239e5SApple OSS Distributions    'gid_t'		=> 4,
69855239e5SApple OSS Distributions    'id_t'		=> 4,
70855239e5SApple OSS Distributions    'idtype_t'		=> 4,
71855239e5SApple OSS Distributions    'int'		=> 4,
72855239e5SApple OSS Distributions    'int32_t'		=> 4,
73855239e5SApple OSS Distributions    'int64_t'		=> 8,
74855239e5SApple OSS Distributions    'key_t'		=> 4,
75855239e5SApple OSS Distributions    'long'		=> 4,
76855239e5SApple OSS Distributions    'mach_port_name_t'	=> 4,
77855239e5SApple OSS Distributions    'mode_t'		=> 4,
78855239e5SApple OSS Distributions    'off_t'		=> 8,
79855239e5SApple OSS Distributions    'pid_t'		=> 4,
80855239e5SApple OSS Distributions    'semun_t'		=> 4,
81855239e5SApple OSS Distributions    'sigset_t'		=> 4,
82855239e5SApple OSS Distributions    'size_t'		=> 4,
83*8d741a5dSApple OSS Distributions    'size_ut'		=> 4,
84855239e5SApple OSS Distributions    'socklen_t'		=> 4,
85855239e5SApple OSS Distributions    'ssize_t'		=> 4,
86855239e5SApple OSS Distributions    'u_int'		=> 4,
87855239e5SApple OSS Distributions    'u_long'		=> 4,
88855239e5SApple OSS Distributions    'uid_t'		=> 4,
89855239e5SApple OSS Distributions    'uint32_t'		=> 4,
90855239e5SApple OSS Distributions    'uint64_t'		=> 8,
91855239e5SApple OSS Distributions    'user_addr_t'	=> 4,
92*8d741a5dSApple OSS Distributions    'user_addr_ut'	=> 4,
93855239e5SApple OSS Distributions    'user_long_t'	=> 4,
94855239e5SApple OSS Distributions    'user_size_t'	=> 4,
95*8d741a5dSApple OSS Distributions    'user_size_ut'	=> 4,
96855239e5SApple OSS Distributions    'user_ssize_t'	=> 4,
97855239e5SApple OSS Distributions    'user_ulong_t'	=> 4,
98186b8fceSApple OSS Distributions    'uuid_t'		=> 4,
99855239e5SApple OSS Distributions);
100855239e5SApple OSS Distributions
101cc9a6355SApple OSS Distributions# Types that potentially have different sizes in user-space compared to
102cc9a6355SApple OSS Distributions# kernel-space as well as whether the value should be sign/zero-extended when
103cc9a6355SApple OSS Distributions# passing the user/kernel boundary.
104cc9a6355SApple OSS Distributionsmy %UserKernelMismatchTypes = (
105cc9a6355SApple OSS Distributions    'long'          => 'SIGN_EXTEND',
106cc9a6355SApple OSS Distributions    'size_t'        => 'ZERO_EXTEND',
107*8d741a5dSApple OSS Distributions    'size_ut'       => 'ZERO_EXTEND',
108cc9a6355SApple OSS Distributions    'u_long'        => 'ZERO_EXTEND',
109cc9a6355SApple OSS Distributions    'user_size_t'   => 'ZERO_EXTEND',
110*8d741a5dSApple OSS Distributions    'user_size_ut'  => 'ZERO_EXTEND',
111cc9a6355SApple OSS Distributions    'user_ssize_t'  => 'SIGN_EXTEND'
112cc9a6355SApple OSS Distributions);
113cc9a6355SApple OSS Distributions
114855239e5SApple OSS Distributions# Moving towards storing all data in this hash, then we always know
115855239e5SApple OSS Distributions# if data is aliased or not, or promoted or not.
116855239e5SApple OSS Distributionsmy %Symbols = (
117855239e5SApple OSS Distributions    "syscall" => {
118855239e5SApple OSS Distributions        c_sym => "syscall",
119855239e5SApple OSS Distributions        syscall => "syscall",
120855239e5SApple OSS Distributions        asm_sym => "_syscall",
121855239e5SApple OSS Distributions        is_private => undef,
122855239e5SApple OSS Distributions        is_custom => undef,
123855239e5SApple OSS Distributions        nargs => 0,
124855239e5SApple OSS Distributions        bytes => 0,
125855239e5SApple OSS Distributions        aliases => {},
126cc9a6355SApple OSS Distributions        mismatch_args => {}, # Arguments that might need to be zero/sign-extended
127855239e5SApple OSS Distributions    },
128855239e5SApple OSS Distributions);
129855239e5SApple OSS Distributions
130d0c1fef6SApple OSS Distributions# An explicit list of cancelable syscalls. For creating stubs that call the
131d0c1fef6SApple OSS Distributions# cancellable version of cerror.
132d0c1fef6SApple OSS Distributionsmy @Cancelable = qw/
133d0c1fef6SApple OSS Distributions	accept access aio_suspend
134186b8fceSApple OSS Distributions	close connect connectx
135186b8fceSApple OSS Distributions	disconnectx
136a3bb9fccSApple OSS Distributions	faccessat fcntl fdatasync fpathconf fstat fstatat fsync
137d0c1fef6SApple OSS Distributions	getlogin
138d0c1fef6SApple OSS Distributions	ioctl
139a3bb9fccSApple OSS Distributions	link linkat lseek lstat
140d0c1fef6SApple OSS Distributions	msgrcv msgsnd msync
141a3bb9fccSApple OSS Distributions	open openat
142bb611c8fSApple OSS Distributions	pathconf peeloff poll posix_spawn pread preadv pselect pwrite pwritev
143a3bb9fccSApple OSS Distributions	read readv recvfrom recvmsg rename renameat
144a3bb9fccSApple OSS Distributions	rename_ext
145d0c1fef6SApple OSS Distributions	__semwait_signal __sigwait
146a3bb9fccSApple OSS Distributions	select sem_wait semop sendmsg sendto sigsuspend stat symlink symlinkat sync
147a3bb9fccSApple OSS Distributions	unlink unlinkat
148d0c1fef6SApple OSS Distributions	wait4 waitid write writev
149d0c1fef6SApple OSS Distributions/;
150d0c1fef6SApple OSS Distributions
151855239e5SApple OSS Distributionssub usage {
152186b8fceSApple OSS Distributions    die "Usage: $MyName syscalls.master custom-directory platforms-directory platform-name out-directory\n";
153855239e5SApple OSS Distributions}
154855239e5SApple OSS Distributions
155855239e5SApple OSS Distributions##########################################################################
156855239e5SApple OSS Distributions# Read the syscall.master file and collect the system call names and number
157855239e5SApple OSS Distributions# of arguments.  It looks for the NO_SYSCALL_STUB quailifier following the
158855239e5SApple OSS Distributions# prototype to determine if no automatic stub should be created by Libsystem.
159a5e72196SApple OSS Distributions#
160a5e72196SApple OSS Distributions# The `sys_` prefix is stripped from syscall names, and is only kept for
161a5e72196SApple OSS Distributions# the kernel symbol in order to avoid namespace clashes and identify
162a5e72196SApple OSS Distributions# syscalls more easily.
163855239e5SApple OSS Distributions#
164855239e5SApple OSS Distributions# For the #if lines in syscall.master, all macros are assumed to be defined,
165855239e5SApple OSS Distributions# except COMPAT_GETFSSTAT (assumed undefined).
166855239e5SApple OSS Distributions##########################################################################
167855239e5SApple OSS Distributionssub readMaster {
168855239e5SApple OSS Distributions    my $file = shift;
169855239e5SApple OSS Distributions    local $_;
170855239e5SApple OSS Distributions    my $f = IO::File->new($file, 'r');
171855239e5SApple OSS Distributions    die "$MyName: $file: $!\n" unless defined($f);
172855239e5SApple OSS Distributions    my $line = 0;
173855239e5SApple OSS Distributions    my $skip = 0;
174bb611c8fSApple OSS Distributions    my $allow_missing = 0;
175855239e5SApple OSS Distributions    while(<$f>) {
176855239e5SApple OSS Distributions        $line++;
177855239e5SApple OSS Distributions        if(/^#\s*endif/) {
178855239e5SApple OSS Distributions            $skip = 0;
179bb611c8fSApple OSS Distributions            $allow_missing = 0;
180855239e5SApple OSS Distributions            next;
181855239e5SApple OSS Distributions        }
182855239e5SApple OSS Distributions        if(/^#\s*else/) {
183855239e5SApple OSS Distributions            $skip = -$skip;
184bb611c8fSApple OSS Distributions            $allow_missing = 0;
185855239e5SApple OSS Distributions            next;
186855239e5SApple OSS Distributions        }
187855239e5SApple OSS Distributions        chomp;
188bb611c8fSApple OSS Distributions        if(/^#\s*ifndef\s+(RC_HIDE\S+)$/) {
189bb611c8fSApple OSS Distributions            $skip = 1;
190bb611c8fSApple OSS Distributions            $allow_missing = 1;
191bb611c8fSApple OSS Distributions        }
192855239e5SApple OSS Distributions        if(/^#\s*if\s+(\S+)$/) {
193855239e5SApple OSS Distributions            $skip = ($1 eq 'COMPAT_GETFSSTAT') ? -1 : 1;
194855239e5SApple OSS Distributions            next;
195855239e5SApple OSS Distributions        }
196855239e5SApple OSS Distributions        next if $skip < 0;
197855239e5SApple OSS Distributions        next unless /^\d/;
198855239e5SApple OSS Distributions        s/^[^{]*{\s*//;
199855239e5SApple OSS Distributions        s/\s*}.*$//; # }
200855239e5SApple OSS Distributions        die "$MyName: no function prototype on line $line\n" unless length($_) > 0 && /;$/;
201855239e5SApple OSS Distributions        my $no_syscall_stub = /\)\s*NO_SYSCALL_STUB\s*;/;
202855239e5SApple OSS Distributions        my($name, $args) = /\s(\S+)\s*\(([^)]*)\)/;
203855239e5SApple OSS Distributions        next if $name =~ /e?nosys/;
204a5e72196SApple OSS Distributions        $name =~ s/^sys_//;
205855239e5SApple OSS Distributions        $args =~ s/^\s+//;
206855239e5SApple OSS Distributions        $args =~ s/\s+$//;
207855239e5SApple OSS Distributions        my $argbytes = 0;
208855239e5SApple OSS Distributions        my $nargs = 0;
209cc9a6355SApple OSS Distributions        my %mismatch_args;
210855239e5SApple OSS Distributions        if($args ne '' && $args ne 'void') {
211855239e5SApple OSS Distributions            my @a = split(',', $args);
212855239e5SApple OSS Distributions            $nargs = scalar(@a);
213cc9a6355SApple OSS Distributions            my $index = 0;
214855239e5SApple OSS Distributions            for my $type (@a) {
215855239e5SApple OSS Distributions                $type =~ s/\s*\w+$//; # remove the argument name
216cc9a6355SApple OSS Distributions
217cc9a6355SApple OSS Distributions                # Calculate the size of all the arguments (only used for i386)
218855239e5SApple OSS Distributions                if($type =~ /\*$/) {
219855239e5SApple OSS Distributions                    $argbytes += 4; # a pointer type
220855239e5SApple OSS Distributions                } else {
221855239e5SApple OSS Distributions                    $type =~ s/^.*\s//; # remove any type qualifier, like unsigned
222855239e5SApple OSS Distributions                    my $b = $TypeBytes{$type};
223855239e5SApple OSS Distributions                    die "$MyName: $name: unknown type '$type'\n" unless defined($b);
224855239e5SApple OSS Distributions                    $argbytes += $b;
225855239e5SApple OSS Distributions                }
226cc9a6355SApple OSS Distributions                # Determine which arguments might need to be zero/sign-extended
227cc9a6355SApple OSS Distributions                if(exists $UserKernelMismatchTypes{$type}) {
228cc9a6355SApple OSS Distributions                    $mismatch_args{$index} = $UserKernelMismatchTypes{$type};
229cc9a6355SApple OSS Distributions                }
230cc9a6355SApple OSS Distributions
231cc9a6355SApple OSS Distributions                $index++;
232855239e5SApple OSS Distributions            }
233855239e5SApple OSS Distributions        }
234855239e5SApple OSS Distributions        $Symbols{$name} = {
235855239e5SApple OSS Distributions            c_sym => $name,
236855239e5SApple OSS Distributions            syscall => $name,
237855239e5SApple OSS Distributions            asm_sym => $no_syscall_stub ? "___$name" : "_$name",
238855239e5SApple OSS Distributions            is_private => $no_syscall_stub,
239855239e5SApple OSS Distributions            is_custom => undef,
240855239e5SApple OSS Distributions            nargs => $nargs,
241855239e5SApple OSS Distributions            bytes => $argbytes,
242855239e5SApple OSS Distributions            aliases => {},
243cc9a6355SApple OSS Distributions            mismatch_args => \%mismatch_args, # Arguments that might need to be zero/sign-extended
244855239e5SApple OSS Distributions            except => [],
245bb611c8fSApple OSS Distributions            allow_missing => $allow_missing,
246855239e5SApple OSS Distributions        };
247855239e5SApple OSS Distributions    }
248855239e5SApple OSS Distributions}
249855239e5SApple OSS Distributions
250855239e5SApple OSS Distributionssub checkForCustomStubs {
251855239e5SApple OSS Distributions    my ($dir) = @_;
252855239e5SApple OSS Distributions
253855239e5SApple OSS Distributions    my ($c_sym_name, $sym);
254855239e5SApple OSS Distributions    while (($c_sym_name, $sym) = each %Symbols) {
255855239e5SApple OSS Distributions        my $source = "__".$$sym{c_sym}.".s";
256855239e5SApple OSS Distributions        my $custom = File::Spec->join($dir, $source);
257855239e5SApple OSS Distributions        next unless -f $custom;
258855239e5SApple OSS Distributions
259855239e5SApple OSS Distributions        $$sym{is_custom} = $source;
260855239e5SApple OSS Distributions        if (!$$sym{is_private}) {
261855239e5SApple OSS Distributions            foreach my $subarch (@Architectures) {
262d0c1fef6SApple OSS Distributions                (my $arch = $subarch) =~ s/arm(v.*)/arm/;
263a3bb9fccSApple OSS Distributions                $arch =~ s/x86_64(.*)/x86_64/;
26476e12aa3SApple OSS Distributions                $arch =~ s/arm64(.*)/arm64/;
265855239e5SApple OSS Distributions                $$sym{aliases}{$arch} = [] unless $$sym{aliases}{$arch};
266855239e5SApple OSS Distributions                push(@{$$sym{aliases}{$arch}}, $$sym{asm_sym});
267855239e5SApple OSS Distributions            }
268855239e5SApple OSS Distributions            $$sym{asm_sym} = "__".$$sym{asm_sym};
269855239e5SApple OSS Distributions            $$sym{is_private} = 1;
270855239e5SApple OSS Distributions        }
271855239e5SApple OSS Distributions    }
272855239e5SApple OSS Distributions}
273855239e5SApple OSS Distributions
274855239e5SApple OSS Distributionssub readAliases {
275855239e5SApple OSS Distributions    my ($platformDir, $platformName) = @_;
276855239e5SApple OSS Distributions    my $genericMap = File::Spec->join($platformDir, "syscall.map");
277855239e5SApple OSS Distributions
278855239e5SApple OSS Distributions    my %sym_to_c;
279855239e5SApple OSS Distributions    foreach my $k (keys %Symbols) {
280855239e5SApple OSS Distributions        $sym_to_c{$Symbols{$k}{asm_sym}} = $k;
281855239e5SApple OSS Distributions    }
282855239e5SApple OSS Distributions
283855239e5SApple OSS Distributions    my @a = ();
284855239e5SApple OSS Distributions    for my $arch (@Architectures) {
285d0c1fef6SApple OSS Distributions        (my $new_arch = $arch) =~ s/arm(v.*)/arm/g;
286a3bb9fccSApple OSS Distributions        $new_arch =~ s/x86_64(.*)/x86_64/g;
28776e12aa3SApple OSS Distributions        $new_arch =~ s/arm64(.*)/arm64/g;
288855239e5SApple OSS Distributions        push(@a, $new_arch) unless grep { $_ eq $new_arch } @a;
289855239e5SApple OSS Distributions    }
290855239e5SApple OSS Distributions
291855239e5SApple OSS Distributions    foreach my $arch (@a) {
292855239e5SApple OSS Distributions        my $syscallFile = File::Spec->join($platformDir, $platformName, $arch, "syscall.map");
293855239e5SApple OSS Distributions
294855239e5SApple OSS Distributions        my @files = ();
295855239e5SApple OSS Distributions        push(@files, IO::File->new($syscallFile, 'r'));
296855239e5SApple OSS Distributions        die "$MyName: $syscallFile: $!\n" unless defined($files[$#files]);
297855239e5SApple OSS Distributions        push(@files, IO::File->new($genericMap, 'r'));
298855239e5SApple OSS Distributions        die "$MyName: $genericMap: $!\n" unless defined($files[$#files]);
299855239e5SApple OSS Distributions
300855239e5SApple OSS Distributions        foreach my $f (@files) {
301855239e5SApple OSS Distributions            while (<$f>) {
302855239e5SApple OSS Distributions                next if /^#/;
303855239e5SApple OSS Distributions                chomp;
304855239e5SApple OSS Distributions
305855239e5SApple OSS Distributions                my ($alias, $target_symbol) = split;
306855239e5SApple OSS Distributions                if (defined($target_symbol)) {
307855239e5SApple OSS Distributions                    foreach my $sym (values %Symbols) {
308855239e5SApple OSS Distributions                        # I've eliminated most of the ugly from this script except
309855239e5SApple OSS Distributions                        # the need to try stripping underbars here.
310855239e5SApple OSS Distributions                        if ($$sym{is_private}) {
311855239e5SApple OSS Distributions                            next unless $$sym{asm_sym} eq $target_symbol;
312855239e5SApple OSS Distributions                        } else {
313855239e5SApple OSS Distributions                            (my $target = $target_symbol) =~ s/^__//;
314855239e5SApple OSS Distributions                            next unless ($$sym{asm_sym} eq $target || $$sym{asm_sym} eq $target_symbol);
315855239e5SApple OSS Distributions                        }
316855239e5SApple OSS Distributions                        $$sym{aliases}{$arch} = [] unless $$sym{aliases}{$arch};
317855239e5SApple OSS Distributions
318855239e5SApple OSS Distributions                        die "$MyName: $arch $$sym{asm_sym} -> $alias: Duplicate alias.\n" if grep { $_ eq $alias } @{$$sym{aliases}{$arch}};
319855239e5SApple OSS Distributions                        push(@{$$sym{aliases}{$arch}}, $alias);
320855239e5SApple OSS Distributions
321855239e5SApple OSS Distributions                        # last thing to do, if we aliased over a first class symbol, we need
322855239e5SApple OSS Distributions                        # to mark it
323855239e5SApple OSS Distributions                        my $c = $sym_to_c{$alias};
324855239e5SApple OSS Distributions                        if ($Symbols{$c}) {
325855239e5SApple OSS Distributions                            push(@{$Symbols{$c}{except}}, $arch);
326855239e5SApple OSS Distributions                        }
327855239e5SApple OSS Distributions                    }
328855239e5SApple OSS Distributions                }
329855239e5SApple OSS Distributions            }
330855239e5SApple OSS Distributions        }
331855239e5SApple OSS Distributions    }
332855239e5SApple OSS Distributions}
333855239e5SApple OSS Distributions
334855239e5SApple OSS Distributions##########################################################################
335855239e5SApple OSS Distributions# Make a __xxx.s file: if it exists in the $CustomDir, just copy it, otherwise
336855239e5SApple OSS Distributions# create one.  We define the macro __SYSCALL_32BIT_ARG_BYTES so that SYS.h could
337855239e5SApple OSS Distributions# use that to define __SYSCALL dependent on the arguments' total size.
338855239e5SApple OSS Distributions##########################################################################
339855239e5SApple OSS Distributionssub writeStubForSymbol {
340855239e5SApple OSS Distributions    my ($f, $symbol) = @_;
341855239e5SApple OSS Distributions
342855239e5SApple OSS Distributions    my @conditions;
343cc9a6355SApple OSS Distributions    my $has_arm64 = 0;
344855239e5SApple OSS Distributions    for my $subarch (@Architectures) {
345d0c1fef6SApple OSS Distributions        (my $arch = $subarch) =~ s/arm(v.*)/arm/;
346a3bb9fccSApple OSS Distributions        $arch =~ s/x86_64(.*)/x86_64/;
34776e12aa3SApple OSS Distributions        $arch =~ s/arm64(.*)/arm64/;
348855239e5SApple OSS Distributions        push(@conditions, "defined(__${arch}__)") unless grep { $_ eq $arch } @{$$symbol{except}};
349cc9a6355SApple OSS Distributions
350a5e72196SApple OSS Distributions        if($arch eq "arm64") {
351cc9a6355SApple OSS Distributions            $has_arm64 = 1 unless grep { $_ eq $arch } @{$$symbol{except}};
352cc9a6355SApple OSS Distributions        }
353855239e5SApple OSS Distributions    }
354855239e5SApple OSS Distributions
355d0c1fef6SApple OSS Distributions    my %is_cancel;
356d0c1fef6SApple OSS Distributions    for (@Cancelable) { $is_cancel{$_} = 1 };
357d0c1fef6SApple OSS Distributions
358855239e5SApple OSS Distributions    print $f "#define __SYSCALL_32BIT_ARG_BYTES $$symbol{bytes}\n";
359855239e5SApple OSS Distributions    print $f "#include \"SYS.h\"\n\n";
360bb611c8fSApple OSS Distributions    if ($$symbol{allow_missing}) {
361bb611c8fSApple OSS Distributions        printf $f "#ifdef SYS_%s\n", $$symbol{syscall};
362bb611c8fSApple OSS Distributions    }
363cc9a6355SApple OSS Distributions
364855239e5SApple OSS Distributions    if (scalar(@conditions)) {
365186b8fceSApple OSS Distributions        printf $f "#ifndef SYS_%s\n", $$symbol{syscall};
366186b8fceSApple OSS Distributions        printf $f "#error \"SYS_%s not defined. The header files libsyscall is building against do not match syscalls.master.\"\n", $$symbol{syscall};
367186b8fceSApple OSS Distributions        printf $f "#endif\n\n";
368cc9a6355SApple OSS Distributions    }
369cc9a6355SApple OSS Distributions
370d0c1fef6SApple OSS Distributions    my $nc = ($is_cancel{$$symbol{syscall}} ? "cerror" : "cerror_nocancel");
371cc9a6355SApple OSS Distributions
372cc9a6355SApple OSS Distributions    if($has_arm64) {
373cc9a6355SApple OSS Distributions        printf $f "#if defined(__arm64__)\n";
374cc9a6355SApple OSS Distributions        printf $f "MI_ENTRY_POINT(%s)\n", $$symbol{asm_sym};
375cc9a6355SApple OSS Distributions        if(keys %{$$symbol{mismatch_args}}) {
376cc9a6355SApple OSS Distributions            while(my($argnum, $extend) = each %{$$symbol{mismatch_args}}) {
377cc9a6355SApple OSS Distributions                printf $f "%s(%d)\n", $extend, $argnum;
378cc9a6355SApple OSS Distributions            }
379cc9a6355SApple OSS Distributions        }
380cc9a6355SApple OSS Distributions
381cc9a6355SApple OSS Distributions        printf $f "SYSCALL_NONAME(%s, %d, %s)\n", $$symbol{syscall}, $$symbol{nargs}, $nc;
382cc9a6355SApple OSS Distributions        printf $f "ret\n";
383cc9a6355SApple OSS Distributions        printf $f "#else\n";
384cc9a6355SApple OSS Distributions    }
385cc9a6355SApple OSS Distributions
386cc9a6355SApple OSS Distributions    if (scalar(@conditions)) {
387855239e5SApple OSS Distributions        printf $f "#if " . join(" || ", @conditions) . "\n";
388d0c1fef6SApple OSS Distributions        printf $f "__SYSCALL2(%s, %s, %d, %s)\n", $$symbol{asm_sym}, $$symbol{syscall}, $$symbol{nargs}, $nc;
389855239e5SApple OSS Distributions        if (!$$symbol{is_private} && (scalar(@conditions) < scalar(@Architectures))) {
390855239e5SApple OSS Distributions            printf $f "#else\n";
391d0c1fef6SApple OSS Distributions            printf $f "__SYSCALL2(%s, %s, %d, %s)\n", "__".$$symbol{asm_sym}, $$symbol{syscall}, $$symbol{nargs}, $nc;
392855239e5SApple OSS Distributions        }
393855239e5SApple OSS Distributions        printf $f "#endif\n\n";
394855239e5SApple OSS Distributions    } else {
395855239e5SApple OSS Distributions        # actually this isnt an inconsistency. kernel can expose what it wants but if all our arches
396855239e5SApple OSS Distributions        # override it we need to honour that.
397855239e5SApple OSS Distributions    }
398cc9a6355SApple OSS Distributions
399bb611c8fSApple OSS Distributions    if ($$symbol{allow_missing}) {
400bb611c8fSApple OSS Distributions        printf $f "#endif\n";
401bb611c8fSApple OSS Distributions    }
402bb611c8fSApple OSS Distributions
403cc9a6355SApple OSS Distributions    if($has_arm64) {
404cc9a6355SApple OSS Distributions        printf $f "#endif\n\n";
405cc9a6355SApple OSS Distributions    }
406855239e5SApple OSS Distributions}
407855239e5SApple OSS Distributions
408855239e5SApple OSS Distributionssub writeAliasesForSymbol {
409855239e5SApple OSS Distributions    my ($f, $symbol) = @_;
410855239e5SApple OSS Distributions
411bb611c8fSApple OSS Distributions    if ($$symbol{allow_missing}) {
412bb611c8fSApple OSS Distributions        printf $f "#ifdef SYS_%s\n", $$symbol{syscall};
413bb611c8fSApple OSS Distributions    }
414bb611c8fSApple OSS Distributions
415855239e5SApple OSS Distributions    foreach my $subarch (@Architectures) {
416d0c1fef6SApple OSS Distributions        (my $arch = $subarch) =~ s/arm(v.*)/arm/;
417a3bb9fccSApple OSS Distributions        $arch =~ s/x86_64(.*)/x86_64/;
41876e12aa3SApple OSS Distributions        $arch =~ s/arm64(.*)/arm64/;
419855239e5SApple OSS Distributions
420855239e5SApple OSS Distributions        next unless scalar($$symbol{aliases}{$arch});
421855239e5SApple OSS Distributions
422855239e5SApple OSS Distributions				printf $f "#if defined(__${arch}__)\n";
423855239e5SApple OSS Distributions        foreach my $alias_sym (@{$$symbol{aliases}{$arch}}) {
424855239e5SApple OSS Distributions            my $sym = (grep { $_ eq $arch } @{$$symbol{except}}) ? "__".$$symbol{asm_sym} : $$symbol{asm_sym};
425855239e5SApple OSS Distributions
426855239e5SApple OSS Distributions						printf $f "\t.globl\t$alias_sym\n";
427855239e5SApple OSS Distributions						printf $f "\t.set\t$alias_sym, $sym\n";
428855239e5SApple OSS Distributions        }
429855239e5SApple OSS Distributions				printf $f "#endif\n\n";
430855239e5SApple OSS Distributions    }
431bb611c8fSApple OSS Distributions    if ($$symbol{allow_missing}) {
432bb611c8fSApple OSS Distributions        printf $f "#endif\n";
433bb611c8fSApple OSS Distributions    }
434855239e5SApple OSS Distributions}
435855239e5SApple OSS Distributions
436855239e5SApple OSS Distributionsusage() unless scalar(@ARGV) == 5;
437855239e5SApple OSS Distributions$CustomDir = $ARGV[1];
438855239e5SApple OSS Distributionsdie "$MyName: $CustomDir: No such directory\n" unless -d $CustomDir;
439855239e5SApple OSS Distributions$PlatformsDir = $ARGV[2];
440855239e5SApple OSS Distributionsdie "$MyName: $PlatformsDir: No such directory\n" unless -d $PlatformsDir;
441855239e5SApple OSS Distributions$PlatformName = $ARGV[3];
442855239e5SApple OSS Distributionsdie "$MyName: $PlatformsDir/$PlatformName: No such directory\n" unless -d "$PlatformsDir/$PlatformName";
443855239e5SApple OSS Distributions$OutDir = $ARGV[4];
444855239e5SApple OSS Distributionsdie "$MyName: $OutDir: No such directory\n" unless -d $OutDir;
445855239e5SApple OSS Distributions
446855239e5SApple OSS DistributionsreadMaster($ARGV[0]);
447855239e5SApple OSS DistributionscheckForCustomStubs($CustomDir);
448855239e5SApple OSS DistributionsreadAliases($PlatformsDir, $PlatformName);
449855239e5SApple OSS Distributions
450855239e5SApple OSS Distributions##########################################################################
451855239e5SApple OSS Distributions# copy the files specified in @Copy from the $CustomDir to $OutDir
452855239e5SApple OSS Distributions##########################################################################
453855239e5SApple OSS Distributionsfor(@Copy) {
454855239e5SApple OSS Distributions    my $custom = File::Spec->join($CustomDir, $_);
455855239e5SApple OSS Distributions    my $path = File::Spec->join($OutDir, $_);
456855239e5SApple OSS Distributions    print "Copy $custom -> $path\n";
457855239e5SApple OSS Distributions    File::Copy::copy($custom, $path) || die "$MyName: copy($custom, $path): $!\n";
458855239e5SApple OSS Distributions}
459855239e5SApple OSS Distributions
460855239e5SApple OSS Distributions##########################################################################
461855239e5SApple OSS Distributions# make all the *.s files
462855239e5SApple OSS Distributions##########################################################################
463855239e5SApple OSS Distributionsmy @src;
464855239e5SApple OSS Distributionsmy($k, $sym);
465855239e5SApple OSS Distributionswhile (($k, $sym) = each %Symbols)
466855239e5SApple OSS Distributions{
467855239e5SApple OSS Distributions	my $srcname = $$sym{asm_sym} . ".s";
468855239e5SApple OSS Distributions	my $outpath = File::Spec->join($OutDir, $srcname);
469855239e5SApple OSS Distributions
470855239e5SApple OSS Distributions	if ($$sym{is_custom}) {
471855239e5SApple OSS Distributions		my $custom = File::Spec->join($CustomDir, $$sym{is_custom});
472855239e5SApple OSS Distributions		File::Copy::copy($custom, $outpath);
473855239e5SApple OSS Distributions		print "Copied $outpath\n";
474855239e5SApple OSS Distributions
475855239e5SApple OSS Distributions		print "Writing aliases for $srcname\n";
476855239e5SApple OSS Distributions		my $f = IO::File->new($outpath, 'a');
477855239e5SApple OSS Distributions		die "$MyName: $outpath: $!\n" unless defined($f);
478855239e5SApple OSS Distributions		writeAliasesForSymbol($f, $sym);
479855239e5SApple OSS Distributions		undef $f;
480855239e5SApple OSS Distributions	} else {
481855239e5SApple OSS Distributions		my $f = IO::File->new($outpath, 'w');
482855239e5SApple OSS Distributions		die "$MyName: $outpath: $!\n" unless defined($f);
483855239e5SApple OSS Distributions
484855239e5SApple OSS Distributions		printf "Creating $outpath\n";
485855239e5SApple OSS Distributions		writeStubForSymbol($f, $sym);
486855239e5SApple OSS Distributions		writeAliasesForSymbol($f, $sym);
487855239e5SApple OSS Distributions		undef $f;
488855239e5SApple OSS Distributions	}
489855239e5SApple OSS Distributions	push(@src, $srcname);
490855239e5SApple OSS Distributions}
491855239e5SApple OSS Distributions
492855239e5SApple OSS Distributions##########################################################################
493855239e5SApple OSS Distributions# create the Makefile.inc file from the list for files in @src and @CustomSrc
494855239e5SApple OSS Distributions##########################################################################
495855239e5SApple OSS Distributionsmy $path = File::Spec->join($OutDir, 'stubs.list');
496855239e5SApple OSS Distributionsmy $f = IO::File->new($path, 'w');
497855239e5SApple OSS Distributionsmy @sources = sort(@src, @CustomSrc);
498855239e5SApple OSS Distributionsfor my $s (@sources) {
499855239e5SApple OSS Distributions	printf $f File::Spec->join($OutDir, $s) . "\n";
500855239e5SApple OSS Distributions}
501855239e5SApple OSS Distributionsundef $f;
502855239e5SApple OSS Distributionsundef $path;
503855239e5SApple OSS Distributions
504