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 local *FH; 32 $filename = $file; 33 open(FH, "<$filename") or die "$filename: $!\n"; 34 $lineno = 0; 35 while ($line = <FH>) { 36 $lineno++; 37 &check_include(); 38 &check_asm_types(); 39 &check_sizetypes(); 40 &check_declarations(); 41 # Dropped for now. Too much noise &check_config(); 42 } 43 close FH; 44} 45exit $ret; 46 47sub check_include 48{ 49 if ($line =~ m/^\s*#\s*include\s+<((asm|linux).*)>/) { 50 my $inc = $1; 51 my $found; 52 $found = stat($dir . "/" . $inc); 53 if (!$found) { 54 $inc =~ s#asm/#asm-$arch/#; 55 $found = stat($dir . "/" . $inc); 56 } 57 if (!$found) { 58 printf STDERR "$filename:$lineno: included file '$inc' is not exported\n"; 59 $ret = 1; 60 } 61 } 62} 63 64sub check_declarations 65{ 66 if ($line =~m/^\s*extern\b/) { 67 printf STDERR "$filename:$lineno: " . 68 "userspace cannot call function or variable " . 69 "defined in the kernel\n"; 70 } 71} 72 73sub check_config 74{ 75 if ($line =~ m/[^a-zA-Z0-9_]+CONFIG_([a-zA-Z0-9_]+)[^a-zA-Z0-9_]/) { 76 printf STDERR "$filename:$lineno: leaks CONFIG_$1 to userspace where it is not valid\n"; 77 } 78} 79 80my $linux_asm_types; 81sub check_asm_types() 82{ 83 if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) { 84 return; 85 } 86 if ($lineno == 1) { 87 $linux_asm_types = 0; 88 } elsif ($linux_asm_types >= 1) { 89 return; 90 } 91 if ($line =~ m/^\s*#\s*include\s+<asm\/types.h>/) { 92 $linux_asm_types = 1; 93 printf STDERR "$filename:$lineno: " . 94 "include of <linux/types.h> is preferred over <asm/types.h>\n" 95 # Warn until headers are all fixed 96 #$ret = 1; 97 } 98} 99 100my $linux_types; 101sub check_sizetypes 102{ 103 if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) { 104 return; 105 } 106 if ($lineno == 1) { 107 $linux_types = 0; 108 } elsif ($linux_types >= 1) { 109 return; 110 } 111 if ($line =~ m/^\s*#\s*include\s+<linux\/types.h>/) { 112 $linux_types = 1; 113 return; 114 } 115 if ($line =~ m/__[us](8|16|32|64)\b/) { 116 printf STDERR "$filename:$lineno: " . 117 "found __[us]{8,16,32,64} type " . 118 "without #include <linux/types.h>\n"; 119 $linux_types = 2; 120 # Warn until headers are all fixed 121 #$ret = 1; 122 } 123} 124 125