0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 use warnings;
0023 use strict;
0024 use File::Basename;
0025
0026 my ($dir, $arch, @files) = @ARGV;
0027
0028 my $ret = 0;
0029 my $line;
0030 my $lineno = 0;
0031 my $filename;
0032
0033 foreach my $file (@files) {
0034 $filename = $file;
0035
0036 open(my $fh, '<', $filename)
0037 or die "$filename: $!\n";
0038 $lineno = 0;
0039 while ($line = <$fh>) {
0040 $lineno++;
0041 &check_include();
0042 &check_asm_types();
0043 &check_sizetypes();
0044 &check_declarations();
0045
0046 }
0047 close $fh;
0048 }
0049 exit $ret;
0050
0051 sub check_include
0052 {
0053 if ($line =~ ) {
0054 my $inc = $1;
0055 my $found;
0056 $found = stat($dir . "/" . $inc);
0057 if (!$found) {
0058 $inc =~ s#asm/#asm-$arch/#;
0059 $found = stat($dir . "/" . $inc);
0060 }
0061 if (!$found) {
0062 printf STDERR "$filename:$lineno: included file '$inc' is not exported\n";
0063 $ret = 1;
0064 }
0065 }
0066 }
0067
0068 sub check_declarations
0069 {
0070
0071 if ($line =~ ) {
0072 return;
0073 }
0074
0075 if ($line =~ ) {
0076 return;
0077 }
0078 if ($line =~ ) {
0079 printf STDERR "$filename:$lineno: " .
0080 "userspace cannot reference function or " .
0081 "variable defined in the kernel\n";
0082 }
0083 }
0084
0085 sub check_config
0086 {
0087 if ($line =~ ) {
0088 printf STDERR "$filename:$lineno: leaks CONFIG_$1 to userspace where it is not valid\n";
0089 }
0090 }
0091
0092 my $linux_asm_types;
0093 sub check_asm_types
0094 {
0095 if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
0096 return;
0097 }
0098 if ($lineno == 1) {
0099 $linux_asm_types = 0;
0100 } elsif ($linux_asm_types >= 1) {
0101 return;
0102 }
0103 if ($line =~ ) {
0104 $linux_asm_types = 1;
0105 printf STDERR "$filename:$lineno: " .
0106 "include of <linux/types.h> is preferred over <asm/types.h>\n"
0107
0108
0109 }
0110 }
0111
0112 my $linux_types;
0113 my %import_stack = ();
0114 sub check_include_typesh
0115 {
0116 my $path = $_[0];
0117 my $import_path;
0118
0119 my $fh;
0120 my @file_paths = ($path, $dir . "/" . $path, dirname($filename) . "/" . $path);
0121 for my $possible ( @file_paths ) {
0122 if (not $import_stack{$possible} and open($fh, '<', $possible)) {
0123 $import_path = $possible;
0124 $import_stack{$import_path} = 1;
0125 last;
0126 }
0127 }
0128 if (eof $fh) {
0129 return;
0130 }
0131
0132 my $line;
0133 while ($line = <$fh>) {
0134 if ($line =~ ) {
0135 $linux_types = 1;
0136 last;
0137 }
0138 if (my $included = ($line =~ /^\s*
0139 check_include_typesh($included);
0140 }
0141 }
0142 close $fh;
0143 delete $import_stack{$import_path};
0144 }
0145
0146 sub check_sizetypes
0147 {
0148 if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
0149 return;
0150 }
0151 if ($lineno == 1) {
0152 $linux_types = 0;
0153 } elsif ($linux_types >= 1) {
0154 return;
0155 }
0156 if ($line =~ ) {
0157 $linux_types = 1;
0158 return;
0159 }
0160 if (my $included = ($line =~ /^\s*
0161 check_include_typesh($included);
0162 }
0163 if ($line =~ ) {
0164 printf STDERR "$filename:$lineno: " .
0165 "found __[us]{8,16,32,64} type " .
0166 "without #include <linux/types.h>\n";
0167 $linux_types = 2;
0168
0169
0170 }
0171 }