diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-07-23 10:20:10 +0100 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2007-07-23 10:20:10 +0100 |
commit | 39fe5434cb9de5da40510028b17b96bc4eb312b3 (patch) | |
tree | 7a02a317b9ad57da51ca99887c119e779ccf3f13 /scripts | |
parent | 0fc72b81d3111d114ab378935b1cf07680ca1289 (diff) | |
parent | f695baf2df9e0413d3521661070103711545207a (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/Kbuild.include | 7 | ||||
-rwxr-xr-x | scripts/Lindent | 2 | ||||
-rw-r--r-- | scripts/Makefile.build | 16 | ||||
-rw-r--r-- | scripts/Makefile.headersinst | 14 | ||||
-rw-r--r-- | scripts/Makefile.modpost | 4 | ||||
-rwxr-xr-x | scripts/checkpatch.pl | 535 | ||||
-rwxr-xr-x | scripts/cleanfile | 54 | ||||
-rwxr-xr-x | scripts/cleanpatch | 58 | ||||
-rw-r--r-- | scripts/decodecode | 51 | ||||
-rw-r--r-- | scripts/gcc-version.sh | 15 | ||||
-rw-r--r-- | scripts/gen_initramfs_list.sh | 12 | ||||
-rw-r--r-- | scripts/kallsyms.c | 21 | ||||
-rw-r--r-- | scripts/kconfig/Makefile | 35 | ||||
-rw-r--r-- | scripts/kconfig/confdata.c | 37 | ||||
-rw-r--r-- | scripts/kconfig/kxgettext.c | 4 | ||||
-rw-r--r-- | scripts/kconfig/lxdialog/check-lxdialog.sh | 2 | ||||
-rw-r--r-- | scripts/kconfig/mconf.c | 11 | ||||
-rwxr-xr-x | scripts/kernel-doc | 28 | ||||
-rw-r--r-- | scripts/mod/modpost.c | 313 | ||||
-rw-r--r-- | scripts/mod/modpost.h | 3 |
20 files changed, 805 insertions, 417 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 06c1a377c4c..677bc6c175c 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -100,9 +100,14 @@ cc-option-align = $(subst -functions=0,,\ $(call cc-option,-falign-functions=0,-malign-functions=0)) # cc-version -# Usage gcc-ver := $(call cc-version,$(CC)) +# Usage gcc-ver := $(call cc-version) cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC)) +# cc-fullversion +# Usage gcc-ver := $(call cc-fullversion) +cc-fullversion = $(shell $(CONFIG_SHELL) \ + $(srctree)/scripts/gcc-version.sh -p $(CC)) + # cc-ifversion # Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) cc-ifversion = $(shell [ $(call cc-version, $(CC)) $(1) $(2) ] && echo $(3)) diff --git a/scripts/Lindent b/scripts/Lindent index 7d8d8896e30..9468ec7971d 100755 --- a/scripts/Lindent +++ b/scripts/Lindent @@ -1,2 +1,2 @@ #!/bin/sh -indent -npro -kr -i8 -ts8 -sob -l80 -ss -ncs "$@" +indent -npro -kr -i8 -ts8 -sob -l80 -ss -ncs -cp1 "$@" diff --git a/scripts/Makefile.build b/scripts/Makefile.build index a525112847f..3f7b451f395 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -7,6 +7,22 @@ src := $(obj) PHONY := __build __build: +# Init all relevant variables used in kbuild files so +# 1) they have correct type +# 2) they do not inherit any value from the environment +obj-y := +obj-m := +lib-y := +lib-m := +always := +targets := +subdir-y := +subdir-m := +EXTRA_AFLAGS := +EXTRA_CFLAGS := +EXTRA_CPPFLAGS := +EXTRA_LDFLAGS := + # Read .config if it exist, otherwise ignore -include include/config/auto.conf diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst index f98d772aac8..53dae3eb3d1 100644 --- a/scripts/Makefile.headersinst +++ b/scripts/Makefile.headersinst @@ -11,13 +11,13 @@ UNIFDEF := scripts/unifdef -U__KERNEL__ # Eliminate the contents of (and inclusions of) compiler.h HDRSED := sed -e "s/ inline / __inline__ /g" \ - -e "s/[[:space:]]__user[[:space:]]\+/ /g" \ - -e "s/(__user[[:space:]]\+/ (/g" \ - -e "s/[[:space:]]__force[[:space:]]\+/ /g" \ - -e "s/(__force[[:space:]]\+/ (/g" \ - -e "s/[[:space:]]__iomem[[:space:]]\+/ /g" \ - -e "s/(__iomem[[:space:]]\+/ (/g" \ - -e "s/[[:space:]]__attribute_const__[[:space:]]\+/\ /g" \ + -e "s/[[:space:]]__user[[:space:]]\{1,\}/ /g" \ + -e "s/(__user[[:space:]]\{1,\}/ (/g" \ + -e "s/[[:space:]]__force[[:space:]]\{1,\}/ /g" \ + -e "s/(__force[[:space:]]\{1,\}/ (/g" \ + -e "s/[[:space:]]__iomem[[:space:]]\{1,\}/ /g" \ + -e "s/(__iomem[[:space:]]\{1,\}/ (/g" \ + -e "s/[[:space:]]__attribute_const__[[:space:]]\{1,\}/\ /g" \ -e "s/[[:space:]]__attribute_const__$$//" \ -e "/^\#include <linux\/compiler.h>/d" diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index d5bbbcce31e..c6fcc597b3b 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -70,10 +70,10 @@ __modpost: $(modules:.ko=.o) FORCE $(call cmd,modpost) $(wildcard vmlinux) $(filter-out FORCE,$^) quiet_cmd_kernel-mod = MODPOST $@ - cmd_kernel-mod = $(cmd_modpost) $(KBUILD_VMLINUX_OBJS) + cmd_kernel-mod = $(cmd_modpost) $@ PHONY += vmlinux -vmlinux: FORCE +vmlinux.o: FORCE $(call cmd,kernel-mod) # Declare generated files as targets for modpost diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 277c32647f3..73751ab6ec0 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -9,7 +9,7 @@ use strict; my $P = $0; $P =~ s@.*/@@g; -my $V = '0.06'; +my $V = '0.08'; use Getopt::Long qw(:config no_auto_abbrev); @@ -47,16 +47,14 @@ my $removal = 'Documentation/feature-removal-schedule.txt'; if ($tree && -f $removal) { open(REMOVE, "<$removal") || die "$P: $removal: open failed - $!\n"; while (<REMOVE>) { - if (/^Files:\s+(.*\S)/) { - for my $file (split(/[, ]+/, $1)) { - if ($file =~ m@include/(.*)@) { + if (/^Check:\s+(.*\S)/) { + for my $entry (split(/[, ]+/, $1)) { + if ($entry =~ m@include/(.*)@) { push(@dep_includes, $1); - } - } - } elsif (/^Funcs:\s+(.*\S)/) { - for my $func (split(/[, ]+/, $1)) { - push(@dep_functions, $func); + } elsif ($entry !~ m@/@) { + push(@dep_functions, $entry); + } } } } @@ -153,7 +151,7 @@ sub sanitise_line { } sub ctx_block_get { - my ($linenr, $remain, $outer, $open, $close) = @_; + my ($linenr, $remain, $outer, $open, $close, $off) = @_; my $line; my $start = $linenr - 1; my $blk = ''; @@ -161,38 +159,58 @@ sub ctx_block_get { my @c; my @res = (); + my $level = 0; for ($line = $start; $remain > 0; $line++) { next if ($rawlines[$line] =~ /^-/); $remain--; $blk .= $rawlines[$line]; + foreach my $c (split(//, $rawlines[$line])) { + ##print "C<$c>L<$level><$open$close>O<$off>\n"; + if ($off > 0) { + $off--; + next; + } - @o = ($blk =~ /$open/g); - @c = ($blk =~ /$close/g); + if ($c eq $close && $level > 0) { + $level--; + last if ($level == 0); + } elsif ($c eq $open) { + $level++; + } + } - if (!$outer || (scalar(@o) - scalar(@c)) == 1) { + if (!$outer || $level <= 1) { push(@res, $rawlines[$line]); } - last if (scalar(@o) == scalar(@c)); + last if ($level == 0); } - return @res; + return ($level, @res); } sub ctx_block_outer { my ($linenr, $remain) = @_; - return ctx_block_get($linenr, $remain, 1, '\{', '\}'); + my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); + return @r; } sub ctx_block { my ($linenr, $remain) = @_; - return ctx_block_get($linenr, $remain, 0, '\{', '\}'); + my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); + return @r; } sub ctx_statement { + my ($linenr, $remain, $off) = @_; + + my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); + return @r; +} +sub ctx_block_level { my ($linenr, $remain) = @_; - return ctx_block_get($linenr, $remain, 0, '\(', '\)'); + return ctx_block_get($linenr, $remain, 0, '{', '}', 0); } sub ctx_locate_comment { @@ -246,6 +264,26 @@ sub cat_vet { return $vet; } +my @report = (); +sub report { + push(@report, $_[0]); +} +sub report_dump { + @report; +} +sub ERROR { + report("ERROR: $_[0]\n"); + our $clean = 0; +} +sub WARN { + report("WARNING: $_[0]\n"); + our $clean = 0; +} +sub CHK { + report("CHECK: $_[0]\n"); + our $clean = 0; +} + sub process { my $filename = shift; my @lines = @_; @@ -259,7 +297,7 @@ sub process { my $previndent=0; my $stashindent=0; - my $clean = 1; + our $clean = 1; my $signoff = 0; my $is_patch = 0; @@ -290,8 +328,11 @@ sub process { long\s+int| long\s+long| long\s+long\s+int| + u8|u16|u32|u64| + s8|s16|s32|s64| struct\s+$Ident| union\s+$Ident| + enum\s+$Ident| ${Ident}_t ) (?:\s+$Sparse)* @@ -302,7 +343,27 @@ sub process { (?:\s*\*+\s*const|\s*\*+)? }x; my $Declare = qr{(?:$Storage\s+)?$Type}; - my $Attribute = qr{__read_mostly|__init|__initdata}; + my $Attribute = qr{const|__read_mostly|__init|__initdata|__meminit}; + + my $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; + my $Lval = qr{$Ident(?:$Member)*}; + + # Pre-scan the patch looking for any __setup documentation. + my @setup_docs = (); + my $setup_docs = 0; + foreach my $line (@lines) { + if ($line=~/^\+\+\+\s+(\S+)/) { + $setup_docs = 0; + if ($1 =~ m@Documentation/kernel-parameters.txt$@) { + $setup_docs = 1; + } + next; + } + + if ($setup_docs && $line =~ /^\+/) { + push(@setup_docs, $line); + } + } foreach my $line (@lines) { $linenr++; @@ -369,30 +430,42 @@ sub process { $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); my $hereline = "$here\n$line\n"; - my $herecurr = "$here\n$line\n\n"; - my $hereprev = "$here\n$prevline\n$line\n\n"; + my $herecurr = "$here\n$line\n"; + my $hereprev = "$here\n$prevline\n$line\n"; #check the patch for a signoff: if ($line =~ /^\s*signed-off-by:/i) { # This is a signoff, if ugly, so do not double report. $signoff++; if (!($line =~ /^\s*Signed-off-by:/)) { - print "Signed-off-by: is the preferred form\n"; - print "$herecurr"; - $clean = 0; + WARN("Signed-off-by: is the preferred form\n" . + $herecurr); } if ($line =~ /^\s*signed-off-by:\S/i) { - print "need space after Signed-off-by:\n"; - print "$herecurr"; - $clean = 0; + WARN("need space after Signed-off-by:\n" . + $herecurr); } } # Check for wrappage within a valid hunk of the file if ($realcnt != 0 && $line !~ m{^(?:\+|-| |$)}) { - print "patch seems to be corrupt (line wrapped?) [$realcnt]\n"; - print "$herecurr"; - $clean = 0; + ERROR("patch seems to be corrupt (line wrapped?)\n" . + $herecurr); + } + +# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php + if (($realfile =~ /^$/ || $line =~ /^\+/) && + !($line =~ m/^( + [\x09\x0A\x0D\x20-\x7E] # ASCII + | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte + | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs + | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte + | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates + | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 + | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 + | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 + )*$/x )) { + ERROR("Invalid UTF-8\n" . $herecurr); } #ignore lines being removed @@ -403,16 +476,12 @@ sub process { #trailing whitespace if ($line =~ /^\+.*\S\s+$/ || $line =~ /^\+\s+$/) { - my $herevet = "$here\n" . cat_vet($line) . "\n\n"; - print "trailing whitespace\n"; - print "$herevet"; - $clean = 0; + my $herevet = "$here\n" . cat_vet($line) . "\n"; + ERROR("trailing whitespace\n" . $herevet); } #80 column limit if ($line =~ /^\+/ && !($prevline=~/\/\*\*/) && $length > 80) { - print "line over 80 characters\n"; - print "$herecurr"; - $clean = 0; + WARN("line over 80 characters\n" . $herecurr); } # check we are in a valid source file *.[hc] if not then ignore this hunk @@ -421,10 +490,8 @@ sub process { # at the beginning of a line any tabs must come first and anything # more than 8 must use tabs. if ($line=~/^\+\s* \t\s*\S/ or $line=~/^\+\s* \s*/) { - my $herevet = "$here\n" . cat_vet($line) . "\n\n"; - print "use tabs not spaces\n"; - print "$herevet"; - $clean = 0; + my $herevet = "$here\n" . cat_vet($line) . "\n"; + ERROR("use tabs not spaces\n" . $herevet); } # @@ -463,9 +530,27 @@ sub process { } } if ($err ne '') { - print "switch and case should be at the same indent\n"; - print "$here\n$line\n$err\n"; - $clean = 0; + ERROR("switch and case should be at the same indent\n$hereline\n$err\n"); + } + } + +# if/while/etc brace do not go on next line, unless defining a do while loop, +# or if that brace on the next line is for something else + if ($line =~ /\b(?:(if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.#/) { + my @ctx = ctx_statement($linenr, $realcnt, 0); + my $ctx_ln = $linenr + $#ctx + 1; + my $ctx_cnt = $realcnt - $#ctx - 1; + my $ctx = join("\n", @ctx); + + while ($ctx_cnt > 0 && $lines[$ctx_ln - 1] =~ /^-/) { + $ctx_ln++; + $ctx_cnt--; + } + ##warn "line<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>"; + + if ($ctx !~ /{\s*/ && $ctx_cnt > 0 && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { + ERROR("That open brace { should be on the previous line\n" . + "$here\n$ctx\n$lines[$ctx_ln - 1]"); } } @@ -474,12 +559,16 @@ sub process { # TEST: allow direct testing of the type matcher. if ($tst_type && $line =~ /^.$Declare$/) { - print "TEST: is type $Declare\n"; - print "$herecurr"; - $clean = 0; + ERROR("TEST: is type $Declare\n" . $herecurr); next; } +# check for initialisation to aggregates open brace on the next line + if ($prevline =~ /$Declare\s*$Ident\s*=\s*$/ && + $line =~ /^.\s*{/) { + ERROR("That open brace { should be on the previous line\n" . $hereprev); + } + # # Checks which are anchored on the added line. # @@ -488,9 +577,8 @@ sub process { if ($rawline =~ m{^.#\s*include\s+[<"](.*)[">]}) { my $path = $1; if ($path =~ m{//}) { - print "malformed #include filename\n"; - print "$herecurr"; - $clean = 0; + ERROR("malformed #include filename\n" . + $herecurr); } # Sanitise this special form of string. $path = 'X' x length($path); @@ -499,9 +587,7 @@ sub process { # no C99 // comments if ($line =~ m{//}) { - print "do not use C99 // comments\n"; - print "$herecurr"; - $clean = 0; + ERROR("do not use C99 // comments\n" . $herecurr); } # Remove C99 comments. $line =~ s@//.*@@; @@ -514,49 +600,45 @@ sub process { ($prevline !~ /^\+}/) && ($prevline !~ /^ }/) && ($prevline !~ /\s$name(?:\s+$Attribute)?\s*(?:;|=)/)) { - print "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n"; - print "$herecurr"; - $clean = 0; + WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); } } +# check for external initialisers. + if ($line =~ /^.$Type\s*$Ident\s*=\s*(0|NULL);/) { + ERROR("do not initialise externals to 0 or NULL\n" . + $herecurr); + } # check for static initialisers. - if ($line=~/\s*static\s.*=\s+(0|NULL);/) { - print "do not initialise statics to 0 or NULL\n"; - print "$herecurr"; - $clean = 0; + if ($line =~ /\s*static\s.*=\s*(0|NULL);/) { + ERROR("do not initialise statics to 0 or NULL\n" . + $herecurr); } # check for new typedefs, only function parameters and sparse annotations # make sense. if ($line =~ /\btypedef\s/ && - $line !~ /\btypedef\s+$Type\s+\(\s*$Ident\s*\)\s*\(/ && + $line !~ /\btypedef\s+$Type\s+\(\s*\*$Ident\s*\)\s*\(/ && $line !~ /\b__bitwise(?:__|)\b/) { - print "do not add new typedefs\n"; - print "$herecurr"; - $clean = 0; + WARN("do not add new typedefs\n" . $herecurr); } # * goes on variable not on type if ($line =~ m{\($NonptrType(\*+)(?:\s+const)?\)}) { - print "\"(foo$1)\" should be \"(foo $1)\"\n"; - print "$herecurr"; - $clean = 0; + ERROR("\"(foo$1)\" should be \"(foo $1)\"\n" . + $herecurr); } elsif ($line =~ m{\($NonptrType\s+(\*+)(?!\s+const)\s+\)}) { - print "\"(foo $1 )\" should be \"(foo $1)\"\n"; - print "$herecurr"; - $clean = 0; + ERROR("\"(foo $1 )\" should be \"(foo $1)\"\n" . + $herecurr); - } elsif ($line =~ m{$NonptrType(\*+)(?:\s+const)?\s+[A-Za-z\d_]+}) { - print "\"foo$1 bar\" should be \"foo $1bar\"\n"; - print "$herecurr"; - $clean = 0; + } elsif ($line =~ m{$NonptrType(\*+)(?:\s+$Attribute)?\s+[A-Za-z\d_]+}) { + ERROR("\"foo$1 bar\" should be \"foo $1bar\"\n" . + $herecurr); - } elsif ($line =~ m{$NonptrType\s+(\*+)(?!\s+const)\s+[A-Za-z\d_]+}) { - print "\"foo $1 bar\" should be \"foo $1bar\"\n"; - print "$herecurr"; - $clean = 0; + } elsif ($line =~ m{$NonptrType\s+(\*+)(?!\s+$Attribute)\s+[A-Za-z\d_]+}) { + ERROR("\"foo $1 bar\" should be \"foo $1bar\"\n" . + $herecurr); } # # no BUG() or BUG_ON() @@ -571,7 +653,7 @@ sub process { # to try and find and validate the current printk. In summary the current # printk includes all preceeding printk's which have no newline on the end. # we assume the first bad printk is the one to report. - if ($line =~ /\bprintk\((?!KERN_)/) { + if ($line =~ /\bprintk\((?!KERN_)\s*"/) { my $ok = 0; for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { #print "CHECK<$lines[$ln - 1]\n"; @@ -585,9 +667,7 @@ sub process { } } if ($ok == 0) { - print "printk() should include KERN_ facility level\n"; - print "$herecurr"; - $clean = 0; + WARN("printk() should include KERN_ facility level\n" . $herecurr); } } @@ -595,11 +675,15 @@ sub process { # or if closed on same line if (($line=~/$Type\s*[A-Za-z\d_]+\(.*\).* {/) and !($line=~/\#define.*do\s{/) and !($line=~/}/)) { - print "braces following function declarations go on the next line\n"; - print "$herecurr"; - $clean = 0; + ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr); } +# check for spaces between functions and their parentheses. + if ($line =~ /($Ident)\s+\(/ && + $1 !~ /^(?:if|for|while|switch|return|volatile)$/ && + $line !~ /$Type\s+\(/ && $line !~ /^.\#\s*define\b/) { + ERROR("no space between function name and open parenthesis '('\n" . $herecurr); + } # Check operator spacing. # Note we expand the line with the leading + as the real # line will be displayed with the leading + and the tabs @@ -608,7 +692,7 @@ sub process { $opline = expand_tabs($opline); $opline =~ s/^./ /; if (!($line=~/\#\s*include/)) { - my @elements = split(/(<<=|>>=|<=|>=|==|!=|\+=|-=|\*=|\/=|%=|\^=|\|=|&=|->|<<|>>|<|>|=|!|~|&&|\|\||,|\^|\+\+|--|;|&|\||\+|-|\*|\/\/|\/)/, $opline); + my @elements = split(/(<<=|>>=|<=|>=|==|!=|\+=|-=|\*=|\/=|%=|\^=|\|=|&=|=>|->|<<|>>|<|>|=|!|~|&&|\|\||,|\^|\+\+|--|;|&|\||\+|-|\*|\/\/|\/)/, $opline); my $off = 0; for (my $n = 0; $n < $#elements; $n += 2) { $off += length($elements[$n]); @@ -633,27 +717,27 @@ sub process { } # Pick up the preceeding and succeeding characters. - my $ca = substr($opline, $off - 1, 1); + my $ca = substr($opline, 0, $off); my $cc = ''; if (length($opline) >= ($off + length($elements[$n + 1]))) { $cc = substr($opline, $off + length($elements[$n + 1])); } + my $cb = "$ca$;$cc"; my $ctx = "${a}x${c}"; my $at = "(ctx:$ctx)"; my $ptr = (" " x $off) . "^"; - my $hereptr = "$hereline$ptr\n\n"; + my $hereptr = "$hereline$ptr\n"; ##print "<$s1:$op:$s2> <$elements[$n]:$elements[$n + 1]:$elements[$n + 2]>\n"; # ; should have either the end of line or a space or \ after it if ($op eq ';') { - if ($ctx !~ /.x[WE]/ && $cc !~ /^\\/) { - print "need space after that '$op' $at\n"; - print "$hereptr"; - $clean = 0; + if ($ctx !~ /.x[WEB]/ && $cc !~ /^\\/ && + $cc !~ /^;/) { + ERROR("need space after that '$op' $at\n" . $hereptr); } # // is a comment @@ -662,43 +746,31 @@ sub process { # -> should have no spaces } elsif ($op eq '->') { if ($ctx =~ /Wx.|.xW/) { - print "no spaces around that '$op' $at\n"; - print "$hereptr"; - $clean = 0; + ERROR("no spaces around that '$op' $at\n" . $hereptr); } # , must have a space on the right. } elsif ($op eq ',') { if ($ctx !~ /.xW|.xE/ && $cc !~ /^}/) { - print "need space after that '$op' $at\n"; - print "$hereptr"; - $clean = 0; + ERROR("need space after that '$op' $at\n" . $hereptr); } # unary ! and unary ~ are allowed no space on the right } elsif ($op eq '!' or $op eq '~') { if ($ctx !~ /[WOEB]x./) { - print "need space before that '$op' $at\n"; - print "$hereptr"; - $clean = 0; + ERROR("need space before that '$op' $at\n" . $hereptr); } if ($ctx =~ /.xW/) { - print "no space after that '$op' $at\n"; - print "$hereptr"; - $clean = 0; + ERROR("no space after that '$op' $at\n" . $hereptr); } # unary ++ and unary -- are allowed no space on one side. } elsif ($op eq '++' or $op eq '--') { if ($ctx !~ /[WOB]x[^W]/ && $ctx !~ /[^W]x[WOBE]/) { - print "need space one side of that '$op' $at\n"; - print "$hereptr"; - $clean = 0; + ERROR("need space one side of that '$op' $at\n" . $hereptr); } if ($ctx =~ /Wx./ && $cc =~ /^;/) { - print "no space before that '$op' $at\n"; - print "$hereptr"; - $clean = 0; + ERROR("no space before that '$op' $at\n" . $hereptr); } # & is both unary and binary @@ -715,9 +787,7 @@ sub process { # } elsif ($op eq '&' or $op eq '-') { if ($ctx !~ /VxV|[EW]x[WE]|[EWB]x[VO]/) { - print "need space before that '$op' $at\n"; - print "$hereptr"; - $clean = 0; + ERROR("need space before that '$op' $at\n" . $hereptr); } # * is the same as & only adding: @@ -726,16 +796,9 @@ sub process { # (foo **) # } elsif ($op eq '*') { - if ($ca eq '*') { - if ($cc =~ /^\s(?!\s*const)/) { - print "no space after that '$op' $at\n"; - print "$hereptr"; - $clean = 0; - } - } elsif ($ctx !~ /VxV|[EW]x[WE]|[EWB]x[VO]|OxV|WxB|BxB/) { - print "need space before that '$op' $at\n"; - print "$hereptr"; - $clean = 0; + if ($ca !~ /$Type$/ && $cb !~ /(\*$;|$;\*)/ && + $ctx !~ /VxV|[EW]x[WE]|[EWB]x[VO]|OxV|WxB|BxB/) { + ERROR("need space before that '$op' $at\n" . $hereptr); } # << and >> may either have or not have spaces both sides @@ -743,58 +806,63 @@ sub process { $op eq '^' or $op eq '|') { if ($ctx !~ /VxV|WxW|VxE|WxE/) { - print "need consistent spacing around '$op' $at\n"; - print "$hereptr"; - $clean = 0; + ERROR("need consistent spacing around '$op' $at\n" . + $hereptr); } # All the others need spaces both sides. } elsif ($ctx !~ /[EW]x[WE]/) { - print "need spaces around that '$op' $at\n"; - print "$hereptr"; - $clean = 0; + ERROR("need spaces around that '$op' $at\n" . $hereptr); } $off += length($elements[$n + 1]); } } +# check for multiple assignments + if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { + WARN("multiple assignments should be avoided\n" . $herecurr); + } + +# check for multiple declarations, allowing for a function declaration +# continuation. + if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && + $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { + WARN("declaring multiple variables together should be avoided\n" . $herecurr); + } + #need space before brace following if, while, etc - if ($line=~/\(.*\){/) { - print "need a space before the brace\n"; - print "$herecurr"; - $clean = 0; + if ($line =~ /\(.*\){/ || $line =~ /do{/) { + ERROR("need a space before the open brace '{'\n" . $herecurr); + } + +# closing brace should have a space following it when it has anything +# on the line + if ($line =~ /}(?!(?:,|;|\)))\S/) { + ERROR("need a space after that close brace '}'\n" . $herecurr); } #goto labels aren't indented, allow a single space however if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { - print "labels should not be indented\n"; - print "$herecurr"; - $clean = 0; + WARN("labels should not be indented\n" . $herecurr); } # Need a space before open parenthesis after if, while etc if ($line=~/\b(if|while|for|switch)\(/) { - print "need a space before the open parenthesis\n"; - print "$herecurr"; - $clean = 0; + ERROR("need a space before the open parenthesis '('\n" . $herecurr); } # Check for illegal assignment in if conditional. if ($line=~/\bif\s*\(.*[^<>!=]=[^=].*\)/) { #next if ($line=~/\".*\Q$op\E.*\"/ or $line=~/\'\Q$op\E\'/); - print "do not use assignment in if condition\n"; - print "$herecurr"; - $clean = 0; + ERROR("do not use assignment in if condition\n" . $herecurr); } # Check for }<nl>else {, these must be at the same # indent level to be relevant to each other. if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and $previndent == $indent) { - print "else should follow close brace\n"; - print "$hereprev"; - $clean = 0; + ERROR("else should follow close brace '}'\n" . $hereprev); } #studly caps, commented out until figure out how to distinguish between use of existing and adding new @@ -806,57 +874,22 @@ sub process { #no spaces allowed after \ in define if ($line=~/\#define.*\\\s$/) { - print("Whitepspace after \\ makes next lines useless\n"); - print "$herecurr"; - $clean = 0; + WARN("Whitepspace after \\ makes next lines useless\n" . $herecurr); } #warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line) if ($tree && $rawline =~ m{^.\#\s*include\s*\<asm\/(.*)\.h\>}) { my $checkfile = "include/linux/$1.h"; if (-f $checkfile) { - print "Use #include <linux/$1.h> instead of <asm/$1.h>\n"; - print $herecurr; - $clean = 0; - } - } - -# if/while/etc brace do not go on next line, unless defining a do while loop, -# or if that brace on the next line is for something else - if ($prevline=~/\b(?:(if|while|for|switch)\s*\(|do\b|else\b)/) { - my @opened = $prevline=~/\(/g; - my @closed = $prevline=~/\)/g; - my $nr_line = $linenr; - my $remaining = $realcnt - 1; - my $next_line = $line; - my $extra_lines = 0; - my $display_segment = $prevline; - - while ($remaining > 0 && scalar @opened > scalar @closed) { - $prevline .= $next_line; - $display_segment .= "\n" . $next_line; - $next_line = $lines[$nr_line]; - $nr_line++; - $remaining--; - - @opened = $prevline=~/\(/g; - @closed = $prevline=~/\)/g; - } - - if (($prevline=~/\b(?:(if|while|for|switch)\s*\(.*\)|do|else)\s*$/) and ($next_line=~/{/) and - !($next_line=~/\b(?:if|while|for|switch|do|else)\b/) and !($next_line=~/\#define.*do.*while/)) { - print "That { should be on the previous line\n"; - print "$here\n$display_segment\n$next_line\n\n"; - $clean = 0; + CHK("Use #include <linux/$1.h> instead of <asm/$1.h>\n" . + $herecurr); } } # if and else should not have general statements after it if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/ && - $1 !~ /^\s*(?:\sif|{|$)/) { - print "trailing statements should be on next line\n"; - print "$herecurr"; - $clean = 0; + $1 !~ /^\s*(?:\sif|{|\\|$)/) { + ERROR("trailing statements should be on next line\n" . $herecurr); } # multi-statement macros should be enclosed in a do while loop, grab the @@ -871,55 +904,106 @@ sub process { # or the one below. my $ln = $linenr; my $cnt = $realcnt; + my $off = 0; - # If the macro starts on the define line start there. - if ($prevline !~ m{^.#\s*define\s*$Ident(?:\([^\)]*\))?\s*\\\s*$}) { + # If the macro starts on the define line start + # grabbing the statement after the identifier + $prevline =~ m{^(.#\s*define\s*$Ident(?:\([^\)]*\))?\s*)(.*)\\\s*$}; + ##print "1<$1> 2<$2>\n"; + if ($2 ne '') { + $off = length($1); $ln--; $cnt++; } - my $ctx = join('', ctx_statement($ln, $cnt)); + my @ctx = ctx_statement($ln, $cnt, $off); + my $ctx_ln = $ln + $#ctx + 1; + my $ctx = join("\n", @ctx); + + # Pull in any empty extension lines. + while ($ctx =~ /\\$/ && + $lines[$ctx_ln - 1] =~ /^.\s*(?:\\)?$/) { + $ctx .= $lines[$ctx_ln - 1]; + $ctx_ln++; + } if ($ctx =~ /\\$/) { if ($ctx =~ /;/) { - print "Macros with multiple statements should be enclosed in a do - while loop\n"; + ERROR("Macros with multiple statements should be enclosed in a do - while loop\n" . "$here\n$ctx\n"); } else { - print "Macros with complex values should be enclosed in parenthesis\n"; + ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n"); + } + } + } + +# check for redundant bracing round if etc + if ($line =~ /\b(if|while|for|else)\b/) { + # Locate the end of the opening statement. + my @control = ctx_statement($linenr, $realcnt, 0); + my $nr = $linenr + (scalar(@control) - 1); + my $cnt = $realcnt - (scalar(@control) - 1); + + my $off = $realcnt - $cnt; + #print "$off: line<$line>end<" . $lines[$nr - 1] . ">\n"; + + # If this is is a braced statement group check it + if ($lines[$nr - 1] =~ /{\s*$/) { + my ($lvl, @block) = ctx_block_level($nr, $cnt); + + my $stmt = join(' ', @block); + $stmt =~ s/^[^{]*{//; + $stmt =~ s/}[^}]*$//; + + #print "block<" . join(' ', @block) . "><" . scalar(@block) . ">\n"; + #print "stmt<$stmt>\n\n"; + + # Count the ;'s if there is fewer than two + # then there can only be one statement, + # if there is a brace inside we cannot + # trivially detect if its one statement. + # Also nested if's often require braces to + # disambiguate the else binding so shhh there. + my @semi = ($stmt =~ /;/g); + ##print "semi<" . scalar(@semi) . ">\n"; + if ($lvl == 0 && scalar(@semi) < 2 && + $stmt !~ /{/ && $stmt !~ /\bif\b/) { + my $herectx = "$here\n" . join("\n", @control, @block[1 .. $#block]) . "\n"; + shift(@block); + ERROR("braces {} are not necessary for single statement blocks\n" . $herectx); } - print "$hereprev"; - $clean = 0; } } # don't include deprecated include files (uses RAW line) for my $inc (@dep_includes) { if ($rawline =~ m@\#\s*include\s*\<$inc>@) { - print "Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n"; - print "$herecurr"; - $clean = 0; + ERROR("Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n" . $herecurr); } } # don't use deprecated functions for my $func (@dep_functions) { if ($line =~ /\b$func\b/) { - print "Don't use $func(): see Documentation/feature-removal-schedule.txt\n"; - print "$herecurr"; - $clean = 0; + ERROR("Don't use $func(): see Documentation/feature-removal-schedule.txt\n" . $herecurr); } } # no volatiles please if ($line =~ /\bvolatile\b/ && $line !~ /\basm\s+volatile\b/) { - print "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n"; - print "$herecurr"; - $clean = 0; + WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); } # warn about #if 0 if ($line =~ /^.#\s*if\s+0\b/) { - print "#if 0 -- if this code redundant remove it\n"; - print "$herecurr"; - $clean = 0; + CHK("if this code is redundant consider removing it\n" . + $herecurr); + } + +# check for needless kfree() checks + if ($prevline =~ /\bif\s*\(([^\)]*)\)/) { + my $expr = $1; + if ($line =~ /\bkfree\(\Q$expr\E\);/) { + WARN("kfree(NULL) is safe this check is probabally not required\n" . $hereprev); + } } # warn about #ifdefs in C files @@ -933,43 +1017,52 @@ sub process { if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/) { my $which = $1; if (!ctx_has_comment($first_line, $linenr)) { - print "$1 definition without comment\n"; - print "$herecurr"; - $clean = 0; + CHK("$1 definition without comment\n" . $herecurr); } } # check for memory barriers without a comment. if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) { if (!ctx_has_comment($first_line, $linenr)) { - print "memory barrier without comment\n"; - print "$herecurr"; - $clean = 0; + CHK("memory barrier without comment\n" . $herecurr); } } # check of hardware specific defines if ($line =~ m@^.#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@) { - print "architecture specific defines should be avoided\n"; - print "$herecurr"; - $clean = 0; + CHK("architecture specific defines should be avoided\n" . $herecurr); } +# check the location of the inline attribute, that it is between +# storage class and type. if ($line =~ /$Type\s+(?:inline|__always_inline)\b/ || $line =~ /\b(?:inline|always_inline)\s+$Storage/) { - print "inline keyword should sit between storage class and type\n"; - print "$herecurr"; - $clean = 0; + ERROR("inline keyword should sit between storage class and type\n" . $herecurr); + } + +# check for new externs in .c files. + if ($line =~ /^.\s*extern\s/ && ($realfile =~ /\.c$/)) { + WARN("externs should be avoided in .c files\n" . $herecurr); + } + +# checks for new __setup's + if ($rawline =~ /\b__setup\("([^"]*)"/) { + my $name = $1; + + if (!grep(/$name/, @setup_docs)) { + CHK("__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr); + } } } if ($chk_patch && !$is_patch) { - $clean = 0; - print "Does not appear to be a unified-diff format patch\n"; + ERROR("Does not appear to be a unified-diff format patch\n"); } if ($is_patch && $chk_signoff && $signoff == 0) { - $clean = 0; - print "Missing Signed-off-by: line(s)\n"; + ERROR("Missing Signed-off-by: line(s)\n"); } + if ($clean == 0 && ($chk_patch || $is_patch)) { + print report_dump(); + } if ($clean == 1 && $quiet == 0) { print "Your patch has no obvious style problems and is ready for submission.\n" } diff --git a/scripts/cleanfile b/scripts/cleanfile index f1ba8aa58a4..cefd29e5229 100755 --- a/scripts/cleanfile +++ b/scripts/cleanfile @@ -7,7 +7,9 @@ use bytes; use File::Basename; -# +# Default options +$max_width = 79; + # Clean up space-tab sequences, either by removing spaces or # replacing them with tabs. sub clean_space_tabs($) @@ -48,9 +50,49 @@ sub clean_space_tabs($) return $lo; } +# Compute the visual width of a string +sub strwidth($) { + no bytes; # Tab alignment depends on characters + + my($li) = @_; + my($c, $i); + my $pos = 0; + my $mlen = 0; + + for ($i = 0; $i < length($li); $i++) { + $c = substr($li,$i,1); + if ($c eq "\t") { + $pos = ($pos+8) & ~7; + } elsif ($c eq "\n") { + $mlen = $pos if ($pos > $mlen); + $pos = 0; + } else { + $pos++; + } + } + + $mlen = $pos if ($pos > $mlen); + return $mlen; +} + $name = basename($0); -foreach $f ( @ARGV ) { +@files = (); + +while (defined($a = shift(@ARGV))) { + if ($a =~ /^-/) { + if ($a eq '-width' || $a eq '-w') { + $max_width = shift(@ARGV)+0; + } else { + print STDERR "Usage: $name [-width #] files...\n"; + exit 1; + } + } else { + push(@files, $a); + } +} + +foreach $f ( @files ) { print STDERR "$name: $f\n"; if (! -f $f) { @@ -90,8 +132,10 @@ foreach $f ( @ARGV ) { @blanks = (); @lines = (); + $lineno = 0; while ( defined($line = <FILE>) ) { + $lineno++; $in_bytes += length($line); $line =~ s/[ \t\r]*$//; # Remove trailing spaces $line = clean_space_tabs($line); @@ -107,6 +151,12 @@ foreach $f ( @ARGV ) { @blanks = (); $blank_bytes = 0; } + + $l_width = strwidth($line); + if ($max_width && $l_width > $max_width) { + print STDERR + "$f:$lineno: line exceeds $max_width characters ($l_width)\n"; + } } # Any blanks at the end of the file are discarded diff --git a/scripts/cleanpatch b/scripts/cleanpatch index a53f987708f..9680d03ad2b 100755 --- a/scripts/cleanpatch +++ b/scripts/cleanpatch @@ -7,7 +7,9 @@ use bytes; use File::Basename; -# +# Default options +$max_width = 79; + # Clean up space-tab sequences, either by removing spaces or # replacing them with tabs. sub clean_space_tabs($) @@ -48,9 +50,49 @@ sub clean_space_tabs($) return $lo; } +# Compute the visual width of a string +sub strwidth($) { + no bytes; # Tab alignment depends on characters + + my($li) = @_; + my($c, $i); + my $pos = 0; + my $mlen = 0; + + for ($i = 0; $i < length($li); $i++) { + $c = substr($li,$i,1); + if ($c eq "\t") { + $pos = ($pos+8) & ~7; + } elsif ($c eq "\n") { + $mlen = $pos if ($pos > $mlen); + $pos = 0; + } else { + $pos++; + } + } + + $mlen = $pos if ($pos > $mlen); + return $mlen; +} + $name = basename($0); -foreach $f ( @ARGV ) { +@files = (); + +while (defined($a = shift(@ARGV))) { + if ($a =~ /^-/) { + if ($a eq '-width' || $a eq '-w') { + $max_width = shift(@ARGV)+0; + } else { + print STDERR "Usage: $name [-width #] files...\n"; + exit 1; + } + } else { + push(@files, $a); + } +} + +foreach $f ( @files ) { print STDERR "$name: $f\n"; if (! -f $f) { @@ -86,6 +128,7 @@ foreach $f ( @ARGV ) { $in_bytes = 0; $out_bytes = 0; + $lineno = 0; @lines = (); @@ -93,10 +136,12 @@ foreach $f ( @ARGV ) { $err = 0; while ( defined($line = <FILE>) ) { + $lineno++; $in_bytes += length($line); if (!$in_hunk) { - if ($line =~ /^\@\@\s+\-([0-9]+),([0-9]+)\s+\+([0-9]+),([0-9]+)\s\@\@/) { + if ($line =~ + /^\@\@\s+\-([0-9]+),([0-9]+)\s+\+([0-9]+),([0-9]+)\s\@\@/) { $minus_lines = $2; $plus_lines = $4; if ($minus_lines || $plus_lines) { @@ -117,6 +162,13 @@ foreach $f ( @ARGV ) { $text =~ s/[ \t\r]*$//; # Remove trailing spaces $text = clean_space_tabs($text); + $l_width = strwidth($text); + if ($max_width && $l_width > $max_width) { + print STDERR + "$f:$lineno: adds line exceeds $max_width ", + "characters ($l_width)\n"; + } + push(@hunk_lines, '+'.$text); } elsif ($line =~ /^\-/) { $minus_lines--; diff --git a/scripts/decodecode b/scripts/decodecode new file mode 100644 index 00000000000..1e1a8f620c4 --- /dev/null +++ b/scripts/decodecode @@ -0,0 +1,51 @@ +#!/bin/sh +# Disassemble the Code: line in Linux oopses +# usage: decodecode < oops.file +# +# options: set env. variable AFLAGS=options to pass options to "as"; +# e.g., to decode an i386 oops on an x86_64 system, use: +# AFLAGS=--32 decodecode < 386.oops + +T=`mktemp` +code= + +while read i ; do + +case "$i" in +*Code:*) + code=$i + ;; +esac + +done + +if [ -z "$code" ]; then + exit +fi + +echo $code +code=`echo $code | sed -e 's/.*Code: //'` + +marker=`expr index "$code" "\<"` +if [ $marker -eq 0 ]; then + marker=`expr index "$code" "\("` +fi + +if [ $marker -ne 0 ]; then + beforemark=`echo "$code" | cut -c-$((${marker} - 1))` + echo -n " .byte 0x" > $T.s + echo $beforemark | sed -e 's/ /,0x/g' >> $T.s + as $AFLAGS -o $T.o $T.s + objdump -S $T.o + rm $T.o $T.s + +# and fix code at-and-after marker + code=`echo "$code" | cut -c$((${marker} + 1))-` +fi + +code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g'` +echo -n " .byte 0x" > $T.s +echo $code >> $T.s +as $AFLAGS -o $T.o $T.s +objdump -S $T.o +rm $T.o $T.s diff --git a/scripts/gcc-version.sh b/scripts/gcc-version.sh index bb4fbeab832..8a1d1879c7a 100644 --- a/scripts/gcc-version.sh +++ b/scripts/gcc-version.sh @@ -1,14 +1,23 @@ #!/bin/sh # -# gcc-version gcc-command +# gcc-version [-p] gcc-command # # Prints the gcc version of `gcc-command' in a canonical 4-digit form # such as `0295' for gcc-2.95, `0303' for gcc-3.3, etc. # +# With the -p option, prints the patchlevel as well, for example `029503' for +# gcc-2.95.3, `030301' for gcc-3.3.1, etc. +# + +if [ $1 = "-p" ] ; then with_patchlevel=1; shift; fi compiler="$*" MAJOR=$(echo __GNUC__ | $compiler -E -xc - | tail -n 1) MINOR=$(echo __GNUC_MINOR__ | $compiler -E -xc - | tail -n 1) -printf "%02d%02d\\n" $MAJOR $MINOR - +if [ "x$with_patchlevel" != "x" ] ; then + PATCHLEVEL=$(echo __GNUC_PATCHLEVEL__ | $compiler -E -xc - | tail -n 1) + printf "%02d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL +else + printf "%02d%02d\\n" $MAJOR $MINOR +fi diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh index 683eb12babb..684fb9cdc05 100644 --- a/scripts/gen_initramfs_list.sh +++ b/scripts/gen_initramfs_list.sh @@ -19,11 +19,11 @@ $0 [-o <file>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ... -o <file> Create gzipped initramfs file named <file> using gen_init_cpio and gzip -u <uid> User ID to map to user ID 0 (root). - <uid> is only meaningful if <cpio_source> - is a directory. + <uid> is only meaningful if <cpio_source> is a + directory. "squash" forces all files to uid 0. -g <gid> Group ID to map to group ID 0 (root). - <gid> is only meaningful if <cpio_source> - is a directory. + <gid> is only meaningful if <cpio_source> is a + directory. "squash" forces all files to gid 0. <cpio_source> File list or directory for cpio archive. If <cpio_source> is a .cpio file it will be used as direct input to initramfs. @@ -113,8 +113,8 @@ parse() { local gid="$4" local ftype=$(filetype "${location}") # remap uid/gid to 0 if necessary - [ "$uid" -eq "$root_uid" ] && uid=0 - [ "$gid" -eq "$root_gid" ] && gid=0 + [ "$root_uid" = "squash" ] && uid=0 || [ "$uid" -eq "$root_uid" ] && uid=0 + [ "$root_gid" = "squash" ] && gid=0 || [ "$gid" -eq "$root_gid" ] && gid=0 local str="${mode} ${uid} ${gid}" [ "${ftype}" == "invalid" ] && return 0 diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 8b809b264d1..1f11d848532 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -24,14 +24,12 @@ * */ -#define _GNU_SOURCE - #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> -#define KSYM_NAME_LEN 127 +#define KSYM_NAME_LEN 128 struct sym_entry { @@ -254,7 +252,7 @@ static void write_src(void) unsigned int i, k, off; unsigned int best_idx[256]; unsigned int *markers; - char buf[KSYM_NAME_LEN+1]; + char buf[KSYM_NAME_LEN]; printf("#include <asm/types.h>\n"); printf("#if BITS_PER_LONG == 64\n"); @@ -378,6 +376,17 @@ static void build_initial_tok_table(void) table_cnt = pos; } +static void *find_token(unsigned char *str, int len, unsigned char *token) +{ + int i; + + for (i = 0; i < len - 1; i++) { + if (str[i] == token[0] && str[i+1] == token[1]) + return &str[i]; + } + return NULL; +} + /* replace a given token in all the valid symbols. Use the sampled symbols * to update the counts */ static void compress_symbols(unsigned char *str, int idx) @@ -391,7 +400,7 @@ static void compress_symbols(unsigned char *str, int idx) p1 = table[i].sym; /* find the token on the symbol */ - p2 = memmem(p1, len, str, 2); + p2 = find_token(p1, len, str); if (!p2) continue; /* decrease the counts for this symbol's tokens */ @@ -410,7 +419,7 @@ static void compress_symbols(unsigned char *str, int idx) if (size < 2) break; /* find the token on the symbol */ - p2 = memmem(p1, size, str, 2); + p2 = find_token(p1, size, str); } while (p2); diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index fb2bb3099dd..8986a48c8c4 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -22,24 +22,25 @@ oldconfig: $(obj)/conf silentoldconfig: $(obj)/conf $< -s arch/$(ARCH)/Kconfig +# Create new linux.po file +# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files +# The symlink is used to repair a deficiency in arch/um update-po-config: $(obj)/kxgettext - xgettext --default-domain=linux \ - --add-comments --keyword=_ --keyword=N_ \ - --files-from=scripts/kconfig/POTFILES.in \ - --output scripts/kconfig/config.pot - $(Q)ln -fs Kconfig_i386 arch/um/Kconfig_arch - $(Q)for i in `ls arch/`; \ - do \ - scripts/kconfig/kxgettext arch/$$i/Kconfig \ - | msguniq -o scripts/kconfig/linux_$${i}.pot; \ - done - $(Q)msgcat scripts/kconfig/config.pot \ - `find scripts/kconfig/ -type f -name linux_*.pot` \ - --output scripts/kconfig/linux_raw.pot - $(Q)msguniq --sort-by-file scripts/kconfig/linux_raw.pot \ - --output scripts/kconfig/linux.pot - $(Q)rm -f arch/um/Kconfig_arch - $(Q)rm -f scripts/kconfig/linux_*.pot scripts/kconfig/config.pot + xgettext --default-domain=linux \ + --add-comments --keyword=_ --keyword=N_ \ + --from-code=UTF-8 \ + --files-from=scripts/kconfig/POTFILES.in \ + --output $(obj)/config.pot + $(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot + $(Q)ln -fs Kconfig.i386 arch/um/Kconfig.arch + (for i in `ls arch/`; \ + do \ + $(obj)/kxgettext arch/$$i/Kconfig; \ + done ) >> $(obj)/config.pot + msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \ + --output $(obj)/linux.pot + $(Q)rm -f arch/um/Kconfig.arch + $(Q)rm -f $(obj)/config.pot PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 664fe29dace..b2913e9da49 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -341,27 +341,42 @@ int conf_read(const char *name) conf_unsaved++; /* maybe print value in verbose mode... */ sym_ok: + if (!sym_is_choice(sym)) + continue; + /* The choice symbol only has a set value (and thus is not new) + * if all its visible childs have values. + */ + prop = sym_get_choice_prop(sym); + flags = sym->flags; + for (e = prop->expr; e; e = e->left.expr) + if (e->right.sym->visible != no) + flags &= e->right.sym->flags; + sym->flags &= flags | ~SYMBOL_DEF_USER; + } + + for_all_symbols(i, sym) { if (sym_has_value(sym) && !sym_is_choice_value(sym)) { - if (sym->visible == no) + /* Reset values of generates values, so they'll appear + * as new, if they should become visible, but that + * doesn't quite work if the Kconfig and the saved + * configuration disagree. + */ + if (sym->visible == no && !conf_unsaved) sym->flags &= ~SYMBOL_DEF_USER; switch (sym->type) { case S_STRING: case S_INT: case S_HEX: - if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val)) - sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER); + /* Reset a string value if it's out of range */ + if (sym_string_within_range(sym, sym->def[S_DEF_USER].val)) + break; + sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER); + conf_unsaved++; + break; default: break; } } - if (!sym_is_choice(sym)) - continue; - prop = sym_get_choice_prop(sym); - flags = sym->flags; - for (e = prop->expr; e; e = e->left.expr) - if (e->right.sym->visible != no) - flags &= e->right.sym->flags; - sym->flags &= flags | ~SYMBOL_DEF_USER; } sym_add_change_count(conf_warnings || conf_unsaved); diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c index abee55ca617..11f7dab9471 100644 --- a/scripts/kconfig/kxgettext.c +++ b/scripts/kconfig/kxgettext.c @@ -212,7 +212,9 @@ void menu__xgettext(void) struct message *m = message__list; while (m != NULL) { - message__print_gettext_msgid_msgstr(m); + /* skip empty lines ("") */ + if (strlen(m->msg) > sizeof("\"\"")) + message__print_gettext_msgid_msgstr(m); m = m->next; } } diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index cdca7388e0f..9681476b96e 100644 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -51,7 +51,7 @@ usage() { printf "Usage: $0 [-check compiler options|-header|-library]\n" } -if [ $# == 0 ]; then +if [ $# -eq 0 ]; then usage exit 1 fi diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index d0e4fa594fc..d2c2a429887 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -419,11 +419,13 @@ static void search_conf(void) { struct symbol **sym_arr; struct gstr res; + char *dialog_input; int dres; again: dialog_clear(); dres = dialog_inputbox(_("Search Configuration Parameter"), - _("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"), + _("Enter CONFIG_ (sub)string to search for " + "(with or without \"CONFIG\")"), 10, 75, ""); switch (dres) { case 0: @@ -435,7 +437,12 @@ again: return; } - sym_arr = sym_re_search(dialog_input_result); + /* strip CONFIG_ if necessary */ + dialog_input = dialog_input_result; + if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0) + dialog_input += 7; + + sym_arr = sym_re_search(dialog_input); res = get_relations_str(sym_arr); free(sym_arr); show_textbox(_("Search Results"), str_get(&res), 0, 0); diff --git a/scripts/kernel-doc b/scripts/kernel-doc index e5bf649e516..1f5835115ca 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -154,6 +154,7 @@ use strict; my $errors = 0; my $warnings = 0; +my $anon_struct_union = 0; # match expressions used to find embedded type information my $type_constant = '\%([-_\w]+)'; @@ -403,7 +404,11 @@ sub output_highlight { print $lineprefix, $blankline; } else { $line =~ s/\\\\\\/\&/g; - print $lineprefix, $line; + if ($output_mode eq "man" && substr($line, 0, 1) eq ".") { + print "\\&$line"; + } else { + print $lineprefix, $line; + } } print "\n"; } @@ -718,6 +723,7 @@ sub output_struct_xml(%) { # pointer-to-function print " $1 $parameter) ($2);\n"; } elsif ($type =~ m/^(.*?)\s*(:.*)/) { + # bitfield print " $1 $parameter$2;\n"; } else { print " ".$type." ".$parameter.";\n"; @@ -1260,6 +1266,7 @@ sub output_struct_text(%) { # pointer-to-function print "\t$1 $parameter) ($2);\n"; } elsif ($type =~ m/^(.*?)\s*(:.*)/) { + # bitfield print "\t$1 $parameter$2;\n"; } else { print "\t".$type." ".$parameter.";\n"; @@ -1510,8 +1517,13 @@ sub push_parameter($$$) { my $param = shift; my $type = shift; my $file = shift; - my $anon = 0; + if (($anon_struct_union == 1) && ($type eq "") && + ($param eq "}")) { + return; # ignore the ending }; from anon. struct/union + } + + $anon_struct_union = 0; my $param_name = $param; $param_name =~ s/\[.*//; @@ -1530,16 +1542,16 @@ sub push_parameter($$$) { # handle unnamed (anonymous) union or struct: { $type = $param; - $param = "{unnamed_" . $param. "}"; + $param = "{unnamed_" . $param . "}"; $parameterdescs{$param} = "anonymous\n"; - $anon = 1; + $anon_struct_union = 1; } # warn if parameter has no description # (but ignore ones starting with # as these are not parameters # but inline preprocessor statements); # also ignore unnamed structs/unions; - if (!$anon) { + if (!$anon_struct_union) { if (!defined $parameterdescs{$param_name} && $param_name !~ /^#/) { $parameterdescs{$param_name} = $undescribed; @@ -1691,6 +1703,8 @@ sub process_state3_function($$) { my $x = shift; my $file = shift; + $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line + if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#define/)) { # do nothing } @@ -1713,6 +1727,8 @@ sub process_state3_type($$) { $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's. $x =~ s@^\s+@@gos; # strip leading spaces $x =~ s@\s+$@@gos; # strip trailing spaces + $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line + if ($x =~ /^#/) { # To distinguish preprocessor directive from regular declaration later. $x .= ";"; @@ -1796,7 +1812,7 @@ sub process_file($) { $state = 2; if (/-(.*)/) { - # strip leading/trailing/multiple spaces #RDD:T: + # strip leading/trailing/multiple spaces $descr= $1; $descr =~ s/^\s*//; $descr =~ s/\s*$//; diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 3645e980da7..5ab7914d30e 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -75,7 +75,8 @@ static int is_vmlinux(const char *modname) else myname = modname; - return strcmp(myname, "vmlinux") == 0; + return (strcmp(myname, "vmlinux") == 0) || + (strcmp(myname, "vmlinux.o") == 0); } void *do_nofail(void *ptr, const char *expr) @@ -374,6 +375,7 @@ static int parse_elf(struct elf_info *info, const char *filename) hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); hdr->e_shnum = TO_NATIVE(hdr->e_shnum); hdr->e_machine = TO_NATIVE(hdr->e_machine); + hdr->e_type = TO_NATIVE(hdr->e_type); sechdrs = (void *)hdr + hdr->e_shoff; info->sechdrs = sechdrs; @@ -384,6 +386,8 @@ static int parse_elf(struct elf_info *info, const char *filename) sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size); sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link); sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); + sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info); + sechdrs[i].sh_addr = TO_NATIVE(sechdrs[i].sh_addr); } /* Find symbol table. */ for (i = 1; i < hdr->e_shnum; i++) { @@ -605,18 +609,14 @@ static int strrcmp(const char *s, const char *sub) * warn here. * the pattern is identified by: * tosec = .init.text | .exit.text | .init.data - * fromsec = .data - * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console + * fromsec = .data | .data.rel | .data.rel.* + * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console, *_timer * * Pattern 3: - * Whitelist all references from .pci_fixup* section to .init.text - * This is part of the PCI init when built-in - * - * Pattern 4: * Whitelist all refereces from .text.head to .init.data * Whitelist all refereces from .text.head to .init.text * - * Pattern 5: + * Pattern 4: * Some symbols belong to init section but still it is ok to reference * these from non-init sections as these symbols don't have any memory * allocated for them and symbol address and value are same. So even @@ -625,26 +625,6 @@ static int strrcmp(const char *s, const char *sub) * This pattern is identified by * refsymname = __init_begin, _sinittext, _einittext * - * Pattern 7: - * Logos used in drivers/video/logo reside in __initdata but the - * funtion that references them are EXPORT_SYMBOL() so cannot be - * marker __init. So we whitelist them here. - * The pattern is: - * tosec = .init.data - * fromsec = .text* - * refsymname = logo_ - * - * Pattern 8: - * Symbols contained in .paravirtprobe may safely reference .init.text. - * The pattern is: - * tosec = .init.text - * fromsec = .paravirtprobe - * - * Pattern 10: - * ia64 has machvec table for each platform and - * powerpc has a machine desc table for each platform. - * It is mixture of function pointers of .init.text and .text. - * fromsec = .machvec | .machine.desc **/ static int secref_whitelist(const char *modname, const char *tosec, const char *fromsec, const char *atsym, @@ -655,12 +635,12 @@ static int secref_whitelist(const char *modname, const char *tosec, const char *pat2sym[] = { "driver", "_template", /* scsi uses *_template a lot */ + "_timer", /* arm uses ops structures named _timer a lot */ "_sht", /* scsi also used *_sht to some extent */ "_ops", "_probe", "_probe_one", "_console", - "apic_es7000", NULL }; @@ -692,7 +672,9 @@ static int secref_whitelist(const char *modname, const char *tosec, (strcmp(tosec, ".exit.text") != 0) && (strcmp(tosec, ".init.data") != 0)) f2 = 0; - if (strcmp(fromsec, ".data") != 0) + if ((strcmp(fromsec, ".data") != 0) && + (strcmp(fromsec, ".data.rel") != 0) && + (strncmp(fromsec, ".data.rel.", strlen(".data.rel.")) != 0)) f2 = 0; for (s = pat2sym; *s; s++) @@ -702,37 +684,16 @@ static int secref_whitelist(const char *modname, const char *tosec, return 1; /* Check for pattern 3 */ - if ((strncmp(fromsec, ".pci_fixup", strlen(".pci_fixup")) == 0) && - (strcmp(tosec, ".init.text") == 0)) - return 1; - - /* Check for pattern 4 */ if ((strcmp(fromsec, ".text.head") == 0) && ((strcmp(tosec, ".init.data") == 0) || (strcmp(tosec, ".init.text") == 0))) return 1; - /* Check for pattern 5 */ + /* Check for pattern 4 */ for (s = pat3refsym; *s; s++) if (strcmp(refsymname, *s) == 0) return 1; - /* Check for pattern 7 */ - if ((strcmp(tosec, ".init.data") == 0) && - (strncmp(fromsec, ".text", strlen(".text")) == 0) && - (strncmp(refsymname, "logo_", strlen("logo_")) == 0)) - return 1; - - /* Check for pattern 8 */ - if ((strcmp(tosec, ".init.text") == 0) && - (strcmp(fromsec, ".paravirtprobe") == 0)) - return 1; - - /* Check for pattern 10 */ - if ((strcmp(fromsec, ".machvec") == 0) || - (strcmp(fromsec, ".machine.desc") == 0)) - return 1; - return 0; } @@ -753,6 +714,8 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr, for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { if (sym->st_shndx != relsym->st_shndx) continue; + if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) + continue; if (sym->st_value == addr) return sym; } @@ -864,11 +827,6 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, elf->strtab + before->st_name, refsymname)) return; - /* fromsec whitelist - without a valid 'before' - * powerpc has a GOT table in .got2 section */ - if (strcmp(fromsec, ".got2") == 0) - return; - if (before && after) { warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " "(between '%s' and '%s')\n", @@ -895,6 +853,78 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, } } +static unsigned int *reloc_location(struct elf_info *elf, + int rsection, Elf_Rela *r) +{ + Elf_Shdr *sechdrs = elf->sechdrs; + int section = sechdrs[rsection].sh_info; + + return (void *)elf->hdr + sechdrs[section].sh_offset + + (r->r_offset - sechdrs[section].sh_addr); +} + +static int addend_386_rel(struct elf_info *elf, int rsection, Elf_Rela *r) +{ + unsigned int r_typ = ELF_R_TYPE(r->r_info); + unsigned int *location = reloc_location(elf, rsection, r); + + switch (r_typ) { + case R_386_32: + r->r_addend = TO_NATIVE(*location); + break; + case R_386_PC32: + r->r_addend = TO_NATIVE(*location) + 4; + /* For CONFIG_RELOCATABLE=y */ + if (elf->hdr->e_type == ET_EXEC) + r->r_addend += r->r_offset; + break; + } + return 0; +} + +static int addend_arm_rel(struct elf_info *elf, int rsection, Elf_Rela *r) +{ + unsigned int r_typ = ELF_R_TYPE(r->r_info); + + switch (r_typ) { + case R_ARM_ABS32: + /* From ARM ABI: (S + A) | T */ + r->r_addend = (int)(long)(elf->symtab_start + ELF_R_SYM(r->r_info)); + break; + case R_ARM_PC24: + /* From ARM ABI: ((S + A) | T) - P */ + r->r_addend = (int)(long)(elf->hdr + elf->sechdrs[rsection].sh_offset + + (r->r_offset - elf->sechdrs[rsection].sh_addr)); + break; + default: + return 1; + } + return 0; +} + +static int addend_mips_rel(struct elf_info *elf, int rsection, Elf_Rela *r) +{ + unsigned int r_typ = ELF_R_TYPE(r->r_info); + unsigned int *location = reloc_location(elf, rsection, r); + unsigned int inst; + + if (r_typ == R_MIPS_HI16) + return 1; /* skip this */ + inst = TO_NATIVE(*location); + switch (r_typ) { + case R_MIPS_LO16: + r->r_addend = inst & 0xffff; + break; + case R_MIPS_26: + r->r_addend = (inst & 0x03ffffff) << 2; + break; + case R_MIPS_32: + r->r_addend = inst; + break; + } + return 0; +} + /** * A module includes a number of sections that are discarded * either when loaded or when used as built-in. @@ -938,8 +968,11 @@ static void check_sec_ref(struct module *mod, const char *modname, r.r_offset = TO_NATIVE(rela->r_offset); #if KERNEL_ELFCLASS == ELFCLASS64 if (hdr->e_machine == EM_MIPS) { + unsigned int r_typ; r_sym = ELF64_MIPS_R_SYM(rela->r_info); r_sym = TO_NATIVE(r_sym); + r_typ = ELF64_MIPS_R_TYPE(rela->r_info); + r.r_info = ELF64_R_INFO(r_sym, r_typ); } else { r.r_info = TO_NATIVE(rela->r_info); r_sym = ELF_R_SYM(r.r_info); @@ -972,8 +1005,11 @@ static void check_sec_ref(struct module *mod, const char *modname, r.r_offset = TO_NATIVE(rel->r_offset); #if KERNEL_ELFCLASS == ELFCLASS64 if (hdr->e_machine == EM_MIPS) { + unsigned int r_typ; r_sym = ELF64_MIPS_R_SYM(rel->r_info); r_sym = TO_NATIVE(r_sym); + r_typ = ELF64_MIPS_R_TYPE(rel->r_info); + r.r_info = ELF64_R_INFO(r_sym, r_typ); } else { r.r_info = TO_NATIVE(rel->r_info); r_sym = ELF_R_SYM(r.r_info); @@ -983,6 +1019,20 @@ static void check_sec_ref(struct module *mod, const char *modname, r_sym = ELF_R_SYM(r.r_info); #endif r.r_addend = 0; + switch (hdr->e_machine) { + case EM_386: + if (addend_386_rel(elf, i, &r)) + continue; + break; + case EM_ARM: + if(addend_arm_rel(elf, i, &r)) + continue; + break; + case EM_MIPS: + if (addend_mips_rel(elf, i, &r)) + continue; + break; + } sym = elf->symtab_start + r_sym; /* Skip special sections */ if (sym->st_shndx >= SHN_LORESERVE) @@ -998,6 +1048,64 @@ static void check_sec_ref(struct module *mod, const char *modname, } } +/* + * Identify sections from which references to either a + * .init or a .exit section is OK. + * + * [OPD] Keith Ownes <kaos@sgi.com> commented: + * For our future {in}sanity, add a comment that this is the ppc .opd + * section, not the ia64 .opd section. + * ia64 .opd should not point to discarded sections. + * [.rodata] like for .init.text we ignore .rodata references -same reason + */ +static int initexit_section_ref_ok(const char *name) +{ + const char **s; + /* Absolute section names */ + const char *namelist1[] = { + "__bug_table", /* used by powerpc for BUG() */ + "__ex_table", + ".altinstructions", + ".cranges", /* used by sh64 */ + ".fixup", + ".machvec", /* ia64 + powerpc uses these */ + ".machine.desc", + ".opd", /* See comment [OPD] */ + ".parainstructions", + ".pdr", + ".plt", /* seen on ARCH=um build on x86_64. Harmless */ + ".smp_locks", + ".stab", + ".m68k_fixup", + NULL + }; + /* Start of section names */ + const char *namelist2[] = { + ".debug", + ".eh_frame", + ".note", /* ignore ELF notes - may contain anything */ + ".got", /* powerpc - global offset table */ + ".toc", /* powerpc - table of contents */ + NULL + }; + /* part of section name */ + const char *namelist3 [] = { + ".unwind", /* Sample: IA_64.unwind.exit.text */ + NULL + }; + + for (s = namelist1; *s; s++) + if (strcmp(*s, name) == 0) + return 1; + for (s = namelist2; *s; s++) + if (strncmp(*s, name, strlen(*s)) == 0) + return 1; + for (s = namelist3; *s; s++) + if (strstr(name, *s) != NULL) + return 1; + return 0; +} + /** * Functions used only during module init is marked __init and is stored in * a .init.text section. Likewise data is marked __initdata and stored in @@ -1014,7 +1122,7 @@ static int init_section(const char *name) return 0; } -/** +/* * Identify sections from which references to a .init section is OK. * * Unfortunately references to read only data that referenced .init @@ -1028,48 +1136,31 @@ static int init_section(const char *name) * * where vgacon_startup is __init. If you want to wade through the false * positives, take out the check for rodata. - **/ + */ static int init_section_ref_ok(const char *name) { const char **s; /* Absolute section names */ const char *namelist1[] = { - ".init", - ".opd", /* see comment [OPD] at exit_section_ref_ok() */ - ".toc1", /* used by ppc64 */ - ".stab", - ".data.rel.ro", /* used by parisc64 */ - ".parainstructions", - ".text.lock", - "__bug_table", /* used by powerpc for BUG() */ - ".pci_fixup_header", - ".pci_fixup_final", - ".pdr", - "__param", - "__ex_table", - ".fixup", - ".smp_locks", - ".plt", /* seen on ARCH=um build on x86_64. Harmless */ + "__dbe_table", /* MIPS generate these */ "__ftr_fixup", /* powerpc cpu feature fixup */ "__fw_ftr_fixup", /* powerpc firmware feature fixup */ - ".cranges", /* used by sh64 */ + "__param", + ".data.rel.ro", /* used by parisc64 */ + ".init", + ".text.lock", NULL }; /* Start of section names */ const char *namelist2[] = { ".init.", - ".altinstructions", - ".eh_frame", - ".debug", - ".parainstructions", + ".pci_fixup", ".rodata", NULL }; - /* part of section name */ - const char *namelist3 [] = { - ".unwind", /* sample: IA_64.unwind.init.text */ - NULL - }; + + if (initexit_section_ref_ok(name)) + return 1; for (s = namelist1; *s; s++) if (strcmp(*s, name) == 0) @@ -1077,9 +1168,10 @@ static int init_section_ref_ok(const char *name) for (s = namelist2; *s; s++) if (strncmp(*s, name, strlen(*s)) == 0) return 1; - for (s = namelist3; *s; s++) - if (strstr(name, *s) != NULL) - return 1; + + /* If section name ends with ".init" we allow references + * as is the case with .initcallN.init, .early_param.init, .taglist.init etc + */ if (strrcmp(name, ".init") == 0) return 1; return 0; @@ -1104,58 +1196,25 @@ static int exit_section(const char *name) /* * Identify sections from which references to a .exit section is OK. - * - * [OPD] Keith Ownes <kaos@sgi.com> commented: - * For our future {in}sanity, add a comment that this is the ppc .opd - * section, not the ia64 .opd section. - * ia64 .opd should not point to discarded sections. - * [.rodata] like for .init.text we ignore .rodata references -same reason - **/ + */ static int exit_section_ref_ok(const char *name) { const char **s; /* Absolute section names */ const char *namelist1[] = { - ".exit.text", ".exit.data", - ".init.text", - ".rodata", - ".opd", /* See comment [OPD] */ - ".toc1", /* used by ppc64 */ - ".altinstructions", - ".pdr", - "__bug_table", /* used by powerpc for BUG() */ + ".exit.text", ".exitcall.exit", - ".eh_frame", - ".parainstructions", - ".stab", - "__ex_table", - ".fixup", - ".smp_locks", - ".plt", /* seen on ARCH=um build on x86_64. Harmless */ - ".cranges", /* used by sh64 */ - NULL - }; - /* Start of section names */ - const char *namelist2[] = { - ".debug", - NULL - }; - /* part of section name */ - const char *namelist3 [] = { - ".unwind", /* Sample: IA_64.unwind.exit.text */ + ".rodata", NULL }; + if (initexit_section_ref_ok(name)) + return 1; + for (s = namelist1; *s; s++) if (strcmp(*s, name) == 0) return 1; - for (s = namelist2; *s; s++) - if (strncmp(*s, name, strlen(*s)) == 0) - return 1; - for (s = namelist3; *s; s++) - if (strstr(name, *s) != NULL) - return 1; return 0; } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 0858caa9c03..4156dd34c5d 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -60,6 +60,9 @@ typedef union #define ELF64_MIPS_R_SYM(i) \ ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym) +#define ELF64_MIPS_R_TYPE(i) \ + ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type1) + #if KERNEL_ELFDATA != HOST_ELFDATA static inline void __endian(const void *src, void *dest, unsigned int size) |