Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/usr/include/headers_check.pl
29266 views
1
#!/usr/bin/env perl
2
# SPDX-License-Identifier: GPL-2.0
3
#
4
# headers_check.pl execute a number of trivial consistency checks
5
#
6
# Usage: headers_check.pl dir [files...]
7
# dir: dir to look for included files
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
21
use warnings;
22
use strict;
23
use File::Basename;
24
25
my ($dir, @files) = @ARGV;
26
27
my $ret = 0;
28
my $line;
29
my $lineno = 0;
30
my $filename;
31
32
foreach my $file (@files) {
33
$filename = $file;
34
35
open(my $fh, '<', $filename)
36
or die "$filename: $!\n";
37
$lineno = 0;
38
while ($line = <$fh>) {
39
$lineno++;
40
&check_include();
41
&check_asm_types();
42
&check_sizetypes();
43
&check_declarations();
44
# Dropped for now. Too much noise &check_config();
45
}
46
close $fh;
47
}
48
exit $ret;
49
50
sub check_include
51
{
52
if ($line =~ m/^\s*#\s*include\s+<((asm|linux).*)>/) {
53
my $inc = $1;
54
my $found;
55
$found = stat($dir . "/" . $inc);
56
if (!$found) {
57
printf STDERR "$filename:$lineno: included file '$inc' is not exported\n";
58
$ret = 1;
59
}
60
}
61
}
62
63
sub check_declarations
64
{
65
# soundcard.h is what it is
66
if ($line =~ m/^void seqbuf_dump\(void\);/) {
67
return;
68
}
69
# drm headers are being C++ friendly
70
if ($line =~ m/^extern "C"/) {
71
return;
72
}
73
if ($line =~ m/^(\s*extern|unsigned|char|short|int|long|void)\b/) {
74
printf STDERR "$filename:$lineno: " .
75
"userspace cannot reference function or " .
76
"variable defined in the kernel\n";
77
$ret = 1;
78
}
79
}
80
81
sub check_config
82
{
83
if ($line =~ m/[^a-zA-Z0-9_]+CONFIG_([a-zA-Z0-9_]+)[^a-zA-Z0-9_]/) {
84
printf STDERR "$filename:$lineno: leaks CONFIG_$1 to userspace where it is not valid\n";
85
}
86
}
87
88
my $linux_asm_types;
89
sub check_asm_types
90
{
91
if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
92
return;
93
}
94
if ($lineno == 1) {
95
$linux_asm_types = 0;
96
} elsif ($linux_asm_types >= 1) {
97
return;
98
}
99
if ($line =~ m/^\s*#\s*include\s+<asm\/types.h>/) {
100
$linux_asm_types = 1;
101
printf STDERR "$filename:$lineno: " .
102
"include of <linux/types.h> is preferred over <asm/types.h>\n";
103
$ret = 1;
104
}
105
}
106
107
my $linux_types;
108
my %import_stack = ();
109
sub check_include_typesh
110
{
111
my $path = $_[0];
112
my $import_path;
113
114
my $fh;
115
my @file_paths = ($path, $dir . "/" . $path, dirname($filename) . "/" . $path);
116
for my $possible ( @file_paths ) {
117
if (not $import_stack{$possible} and open($fh, '<', $possible)) {
118
$import_path = $possible;
119
$import_stack{$import_path} = 1;
120
last;
121
}
122
}
123
if (eof $fh) {
124
return;
125
}
126
127
my $line;
128
while ($line = <$fh>) {
129
if ($line =~ m/^\s*#\s*include\s+<linux\/types.h>/) {
130
$linux_types = 1;
131
last;
132
}
133
if (my $included = ($line =~ /^\s*#\s*include\s+[<"](\S+)[>"]/)[0]) {
134
check_include_typesh($included);
135
}
136
}
137
close $fh;
138
delete $import_stack{$import_path};
139
}
140
141
sub check_sizetypes
142
{
143
if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
144
return;
145
}
146
if ($lineno == 1) {
147
$linux_types = 0;
148
} elsif ($linux_types >= 1) {
149
return;
150
}
151
if ($line =~ m/^\s*#\s*include\s+<linux\/types.h>/) {
152
$linux_types = 1;
153
return;
154
}
155
if (my $included = ($line =~ /^\s*#\s*include\s+[<"](\S+)[>"]/)[0]) {
156
check_include_typesh($included);
157
}
158
if ($line =~ m/__[us](8|16|32|64)\b/) {
159
printf STDERR "$filename:$lineno: " .
160
"found __[us]{8,16,32,64} type " .
161
"without #include <linux/types.h>\n";
162
$linux_types = 2;
163
$ret = 1;
164
}
165
}
166
167