Initial Contribution
msm-2.6.38: tag AU_LINUX_ANDROID_GINGERBREAD.02.03.04.00.142
Signed-off-by: Bryan Huntsman <bryanh@codeaurora.org>
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 56dfafc..93b2f69 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -80,6 +80,7 @@
$(if $(KBUILD_EXTRA_SYMBOLS), $(patsubst %, -e %,$(KBUILD_EXTRA_SYMBOLS))) \
$(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
$(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \
+ $(if $(CONFIG_NO_ERROR_ON_MISMATCH),,-E) \
$(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \
$(if $(cross_build),-c)
diff --git a/scripts/build-all.py b/scripts/build-all.py
new file mode 100755
index 0000000..6135253
--- /dev/null
+++ b/scripts/build-all.py
@@ -0,0 +1,266 @@
+#! /usr/bin/env python
+
+# Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of Code Aurora nor
+# the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Build the kernel for all targets using the Android build environment.
+#
+# TODO: Accept arguments to indicate what to build.
+
+import glob
+from optparse import OptionParser
+import subprocess
+import os
+import os.path
+import shutil
+import sys
+
+version = 'build-all.py, version 0.01'
+
+build_dir = '../all-kernels'
+make_command = ["vmlinux", "modules"]
+make_env = os.environ
+make_env.update({
+ 'ARCH': 'arm',
+ 'CROSS_COMPILE': 'arm-none-linux-gnueabi-',
+ 'KCONFIG_NOTIMESTAMP': 'true' })
+all_options = {}
+
+def error(msg):
+ sys.stderr.write("error: %s\n" % msg)
+
+def fail(msg):
+ """Fail with a user-printed message"""
+ error(msg)
+ sys.exit(1)
+
+def check_kernel():
+ """Ensure that PWD is a kernel directory"""
+ if (not os.path.isfile('MAINTAINERS') or
+ not os.path.isfile('arch/arm/mach-msm/Kconfig')):
+ fail("This doesn't seem to be an MSM kernel dir")
+
+def check_build():
+ """Ensure that the build directory is present."""
+ if not os.path.isdir(build_dir):
+ try:
+ os.makedirs(build_dir)
+ except OSError as exc:
+ if exc.errno == errno.EEXIST:
+ pass
+ else:
+ raise
+
+def update_config(file, str):
+ print 'Updating %s with \'%s\'\n' % (file, str)
+ defconfig = open(file, 'a')
+ defconfig.write(str + '\n')
+ defconfig.close()
+
+def scan_configs():
+ """Get the full list of defconfigs appropriate for this tree."""
+ names = {}
+ for n in glob.glob('arch/arm/configs/msm[0-9]*_defconfig'):
+ names[os.path.basename(n)[:-10]] = n
+ for n in glob.glob('arch/arm/configs/qsd*_defconfig'):
+ names[os.path.basename(n)[:-10]] = n
+ return names
+
+class Builder:
+ def __init__(self, logname):
+ self.logname = logname
+ self.fd = open(logname, 'w')
+
+ def run(self, args):
+ devnull = open('/dev/null', 'r')
+ proc = subprocess.Popen(args, stdin=devnull,
+ env=make_env,
+ bufsize=0,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ count = 0
+ # for line in proc.stdout:
+ rawfd = proc.stdout.fileno()
+ while True:
+ line = os.read(rawfd, 1024)
+ if not line:
+ break
+ self.fd.write(line)
+ self.fd.flush()
+ if all_options.verbose:
+ sys.stdout.write(line)
+ sys.stdout.flush()
+ else:
+ for i in range(line.count('\n')):
+ count += 1
+ if count == 64:
+ count = 0
+ print
+ sys.stdout.write('.')
+ sys.stdout.flush()
+ print
+ result = proc.wait()
+
+ self.fd.close()
+ return result
+
+failed_targets = []
+
+def build(target):
+ dest_dir = os.path.join(build_dir, target)
+ log_name = '%s/log-%s.log' % (build_dir, target)
+ print 'Building %s in %s log %s' % (target, dest_dir, log_name)
+ if not os.path.isdir(dest_dir):
+ os.mkdir(dest_dir)
+ defconfig = 'arch/arm/configs/%s_defconfig' % target
+ dotconfig = '%s/.config' % dest_dir
+ savedefconfig = '%s/defconfig' % dest_dir
+ shutil.copyfile(defconfig, dotconfig)
+
+ devnull = open('/dev/null', 'r')
+ subprocess.check_call(['make', 'O=%s' % dest_dir,
+ '%s_defconfig' % target], env=make_env, stdin=devnull)
+ devnull.close()
+
+ if not all_options.updateconfigs:
+ build = Builder(log_name)
+
+ result = build.run(['make', 'O=%s' % dest_dir] + make_command)
+
+ if result != 0:
+ if all_options.keep_going:
+ failed_targets.append(target)
+ fail_or_error = error
+ else:
+ fail_or_error = fail
+ fail_or_error("Failed to build %s, see %s" % (target, build.logname))
+
+ # Copy the defconfig back.
+ if all_options.configs or all_options.updateconfigs:
+ devnull = open('/dev/null', 'r')
+ subprocess.check_call(['make', 'O=%s' % dest_dir,
+ 'savedefconfig'], env=make_env, stdin=devnull)
+ devnull.close()
+ shutil.copyfile(savedefconfig, defconfig)
+
+def build_many(allconf, targets):
+ print "Building %d target(s)" % len(targets)
+ for target in targets:
+ if all_options.updateconfigs:
+ update_config(allconf[target], all_options.updateconfigs)
+ build(target)
+ if failed_targets:
+ fail('\n '.join(["Failed targets:"] +
+ [target for target in failed_targets]))
+
+def main():
+ global make_command
+
+ check_kernel()
+ check_build()
+
+ configs = scan_configs()
+
+ usage = ("""
+ %prog [options] all -- Build all targets
+ %prog [options] target target ... -- List specific targets
+ %prog [options] perf -- Build all perf targets
+ %prog [options] noperf -- Build all non-perf targets""")
+ parser = OptionParser(usage=usage, version=version)
+ parser.add_option('--configs', action='store_true',
+ dest='configs',
+ help="Copy configs back into tree")
+ parser.add_option('--list', action='store_true',
+ dest='list',
+ help='List available targets')
+ parser.add_option('-v', '--verbose', action='store_true',
+ dest='verbose',
+ help='Output to stdout in addition to log file')
+ parser.add_option('--oldconfig', action='store_true',
+ dest='oldconfig',
+ help='Only process "make oldconfig"')
+ parser.add_option('--updateconfigs',
+ dest='updateconfigs',
+ help="Update defconfigs with provided option setting, "
+ "e.g. --updateconfigs=\'CONFIG_USE_THING=y\'")
+ parser.add_option('-j', '--jobs', type='int', dest="jobs",
+ help="Number of simultaneous jobs")
+ parser.add_option('-l', '--load-average', type='int',
+ dest='load_average',
+ help="Don't start multiple jobs unless load is below LOAD_AVERAGE")
+ parser.add_option('-k', '--keep-going', action='store_true',
+ dest='keep_going', default=False,
+ help="Keep building other targets if a target fails")
+ parser.add_option('-m', '--make-target', action='append',
+ help='Build the indicated make target (default: %s)' %
+ ' '.join(make_command))
+
+ (options, args) = parser.parse_args()
+ global all_options
+ all_options = options
+
+ if options.list:
+ print "Available targets:"
+ for target in configs.keys():
+ print " %s" % target
+ sys.exit(0)
+
+ if options.oldconfig:
+ make_command = ["oldconfig"]
+ elif options.make_target:
+ make_command = options.make_target
+
+ if options.jobs:
+ make_command.append("-j%d" % options.jobs)
+ if options.load_average:
+ make_command.append("-l%d" % options.load_average)
+
+ if args == ['all']:
+ build_many(configs, configs.keys())
+ elif args == ['perf']:
+ targets = []
+ for t in configs.keys():
+ if "perf" in t:
+ targets.append(t)
+ build_many(configs, targets)
+ elif args == ['noperf']:
+ targets = []
+ for t in configs.keys():
+ if "perf" not in t:
+ targets.append(t)
+ build_many(configs, targets)
+ elif len(args) > 0:
+ targets = []
+ for t in args:
+ if t not in configs.keys():
+ parser.error("Target '%s' not one of %s" % (t, configs.keys()))
+ targets.append(t)
+ build_many(configs, targets)
+ else:
+ parser.error("Must specify a target to build, or 'all'")
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index b0aa2c6..2d4ce15 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -7,6 +7,12 @@
use strict;
+use constant BEFORE_SHORTTEXT => 0;
+use constant IN_SHORTTEXT => 1;
+use constant AFTER_SHORTTEXT => 2;
+use constant CHECK_NEXT_SHORTTEXT => 3;
+use constant SHORTTEXT_LIMIT => 75;
+
my $P = $0;
$P =~ s@.*/@@g;
@@ -1155,6 +1161,8 @@
my $prevrawline="";
my $stashline="";
my $stashrawline="";
+ my $subjectline="";
+ my $sublinenr="";
my $length;
my $indent;
@@ -1194,8 +1202,36 @@
my @setup_docs = ();
my $setup_docs = 0;
+ my $in_code_block = 0;
+ my $exec_file = "";
+
+ my $shorttext = BEFORE_SHORTTEXT;
+ my $shorttext_exspc = 0;
+
sanitise_line_reset();
my $line;
+ # Before sanitizing the rawlines, collapse any header-continuation
+ # lines into a single line so they can be parsed meaningfully.
+ my $end_of_hdrs = 0;
+ foreach my $rawline (@rawlines) {
+ if ($rawline=~/^\s*$/) {
+ last;
+ } else {
+ $end_of_hdrs++;
+ }
+ }
+ my @continuation_hdrs;
+ foreach my $n (0 .. $end_of_hdrs) {
+ if ($rawlines[$n]=~/^\s+/) {
+ push @continuation_hdrs, $n;
+ }
+ }
+ while (my $n = pop @continuation_hdrs) {
+ $line = splice @rawlines, $n, 1;
+ $line=~s/^\s+/ /;
+ $rawlines[$n - 1] .= $line;
+ }
+
foreach my $rawline (@rawlines) {
$linenr++;
$line = $rawline;
@@ -1346,15 +1382,84 @@
if ($realfile =~ m@^include/asm/@) {
ERROR("do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
}
+ $in_code_block = 1;
next;
}
-
+ elsif ($rawline =~ /^diff.+a\/(.+)\sb\/.+$/) {
+ $exec_file = $1;
+ $in_code_block = 0;
+ }
+ #Check state to make sure we aren't in code block.
+ elsif (!$in_code_block &&
+ ($exec_file =~ /^.+\.[chS]$/ or
+ $exec_file =~ /^.+\.txt$/ or
+ $exec_file =~ /^.+\.ihex$/ or
+ $exec_file =~ /^.+\.hex$/ or
+ $exec_file =~ /^.+\.HEX$/ or
+ $exec_file =~ /^.+defconfig$/ or
+ $exec_file =~ /^Makefile$/ or
+ $exec_file =~ /^Kconfig$/) &&
+ $rawline =~ /^new (file )?mode\s([0-9]+)$/ &&
+ (oct($2) & 0111)) {
+ ERROR("Source file has +x permissions: " .
+ "$exec_file\n");
+ }
$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
my $hereline = "$here\n$rawline\n";
my $herecurr = "$here\n$rawline\n";
my $hereprev = "$here\n$prevrawline\n$rawline\n";
+ if ($shorttext != AFTER_SHORTTEXT) {
+ if ($shorttext == IN_SHORTTEXT) {
+ if ($line=~/^---/ || $line=~/^diff.*/) {
+ $shorttext = AFTER_SHORTTEXT;
+ } elsif (length($line) > (SHORTTEXT_LIMIT +
+ $shorttext_exspc)
+ && $line !~ /^:([0-7]{6}\s){2}
+ ([[:xdigit:]]+\.*
+ \s){2}\w+\s\w+/xms) {
+ WARN("commit text line over " .
+ SHORTTEXT_LIMIT .
+ " characters\n" . $herecurr);
+ }
+ } elsif ($shorttext == CHECK_NEXT_SHORTTEXT) {
+# The Subject line doesn't have to be the last header in the patch.
+# Avoid moving to the IN_SHORTTEXT state until clear of all headers.
+# Per RFC5322, continuation lines must be folded, so any left-justified
+# text which looks like a header is definitely a header.
+ if ($line!~/^[\x21-\x39\x3b-\x7e]+:/) {
+ $shorttext = IN_SHORTTEXT;
+# Check for Subject line followed by a blank line.
+ if (length($line) != 0) {
+ WARN("non-blank line after " .
+ "summary line\n" .
+ $sublinenr . $here .
+ "\n" . $subjectline .
+ "\n" . $line . "\n");
+ }
+ }
+ } elsif ($line=~/^Subject: \[[^\]]*\] (.*)/) {
+ $shorttext = CHECK_NEXT_SHORTTEXT;
+ $subjectline = $line;
+ $sublinenr = "#$linenr & ";
+# Check for Subject line less than line limit
+ if (length($1) > SHORTTEXT_LIMIT) {
+ WARN("summary line over " .
+ SHORTTEXT_LIMIT .
+ " characters\n" . $herecurr);
+ }
+ } elsif ($line=~/^ (.*)/) {
+ $shorttext = IN_SHORTTEXT;
+ $shorttext_exspc = 4;
+ if (length($1) > SHORTTEXT_LIMIT) {
+ WARN("summary line over " .
+ SHORTTEXT_LIMIT .
+ " characters\n" . $herecurr);
+ }
+ }
+ }
+
$cnt_lines++ if ($realcnt != 0);
# Check for incorrect file permissions
@@ -1377,6 +1482,14 @@
WARN("space required after Signed-off-by:\n" .
$herecurr);
}
+ if ($line =~ /^\s*signed-off-by:.*(quicinc|qualcomm)\.com/i) {
+ WARN("invalid Signed-off-by identity\n" . $line );
+ }
+ }
+
+#check the patch for invalid author credentials
+ if ($line =~ /^From:.*(quicinc|qualcomm)\.com/) {
+ WARN("invalid author identity\n" . $line );
}
# Check for wrappage within a valid hunk of the file
@@ -1425,37 +1538,6 @@
$rpt_cleaners = 1;
}
-# check for Kconfig help text having a real description
-# Only applies when adding the entry originally, after that we do not have
-# sufficient context to determine whether it is indeed long enough.
- if ($realfile =~ /Kconfig/ &&
- $line =~ /\+\s*(?:---)?help(?:---)?$/) {
- my $length = 0;
- my $cnt = $realcnt;
- my $ln = $linenr + 1;
- my $f;
- my $is_end = 0;
- while ($cnt > 0 && defined $lines[$ln - 1]) {
- $f = $lines[$ln - 1];
- $cnt-- if ($lines[$ln - 1] !~ /^-/);
- $is_end = $lines[$ln - 1] =~ /^\+/;
- $ln++;
-
- next if ($f =~ /^-/);
- $f =~ s/^.//;
- $f =~ s/#.*//;
- $f =~ s/^\s+//;
- next if ($f =~ /^$/);
- if ($f =~ /^\s*config\s/) {
- $is_end = 1;
- last;
- }
- $length++;
- }
- WARN("please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_end && $length < 4);
- #print "is_end<$is_end> length<$length>\n";
- }
-
# check we are in a valid source file if not then ignore this hunk
next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
@@ -1464,6 +1546,7 @@
$rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
!($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ ||
$line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) &&
+ $realfile ne "scripts/checkpatch.pl" &&
$length > 80)
{
WARN("line over 80 characters\n" . $herecurr);
@@ -2245,7 +2328,7 @@
# check spacing on parentheses
if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
- $line !~ /for\s*\(\s+;/) {
+ $line !~ /for\s*\(\s+;/ && $line !~ /^\+\s*[A-Z_][A-Z\d_]*\(\s*\d+(\,.*)?\)\,?$/) {
ERROR("space prohibited after that open parenthesis '('\n" . $herecurr);
}
if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
@@ -2439,7 +2522,7 @@
if ($realfile !~ m@/vmlinux.lds.h$@ &&
$line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
my $ln = $linenr;
- my $cnt = $realcnt;
+ my $cnt = $realcnt - 1;
my ($off, $dstat, $dcond, $rest);
my $ctx = '';
@@ -2495,12 +2578,19 @@
{
}
+ # Extremely long macros may fall off the end of the
+ # available context without closing. Give a dangling
+ # backslash the benefit of the doubt and allow it
+ # to gobble any hanging open-parens.
+ $dstat =~ s/\(.+\\$/1/;
+
my $exceptions = qr{
$Declare|
module_param_named|
MODULE_PARAM_DESC|
DECLARE_PER_CPU|
DEFINE_PER_CPU|
+ CLK_[A-Z\d_]+|
__typeof__\(|
union|
struct|
@@ -2659,10 +2749,70 @@
WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
}
+# sys_open/read/write/close are not allowed in the kernel
+ if ($line =~ /\b(sys_(?:open|read|write|close))\b/) {
+ ERROR("$1 is inappropriate in kernel code.\n" .
+ $herecurr);
+ }
+
+# filp_open is a backdoor for sys_open
+ if ($line =~ /\b(filp_open)\b/) {
+ ERROR("$1 is inappropriate in kernel code.\n" .
+ $herecurr);
+ }
+
+# read[bwl] & write[bwl] use too many barriers, use the _relaxed variants
+ if ($line =~ /\b((?:read|write)[bwl])\b/) {
+ ERROR("Use of $1 is deprecated: use $1_relaxed\n\t" .
+ "with appropriate memory barriers instead.\n" .
+ $herecurr);
+ }
+
+# likewise, in/out[bwl] should be __raw_read/write[bwl]...
+ if ($line =~ /\b((in|out)([bwl]))\b/) {
+ my ($all, $pref, $suf) = ($1, $2, $3);
+ $pref =~ s/in/read/;
+ $pref =~ s/out/write/;
+ ERROR("Use of $all is deprecated: use " .
+ "__raw_$pref$suf\n\t" .
+ "with appropriate memory barriers instead.\n" .
+ $herecurr);
+ }
+
+# dsb is too ARMish, and should usually be mb.
+ if ($line =~ /\bdsb\b/) {
+ WARN("Use of dsb is discouranged: prefer mb.\n" .
+ $herecurr);
+ }
+
+# unbounded string functions are overflow risks
+ my %str_fns = (
+ "sprintf" => "snprintf",
+ "strcpy" => "strncpy",
+ "strcat" => "strncat",
+ "strcmp" => "strncmp",
+ "strcasecmp" => "strncasecmp",
+ "strchr" => "strnchr",
+ "strstr" => "strnstr",
+ "strlen" => "strnlen",
+ );
+ foreach my $k (keys %str_fns) {
+ if ($line =~ /\b$k\b/) {
+ ERROR("Use of $k is deprecated: " .
+ "use $str_fns{$k} instead.\n" .
+ $herecurr);
+ }
+ }
+
# warn about #if 0
if ($line =~ /^.\s*\#\s*if\s+0\b/) {
- CHK("if this code is redundant consider removing it\n" .
- $herecurr);
+ WARN("if this code is redundant consider removing it\n"
+ . $herecurr);
+ }
+# warn about #if 1
+ if ($line =~ /^.\s*\#\s*if\s+1\b/) {
+ WARN("if this code is required consider removing"
+ . " #if 1\n" . $herecurr);
}
# check for needless kfree() checks
@@ -2695,6 +2845,11 @@
}
}
+# check the patch for use of mdelay
+ if ($line =~ /\bmdelay\s*\(/) {
+ WARN("use of mdelay() found: msleep() is the preferred API.\n" . $line );
+ }
+
# warn about #ifdefs in C files
# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
# print "#ifdef in C files should be avoided\n";
@@ -2804,6 +2959,11 @@
WARN("Statements terminations use 1 semicolon\n" . $herecurr);
}
+# check for return codes on error paths
+ if ($line =~ /\breturn\s+-\d+/) {
+ ERROR("illegal return value, please use an error code\n" . $herecurr);
+ }
+
# check for gcc specific __FUNCTION__
if ($line =~ /__FUNCTION__/) {
WARN("__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr);
diff --git a/scripts/gcc-wrapper.py b/scripts/gcc-wrapper.py
new file mode 100755
index 0000000..cbe2eae
--- /dev/null
+++ b/scripts/gcc-wrapper.py
@@ -0,0 +1,117 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of Code Aurora nor
+# the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Invoke gcc, looking for warnings, and causing a failure if there are
+# non-whitelisted warnings.
+
+import errno
+import re
+import os
+import sys
+import subprocess
+
+# Note that gcc uses unicode, which may depend on the locale. TODO:
+# force LANG to be set to en_US.UTF-8 to get consistent warnings.
+
+allowed_warnings = set([
+ "alignment.c:720",
+ "async.c:122",
+ "async.c:270",
+ "dir.c:43",
+ "dm.c:1053",
+ "dm.c:1080",
+ "dm-table.c:1120",
+ "dm-table.c:1126",
+ "drm_edid.c:1303",
+ "eventpoll.c:1143",
+ "f_mass_storage.c:3368",
+ "inode.c:72",
+ "inode.c:73",
+ "inode.c:74",
+ "msm_sdcc.c:126",
+ "msm_sdcc.c:128",
+ "nf_conntrack_netlink.c:790",
+ "nf_nat_standalone.c:118",
+ "return_address.c:62",
+ "soc-core.c:1719",
+ "xt_log.h:50",
+ "vx6953.c:3124",
+ ])
+
+# Capture the name of the object file, can find it.
+ofile = None
+
+warning_re = re.compile(r'''(.*/|)([^/]+\.[a-z]+:\d+):(\d+:)? warning:''')
+def interpret_warning(line):
+ """Decode the message from gcc. The messages we care about have a filename, and a warning"""
+ line = line.rstrip('\n')
+ m = warning_re.match(line)
+ if m and m.group(2) not in allowed_warnings:
+ print "error, forbidden warning:", m.group(2)
+
+ # If there is a warning, remove any object if it exists.
+ if ofile:
+ try:
+ os.remove(ofile)
+ except OSError:
+ pass
+ sys.exit(1)
+
+def run_gcc():
+ args = sys.argv[1:]
+ # Look for -o
+ try:
+ i = args.index('-o')
+ global ofile
+ ofile = args[i+1]
+ except (ValueError, IndexError):
+ pass
+
+ compiler = sys.argv[0]
+
+ try:
+ proc = subprocess.Popen(args, stderr=subprocess.PIPE)
+ for line in proc.stderr:
+ print line,
+ interpret_warning(line)
+
+ result = proc.wait()
+ except OSError as e:
+ result = e.errno
+ if result == errno.ENOENT:
+ print args[0] + ':',e.strerror
+ print 'Is your PATH set correctly?'
+ else:
+ print ' '.join(args), str(e)
+
+ return result
+
+if __name__ == '__main__':
+ status = run_gcc()
+ sys.exit(status)
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 413c536..d3e509e 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -37,6 +37,8 @@
static int external_module = 0;
/* Warn about section mismatch in vmlinux if set to 1 */
static int vmlinux_section_warnings = 1;
+/* Exit with an error when there is a section mismatch if set to 1 */
+static int section_error_on_mismatch;
/* Only warn about unresolved symbols */
static int warn_unresolved = 0;
/* How a symbol is exported */
@@ -2068,7 +2070,7 @@
struct ext_sym_list *extsym_iter;
struct ext_sym_list *extsym_start = NULL;
- while ((opt = getopt(argc, argv, "i:I:e:cmsSo:awM:K:")) != -1) {
+ while ((opt = getopt(argc, argv, "i:I:e:cmsSo:awM:K:E")) != -1) {
switch (opt) {
case 'i':
kernel_read = optarg;
@@ -2106,6 +2108,9 @@
case 'w':
warn_unresolved = 1;
break;
+ case 'E':
+ section_error_on_mismatch = 1;
+ break;
default:
exit(1);
}
@@ -2154,11 +2159,23 @@
if (dump_write)
write_dump(dump_write);
- if (sec_mismatch_count && !sec_mismatch_verbose)
- warn("modpost: Found %d section mismatch(es).\n"
- "To see full details build your kernel with:\n"
- "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n",
- sec_mismatch_count);
+
+ if (sec_mismatch_count && !sec_mismatch_verbose) {
+ merror(
+ "modpost: Found %d section mismatch(es).\n"
+ "To see full details build your kernel with:\n"
+ "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n",
+ sec_mismatch_count);
+
+ }
+
+ if (sec_mismatch_count && section_error_on_mismatch) {
+ err |= 1;
+ printf(
+ "To build the kernel despite the mismatches, "
+ "build with:\n'make CONFIG_NO_ERROR_ON_MISMATCH=y'\n"
+ "(NOTE: This is not recommended)\n");
+ }
return err;
}