linux-brain/scripts/headers_check.pl
Arnd Bergmann 92181d47ee headers_check: don't warn about c++ guards
A recent addition to the DRM tree for 4.7 added 'extern "C"' guards
for c++ to all the DRM headers, and that now causes warnings
in 'make headers_check':

usr/include/drm/amdgpu_drm.h:38: userspace cannot reference function or variable defined in the kernel
usr/include/drm/drm.h:63: userspace cannot reference function or variable defined in the kernel
usr/include/drm/drm.h:699: userspace cannot reference function or variable defined in the kernel
usr/include/drm/drm_fourcc.h:30: userspace cannot reference function or variable defined in the kernel
usr/include/drm/drm_mode.h:33: userspace cannot reference function or variable defined in the kernel
usr/include/drm/drm_sarea.h:38: userspace cannot reference function or variable defined in the kernel
usr/include/drm/exynos_drm.h:21: userspace cannot reference function or variable defined in the kernel
usr/include/drm/i810_drm.h:7: userspace cannot reference function or variable defined in the kernel

This changes the headers_check.pl script to not warn about this.
I'm listing the merge commit as introducing the problem, because
there are several patches in this branch that each do this for
one file.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Fixes: 7c10ddf874 ("Merge branch 'drm-uapi-extern-c-fixes' of https://github.com/evelikov/linux into drm-next")
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2016-05-24 14:12:48 +10:00

170 lines
3.7 KiB
Perl
Executable File

#!/usr/bin/perl -w
#
# headers_check.pl execute a number of trivial consistency checks
#
# Usage: headers_check.pl dir arch [files...]
# dir: dir to look for included files
# arch: architecture
# files: list of files to check
#
# The script reads the supplied files line by line and:
#
# 1) for each include statement it checks if the
# included file actually exists.
# Only include files located in asm* and linux* are checked.
# The rest are assumed to be system include files.
#
# 2) It is checked that prototypes does not use "extern"
#
# 3) Check for leaked CONFIG_ symbols
use strict;
use File::Basename;
my ($dir, $arch, @files) = @ARGV;
my $ret = 0;
my $line;
my $lineno = 0;
my $filename;
foreach my $file (@files) {
$filename = $file;
open(my $fh, '<', $filename)
or die "$filename: $!\n";
$lineno = 0;
while ($line = <$fh>) {
$lineno++;
&check_include();
&check_asm_types();
&check_sizetypes();
&check_declarations();
# Dropped for now. Too much noise &check_config();
}
close $fh;
}
exit $ret;
sub check_include
{
if ($line =~ m/^\s*#\s*include\s+<((asm|linux).*)>/) {
my $inc = $1;
my $found;
$found = stat($dir . "/" . $inc);
if (!$found) {
$inc =~ s#asm/#asm-$arch/#;
$found = stat($dir . "/" . $inc);
}
if (!$found) {
printf STDERR "$filename:$lineno: included file '$inc' is not exported\n";
$ret = 1;
}
}
}
sub check_declarations
{
# soundcard.h is what it is
if ($line =~ m/^void seqbuf_dump\(void\);/) {
return;
}
# drm headers are being C++ friendly
if ($line =~ m/^extern "C"/) {
return;
}
if ($line =~ m/^(\s*extern|unsigned|char|short|int|long|void)\b/) {
printf STDERR "$filename:$lineno: " .
"userspace cannot reference function or " .
"variable defined in the kernel\n";
}
}
sub check_config
{
if ($line =~ m/[^a-zA-Z0-9_]+CONFIG_([a-zA-Z0-9_]+)[^a-zA-Z0-9_]/) {
printf STDERR "$filename:$lineno: leaks CONFIG_$1 to userspace where it is not valid\n";
}
}
my $linux_asm_types;
sub check_asm_types
{
if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
return;
}
if ($lineno == 1) {
$linux_asm_types = 0;
} elsif ($linux_asm_types >= 1) {
return;
}
if ($line =~ m/^\s*#\s*include\s+<asm\/types.h>/) {
$linux_asm_types = 1;
printf STDERR "$filename:$lineno: " .
"include of <linux/types.h> is preferred over <asm/types.h>\n"
# Warn until headers are all fixed
#$ret = 1;
}
}
my $linux_types;
my %import_stack = ();
sub check_include_typesh
{
my $path = $_[0];
my $import_path;
my $fh;
my @file_paths = ($path, $dir . "/" . $path, dirname($filename) . "/" . $path);
for my $possible ( @file_paths ) {
if (not $import_stack{$possible} and open($fh, '<', $possible)) {
$import_path = $possible;
$import_stack{$import_path} = 1;
last;
}
}
if (eof $fh) {
return;
}
my $line;
while ($line = <$fh>) {
if ($line =~ m/^\s*#\s*include\s+<linux\/types.h>/) {
$linux_types = 1;
last;
}
if (my $included = ($line =~ /^\s*#\s*include\s+[<"](\S+)[>"]/)[0]) {
check_include_typesh($included);
}
}
close $fh;
delete $import_stack{$import_path};
}
sub check_sizetypes
{
if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
return;
}
if ($lineno == 1) {
$linux_types = 0;
} elsif ($linux_types >= 1) {
return;
}
if ($line =~ m/^\s*#\s*include\s+<linux\/types.h>/) {
$linux_types = 1;
return;
}
if (my $included = ($line =~ /^\s*#\s*include\s+[<"](\S+)[>"]/)[0]) {
check_include_typesh($included);
}
if ($line =~ m/__[us](8|16|32|64)\b/) {
printf STDERR "$filename:$lineno: " .
"found __[us]{8,16,32,64} type " .
"without #include <linux/types.h>\n";
$linux_types = 2;
# Warn until headers are all fixed
#$ret = 1;
}
}