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     'caddr_t'           => 4,
   74     'gid_t'             => 4,
   75     'id_t'              => 4,
   76     'idtype_t'          => 4,
   77     'int'               => 4,
   78     'int32_t'           => 4,
   79     'int64_t'           => 8,
   80     'key_t'             => 4,
   81     'long'              => 4,
   82     'mode_t'            => 4,
   83     'off_t'             => 8,
   84     'pid_t'             => 4,
   85     'semun_t'           => 4,
   86     'sigset_t'          => 4,
   87     'size_t'            => 4,
   88     'socklen_t'         => 4,
   89     'ssize_t'           => 4,
   90     'time_t'            => 4,
   91     'u_int'             => 4,
   92     'u_long'            => 4,
   93     'uid_t'             => 4,
   94     'uint32_t'          => 4,
   95     'uint64_t'          => 8,
   96     'user_addr_t'       => 4,
   97     'user_long_t'       => 4,
   98     'user_size_t'       => 4,
   99     'user_ssize_t'      => 4,
  100     'user_ulong_t'      => 4,
  101 );
  102 
  103 ##########################################################################
  104 # Make a __xxx.s file: if it exists in the $CustomDir, just copy it, otherwise
  105 # create one.  We define the macro __SYSCALL_I386_ARG_BYTES so that SYS.h could
  106 # use that to define __SYSCALL dependent on the arguments' total size.
  107 ##########################################################################
  108 sub make_s {
  109     my($name, $args, $bytes) = @_;
  110     local $_;
  111     my $pseudo = $name;
  112     $pseudo = '__' . $pseudo unless $pseudo =~ /^__/;
  113     my $file = $pseudo . '.s';
  114     my $custom = File::Spec->join($CustomDir, $file);
  115     my $path = File::Spec->join($OutDir, $file);
  116     if(-f $custom) {
  117         File::Copy::copy($custom, $path) || die "$MyName: copy($custom, $path): $!\n";
  118         print "Copying $path\n";
  119     } else {
  120         my $f = IO::File->new($path, 'w');
  121         die "$MyName: $path: $!\n" unless defined($f);
  122         print $f "#define __SYSCALL_I386_ARG_BYTES $bytes\n\n";
  123         print $f "#include \"SYS.h\"\n\n";
  124         print $f "__SYSCALL($pseudo, $name, $args)\n";
  125         print "Creating $path\n";
  126     }
  127     return $file;
  128 }
  129 
  130 sub usage {
  131     die "Usage: $MyName syscalls.master custom-directory out-directory\n";
  132 }
  133 
  134 ##########################################################################
  135 # Read the syscall.master file and collect the system call names and number
  136 # of arguments.  It looks for the NO_SYSCALL_STUB quailifier following the
  137 # prototype to determine if no automatic stub should be created by Libsystem.
  138 # System call name that are already prefixed with double-underbar are set as
  139 # if the NO_SYSCALL_STUB qualifier were specified (whether it is or not).
  140 #
  141 # For the #if lines in syscall.master, all macros are assumed to be defined,
  142 # except COMPAT_GETFSSTAT (assumed undefined).
  143 ##########################################################################
  144 sub readmaster {
  145     my $file = shift;
  146     local $_;
  147     my $f = IO::File->new($file, 'r');
  148     die "$MyName: $file: $!\n" unless defined($f);
  149     my $line = 0;
  150     my $skip = 0;
  151     while(<$f>) {
  152         $line++;
  153         if(/^#\s*endif/) {
  154             $skip = 0;
  155             next;
  156         }
  157         if(/^#\s*else/) {
  158             $skip = -$skip;
  159             next;
  160         }
  161         chomp;
  162         if(/^#\s*if\s+(\S+)$/) {
  163             $skip = ($1 eq 'COMPAT_GETFSSTAT') ? -1 : 1;
  164             next;
  165         }
  166         next if $skip < 0;
  167         next unless /^\d/;
  168         s/^[^{]*{\s*//;
  169         s/\s*}.*$//; # }
  170         die "$MyName: no function prototype on line $line\n" unless length($_) > 0 && /;$/;
  171         my $no_syscall_stub = /\)\s*NO_SYSCALL_STUB\s*;/;
  172         my($name, $args) = /\s(\S+)\s*\(([^)]*)\)/;
  173         next if $name =~ /e?nosys/;
  174         $args =~ s/^\s+//;
  175         $args =~ s/\s+$//;
  176         my $argbytes = 0;
  177         my $nargs = 0;
  178         if($args ne '' && $args ne 'void') {
  179             my @a = split(',', $args);
  180             $nargs = scalar(@a);
  181             # Calculate the size of all the arguments (only used for i386)
  182             for my $type (@a) {
  183                 $type =~ s/\s*\w+$//; # remove the argument name
  184                 if($type =~ /\*$/) {
  185                     $argbytes += 4; # a pointer type
  186                 } else {
  187                     $type =~ s/^.*\s//; # remove any type qualifier, like unsigned
  188                     my $b = $TypeBytes{$type};
  189                     die "$MyName: $name: unknown type '$type'\n" unless defined($b);
  190                     $argbytes += $b;
  191                 }
  192             }
  193         }
  194         if($no_syscall_stub || $name =~ /^__/) {
  195             $NoStub{$name} = [$nargs, $argbytes];
  196         } else {
  197             $Stub{$name} = [$nargs, $argbytes];
  198         }
  199     }
  200 }
  201 
  202 usage() unless scalar(@ARGV) == 3;
  203 $CustomDir = $ARGV[1];
  204 die "$MyName: $CustomDir: No such directory\n" unless -d $CustomDir;
  205 $OutDir = $ARGV[2];
  206 die "$MyName: $OutDir: No such directory\n" unless -d $OutDir;
  207 
  208 readmaster($ARGV[0]);
  209 
  210 ##########################################################################
  211 # copy the files specified in @Copy from the $CustomDir to $OutDir
  212 ##########################################################################
  213 for(@Copy) {
  214     my $custom = File::Spec->join($CustomDir, $_);
  215     my $path = File::Spec->join($OutDir, $_);
  216     File::Copy::copy($custom, $path) || die "$MyName: copy($custom, $path): $!\n";
  217 }
  218 
  219 ##########################################################################
  220 # make all the *.s files
  221 ##########################################################################
  222 my @src;
  223 my($k, $v);
  224 while(($k, $v) = each(%Stub)) {
  225     push(@src, make_s($k, @$v));
  226 }
  227 while(($k, $v) = each(%NoStub)) {
  228     push(@src, make_s($k, @$v));
  229 }
  230 
  231 ##########################################################################
  232 # create the Makefile.inc file from the list for files in @src and @CustomSrc
  233 ##########################################################################
  234 my $path = File::Spec->join($OutDir, 'Makefile.inc');
  235 my $f = IO::File->new($path, 'w');
  236 die "$MyName: $path: $!\n" unless defined($f);
  237 print $f ".PATH: $OutDir\n\n";
  238 print $f "SYSCALLSRCS= " . join(" \\\n\t", sort(@src, @CustomSrc)) . "\n\n";
  239 print $f "MDSRCS+= \$(SYSCALLSRCS)\n\n";
  240 print $f ".for S in \$(SYSCALLSRCS)\n";
  241 print $f "PRECFLAGS-\$(S)+= -I\$(OBJROOT)/include\n";
  242 print $f ".endfor\n";
  243 undef $f;
  244 
  245 ##########################################################################
  246 # create the libsyscall.list file for Libsystem to use.  For the one that
  247 # should not have auto-generated stubs, the line begins with #.
  248 ##########################################################################
  249 $path = File::Spec->join($OutDir, $StubFile);
  250 $f = IO::File->new($path, 'w');
  251 die "$MyName: $path: $!\n" unless defined($f);
  252 # Add the %NoStub entries to %Stub, appending '#' to the name, so we can sort
  253 while(($k, $v) = each(%NoStub)) {
  254     $k =~ s/^__//;
  255     $Stub{"$k#"} = $v;
  256 }
  257 for(sort(keys(%Stub))) {
  258     $k = $_;
  259     if($k =~ s/#$//) {
  260         printf $f "#___%s\t%s\n", $k, $Stub{$_}->[0];
  261     } else {
  262         printf $f "___%s\t%s\n", $_, $Stub{$_}->[0];
  263     }
  264 }
  265 undef $f;

Cache object: 02d6dbde2e407eb53bc37ef2921e666e


[ 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.