The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/libsyscall/create-syscalls.pl

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 #!/usr/bin/perl
    2 #
    3 # Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
    4 #
    5 # @APPLE_OSREFERENCE_LICENSE_HEADER_START@
    6 # 
    7 # This file contains Original Code and/or Modifications of Original Code
    8 # as defined in and that are subject to the Apple Public Source License
    9 # Version 2.0 (the 'License'). You may not use this file except in
   10 # compliance with the License. Please obtain a copy of the License at
   11 # http://www.opensource.apple.com/apsl/ and read it before using this
   12 # file.
   13 # 
   14 # The Original Code and all software distributed under the License are
   15 # distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   16 # EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   17 # INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   18 # FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   19 # Please see the License for the specific language governing rights and
   20 # limitations under the License.
   21 # 
   22 # @APPLE_OSREFERENCE_LICENSE_HEADER_END@
   23 #
   24 ##########################################################################
   25 #
   26 # % create-syscalls.pl syscalls.master custom-directory out-directory
   27 #
   28 # This script fills the the out-directory with a Makefile.inc and *.s
   29 # files to create the double-underbar syscall stubs.  It reads the
   30 # syscall.master file to get the symbol names and number of arguments,
   31 # and whether Libsystem should automatically create the (non-double-underbar)
   32 # stubs if Libc doesn't provide a wrapper.  Which system calls will get
   33 # the automatic treatment is writen to the libsyscall.list file, also
   34 # written to the out-directory.
   35 #
   36 # The custom-directory contains:
   37 # 1. SYS.h - used by the automatically created *.s and custom files
   38 # 2. custom.s - contains architecture specific additional system calls and
   39 #    auxilliary routines (like cerror)
   40 # 3. special case double-underbar stub files - which are copied into
   41 #    the out-directory
   42 #
   43 # The BSDmakefile copies /usr/include/architecture/ppc/emode_independent_asm.h
   44 # and /usr/include/architecture/i386/asm_help.h to $(OBJDIR)/include,
   45 # replacing .globl with .private_extern.  These headers, along with SYS.h
   46 # make the double-underbar syscall stub private_extern, so that then become
   47 # static in the resulting libSystem.dylib.
   48 #
   49 ##########################################################################
   50 
   51 use strict;
   52 use File::Basename ();
   53 use File::Copy ();
   54 use File::Spec;
   55 use IO::File;
   56 
   57 my $MyName = File::Basename::basename($0);
   58 
   59 my @CustomSrc = qw(custom.s);
   60 
   61 my @Copy = (qw(SYS.h), @CustomSrc);
   62 my $CustomDir;
   63 my %NoStub;
   64 my $OutDir;
   65 my %Stub = (
   66     quota => [4, 0],    # unimplemented
   67     setquota => [2, 0], # unimplemented
   68     syscall => [0, 0],  # custom/__syscall.s will be used
   69 );
   70 my $StubFile = 'libsyscall.list';
   71 # size in bytes of known types (only used for i386)
   72 my %TypeBytes = (
   73     'au_asid_t'         => 4,
   74     'caddr_t'           => 4,
   75     'gid_t'             => 4,
   76     'id_t'              => 4,
   77     'idtype_t'          => 4,
   78     'int'               => 4,
   79     'int32_t'           => 4,
   80     'int64_t'           => 8,
   81     'key_t'             => 4,
   82     'long'              => 4,
   83     'mach_port_name_t'  => 4,
   84     'mode_t'            => 4,
   85     'off_t'             => 8,
   86     'pid_t'             => 4,
   87     'semun_t'           => 4,
   88     'sigset_t'          => 4,
   89     'size_t'            => 4,
   90     'socklen_t'         => 4,
   91     'ssize_t'           => 4,
   92     'u_int'             => 4,
   93     'u_long'            => 4,
   94     'uid_t'             => 4,
   95     'uint32_t'          => 4,
   96     'uint64_t'          => 8,
   97     'user_addr_t'       => 4,
   98     'user_long_t'       => 4,
   99     'user_size_t'       => 4,
  100     'user_ssize_t'      => 4,
  101     'user_ulong_t'      => 4,
  102 );
  103 
  104 ##########################################################################
  105 # Make a __xxx.s file: if it exists in the $CustomDir, just copy it, otherwise
  106 # create one.  We define the macro __SYSCALL_32BIT_ARG_BYTES so that SYS.h could
  107 # use that to define __SYSCALL dependent on the arguments' total size.
  108 ##########################################################################
  109 sub make_s {
  110     my($name, $args, $bytes) = @_;
  111     local $_;
  112     my $pseudo = $name;
  113     $pseudo = '__' . $pseudo unless $pseudo =~ /^__/;
  114     my $file = $pseudo . '.s';
  115     my $custom = File::Spec->join($CustomDir, $file);
  116     my $path = File::Spec->join($OutDir, $file);
  117     if(-f $custom) {
  118         File::Copy::copy($custom, $path) || die "$MyName: copy($custom, $path): $!\n";
  119         print "Copying $path\n";
  120     } else {
  121         my $f = IO::File->new($path, 'w');
  122         die "$MyName: $path: $!\n" unless defined($f);
  123         print $f "#define __SYSCALL_32BIT_ARG_BYTES $bytes\n\n";
  124         print $f "#include \"SYS.h\"\n\n";
  125         print $f "__SYSCALL($pseudo, $name, $args)\n";
  126         print "Creating $path\n";
  127     }
  128     return $file;
  129 }
  130 
  131 sub usage {
  132     die "Usage: $MyName syscalls.master custom-directory out-directory\n";
  133 }
  134 
  135 ##########################################################################
  136 # Read the syscall.master file and collect the system call names and number
  137 # of arguments.  It looks for the NO_SYSCALL_STUB quailifier following the
  138 # prototype to determine if no automatic stub should be created by Libsystem.
  139 # System call name that are already prefixed with double-underbar are set as
  140 # if the NO_SYSCALL_STUB qualifier were specified (whether it is or not).
  141 #
  142 # For the #if lines in syscall.master, all macros are assumed to be defined,
  143 # except COMPAT_GETFSSTAT (assumed undefined).
  144 ##########################################################################
  145 sub readmaster {
  146     my $file = shift;
  147     local $_;
  148     my $f = IO::File->new($file, 'r');
  149     die "$MyName: $file: $!\n" unless defined($f);
  150     my $line = 0;
  151     my $skip = 0;
  152     while(<$f>) {
  153         $line++;
  154         if(/^#\s*endif/) {
  155             $skip = 0;
  156             next;
  157         }
  158         if(/^#\s*else/) {
  159             $skip = -$skip;
  160             next;
  161         }
  162         chomp;
  163         if(/^#\s*if\s+(\S+)$/) {
  164             $skip = ($1 eq 'COMPAT_GETFSSTAT') ? -1 : 1;
  165             next;
  166         }
  167         next if $skip < 0;
  168         next unless /^\d/;
  169         s/^[^{]*{\s*//;
  170         s/\s*}.*$//; # }
  171         die "$MyName: no function prototype on line $line\n" unless length($_) > 0 && /;$/;
  172         my $no_syscall_stub = /\)\s*NO_SYSCALL_STUB\s*;/;
  173         my($name, $args) = /\s(\S+)\s*\(([^)]*)\)/;
  174         next if $name =~ /e?nosys/;
  175         $args =~ s/^\s+//;
  176         $args =~ s/\s+$//;
  177         my $argbytes = 0;
  178         my $nargs = 0;
  179         if($args ne '' && $args ne 'void') {
  180             my @a = split(',', $args);
  181             $nargs = scalar(@a);
  182             # Calculate the size of all the arguments (only used for i386)
  183             for my $type (@a) {
  184                 $type =~ s/\s*\w+$//; # remove the argument name
  185                 if($type =~ /\*$/) {
  186                     $argbytes += 4; # a pointer type
  187                 } else {
  188                     $type =~ s/^.*\s//; # remove any type qualifier, like unsigned
  189                     my $b = $TypeBytes{$type};
  190                     die "$MyName: $name: unknown type '$type'\n" unless defined($b);
  191                     $argbytes += $b;
  192                 }
  193             }
  194         }
  195         if($no_syscall_stub || $name =~ /^__/) {
  196             $NoStub{$name} = [$nargs, $argbytes];
  197         } else {
  198             $Stub{$name} = [$nargs, $argbytes];
  199         }
  200     }
  201 }
  202 
  203 usage() unless scalar(@ARGV) == 3;
  204 $CustomDir = $ARGV[1];
  205 die "$MyName: $CustomDir: No such directory\n" unless -d $CustomDir;
  206 $OutDir = $ARGV[2];
  207 die "$MyName: $OutDir: No such directory\n" unless -d $OutDir;
  208 
  209 readmaster($ARGV[0]);
  210 
  211 ##########################################################################
  212 # copy the files specified in @Copy from the $CustomDir to $OutDir
  213 ##########################################################################
  214 for(@Copy) {
  215     my $custom = File::Spec->join($CustomDir, $_);
  216     my $path = File::Spec->join($OutDir, $_);
  217     File::Copy::copy($custom, $path) || die "$MyName: copy($custom, $path): $!\n";
  218 }
  219 
  220 ##########################################################################
  221 # make all the *.s files
  222 ##########################################################################
  223 my @src;
  224 my($k, $v);
  225 while(($k, $v) = each(%Stub)) {
  226     push(@src, make_s($k, @$v));
  227 }
  228 while(($k, $v) = each(%NoStub)) {
  229     push(@src, make_s($k, @$v));
  230 }
  231 
  232 ##########################################################################
  233 # create the Makefile.inc file from the list for files in @src and @CustomSrc
  234 ##########################################################################
  235 my $path = File::Spec->join($OutDir, 'Makefile.inc');
  236 my $f = IO::File->new($path, 'w');
  237 die "$MyName: $path: $!\n" unless defined($f);
  238 print $f ".PATH: $OutDir\n\n";
  239 print $f "SYSCALLSRCS= " . join(" \\\n\t", sort(@src, @CustomSrc)) . "\n\n";
  240 print $f "MDSRCS+= \$(SYSCALLSRCS)\n\n";
  241 print $f ".for S in \$(SYSCALLSRCS)\n";
  242 print $f "PRECFLAGS-\$(S)+= -I\$(OBJROOT)/include\n";
  243 print $f ".endfor\n";
  244 undef $f;
  245 
  246 ##########################################################################
  247 # create the libsyscall.list file for Libsystem to use.  For the one that
  248 # should not have auto-generated stubs, the line begins with #.
  249 ##########################################################################
  250 $path = File::Spec->join($OutDir, $StubFile);
  251 $f = IO::File->new($path, 'w');
  252 die "$MyName: $path: $!\n" unless defined($f);
  253 # Add the %NoStub entries to %Stub, appending '#' to the name, so we can sort
  254 while(($k, $v) = each(%NoStub)) {
  255     $k =~ s/^__//;
  256     $Stub{"$k#"} = $v;
  257 }
  258 for(sort(keys(%Stub))) {
  259     $k = $_;
  260     if($k =~ s/#$//) {
  261         printf $f "#___%s\t%s\n", $k, $Stub{$_}->[0];
  262     } else {
  263         printf $f "___%s\t%s\n", $_, $Stub{$_}->[0];
  264     }
  265 }
  266 undef $f;

Cache object: 5cf1036251df611cc11e42c6be2e65b1


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.