1#!/usr/bin/perl -w 2# 3# headers_check.pl execute a number of trivial consistency checks 4# 5# Usage: headers_check.pl dir arch [files...] 6# dir: dir to look for included files 7# arch: architecture 8# files: list of files to check 9# 10# The script reads the supplied files line by line and: 11# 12# 1) for each include statement it checks if the 13# included file actually exists. 14# Only include files located in asm* and linux* are checked. 15# The rest are assumed to be system include files. 16# 17# 2) It is checked that prototypes does not use "extern" 18# 19# 3) Check for leaked CONFIG_ symbols 20 21use strict; 22 23my ($dir, $arch, @files) = @ARGV; 24 25my $ret = 0; 26my $line; 27my $lineno = 0; 28my $filename; 29 30foreach my $file (@files) { 31 $filename = $file; 32 33 open(my $fh, '<', $filename) 34 or die "$filename: $!\n"; 35 $lineno = 0; 36 while ($line = <$fh>) { 37 $lineno++; 38 &check_include(); 39 &check_asm_types(); 40 &check_sizetypes(); 41 &check_declarations(); 42 # Dropped for now. Too much noise &check_config(); 43 } 44 close $fh; 45} 46exit $ret; 47 48sub check_include 49{ 50 if ($line =~ m/^\s*#\s*include\s+<((asm|linux).*)>/) { 51 my $inc = $1; 52 my $found; 53 $found = stat($dir . "/" . $inc); 54 if (!$found) { 55 $inc =~ s#asm/#asm-$arch/#; 56 $found = stat($dir . "/" . $inc); 57 } 58 if (!$found) { 59 printf STDERR "$filename:$lineno: included file '$inc' is not exported\n"; 60 $ret = 1; 61 } 62 } 63} 64 65sub check_declarations 66{ 67 if ($line =~m/^(\s*extern|unsigned|char|short|int|long|void)\b/) { 68 printf STDERR "$filename:$lineno: " . 69 "userspace cannot reference function or " . 70 "variable defined in the kernel\n"; 71 } 72} 73 74sub check_config 75{ 76 if ($line =~ m/[^a-zA-Z0-9_]+CONFIG_([a-zA-Z0-9_]+)[^a-zA-Z0-9_]/) { 77 printf STDERR "$filename:$lineno: leaks CONFIG_$1 to userspace where it is not valid\n"; 78 } 79} 80 81my $linux_asm_types; 82sub check_asm_types 83{ 84 if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) { 85 return; 86 } 87 if ($lineno == 1) { 88 $linux_asm_types = 0; 89 } elsif ($linux_asm_types >= 1) { 90 return; 91 } 92 if ($line =~ m/^\s*#\s*include\s+<asm\/types.h>/) { 93 $linux_asm_types = 1; 94 printf STDERR "$filename:$lineno: " . 95 "include of <linux/types.h> is preferred over <asm/types.h>\n" 96 # Warn until headers are all fixed 97 #$ret = 1; 98 } 99} 100 101my $linux_types; 102sub check_sizetypes 103{ 104 if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) { 105 return; 106 } 107 if ($lineno == 1) { 108 $linux_types = 0; 109 } elsif ($linux_types >= 1) { 110 return; 111 } 112 if ($line =~ m/^\s*#\s*include\s+<linux\/types.h>/) { 113 $linux_types = 1; 114 return; 115 } 116 if ($line =~ m/__[us](8|16|32|64)\b/) { 117 printf STDERR "$filename:$lineno: " . 118 "found __[us]{8,16,32,64} type " . 119 "without #include <linux/types.h>\n"; 120 $linux_types = 2; 121 # Warn until headers are all fixed 122 #$ret = 1; 123 } 124} 125 126