diff options
Diffstat (limited to 'scripts')
35 files changed, 1118 insertions, 339 deletions
diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst index a57f5bd5a13d..d3bae5e7b601 100644 --- a/scripts/Makefile.headersinst +++ b/scripts/Makefile.headersinst | |||
@@ -4,12 +4,16 @@ | |||
4 | # header-y - list files to be installed. They are preprocessed | 4 | # header-y - list files to be installed. They are preprocessed |
5 | # to remove __KERNEL__ section of the file | 5 | # to remove __KERNEL__ section of the file |
6 | # objhdr-y - Same as header-y but for generated files | 6 | # objhdr-y - Same as header-y but for generated files |
7 | # genhdr-y - Same as objhdr-y but in a generated/ directory | ||
7 | # | 8 | # |
8 | # ========================================================================== | 9 | # ========================================================================== |
9 | 10 | ||
10 | # called may set destination dir (when installing to asm/) | 11 | # called may set destination dir (when installing to asm/) |
11 | _dst := $(if $(dst),$(dst),$(obj)) | 12 | _dst := $(if $(dst),$(dst),$(obj)) |
12 | 13 | ||
14 | # generated header directory | ||
15 | gen := $(if $(gen),$(gen),$(subst include/,include/generated/,$(obj))) | ||
16 | |||
13 | kbuild-file := $(srctree)/$(obj)/Kbuild | 17 | kbuild-file := $(srctree)/$(obj)/Kbuild |
14 | include $(kbuild-file) | 18 | include $(kbuild-file) |
15 | 19 | ||
@@ -33,9 +37,10 @@ wrapper-files := $(filter $(header-y), $(generic-y)) | |||
33 | 37 | ||
34 | # all headers files for this dir | 38 | # all headers files for this dir |
35 | header-y := $(filter-out $(generic-y), $(header-y)) | 39 | header-y := $(filter-out $(generic-y), $(header-y)) |
36 | all-files := $(header-y) $(objhdr-y) $(wrapper-files) | 40 | all-files := $(header-y) $(objhdr-y) $(genhdr-y) $(wrapper-files) |
37 | input-files := $(addprefix $(srctree)/$(obj)/,$(header-y)) \ | 41 | input-files := $(addprefix $(srctree)/$(obj)/,$(header-y)) \ |
38 | $(addprefix $(objtree)/$(obj)/,$(objhdr-y)) | 42 | $(addprefix $(objtree)/$(obj)/,$(objhdr-y)) \ |
43 | $(addprefix $(objtree)/$(gen)/,$(genhdr-y)) | ||
39 | output-files := $(addprefix $(install)/, $(all-files)) | 44 | output-files := $(addprefix $(install)/, $(all-files)) |
40 | 45 | ||
41 | # Work out what needs to be removed | 46 | # Work out what needs to be removed |
@@ -52,6 +57,7 @@ quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\ | |||
52 | cmd_install = \ | 57 | cmd_install = \ |
53 | $(PERL) $< $(srctree)/$(obj) $(install) $(SRCARCH) $(header-y); \ | 58 | $(PERL) $< $(srctree)/$(obj) $(install) $(SRCARCH) $(header-y); \ |
54 | $(PERL) $< $(objtree)/$(obj) $(install) $(SRCARCH) $(objhdr-y); \ | 59 | $(PERL) $< $(objtree)/$(obj) $(install) $(SRCARCH) $(objhdr-y); \ |
60 | $(PERL) $< $(objtree)/$(gen) $(install) $(SRCARCH) $(genhdr-y); \ | ||
55 | for F in $(wrapper-files); do \ | 61 | for F in $(wrapper-files); do \ |
56 | echo "\#include <asm-generic/$$F>" > $(install)/$$F; \ | 62 | echo "\#include <asm-generic/$$F>" > $(install)/$$F; \ |
57 | done; \ | 63 | done; \ |
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 5d986d9adf1b..00c368c6e996 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib | |||
@@ -93,9 +93,9 @@ obj-dirs := $(addprefix $(obj)/,$(obj-dirs)) | |||
93 | # already | 93 | # already |
94 | # $(modname_flags) #defines KBUILD_MODNAME as the name of the module it will | 94 | # $(modname_flags) #defines KBUILD_MODNAME as the name of the module it will |
95 | # end up in (or would, if it gets compiled in) | 95 | # end up in (or would, if it gets compiled in) |
96 | # Note: It's possible that one object gets potentially linked into more | 96 | # Note: Files that end up in two or more modules are compiled without the |
97 | # than one module. In that case KBUILD_MODNAME will be set to foo_bar, | 97 | # KBUILD_MODNAME definition. The reason is that any made-up name would |
98 | # where foo and bar are the name of the modules. | 98 | # differ in different configs. |
99 | name-fix = $(subst $(comma),_,$(subst -,_,$1)) | 99 | name-fix = $(subst $(comma),_,$(subst -,_,$1)) |
100 | basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" | 100 | basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" |
101 | modname_flags = $(if $(filter 1,$(words $(modname))),\ | 101 | modname_flags = $(if $(filter 1,$(words $(modname))),\ |
@@ -264,7 +264,7 @@ $(obj)/%.dtb.S: $(obj)/%.dtb | |||
264 | $(call cmd,dt_S_dtb) | 264 | $(call cmd,dt_S_dtb) |
265 | 265 | ||
266 | quiet_cmd_dtc = DTC $@ | 266 | quiet_cmd_dtc = DTC $@ |
267 | cmd_dtc = $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 $(DTC_FLAGS) $< | 267 | cmd_dtc = $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 $(DTC_FLAGS) -d $(depfile) $< |
268 | 268 | ||
269 | # Bzip2 | 269 | # Bzip2 |
270 | # --------------------------------------------------------------------------- | 270 | # --------------------------------------------------------------------------- |
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 8fda3b3f7be8..e3bfcbe8a520 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl | |||
@@ -227,7 +227,7 @@ our $Inline = qr{inline|__always_inline|noinline}; | |||
227 | our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; | 227 | our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; |
228 | our $Lval = qr{$Ident(?:$Member)*}; | 228 | our $Lval = qr{$Ident(?:$Member)*}; |
229 | 229 | ||
230 | our $Constant = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*}; | 230 | our $Constant = qr{(?i:(?:[0-9]+|0x[0-9a-f]+)[ul]*)}; |
231 | our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)}; | 231 | our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)}; |
232 | our $Compare = qr{<=|>=|==|!=|<|>}; | 232 | our $Compare = qr{<=|>=|==|!=|<|>}; |
233 | our $Operators = qr{ | 233 | our $Operators = qr{ |
@@ -315,7 +315,7 @@ sub build_types { | |||
315 | $NonptrType = qr{ | 315 | $NonptrType = qr{ |
316 | (?:$Modifier\s+|const\s+)* | 316 | (?:$Modifier\s+|const\s+)* |
317 | (?: | 317 | (?: |
318 | (?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)| | 318 | (?:typeof|__typeof__)\s*\([^\)]*\)| |
319 | (?:$typeTypedefs\b)| | 319 | (?:$typeTypedefs\b)| |
320 | (?:${all}\b) | 320 | (?:${all}\b) |
321 | ) | 321 | ) |
@@ -334,6 +334,7 @@ our $match_balanced_parentheses = qr/(\((?:[^\(\)]+|(-1))*\))/; | |||
334 | 334 | ||
335 | our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; | 335 | our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; |
336 | our $LvalOrFunc = qr{($Lval)\s*($match_balanced_parentheses{0,1})\s*}; | 336 | our $LvalOrFunc = qr{($Lval)\s*($match_balanced_parentheses{0,1})\s*}; |
337 | our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant)}; | ||
337 | 338 | ||
338 | sub deparenthesize { | 339 | sub deparenthesize { |
339 | my ($string) = @_; | 340 | my ($string) = @_; |
@@ -676,6 +677,10 @@ sub ctx_statement_block { | |||
676 | if ($off >= $len) { | 677 | if ($off >= $len) { |
677 | last; | 678 | last; |
678 | } | 679 | } |
680 | if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { | ||
681 | $level++; | ||
682 | $type = '#'; | ||
683 | } | ||
679 | } | 684 | } |
680 | $p = $c; | 685 | $p = $c; |
681 | $c = substr($blk, $off, 1); | 686 | $c = substr($blk, $off, 1); |
@@ -738,6 +743,13 @@ sub ctx_statement_block { | |||
738 | last; | 743 | last; |
739 | } | 744 | } |
740 | } | 745 | } |
746 | # Preprocessor commands end at the newline unless escaped. | ||
747 | if ($type eq '#' && $c eq "\n" && $p ne "\\") { | ||
748 | $level--; | ||
749 | $type = ''; | ||
750 | $off++; | ||
751 | last; | ||
752 | } | ||
741 | $off++; | 753 | $off++; |
742 | } | 754 | } |
743 | # We are truly at the end, so shuffle to the next line. | 755 | # We are truly at the end, so shuffle to the next line. |
@@ -1020,7 +1032,7 @@ sub annotate_values { | |||
1020 | } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { | 1032 | } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { |
1021 | print "CAST($1)\n" if ($dbg_values > 1); | 1033 | print "CAST($1)\n" if ($dbg_values > 1); |
1022 | push(@av_paren_type, $type); | 1034 | push(@av_paren_type, $type); |
1023 | $type = 'C'; | 1035 | $type = 'c'; |
1024 | 1036 | ||
1025 | } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { | 1037 | } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { |
1026 | print "DECLARE($1)\n" if ($dbg_values > 1); | 1038 | print "DECLARE($1)\n" if ($dbg_values > 1); |
@@ -1212,7 +1224,9 @@ sub possible { | |||
1212 | case| | 1224 | case| |
1213 | else| | 1225 | else| |
1214 | asm|__asm__| | 1226 | asm|__asm__| |
1215 | do | 1227 | do| |
1228 | \#| | ||
1229 | \#\#| | ||
1216 | )(?:\s|$)| | 1230 | )(?:\s|$)| |
1217 | ^(?:typedef|struct|enum)\b | 1231 | ^(?:typedef|struct|enum)\b |
1218 | )}x; | 1232 | )}x; |
@@ -1359,6 +1373,7 @@ sub process { | |||
1359 | my %suppress_ifbraces; | 1373 | my %suppress_ifbraces; |
1360 | my %suppress_whiletrailers; | 1374 | my %suppress_whiletrailers; |
1361 | my %suppress_export; | 1375 | my %suppress_export; |
1376 | my $suppress_statement = 0; | ||
1362 | 1377 | ||
1363 | # Pre-scan the patch sanitizing the lines. | 1378 | # Pre-scan the patch sanitizing the lines. |
1364 | # Pre-scan the patch looking for any __setup documentation. | 1379 | # Pre-scan the patch looking for any __setup documentation. |
@@ -1468,6 +1483,7 @@ sub process { | |||
1468 | %suppress_ifbraces = (); | 1483 | %suppress_ifbraces = (); |
1469 | %suppress_whiletrailers = (); | 1484 | %suppress_whiletrailers = (); |
1470 | %suppress_export = (); | 1485 | %suppress_export = (); |
1486 | $suppress_statement = 0; | ||
1471 | next; | 1487 | next; |
1472 | 1488 | ||
1473 | # track the line number as we move through the hunk, note that | 1489 | # track the line number as we move through the hunk, note that |
@@ -1504,9 +1520,11 @@ sub process { | |||
1504 | if ($line =~ /^diff --git.*?(\S+)$/) { | 1520 | if ($line =~ /^diff --git.*?(\S+)$/) { |
1505 | $realfile = $1; | 1521 | $realfile = $1; |
1506 | $realfile =~ s@^([^/]*)/@@; | 1522 | $realfile =~ s@^([^/]*)/@@; |
1523 | $in_commit_log = 0; | ||
1507 | } elsif ($line =~ /^\+\+\+\s+(\S+)/) { | 1524 | } elsif ($line =~ /^\+\+\+\s+(\S+)/) { |
1508 | $realfile = $1; | 1525 | $realfile = $1; |
1509 | $realfile =~ s@^([^/]*)/@@; | 1526 | $realfile =~ s@^([^/]*)/@@; |
1527 | $in_commit_log = 0; | ||
1510 | 1528 | ||
1511 | $p1_prefix = $1; | 1529 | $p1_prefix = $1; |
1512 | if (!$file && $tree && $p1_prefix ne '' && | 1530 | if (!$file && $tree && $p1_prefix ne '' && |
@@ -1546,7 +1564,8 @@ sub process { | |||
1546 | } | 1564 | } |
1547 | 1565 | ||
1548 | # Check signature styles | 1566 | # Check signature styles |
1549 | if ($line =~ /^(\s*)($signature_tags)(\s*)(.*)/) { | 1567 | if (!$in_header_lines && |
1568 | $line =~ /^(\s*)($signature_tags)(\s*)(.*)/) { | ||
1550 | my $space_before = $1; | 1569 | my $space_before = $1; |
1551 | my $sign_off = $2; | 1570 | my $sign_off = $2; |
1552 | my $space_after = $3; | 1571 | my $space_after = $3; |
@@ -1623,7 +1642,7 @@ sub process { | |||
1623 | # Check if it's the start of a commit log | 1642 | # Check if it's the start of a commit log |
1624 | # (not a header line and we haven't seen the patch filename) | 1643 | # (not a header line and we haven't seen the patch filename) |
1625 | if ($in_header_lines && $realfile =~ /^$/ && | 1644 | if ($in_header_lines && $realfile =~ /^$/ && |
1626 | $rawline !~ /^(commit\b|from\b|\w+:).+$/i) { | 1645 | $rawline !~ /^(commit\b|from\b|[\w-]+:).+$/i) { |
1627 | $in_header_lines = 0; | 1646 | $in_header_lines = 0; |
1628 | $in_commit_log = 1; | 1647 | $in_commit_log = 1; |
1629 | } | 1648 | } |
@@ -1655,19 +1674,26 @@ sub process { | |||
1655 | # Only applies when adding the entry originally, after that we do not have | 1674 | # Only applies when adding the entry originally, after that we do not have |
1656 | # sufficient context to determine whether it is indeed long enough. | 1675 | # sufficient context to determine whether it is indeed long enough. |
1657 | if ($realfile =~ /Kconfig/ && | 1676 | if ($realfile =~ /Kconfig/ && |
1658 | $line =~ /\+\s*(?:---)?help(?:---)?$/) { | 1677 | $line =~ /.\s*config\s+/) { |
1659 | my $length = 0; | 1678 | my $length = 0; |
1660 | my $cnt = $realcnt; | 1679 | my $cnt = $realcnt; |
1661 | my $ln = $linenr + 1; | 1680 | my $ln = $linenr + 1; |
1662 | my $f; | 1681 | my $f; |
1682 | my $is_start = 0; | ||
1663 | my $is_end = 0; | 1683 | my $is_end = 0; |
1664 | while ($cnt > 0 && defined $lines[$ln - 1]) { | 1684 | for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { |
1665 | $f = $lines[$ln - 1]; | 1685 | $f = $lines[$ln - 1]; |
1666 | $cnt-- if ($lines[$ln - 1] !~ /^-/); | 1686 | $cnt-- if ($lines[$ln - 1] !~ /^-/); |
1667 | $is_end = $lines[$ln - 1] =~ /^\+/; | 1687 | $is_end = $lines[$ln - 1] =~ /^\+/; |
1668 | $ln++; | ||
1669 | 1688 | ||
1670 | next if ($f =~ /^-/); | 1689 | next if ($f =~ /^-/); |
1690 | |||
1691 | if ($lines[$ln - 1] =~ /.\s*(?:bool|tristate)\s*\"/) { | ||
1692 | $is_start = 1; | ||
1693 | } elsif ($lines[$ln - 1] =~ /.\s*(?:---)?help(?:---)?$/) { | ||
1694 | $length = -1; | ||
1695 | } | ||
1696 | |||
1671 | $f =~ s/^.//; | 1697 | $f =~ s/^.//; |
1672 | $f =~ s/#.*//; | 1698 | $f =~ s/#.*//; |
1673 | $f =~ s/^\s+//; | 1699 | $f =~ s/^\s+//; |
@@ -1679,8 +1705,8 @@ sub process { | |||
1679 | $length++; | 1705 | $length++; |
1680 | } | 1706 | } |
1681 | WARN("CONFIG_DESCRIPTION", | 1707 | WARN("CONFIG_DESCRIPTION", |
1682 | "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_end && $length < 4); | 1708 | "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_start && $is_end && $length < 4); |
1683 | #print "is_end<$is_end> length<$length>\n"; | 1709 | #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; |
1684 | } | 1710 | } |
1685 | 1711 | ||
1686 | if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && | 1712 | if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && |
@@ -1792,12 +1818,24 @@ sub process { | |||
1792 | # Check for potential 'bare' types | 1818 | # Check for potential 'bare' types |
1793 | my ($stat, $cond, $line_nr_next, $remain_next, $off_next, | 1819 | my ($stat, $cond, $line_nr_next, $remain_next, $off_next, |
1794 | $realline_next); | 1820 | $realline_next); |
1795 | if ($realcnt && $line =~ /.\s*\S/) { | 1821 | #print "LINE<$line>\n"; |
1822 | if ($linenr >= $suppress_statement && | ||
1823 | $realcnt && $line =~ /.\s*\S/) { | ||
1796 | ($stat, $cond, $line_nr_next, $remain_next, $off_next) = | 1824 | ($stat, $cond, $line_nr_next, $remain_next, $off_next) = |
1797 | ctx_statement_block($linenr, $realcnt, 0); | 1825 | ctx_statement_block($linenr, $realcnt, 0); |
1798 | $stat =~ s/\n./\n /g; | 1826 | $stat =~ s/\n./\n /g; |
1799 | $cond =~ s/\n./\n /g; | 1827 | $cond =~ s/\n./\n /g; |
1800 | 1828 | ||
1829 | #print "linenr<$linenr> <$stat>\n"; | ||
1830 | # If this statement has no statement boundaries within | ||
1831 | # it there is no point in retrying a statement scan | ||
1832 | # until we hit end of it. | ||
1833 | my $frag = $stat; $frag =~ s/;+\s*$//; | ||
1834 | if ($frag !~ /(?:{|;)/) { | ||
1835 | #print "skip<$line_nr_next>\n"; | ||
1836 | $suppress_statement = $line_nr_next; | ||
1837 | } | ||
1838 | |||
1801 | # Find the real next line. | 1839 | # Find the real next line. |
1802 | $realline_next = $line_nr_next; | 1840 | $realline_next = $line_nr_next; |
1803 | if (defined $realline_next && | 1841 | if (defined $realline_next && |
@@ -1923,6 +1961,9 @@ sub process { | |||
1923 | 1961 | ||
1924 | # Check relative indent for conditionals and blocks. | 1962 | # Check relative indent for conditionals and blocks. |
1925 | if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { | 1963 | if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { |
1964 | ($stat, $cond, $line_nr_next, $remain_next, $off_next) = | ||
1965 | ctx_statement_block($linenr, $realcnt, 0) | ||
1966 | if (!defined $stat); | ||
1926 | my ($s, $c) = ($stat, $cond); | 1967 | my ($s, $c) = ($stat, $cond); |
1927 | 1968 | ||
1928 | substr($s, 0, length($c), ''); | 1969 | substr($s, 0, length($c), ''); |
@@ -2090,7 +2131,7 @@ sub process { | |||
2090 | # XXX(foo); | 2131 | # XXX(foo); |
2091 | # EXPORT_SYMBOL(something_foo); | 2132 | # EXPORT_SYMBOL(something_foo); |
2092 | my $name = $1; | 2133 | my $name = $1; |
2093 | if ($stat =~ /^.([A-Z_]+)\s*\(\s*($Ident)/ && | 2134 | if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && |
2094 | $name =~ /^${Ident}_$2/) { | 2135 | $name =~ /^${Ident}_$2/) { |
2095 | #print "FOO C name<$name>\n"; | 2136 | #print "FOO C name<$name>\n"; |
2096 | $suppress_export{$realline_next} = 1; | 2137 | $suppress_export{$realline_next} = 1; |
@@ -2168,8 +2209,9 @@ sub process { | |||
2168 | 2209 | ||
2169 | # * goes on variable not on type | 2210 | # * goes on variable not on type |
2170 | # (char*[ const]) | 2211 | # (char*[ const]) |
2171 | if ($line =~ m{\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\)}) { | 2212 | while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { |
2172 | my ($from, $to) = ($1, $1); | 2213 | #print "AA<$1>\n"; |
2214 | my ($from, $to) = ($2, $2); | ||
2173 | 2215 | ||
2174 | # Should start with a space. | 2216 | # Should start with a space. |
2175 | $to =~ s/^(\S)/ $1/; | 2217 | $to =~ s/^(\S)/ $1/; |
@@ -2184,8 +2226,10 @@ sub process { | |||
2184 | ERROR("POINTER_LOCATION", | 2226 | ERROR("POINTER_LOCATION", |
2185 | "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr); | 2227 | "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr); |
2186 | } | 2228 | } |
2187 | } elsif ($line =~ m{\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident)}) { | 2229 | } |
2188 | my ($from, $to, $ident) = ($1, $1, $2); | 2230 | while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { |
2231 | #print "BB<$1>\n"; | ||
2232 | my ($from, $to, $ident) = ($2, $2, $3); | ||
2189 | 2233 | ||
2190 | # Should start with a space. | 2234 | # Should start with a space. |
2191 | $to =~ s/^(\S)/ $1/; | 2235 | $to =~ s/^(\S)/ $1/; |
@@ -2568,7 +2612,7 @@ sub process { | |||
2568 | # Flatten any parentheses | 2612 | # Flatten any parentheses |
2569 | $value =~ s/\(/ \(/g; | 2613 | $value =~ s/\(/ \(/g; |
2570 | $value =~ s/\)/\) /g; | 2614 | $value =~ s/\)/\) /g; |
2571 | while ($value =~ s/\[[^\{\}]*\]/1/ || | 2615 | while ($value =~ s/\[[^\[\]]*\]/1/ || |
2572 | $value !~ /(?:$Ident|-?$Constant)\s* | 2616 | $value !~ /(?:$Ident|-?$Constant)\s* |
2573 | $Compare\s* | 2617 | $Compare\s* |
2574 | (?:$Ident|-?$Constant)/x && | 2618 | (?:$Ident|-?$Constant)/x && |
@@ -2593,28 +2637,6 @@ sub process { | |||
2593 | } | 2637 | } |
2594 | } | 2638 | } |
2595 | 2639 | ||
2596 | # typecasts on min/max could be min_t/max_t | ||
2597 | if ($line =~ /^\+(?:.*?)\b(min|max)\s*\($Typecast{0,1}($LvalOrFunc)\s*,\s*$Typecast{0,1}($LvalOrFunc)\s*\)/) { | ||
2598 | if (defined $2 || defined $8) { | ||
2599 | my $call = $1; | ||
2600 | my $cast1 = deparenthesize($2); | ||
2601 | my $arg1 = $3; | ||
2602 | my $cast2 = deparenthesize($8); | ||
2603 | my $arg2 = $9; | ||
2604 | my $cast; | ||
2605 | |||
2606 | if ($cast1 ne "" && $cast2 ne "") { | ||
2607 | $cast = "$cast1 or $cast2"; | ||
2608 | } elsif ($cast1 ne "") { | ||
2609 | $cast = $cast1; | ||
2610 | } else { | ||
2611 | $cast = $cast2; | ||
2612 | } | ||
2613 | WARN("MINMAX", | ||
2614 | "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . $herecurr); | ||
2615 | } | ||
2616 | } | ||
2617 | |||
2618 | # Need a space before open parenthesis after if, while etc | 2640 | # Need a space before open parenthesis after if, while etc |
2619 | if ($line=~/\b(if|while|for|switch)\(/) { | 2641 | if ($line=~/\b(if|while|for|switch)\(/) { |
2620 | ERROR("SPACING", "space required before the open parenthesis '('\n" . $herecurr); | 2642 | ERROR("SPACING", "space required before the open parenthesis '('\n" . $herecurr); |
@@ -2623,6 +2645,9 @@ sub process { | |||
2623 | # Check for illegal assignment in if conditional -- and check for trailing | 2645 | # Check for illegal assignment in if conditional -- and check for trailing |
2624 | # statements after the conditional. | 2646 | # statements after the conditional. |
2625 | if ($line =~ /do\s*(?!{)/) { | 2647 | if ($line =~ /do\s*(?!{)/) { |
2648 | ($stat, $cond, $line_nr_next, $remain_next, $off_next) = | ||
2649 | ctx_statement_block($linenr, $realcnt, 0) | ||
2650 | if (!defined $stat); | ||
2626 | my ($stat_next) = ctx_statement_block($line_nr_next, | 2651 | my ($stat_next) = ctx_statement_block($line_nr_next, |
2627 | $remain_next, $off_next); | 2652 | $remain_next, $off_next); |
2628 | $stat_next =~ s/\n./\n /g; | 2653 | $stat_next =~ s/\n./\n /g; |
@@ -2778,47 +2803,13 @@ sub process { | |||
2778 | my $cnt = $realcnt; | 2803 | my $cnt = $realcnt; |
2779 | my ($off, $dstat, $dcond, $rest); | 2804 | my ($off, $dstat, $dcond, $rest); |
2780 | my $ctx = ''; | 2805 | my $ctx = ''; |
2781 | |||
2782 | my $args = defined($1); | ||
2783 | |||
2784 | # Find the end of the macro and limit our statement | ||
2785 | # search to that. | ||
2786 | while ($cnt > 0 && defined $lines[$ln - 1] && | ||
2787 | $lines[$ln - 1] =~ /^(?:-|..*\\$)/) | ||
2788 | { | ||
2789 | $ctx .= $rawlines[$ln - 1] . "\n"; | ||
2790 | $cnt-- if ($lines[$ln - 1] !~ /^-/); | ||
2791 | $ln++; | ||
2792 | } | ||
2793 | $ctx .= $rawlines[$ln - 1]; | ||
2794 | |||
2795 | ($dstat, $dcond, $ln, $cnt, $off) = | 2806 | ($dstat, $dcond, $ln, $cnt, $off) = |
2796 | ctx_statement_block($linenr, $ln - $linenr + 1, 0); | 2807 | ctx_statement_block($linenr, $realcnt, 0); |
2808 | $ctx = $dstat; | ||
2797 | #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; | 2809 | #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; |
2798 | #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; | 2810 | #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; |
2799 | 2811 | ||
2800 | # Extract the remainder of the define (if any) and | 2812 | $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//; |
2801 | # rip off surrounding spaces, and trailing \'s. | ||
2802 | $rest = ''; | ||
2803 | while ($off != 0 || ($cnt > 0 && $rest =~ /\\\s*$/)) { | ||
2804 | #print "ADDING cnt<$cnt> $off <" . substr($lines[$ln - 1], $off) . "> rest<$rest>\n"; | ||
2805 | if ($off != 0 || $lines[$ln - 1] !~ /^-/) { | ||
2806 | $rest .= substr($lines[$ln - 1], $off) . "\n"; | ||
2807 | $cnt--; | ||
2808 | } | ||
2809 | $ln++; | ||
2810 | $off = 0; | ||
2811 | } | ||
2812 | $rest =~ s/\\\n.//g; | ||
2813 | $rest =~ s/^\s*//s; | ||
2814 | $rest =~ s/\s*$//s; | ||
2815 | |||
2816 | # Clean up the original statement. | ||
2817 | if ($args) { | ||
2818 | substr($dstat, 0, length($dcond), ''); | ||
2819 | } else { | ||
2820 | $dstat =~ s/^.\s*\#\s*define\s+$Ident\s*//; | ||
2821 | } | ||
2822 | $dstat =~ s/$;//g; | 2813 | $dstat =~ s/$;//g; |
2823 | $dstat =~ s/\\\n.//g; | 2814 | $dstat =~ s/\\\n.//g; |
2824 | $dstat =~ s/^\s*//s; | 2815 | $dstat =~ s/^\s*//s; |
@@ -2827,7 +2818,7 @@ sub process { | |||
2827 | # Flatten any parentheses and braces | 2818 | # Flatten any parentheses and braces |
2828 | while ($dstat =~ s/\([^\(\)]*\)/1/ || | 2819 | while ($dstat =~ s/\([^\(\)]*\)/1/ || |
2829 | $dstat =~ s/\{[^\{\}]*\}/1/ || | 2820 | $dstat =~ s/\{[^\{\}]*\}/1/ || |
2830 | $dstat =~ s/\[[^\{\}]*\]/1/) | 2821 | $dstat =~ s/\[[^\[\]]*\]/1/) |
2831 | { | 2822 | { |
2832 | } | 2823 | } |
2833 | 2824 | ||
@@ -2844,23 +2835,32 @@ sub process { | |||
2844 | ^\"|\"$ | 2835 | ^\"|\"$ |
2845 | }x; | 2836 | }x; |
2846 | #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; | 2837 | #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; |
2847 | if ($rest ne '' && $rest ne ',') { | 2838 | if ($dstat ne '' && |
2848 | if ($rest !~ /while\s*\(/ && | 2839 | $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), |
2849 | $dstat !~ /$exceptions/) | 2840 | $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); |
2850 | { | 2841 | $dstat !~ /^(?:$Ident|-?$Constant)$/ && # 10 // foo() |
2851 | ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", | 2842 | $dstat !~ /$exceptions/ && |
2852 | "Macros with multiple statements should be enclosed in a do - while loop\n" . "$here\n$ctx\n"); | 2843 | $dstat !~ /^\.$Ident\s*=/ && # .foo = |
2844 | $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) | ||
2845 | $dstat !~ /^for\s*$Constant$/ && # for (...) | ||
2846 | $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() | ||
2847 | $dstat !~ /^do\s*{/ && # do {... | ||
2848 | $dstat !~ /^\({/) # ({... | ||
2849 | { | ||
2850 | $ctx =~ s/\n*$//; | ||
2851 | my $herectx = $here . "\n"; | ||
2852 | my $cnt = statement_rawlines($ctx); | ||
2853 | |||
2854 | for (my $n = 0; $n < $cnt; $n++) { | ||
2855 | $herectx .= raw_line($linenr, $n) . "\n"; | ||
2853 | } | 2856 | } |
2854 | 2857 | ||
2855 | } elsif ($ctx !~ /;/) { | 2858 | if ($dstat =~ /;/) { |
2856 | if ($dstat ne '' && | 2859 | ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", |
2857 | $dstat !~ /^(?:$Ident|-?$Constant)$/ && | 2860 | "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); |
2858 | $dstat !~ /$exceptions/ && | 2861 | } else { |
2859 | $dstat !~ /^\.$Ident\s*=/ && | ||
2860 | $dstat =~ /$Operators/) | ||
2861 | { | ||
2862 | ERROR("COMPLEX_MACRO", | 2862 | ERROR("COMPLEX_MACRO", |
2863 | "Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n"); | 2863 | "Macros with complex values should be enclosed in parenthesis\n" . "$herectx"); |
2864 | } | 2864 | } |
2865 | } | 2865 | } |
2866 | } | 2866 | } |
@@ -3111,6 +3111,12 @@ sub process { | |||
3111 | "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); | 3111 | "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); |
3112 | } | 3112 | } |
3113 | 3113 | ||
3114 | # Check for __attribute__ format(printf, prefer __printf | ||
3115 | if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { | ||
3116 | WARN("PREFER_PRINTF", | ||
3117 | "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr); | ||
3118 | } | ||
3119 | |||
3114 | # check for sizeof(&) | 3120 | # check for sizeof(&) |
3115 | if ($line =~ /\bsizeof\s*\(\s*\&/) { | 3121 | if ($line =~ /\bsizeof\s*\(\s*\&/) { |
3116 | WARN("SIZEOF_ADDRESS", | 3122 | WARN("SIZEOF_ADDRESS", |
@@ -3123,6 +3129,46 @@ sub process { | |||
3123 | "Avoid line continuations in quoted strings\n" . $herecurr); | 3129 | "Avoid line continuations in quoted strings\n" . $herecurr); |
3124 | } | 3130 | } |
3125 | 3131 | ||
3132 | # Check for misused memsets | ||
3133 | if (defined $stat && | ||
3134 | $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) { | ||
3135 | |||
3136 | my $ms_addr = $2; | ||
3137 | my $ms_val = $8; | ||
3138 | my $ms_size = $14; | ||
3139 | |||
3140 | if ($ms_size =~ /^(0x|)0$/i) { | ||
3141 | ERROR("MEMSET", | ||
3142 | "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); | ||
3143 | } elsif ($ms_size =~ /^(0x|)1$/i) { | ||
3144 | WARN("MEMSET", | ||
3145 | "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); | ||
3146 | } | ||
3147 | } | ||
3148 | |||
3149 | # typecasts on min/max could be min_t/max_t | ||
3150 | if (defined $stat && | ||
3151 | $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { | ||
3152 | if (defined $2 || defined $8) { | ||
3153 | my $call = $1; | ||
3154 | my $cast1 = deparenthesize($2); | ||
3155 | my $arg1 = $3; | ||
3156 | my $cast2 = deparenthesize($8); | ||
3157 | my $arg2 = $9; | ||
3158 | my $cast; | ||
3159 | |||
3160 | if ($cast1 ne "" && $cast2 ne "") { | ||
3161 | $cast = "$cast1 or $cast2"; | ||
3162 | } elsif ($cast1 ne "") { | ||
3163 | $cast = $cast1; | ||
3164 | } else { | ||
3165 | $cast = $cast2; | ||
3166 | } | ||
3167 | WARN("MINMAX", | ||
3168 | "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); | ||
3169 | } | ||
3170 | } | ||
3171 | |||
3126 | # check for new externs in .c files. | 3172 | # check for new externs in .c files. |
3127 | if ($realfile =~ /\.c$/ && defined $stat && | 3173 | if ($realfile =~ /\.c$/ && defined $stat && |
3128 | $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) | 3174 | $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) |
@@ -3294,12 +3340,6 @@ sub process { | |||
3294 | WARN("EXPORTED_WORLD_WRITABLE", | 3340 | WARN("EXPORTED_WORLD_WRITABLE", |
3295 | "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); | 3341 | "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); |
3296 | } | 3342 | } |
3297 | |||
3298 | # Check for memset with swapped arguments | ||
3299 | if ($line =~ /memset.*\,(\ |)(0x|)0(\ |0|)\);/) { | ||
3300 | ERROR("MEMSET", | ||
3301 | "memset size is 3rd argument, not the second.\n" . $herecurr); | ||
3302 | } | ||
3303 | } | 3343 | } |
3304 | 3344 | ||
3305 | # If we have no input at all, then there is nothing to report on | 3345 | # If we have no input at all, then there is nothing to report on |
diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh index 3ab316e52313..d24810fc6af6 100755 --- a/scripts/checksyscalls.sh +++ b/scripts/checksyscalls.sh | |||
@@ -198,11 +198,16 @@ EOF | |||
198 | } | 198 | } |
199 | 199 | ||
200 | syscall_list() { | 200 | syscall_list() { |
201 | sed -n -e '/^\#define/ s/[^_]*__NR_\([^[:space:]]*\).*/\ | 201 | grep '^[0-9]' "$1" | sort -n | ( |
202 | \#if !defined \(__NR_\1\) \&\& !defined \(__IGNORE_\1\)\ | 202 | while read nr abi name entry ; do |
203 | \#warning syscall \1 not implemented\ | 203 | echo <<EOF |
204 | \#endif/p' $1 | 204 | #if !defined(__NR_${name}) && !defined(__IGNORE_${name}) |
205 | #warning syscall ${name} not implemented | ||
206 | #endif | ||
207 | EOF | ||
208 | done | ||
209 | ) | ||
205 | } | 210 | } |
206 | 211 | ||
207 | (ignore_list && syscall_list $(dirname $0)/../arch/x86/include/asm/unistd_32.h) | \ | 212 | (ignore_list && syscall_list $(dirname $0)/../arch/x86/syscalls/syscall_32.tbl) | \ |
208 | $* -E -x c - > /dev/null | 213 | $* -E -x c - > /dev/null |
diff --git a/scripts/coccicheck b/scripts/coccicheck index 1bb1a1bd2daa..3c2776466d87 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck | |||
@@ -9,14 +9,23 @@ if [ "$C" = "1" -o "$C" = "2" ]; then | |||
9 | # FLAGS="-ignore_unknown_options -very_quiet" | 9 | # FLAGS="-ignore_unknown_options -very_quiet" |
10 | # OPTIONS=$* | 10 | # OPTIONS=$* |
11 | 11 | ||
12 | # Workaround for Coccinelle < 0.2.3 | 12 | if [ "$KBUILD_EXTMOD" = "" ] ; then |
13 | FLAGS="-I $srctree/include -very_quiet" | 13 | # Workaround for Coccinelle < 0.2.3 |
14 | shift $(( $# - 1 )) | 14 | FLAGS="-I $srctree/include -very_quiet" |
15 | OPTIONS=$1 | 15 | shift $(( $# - 1 )) |
16 | OPTIONS=$1 | ||
17 | else | ||
18 | echo M= is not currently supported when C=1 or C=2 | ||
19 | exit 1 | ||
20 | fi | ||
16 | else | 21 | else |
17 | ONLINE=0 | 22 | ONLINE=0 |
18 | FLAGS="-very_quiet" | 23 | FLAGS="-very_quiet" |
19 | OPTIONS="-dir $srctree" | 24 | if [ "$KBUILD_EXTMOD" = "" ] ; then |
25 | OPTIONS="-dir $srctree" | ||
26 | else | ||
27 | OPTIONS="-dir $KBUILD_EXTMOD -patch $srctree -I $srctree/include -I $KBUILD_EXTMOD/include" | ||
28 | fi | ||
20 | fi | 29 | fi |
21 | 30 | ||
22 | if [ ! -x "$SPATCH" ]; then | 31 | if [ ! -x "$SPATCH" ]; then |
diff --git a/scripts/coccinelle/api/devm_request_and_ioremap.cocci b/scripts/coccinelle/api/devm_request_and_ioremap.cocci new file mode 100644 index 000000000000..46beb81406ab --- /dev/null +++ b/scripts/coccinelle/api/devm_request_and_ioremap.cocci | |||
@@ -0,0 +1,105 @@ | |||
1 | /// Reimplement a call to devm_request_mem_region followed by a call to ioremap | ||
2 | /// or ioremap_nocache by a call to devm_request_and_ioremap. | ||
3 | /// Devm_request_and_ioremap was introduced in | ||
4 | /// 72f8c0bfa0de64c68ee59f40eb9b2683bffffbb0. It makes the code much more | ||
5 | /// concise. | ||
6 | /// | ||
7 | /// | ||
8 | // Confidence: High | ||
9 | // Copyright: (C) 2011 Julia Lawall, INRIA/LIP6. GPLv2. | ||
10 | // Copyright: (C) 2011 Gilles Muller, INRIA/LiP6. GPLv2. | ||
11 | // URL: http://coccinelle.lip6.fr/ | ||
12 | // Comments: | ||
13 | // Options: -no_includes -include_headers | ||
14 | |||
15 | virtual patch | ||
16 | virtual org | ||
17 | virtual report | ||
18 | virtual context | ||
19 | |||
20 | @nm@ | ||
21 | expression myname; | ||
22 | identifier i; | ||
23 | @@ | ||
24 | |||
25 | struct platform_driver i = { .driver = { .name = myname } }; | ||
26 | |||
27 | @depends on patch@ | ||
28 | expression dev,res,size; | ||
29 | @@ | ||
30 | |||
31 | -if (!devm_request_mem_region(dev, res->start, size, | ||
32 | - \(res->name\|dev_name(dev)\))) { | ||
33 | - ... | ||
34 | - return ...; | ||
35 | -} | ||
36 | ... when != res->start | ||
37 | ( | ||
38 | -devm_ioremap(dev,res->start,size) | ||
39 | +devm_request_and_ioremap(dev,res) | ||
40 | | | ||
41 | -devm_ioremap_nocache(dev,res->start,size) | ||
42 | +devm_request_and_ioremap(dev,res) | ||
43 | ) | ||
44 | ... when any | ||
45 | when != res->start | ||
46 | |||
47 | // this rule is separate from the previous one, because a single file can | ||
48 | // have multiple values of myname | ||
49 | @depends on patch@ | ||
50 | expression dev,res,size; | ||
51 | expression nm.myname; | ||
52 | @@ | ||
53 | |||
54 | -if (!devm_request_mem_region(dev, res->start, size,myname)) { | ||
55 | - ... | ||
56 | - return ...; | ||
57 | -} | ||
58 | ... when != res->start | ||
59 | ( | ||
60 | -devm_ioremap(dev,res->start,size) | ||
61 | +devm_request_and_ioremap(dev,res) | ||
62 | | | ||
63 | -devm_ioremap_nocache(dev,res->start,size) | ||
64 | +devm_request_and_ioremap(dev,res) | ||
65 | ) | ||
66 | ... when any | ||
67 | when != res->start | ||
68 | |||
69 | |||
70 | @pb depends on org || report || context@ | ||
71 | expression dev,res,size; | ||
72 | expression nm.myname; | ||
73 | position p1,p2; | ||
74 | @@ | ||
75 | |||
76 | *if | ||
77 | (!devm_request_mem_region@p1(dev, res->start, size, | ||
78 | \(res->name\|dev_name(dev)\|myname\))) { | ||
79 | ... | ||
80 | return ...; | ||
81 | } | ||
82 | ... when != res->start | ||
83 | ( | ||
84 | *devm_ioremap@p2(dev,res->start,size) | ||
85 | | | ||
86 | *devm_ioremap_nocache@p2(dev,res->start,size) | ||
87 | ) | ||
88 | ... when any | ||
89 | when != res->start | ||
90 | |||
91 | @script:python depends on org@ | ||
92 | p1 << pb.p1; | ||
93 | p2 << pb.p2; | ||
94 | @@ | ||
95 | |||
96 | cocci.print_main("INFO: replace by devm_request_and_ioremap",p1) | ||
97 | cocci.print_secs("",p2) | ||
98 | |||
99 | @script:python depends on report@ | ||
100 | p1 << pb.p1; | ||
101 | p2 << pb.p2; | ||
102 | @@ | ||
103 | |||
104 | msg = "INFO: devm_request_mem_region followed by ioremap on line %s can be replaced by devm_request_and_ioremap" % (p2[0].line) | ||
105 | coccilib.report.print_report(p1[0],msg) | ||
diff --git a/scripts/coccinelle/api/kstrdup.cocci b/scripts/coccinelle/api/kstrdup.cocci index e0805ad08d39..07a74b2c6196 100644 --- a/scripts/coccinelle/api/kstrdup.cocci +++ b/scripts/coccinelle/api/kstrdup.cocci | |||
@@ -1,16 +1,19 @@ | |||
1 | /// Use kstrdup rather than duplicating its implementation | 1 | /// Use kstrdup rather than duplicating its implementation |
2 | /// | 2 | /// |
3 | // Confidence: High | 3 | // Confidence: High |
4 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 4 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
5 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 5 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
6 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 6 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
7 | // URL: http://coccinelle.lip6.fr/ | 7 | // URL: http://coccinelle.lip6.fr/ |
8 | // Comments: | 8 | // Comments: |
9 | // Options: -no_includes -include_headers | 9 | // Options: -no_includes -include_headers |
10 | 10 | ||
11 | virtual patch | 11 | virtual patch |
12 | virtual context | ||
13 | virtual org | ||
14 | virtual report | ||
12 | 15 | ||
13 | @@ | 16 | @depends on patch@ |
14 | expression from,to; | 17 | expression from,to; |
15 | expression flag,E1,E2; | 18 | expression flag,E1,E2; |
16 | statement S; | 19 | statement S; |
@@ -23,7 +26,7 @@ statement S; | |||
23 | ... when != \(from = E2 \| to = E2 \) | 26 | ... when != \(from = E2 \| to = E2 \) |
24 | - strcpy(to, from); | 27 | - strcpy(to, from); |
25 | 28 | ||
26 | @@ | 29 | @depends on patch@ |
27 | expression x,from,to; | 30 | expression x,from,to; |
28 | expression flag,E1,E2,E3; | 31 | expression flag,E1,E2,E3; |
29 | statement S; | 32 | statement S; |
@@ -37,3 +40,65 @@ statement S; | |||
37 | if (to==NULL || ...) S | 40 | if (to==NULL || ...) S |
38 | ... when != \(x = E3 \| from = E3 \| to = E3 \) | 41 | ... when != \(x = E3 \| from = E3 \| to = E3 \) |
39 | - memcpy(to, from, x); | 42 | - memcpy(to, from, x); |
43 | |||
44 | // --------------------------------------------------------------------- | ||
45 | |||
46 | @r1 depends on !patch exists@ | ||
47 | expression from,to; | ||
48 | expression flag,E1,E2; | ||
49 | statement S; | ||
50 | position p1,p2; | ||
51 | @@ | ||
52 | |||
53 | * to = kmalloc@p1(strlen(from) + 1,flag); | ||
54 | ... when != \(from = E1 \| to = E1 \) | ||
55 | if (to==NULL || ...) S | ||
56 | ... when != \(from = E2 \| to = E2 \) | ||
57 | * strcpy@p2(to, from); | ||
58 | |||
59 | @r2 depends on !patch exists@ | ||
60 | expression x,from,to; | ||
61 | expression flag,E1,E2,E3; | ||
62 | statement S; | ||
63 | position p1,p2; | ||
64 | @@ | ||
65 | |||
66 | * x = strlen(from) + 1; | ||
67 | ... when != \( x = E1 \| from = E1 \) | ||
68 | * to = \(kmalloc@p1\|kzalloc@p2\)(x,flag); | ||
69 | ... when != \(x = E2 \| from = E2 \| to = E2 \) | ||
70 | if (to==NULL || ...) S | ||
71 | ... when != \(x = E3 \| from = E3 \| to = E3 \) | ||
72 | * memcpy@p2(to, from, x); | ||
73 | |||
74 | @script:python depends on org@ | ||
75 | p1 << r1.p1; | ||
76 | p2 << r1.p2; | ||
77 | @@ | ||
78 | |||
79 | cocci.print_main("WARNING opportunity for kstrdep",p1) | ||
80 | cocci.print_secs("strcpy",p2) | ||
81 | |||
82 | @script:python depends on org@ | ||
83 | p1 << r2.p1; | ||
84 | p2 << r2.p2; | ||
85 | @@ | ||
86 | |||
87 | cocci.print_main("WARNING opportunity for kstrdep",p1) | ||
88 | cocci.print_secs("memcpy",p2) | ||
89 | |||
90 | @script:python depends on report@ | ||
91 | p1 << r1.p1; | ||
92 | p2 << r1.p2; | ||
93 | @@ | ||
94 | |||
95 | msg = "WARNING opportunity for kstrdep (strcpy on line %s)" % (p2[0].line) | ||
96 | coccilib.report.print_report(p1[0], msg) | ||
97 | |||
98 | @script:python depends on report@ | ||
99 | p1 << r2.p1; | ||
100 | p2 << r2.p2; | ||
101 | @@ | ||
102 | |||
103 | msg = "WARNING opportunity for kstrdep (memcpy on line %s)" % (p2[0].line) | ||
104 | coccilib.report.print_report(p1[0], msg) | ||
diff --git a/scripts/coccinelle/api/memdup.cocci b/scripts/coccinelle/api/memdup.cocci index b5d722077dc1..4dceab6d54de 100644 --- a/scripts/coccinelle/api/memdup.cocci +++ b/scripts/coccinelle/api/memdup.cocci | |||
@@ -1,14 +1,17 @@ | |||
1 | /// Use kmemdup rather than duplicating its implementation | 1 | /// Use kmemdup rather than duplicating its implementation |
2 | /// | 2 | /// |
3 | // Confidence: High | 3 | // Confidence: High |
4 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 4 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
5 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 5 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
6 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 6 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
7 | // URL: http://coccinelle.lip6.fr/ | 7 | // URL: http://coccinelle.lip6.fr/ |
8 | // Comments: | 8 | // Comments: |
9 | // Options: -no_includes -include_headers | 9 | // Options: -no_includes -include_headers |
10 | 10 | ||
11 | virtual patch | 11 | virtual patch |
12 | virtual context | ||
13 | virtual org | ||
14 | virtual report | ||
12 | 15 | ||
13 | @r1@ | 16 | @r1@ |
14 | expression from,to; | 17 | expression from,to; |
@@ -28,7 +31,7 @@ position p; | |||
28 | ... when != \( x = E1 \| from = E1 \) | 31 | ... when != \( x = E1 \| from = E1 \) |
29 | to = \(kmalloc@p\|kzalloc@p\)(x,flag); | 32 | to = \(kmalloc@p\|kzalloc@p\)(x,flag); |
30 | 33 | ||
31 | @@ | 34 | @depends on patch@ |
32 | expression from,to,size,flag; | 35 | expression from,to,size,flag; |
33 | position p != {r1.p,r2.p}; | 36 | position p != {r1.p,r2.p}; |
34 | statement S; | 37 | statement S; |
@@ -38,3 +41,26 @@ statement S; | |||
38 | + to = kmemdup(from,size,flag); | 41 | + to = kmemdup(from,size,flag); |
39 | if (to==NULL || ...) S | 42 | if (to==NULL || ...) S |
40 | - memcpy(to, from, size); | 43 | - memcpy(to, from, size); |
44 | |||
45 | @r depends on !patch@ | ||
46 | expression from,to,size,flag; | ||
47 | position p != {r1.p,r2.p}; | ||
48 | statement S; | ||
49 | @@ | ||
50 | |||
51 | * to = \(kmalloc@p\|kzalloc@p\)(size,flag); | ||
52 | to = kmemdup(from,size,flag); | ||
53 | if (to==NULL || ...) S | ||
54 | * memcpy(to, from, size); | ||
55 | |||
56 | @script:python depends on org@ | ||
57 | p << r.p; | ||
58 | @@ | ||
59 | |||
60 | coccilib.org.print_todo(p[0], "WARNING opportunity for kmemdep") | ||
61 | |||
62 | @script:python depends on report@ | ||
63 | p << r.p; | ||
64 | @@ | ||
65 | |||
66 | coccilib.report.print_report(p[0], "WARNING opportunity for kmemdep") | ||
diff --git a/scripts/coccinelle/api/memdup_user.cocci b/scripts/coccinelle/api/memdup_user.cocci index 72ce012e878a..2efac289fd59 100644 --- a/scripts/coccinelle/api/memdup_user.cocci +++ b/scripts/coccinelle/api/memdup_user.cocci | |||
@@ -1,23 +1,25 @@ | |||
1 | /// Use kmemdup_user rather than duplicating its implementation | 1 | /// Use memdup_user rather than duplicating its implementation |
2 | /// This is a little bit restricted to reduce false positives | 2 | /// This is a little bit restricted to reduce false positives |
3 | /// | 3 | /// |
4 | // Confidence: High | 4 | // Confidence: High |
5 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 5 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
6 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 6 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
7 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 7 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
8 | // URL: http://coccinelle.lip6.fr/ | 8 | // URL: http://coccinelle.lip6.fr/ |
9 | // Comments: | 9 | // Comments: |
10 | // Options: -no_includes -include_headers | 10 | // Options: -no_includes -include_headers |
11 | 11 | ||
12 | virtual patch | 12 | virtual patch |
13 | virtual context | ||
14 | virtual org | ||
15 | virtual report | ||
13 | 16 | ||
14 | @@ | 17 | @depends on patch@ |
15 | expression from,to,size,flag; | 18 | expression from,to,size,flag; |
16 | position p; | ||
17 | identifier l1,l2; | 19 | identifier l1,l2; |
18 | @@ | 20 | @@ |
19 | 21 | ||
20 | - to = \(kmalloc@p\|kzalloc@p\)(size,flag); | 22 | - to = \(kmalloc\|kzalloc\)(size,flag); |
21 | + to = memdup_user(from,size); | 23 | + to = memdup_user(from,size); |
22 | if ( | 24 | if ( |
23 | - to==NULL | 25 | - to==NULL |
@@ -33,3 +35,26 @@ identifier l1,l2; | |||
33 | - -EFAULT | 35 | - -EFAULT |
34 | - ...+> | 36 | - ...+> |
35 | - } | 37 | - } |
38 | |||
39 | @r depends on !patch@ | ||
40 | expression from,to,size,flag; | ||
41 | position p; | ||
42 | statement S1,S2; | ||
43 | @@ | ||
44 | |||
45 | * to = \(kmalloc@p\|kzalloc@p\)(size,flag); | ||
46 | if (to==NULL || ...) S1 | ||
47 | if (copy_from_user(to, from, size) != 0) | ||
48 | S2 | ||
49 | |||
50 | @script:python depends on org@ | ||
51 | p << r.p; | ||
52 | @@ | ||
53 | |||
54 | coccilib.org.print_todo(p[0], "WARNING opportunity for memdep_user") | ||
55 | |||
56 | @script:python depends on report@ | ||
57 | p << r.p; | ||
58 | @@ | ||
59 | |||
60 | coccilib.report.print_report(p[0], "WARNING opportunity for memdep_user") | ||
diff --git a/scripts/coccinelle/free/devm_free.cocci b/scripts/coccinelle/free/devm_free.cocci new file mode 100644 index 000000000000..0a1e36146d76 --- /dev/null +++ b/scripts/coccinelle/free/devm_free.cocci | |||
@@ -0,0 +1,71 @@ | |||
1 | /// Find uses of standard freeing functons on values allocated using devm_ | ||
2 | /// functions. Values allocated using the devm_functions are freed when | ||
3 | /// the device is detached, and thus the use of the standard freeing | ||
4 | /// function would cause a double free. | ||
5 | /// See Documentation/driver-model/devres.txt for more information. | ||
6 | /// | ||
7 | /// A difficulty of detecting this problem is that the standard freeing | ||
8 | /// function might be called from a different function than the one | ||
9 | /// containing the allocation function. It is thus necessary to make the | ||
10 | /// connection between the allocation function and the freeing function. | ||
11 | /// Here this is done using the specific argument text, which is prone to | ||
12 | /// false positives. There is no rule for the request_region and | ||
13 | /// request_mem_region variants because this heuristic seems to be a bit | ||
14 | /// less reliable in these cases. | ||
15 | /// | ||
16 | // Confidence: Moderate | ||
17 | // Copyright: (C) 2011 Julia Lawall, INRIA/LIP6. GPLv2. | ||
18 | // Copyright: (C) 2011 Gilles Muller, INRIA/LiP6. GPLv2. | ||
19 | // URL: http://coccinelle.lip6.fr/ | ||
20 | // Comments: | ||
21 | // Options: -no_includes -include_headers | ||
22 | |||
23 | virtual org | ||
24 | virtual report | ||
25 | virtual context | ||
26 | |||
27 | @r depends on context || org || report@ | ||
28 | expression x; | ||
29 | @@ | ||
30 | |||
31 | ( | ||
32 | x = devm_kzalloc(...) | ||
33 | | | ||
34 | x = devm_request_irq(...) | ||
35 | | | ||
36 | x = devm_ioremap(...) | ||
37 | | | ||
38 | x = devm_ioremap_nocache(...) | ||
39 | | | ||
40 | x = devm_ioport_map(...) | ||
41 | ) | ||
42 | |||
43 | @pb@ | ||
44 | expression r.x; | ||
45 | position p; | ||
46 | @@ | ||
47 | |||
48 | ( | ||
49 | * kfree@p(x) | ||
50 | | | ||
51 | * free_irq@p(x) | ||
52 | | | ||
53 | * iounmap@p(x) | ||
54 | | | ||
55 | * ioport_unmap@p(x) | ||
56 | ) | ||
57 | |||
58 | @script:python depends on org@ | ||
59 | p << pb.p; | ||
60 | @@ | ||
61 | |||
62 | msg="WARNING: invalid free of devm_ allocated data" | ||
63 | coccilib.org.print_todo(p[0], msg) | ||
64 | |||
65 | @script:python depends on report@ | ||
66 | p << pb.p; | ||
67 | @@ | ||
68 | |||
69 | msg="WARNING: invalid free of devm_ allocated data" | ||
70 | coccilib.report.print_report(p[0], msg) | ||
71 | |||
diff --git a/scripts/coccinelle/free/kfree.cocci b/scripts/coccinelle/free/kfree.cocci index f9f79d9245ee..d9ae6d89c2f5 100644 --- a/scripts/coccinelle/free/kfree.cocci +++ b/scripts/coccinelle/free/kfree.cocci | |||
@@ -5,9 +5,9 @@ | |||
5 | //# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument | 5 | //# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument |
6 | /// | 6 | /// |
7 | // Confidence: Moderate | 7 | // Confidence: Moderate |
8 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 8 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
9 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 9 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
10 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 10 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
11 | // URL: http://coccinelle.lip6.fr/ | 11 | // URL: http://coccinelle.lip6.fr/ |
12 | // Comments: | 12 | // Comments: |
13 | // Options: -no_includes -include_headers | 13 | // Options: -no_includes -include_headers |
@@ -23,7 +23,7 @@ position p1; | |||
23 | kfree@p1(E) | 23 | kfree@p1(E) |
24 | 24 | ||
25 | @print expression@ | 25 | @print expression@ |
26 | constant char *c; | 26 | constant char [] c; |
27 | expression free.E,E2; | 27 | expression free.E,E2; |
28 | type T; | 28 | type T; |
29 | position p; | 29 | position p; |
@@ -37,6 +37,10 @@ identifier f; | |||
37 | | | 37 | | |
38 | E@p != E2 | 38 | E@p != E2 |
39 | | | 39 | | |
40 | E2 == E@p | ||
41 | | | ||
42 | E2 != E@p | ||
43 | | | ||
40 | !E@p | 44 | !E@p |
41 | | | 45 | | |
42 | E@p || ... | 46 | E@p || ... |
@@ -113,5 +117,5 @@ p1 << free.p1; | |||
113 | p2 << r.p2; | 117 | p2 << r.p2; |
114 | @@ | 118 | @@ |
115 | 119 | ||
116 | msg = "reference preceded by free on line %s" % (p1[0].line) | 120 | msg = "ERROR: reference preceded by free on line %s" % (p1[0].line) |
117 | coccilib.report.print_report(p2[0],msg) | 121 | coccilib.report.print_report(p2[0],msg) |
diff --git a/scripts/coccinelle/iterators/fen.cocci b/scripts/coccinelle/iterators/fen.cocci index 77bc108c3f59..0a40af828c43 100644 --- a/scripts/coccinelle/iterators/fen.cocci +++ b/scripts/coccinelle/iterators/fen.cocci | |||
@@ -2,16 +2,19 @@ | |||
2 | /// is no point to call of_node_put on the final value. | 2 | /// is no point to call of_node_put on the final value. |
3 | /// | 3 | /// |
4 | // Confidence: High | 4 | // Confidence: High |
5 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 5 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
6 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 6 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
7 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 7 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
8 | // URL: http://coccinelle.lip6.fr/ | 8 | // URL: http://coccinelle.lip6.fr/ |
9 | // Comments: | 9 | // Comments: |
10 | // Options: -no_includes -include_headers | 10 | // Options: -no_includes -include_headers |
11 | 11 | ||
12 | virtual patch | 12 | virtual patch |
13 | virtual context | ||
14 | virtual org | ||
15 | virtual report | ||
13 | 16 | ||
14 | @@ | 17 | @depends on patch@ |
15 | iterator name for_each_node_by_name; | 18 | iterator name for_each_node_by_name; |
16 | expression np,E; | 19 | expression np,E; |
17 | identifier l; | 20 | identifier l; |
@@ -24,7 +27,7 @@ for_each_node_by_name(np,...) { | |||
24 | ... when != np = E | 27 | ... when != np = E |
25 | - of_node_put(np); | 28 | - of_node_put(np); |
26 | 29 | ||
27 | @@ | 30 | @depends on patch@ |
28 | iterator name for_each_node_by_type; | 31 | iterator name for_each_node_by_type; |
29 | expression np,E; | 32 | expression np,E; |
30 | identifier l; | 33 | identifier l; |
@@ -37,7 +40,7 @@ for_each_node_by_type(np,...) { | |||
37 | ... when != np = E | 40 | ... when != np = E |
38 | - of_node_put(np); | 41 | - of_node_put(np); |
39 | 42 | ||
40 | @@ | 43 | @depends on patch@ |
41 | iterator name for_each_compatible_node; | 44 | iterator name for_each_compatible_node; |
42 | expression np,E; | 45 | expression np,E; |
43 | identifier l; | 46 | identifier l; |
@@ -50,7 +53,7 @@ for_each_compatible_node(np,...) { | |||
50 | ... when != np = E | 53 | ... when != np = E |
51 | - of_node_put(np); | 54 | - of_node_put(np); |
52 | 55 | ||
53 | @@ | 56 | @depends on patch@ |
54 | iterator name for_each_matching_node; | 57 | iterator name for_each_matching_node; |
55 | expression np,E; | 58 | expression np,E; |
56 | identifier l; | 59 | identifier l; |
@@ -62,3 +65,59 @@ for_each_matching_node(np,...) { | |||
62 | } | 65 | } |
63 | ... when != np = E | 66 | ... when != np = E |
64 | - of_node_put(np); | 67 | - of_node_put(np); |
68 | |||
69 | // ---------------------------------------------------------------------- | ||
70 | |||
71 | @r depends on !patch forall@ | ||
72 | //iterator name for_each_node_by_name; | ||
73 | //iterator name for_each_node_by_type; | ||
74 | //iterator name for_each_compatible_node; | ||
75 | //iterator name for_each_matching_node; | ||
76 | expression np,E; | ||
77 | identifier l; | ||
78 | position p1,p2; | ||
79 | @@ | ||
80 | |||
81 | ( | ||
82 | *for_each_node_by_name@p1(np,...) | ||
83 | { | ||
84 | ... when != break; | ||
85 | when != goto l; | ||
86 | } | ||
87 | | | ||
88 | *for_each_node_by_type@p1(np,...) | ||
89 | { | ||
90 | ... when != break; | ||
91 | when != goto l; | ||
92 | } | ||
93 | | | ||
94 | *for_each_compatible_node@p1(np,...) | ||
95 | { | ||
96 | ... when != break; | ||
97 | when != goto l; | ||
98 | } | ||
99 | | | ||
100 | *for_each_matching_node@p1(np,...) | ||
101 | { | ||
102 | ... when != break; | ||
103 | when != goto l; | ||
104 | } | ||
105 | ) | ||
106 | ... when != np = E | ||
107 | * of_node_put@p2(np); | ||
108 | |||
109 | @script:python depends on org@ | ||
110 | p1 << r.p1; | ||
111 | p2 << r.p2; | ||
112 | @@ | ||
113 | |||
114 | cocci.print_main("unneeded of_node_put",p2) | ||
115 | cocci.print_secs("iterator",p1) | ||
116 | |||
117 | @script:python depends on report@ | ||
118 | p1 << r.p1; | ||
119 | p2 << r.p2; | ||
120 | @@ | ||
121 | |||
122 | msg = "ERROR: of_node_put not needed after iterator on line %s" % (p1[0].line) | ||
123 | coccilib.report.print_report(p2[0], msg) | ||
diff --git a/scripts/coccinelle/iterators/itnull.cocci b/scripts/coccinelle/iterators/itnull.cocci index baa4297a4ed1..259899f6838e 100644 --- a/scripts/coccinelle/iterators/itnull.cocci +++ b/scripts/coccinelle/iterators/itnull.cocci | |||
@@ -1,20 +1,24 @@ | |||
1 | /// Many iterators have the property that the first argument is always bound | 1 | /// Many iterators have the property that the first argument is always bound |
2 | /// to a real list element, never NULL. False positives arise for some | 2 | /// to a real list element, never NULL. |
3 | /// iterators that do not have this property, or in cases when the loop | 3 | //# False positives arise for some iterators that do not have this property, |
4 | /// cursor is reassigned. The latter should only happen when the matched | 4 | //# or in cases when the loop cursor is reassigned. The latter should only |
5 | /// code is on the way to a loop exit (break, goto, or return). | 5 | //# happen when the matched code is on the way to a loop exit (break, goto, |
6 | //# or return). | ||
6 | /// | 7 | /// |
7 | // Confidence: Moderate | 8 | // Confidence: Moderate |
8 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 9 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
9 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 10 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
10 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 11 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
11 | // URL: http://coccinelle.lip6.fr/ | 12 | // URL: http://coccinelle.lip6.fr/ |
12 | // Comments: | 13 | // Comments: |
13 | // Options: -no_includes -include_headers | 14 | // Options: -no_includes -include_headers |
14 | 15 | ||
15 | virtual patch | 16 | virtual patch |
17 | virtual context | ||
18 | virtual org | ||
19 | virtual report | ||
16 | 20 | ||
17 | @@ | 21 | @depends on patch@ |
18 | iterator I; | 22 | iterator I; |
19 | expression x,E,E1,E2; | 23 | expression x,E,E1,E2; |
20 | statement S,S1,S2; | 24 | statement S,S1,S2; |
@@ -55,4 +59,36 @@ I(x,...) { <... | |||
55 | x != NULL | 59 | x != NULL |
56 | + ) | 60 | + ) |
57 | ) | 61 | ) |
58 | ...> } \ No newline at end of file | 62 | ...> } |
63 | |||
64 | @r depends on !patch exists@ | ||
65 | iterator I; | ||
66 | expression x,E; | ||
67 | position p1,p2; | ||
68 | @@ | ||
69 | |||
70 | *I@p1(x,...) | ||
71 | { ... when != x = E | ||
72 | ( | ||
73 | * x@p2 == NULL | ||
74 | | | ||
75 | * x@p2 != NULL | ||
76 | ) | ||
77 | ... when any | ||
78 | } | ||
79 | |||
80 | @script:python depends on org@ | ||
81 | p1 << r.p1; | ||
82 | p2 << r.p2; | ||
83 | @@ | ||
84 | |||
85 | cocci.print_main("iterator-bound variable",p1) | ||
86 | cocci.print_secs("useless NULL test",p2) | ||
87 | |||
88 | @script:python depends on report@ | ||
89 | p1 << r.p1; | ||
90 | p2 << r.p2; | ||
91 | @@ | ||
92 | |||
93 | msg = "ERROR: iterator variable bound on line %s cannot be NULL" % (p1[0].line) | ||
94 | coccilib.report.print_report(p2[0], msg) | ||
diff --git a/scripts/coccinelle/locks/call_kern.cocci b/scripts/coccinelle/locks/call_kern.cocci index 00af5344a68f..8f10b49603c3 100644 --- a/scripts/coccinelle/locks/call_kern.cocci +++ b/scripts/coccinelle/locks/call_kern.cocci | |||
@@ -1,17 +1,20 @@ | |||
1 | /// Find functions that refer to GFP_KERNEL but are called with locks held. | 1 | /// Find functions that refer to GFP_KERNEL but are called with locks held. |
2 | /// The proposed change of converting the GFP_KERNEL is not necessarily the | 2 | //# The proposed change of converting the GFP_KERNEL is not necessarily the |
3 | /// correct one. It may be desired to unlock the lock, or to not call the | 3 | //# correct one. It may be desired to unlock the lock, or to not call the |
4 | /// function under the lock in the first place. | 4 | //# function under the lock in the first place. |
5 | /// | 5 | /// |
6 | // Confidence: Moderate | 6 | // Confidence: Moderate |
7 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 7 | // Copyright: (C) 2012 Nicolas Palix. GPLv2. |
8 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 8 | // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. |
9 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 9 | // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. |
10 | // URL: http://coccinelle.lip6.fr/ | 10 | // URL: http://coccinelle.lip6.fr/ |
11 | // Comments: | 11 | // Comments: |
12 | // Options: -no_includes -include_headers | 12 | // Options: -no_includes -include_headers |
13 | 13 | ||
14 | virtual patch | 14 | virtual patch |
15 | virtual context | ||
16 | virtual org | ||
17 | virtual report | ||
15 | 18 | ||
16 | @gfp exists@ | 19 | @gfp exists@ |
17 | identifier fn; | 20 | identifier fn; |
@@ -32,28 +35,29 @@ fn(...) { | |||
32 | ... when any | 35 | ... when any |
33 | } | 36 | } |
34 | 37 | ||
35 | @locked@ | 38 | @locked exists@ |
36 | identifier gfp.fn; | 39 | identifier gfp.fn; |
40 | position p1,p2; | ||
37 | @@ | 41 | @@ |
38 | 42 | ||
39 | ( | 43 | ( |
40 | read_lock_irq | 44 | read_lock_irq@p1 |
41 | | | 45 | | |
42 | write_lock_irq | 46 | write_lock_irq@p1 |
43 | | | 47 | | |
44 | read_lock_irqsave | 48 | read_lock_irqsave@p1 |
45 | | | 49 | | |
46 | write_lock_irqsave | 50 | write_lock_irqsave@p1 |
47 | | | 51 | | |
48 | spin_lock | 52 | spin_lock@p1 |
49 | | | 53 | | |
50 | spin_trylock | 54 | spin_trylock@p1 |
51 | | | 55 | | |
52 | spin_lock_irq | 56 | spin_lock_irq@p1 |
53 | | | 57 | | |
54 | spin_lock_irqsave | 58 | spin_lock_irqsave@p1 |
55 | | | 59 | | |
56 | local_irq_disable | 60 | local_irq_disable@p1 |
57 | ) | 61 | ) |
58 | (...) | 62 | (...) |
59 | ... when != read_unlock_irq(...) | 63 | ... when != read_unlock_irq(...) |
@@ -64,11 +68,38 @@ local_irq_disable | |||
64 | when != spin_unlock_irq(...) | 68 | when != spin_unlock_irq(...) |
65 | when != spin_unlock_irqrestore(...) | 69 | when != spin_unlock_irqrestore(...) |
66 | when != local_irq_enable(...) | 70 | when != local_irq_enable(...) |
67 | fn(...) | 71 | fn@p2(...) |
68 | 72 | ||
69 | @depends on locked@ | 73 | @depends on locked && patch@ |
70 | position gfp.p; | 74 | position gfp.p; |
71 | @@ | 75 | @@ |
72 | 76 | ||
73 | - GFP_KERNEL@p | 77 | - GFP_KERNEL@p |
74 | + GFP_ATOMIC | 78 | + GFP_ATOMIC |
79 | |||
80 | @depends on locked && !patch@ | ||
81 | position gfp.p; | ||
82 | @@ | ||
83 | |||
84 | * GFP_KERNEL@p | ||
85 | |||
86 | @script:python depends on !patch && org@ | ||
87 | p << gfp.p; | ||
88 | fn << gfp.fn; | ||
89 | p1 << locked.p1; | ||
90 | p2 << locked.p2; | ||
91 | @@ | ||
92 | |||
93 | cocci.print_main("lock",p1) | ||
94 | cocci.print_secs("call",p2) | ||
95 | cocci.print_secs("GFP_KERNEL",p) | ||
96 | |||
97 | @script:python depends on !patch && report@ | ||
98 | p << gfp.p; | ||
99 | fn << gfp.fn; | ||
100 | p1 << locked.p1; | ||
101 | p2 << locked.p2; | ||
102 | @@ | ||
103 | |||
104 | msg = "ERROR: function %s called on line %s inside lock on line %s but uses GFP_KERNEL" % (fn,p2[0].line,p1[0].line) | ||
105 | coccilib.report.print_report(p[0], msg) | ||
diff --git a/scripts/coccinelle/locks/flags.cocci b/scripts/coccinelle/locks/flags.cocci index b4344d838097..1c4ffe6fd846 100644 --- a/scripts/coccinelle/locks/flags.cocci +++ b/scripts/coccinelle/locks/flags.cocci | |||
@@ -1,9 +1,9 @@ | |||
1 | /// Find nested lock+irqsave functions that use the same flags variables | 1 | /// Find nested lock+irqsave functions that use the same flags variables |
2 | /// | 2 | /// |
3 | // Confidence: High | 3 | // Confidence: High |
4 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 4 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
5 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 5 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
6 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 6 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
7 | // URL: http://coccinelle.lip6.fr/ | 7 | // URL: http://coccinelle.lip6.fr/ |
8 | // Comments: | 8 | // Comments: |
9 | // Options: -no_includes -include_headers | 9 | // Options: -no_includes -include_headers |
@@ -12,7 +12,7 @@ virtual context | |||
12 | virtual org | 12 | virtual org |
13 | virtual report | 13 | virtual report |
14 | 14 | ||
15 | @r@ | 15 | @r exists@ |
16 | expression lock1,lock2,flags; | 16 | expression lock1,lock2,flags; |
17 | position p1,p2; | 17 | position p1,p2; |
18 | @@ | 18 | @@ |
@@ -39,7 +39,7 @@ read_lock_irqsave@p2(lock2,flags) | |||
39 | write_lock_irqsave@p2(lock2,flags) | 39 | write_lock_irqsave@p2(lock2,flags) |
40 | ) | 40 | ) |
41 | 41 | ||
42 | @d@ | 42 | @d exists@ |
43 | expression f <= r.flags; | 43 | expression f <= r.flags; |
44 | expression lock1,lock2,flags; | 44 | expression lock1,lock2,flags; |
45 | position r.p1, r.p2; | 45 | position r.p1, r.p2; |
@@ -76,5 +76,5 @@ p1 << r.p1; | |||
76 | p2 << r.p2; | 76 | p2 << r.p2; |
77 | @@ | 77 | @@ |
78 | 78 | ||
79 | msg="ERROR: nested lock+irqsave that reuses flags from %s." % (p1[0].line) | 79 | msg="ERROR: nested lock+irqsave that reuses flags from line %s." % (p1[0].line) |
80 | coccilib.report.print_report(p2[0], msg) | 80 | coccilib.report.print_report(p2[0], msg) |
diff --git a/scripts/coccinelle/locks/mini_lock.cocci b/scripts/coccinelle/locks/mini_lock.cocci index 7641a2925434..3267d7410bd5 100644 --- a/scripts/coccinelle/locks/mini_lock.cocci +++ b/scripts/coccinelle/locks/mini_lock.cocci | |||
@@ -6,13 +6,14 @@ | |||
6 | /// function call that releases the lock. | 6 | /// function call that releases the lock. |
7 | /// | 7 | /// |
8 | // Confidence: Moderate | 8 | // Confidence: Moderate |
9 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 9 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
10 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 10 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
11 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 11 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
12 | // URL: http://coccinelle.lip6.fr/ | 12 | // URL: http://coccinelle.lip6.fr/ |
13 | // Comments: | 13 | // Comments: |
14 | // Options: -no_includes -include_headers | 14 | // Options: -no_includes -include_headers |
15 | 15 | ||
16 | virtual context | ||
16 | virtual org | 17 | virtual org |
17 | virtual report | 18 | virtual report |
18 | 19 | ||
@@ -57,7 +58,7 @@ position r; | |||
57 | 58 | ||
58 | for(...;...;...) { <+... return@r ...; ...+> } | 59 | for(...;...;...) { <+... return@r ...; ...+> } |
59 | 60 | ||
60 | @err@ | 61 | @err exists@ |
61 | expression E1; | 62 | expression E1; |
62 | position prelocked.p; | 63 | position prelocked.p; |
63 | position up != prelocked.p1; | 64 | position up != prelocked.p1; |
@@ -65,14 +66,14 @@ position r!=looped.r; | |||
65 | identifier lock,unlock; | 66 | identifier lock,unlock; |
66 | @@ | 67 | @@ |
67 | 68 | ||
68 | lock(E1@p,...); | 69 | *lock(E1@p,...); |
69 | <+... when != E1 | 70 | <+... when != E1 |
70 | if (...) { | 71 | if (...) { |
71 | ... when != E1 | 72 | ... when != E1 |
72 | return@r ...; | 73 | * return@r ...; |
73 | } | 74 | } |
74 | ...+> | 75 | ...+> |
75 | unlock@up(E1,...); | 76 | *unlock@up(E1,...); |
76 | 77 | ||
77 | @script:python depends on org@ | 78 | @script:python depends on org@ |
78 | p << prelocked.p1; | 79 | p << prelocked.p1; |
diff --git a/scripts/coccinelle/misc/doubleinit.cocci b/scripts/coccinelle/misc/doubleinit.cocci index 156b20adb351..cf74a00cf597 100644 --- a/scripts/coccinelle/misc/doubleinit.cocci +++ b/scripts/coccinelle/misc/doubleinit.cocci | |||
@@ -3,9 +3,9 @@ | |||
3 | /// initialization. | 3 | /// initialization. |
4 | /// | 4 | /// |
5 | // Confidence: Low | 5 | // Confidence: Low |
6 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 6 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
7 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 7 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
8 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 8 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
9 | // URL: http://coccinelle.lip6.fr/ | 9 | // URL: http://coccinelle.lip6.fr/ |
10 | // Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise | 10 | // Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise |
11 | // Options: -no_includes -include_headers | 11 | // Options: -no_includes -include_headers |
@@ -49,5 +49,5 @@ pr << r.p; | |||
49 | @@ | 49 | @@ |
50 | 50 | ||
51 | if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)): | 51 | if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)): |
52 | msg = "%s: first occurrence %s, second occurrence %s" % (fld,ps[0].line,pr[0].line) | 52 | msg = "%s: first occurrence line %s, second occurrence line %s" % (fld,ps[0].line,pr[0].line) |
53 | coccilib.report.print_report(p0[0],msg) | 53 | coccilib.report.print_report(p0[0],msg) |
diff --git a/scripts/coccinelle/null/eno.cocci b/scripts/coccinelle/null/eno.cocci index 4c9c52b9c413..ed961a1f7d11 100644 --- a/scripts/coccinelle/null/eno.cocci +++ b/scripts/coccinelle/null/eno.cocci | |||
@@ -1,16 +1,19 @@ | |||
1 | /// The various basic memory allocation functions don't return ERR_PTR | 1 | /// The various basic memory allocation functions don't return ERR_PTR |
2 | /// | 2 | /// |
3 | // Confidence: High | 3 | // Confidence: High |
4 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 4 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
5 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 5 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
6 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 6 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
7 | // URL: http://coccinelle.lip6.fr/ | 7 | // URL: http://coccinelle.lip6.fr/ |
8 | // Comments: | 8 | // Comments: |
9 | // Options: -no_includes -include_headers | 9 | // Options: -no_includes -include_headers |
10 | 10 | ||
11 | virtual patch | 11 | virtual patch |
12 | virtual context | ||
13 | virtual org | ||
14 | virtual report | ||
12 | 15 | ||
13 | @@ | 16 | @depends on patch@ |
14 | expression x,E; | 17 | expression x,E; |
15 | @@ | 18 | @@ |
16 | 19 | ||
@@ -18,3 +21,28 @@ x = \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache | |||
18 | ... when != x = E | 21 | ... when != x = E |
19 | - IS_ERR(x) | 22 | - IS_ERR(x) |
20 | + !x | 23 | + !x |
24 | |||
25 | @r depends on !patch exists@ | ||
26 | expression x,E; | ||
27 | position p1,p2; | ||
28 | @@ | ||
29 | |||
30 | *x = \(kmalloc@p1\|kzalloc@p1\|kcalloc@p1\|kmem_cache_alloc@p1\|kmem_cache_zalloc@p1\|kmem_cache_alloc_node@p1\|kmalloc_node@p1\|kzalloc_node@p1\)(...) | ||
31 | ... when != x = E | ||
32 | * IS_ERR@p2(x) | ||
33 | |||
34 | @script:python depends on org@ | ||
35 | p1 << r.p1; | ||
36 | p2 << r.p2; | ||
37 | @@ | ||
38 | |||
39 | cocci.print_main("alloc call",p1) | ||
40 | cocci.print_secs("IS_ERR that should be NULL tests",p2) | ||
41 | |||
42 | @script:python depends on report@ | ||
43 | p1 << r.p1; | ||
44 | p2 << r.p2; | ||
45 | @@ | ||
46 | |||
47 | msg = "ERROR: allocation function on line %s returns NULL not ERR_PTR on failure" % (p1[0].line) | ||
48 | coccilib.report.print_report(p2[0], msg) | ||
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c index cbc0193098e4..451c92d31b19 100644 --- a/scripts/dtc/dtc.c +++ b/scripts/dtc/dtc.c | |||
@@ -71,6 +71,7 @@ static void __attribute__ ((noreturn)) usage(void) | |||
71 | fprintf(stderr, "\t\t\tasm - assembler source\n"); | 71 | fprintf(stderr, "\t\t\tasm - assembler source\n"); |
72 | fprintf(stderr, "\t-V <output version>\n"); | 72 | fprintf(stderr, "\t-V <output version>\n"); |
73 | fprintf(stderr, "\t\tBlob version to produce, defaults to %d (relevant for dtb\n\t\tand asm output only)\n", DEFAULT_FDT_VERSION); | 73 | fprintf(stderr, "\t\tBlob version to produce, defaults to %d (relevant for dtb\n\t\tand asm output only)\n", DEFAULT_FDT_VERSION); |
74 | fprintf(stderr, "\t-d <output dependency file>\n"); | ||
74 | fprintf(stderr, "\t-R <number>\n"); | 75 | fprintf(stderr, "\t-R <number>\n"); |
75 | fprintf(stderr, "\t\tMake space for <number> reserve map entries (relevant for \n\t\tdtb and asm output only)\n"); | 76 | fprintf(stderr, "\t\tMake space for <number> reserve map entries (relevant for \n\t\tdtb and asm output only)\n"); |
76 | fprintf(stderr, "\t-S <bytes>\n"); | 77 | fprintf(stderr, "\t-S <bytes>\n"); |
@@ -99,6 +100,7 @@ int main(int argc, char *argv[]) | |||
99 | const char *inform = "dts"; | 100 | const char *inform = "dts"; |
100 | const char *outform = "dts"; | 101 | const char *outform = "dts"; |
101 | const char *outname = "-"; | 102 | const char *outname = "-"; |
103 | const char *depname = NULL; | ||
102 | int force = 0, check = 0, sort = 0; | 104 | int force = 0, check = 0, sort = 0; |
103 | const char *arg; | 105 | const char *arg; |
104 | int opt; | 106 | int opt; |
@@ -111,7 +113,8 @@ int main(int argc, char *argv[]) | |||
111 | minsize = 0; | 113 | minsize = 0; |
112 | padsize = 0; | 114 | padsize = 0; |
113 | 115 | ||
114 | while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:vH:s")) != EOF) { | 116 | while ((opt = getopt(argc, argv, "hI:O:o:V:d:R:S:p:fcqb:vH:s")) |
117 | != EOF) { | ||
115 | switch (opt) { | 118 | switch (opt) { |
116 | case 'I': | 119 | case 'I': |
117 | inform = optarg; | 120 | inform = optarg; |
@@ -125,6 +128,9 @@ int main(int argc, char *argv[]) | |||
125 | case 'V': | 128 | case 'V': |
126 | outversion = strtol(optarg, NULL, 0); | 129 | outversion = strtol(optarg, NULL, 0); |
127 | break; | 130 | break; |
131 | case 'd': | ||
132 | depname = optarg; | ||
133 | break; | ||
128 | case 'R': | 134 | case 'R': |
129 | reservenum = strtol(optarg, NULL, 0); | 135 | reservenum = strtol(optarg, NULL, 0); |
130 | break; | 136 | break; |
@@ -188,6 +194,14 @@ int main(int argc, char *argv[]) | |||
188 | fprintf(stderr, "DTC: %s->%s on file \"%s\"\n", | 194 | fprintf(stderr, "DTC: %s->%s on file \"%s\"\n", |
189 | inform, outform, arg); | 195 | inform, outform, arg); |
190 | 196 | ||
197 | if (depname) { | ||
198 | depfile = fopen(depname, "w"); | ||
199 | if (!depfile) | ||
200 | die("Couldn't open dependency file %s: %s\n", depname, | ||
201 | strerror(errno)); | ||
202 | fprintf(depfile, "%s:", outname); | ||
203 | } | ||
204 | |||
191 | if (streq(inform, "dts")) | 205 | if (streq(inform, "dts")) |
192 | bi = dt_from_source(arg); | 206 | bi = dt_from_source(arg); |
193 | else if (streq(inform, "fs")) | 207 | else if (streq(inform, "fs")) |
@@ -197,6 +211,11 @@ int main(int argc, char *argv[]) | |||
197 | else | 211 | else |
198 | die("Unknown input format \"%s\"\n", inform); | 212 | die("Unknown input format \"%s\"\n", inform); |
199 | 213 | ||
214 | if (depfile) { | ||
215 | fputc('\n', depfile); | ||
216 | fclose(depfile); | ||
217 | } | ||
218 | |||
200 | if (cmdline_boot_cpuid != -1) | 219 | if (cmdline_boot_cpuid != -1) |
201 | bi->boot_cpuid_phys = cmdline_boot_cpuid; | 220 | bi->boot_cpuid_phys = cmdline_boot_cpuid; |
202 | 221 | ||
diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c index 2dbc874288ca..36a38e9f1a2c 100644 --- a/scripts/dtc/srcpos.c +++ b/scripts/dtc/srcpos.c | |||
@@ -40,6 +40,7 @@ static char *dirname(const char *path) | |||
40 | return NULL; | 40 | return NULL; |
41 | } | 41 | } |
42 | 42 | ||
43 | FILE *depfile; /* = NULL */ | ||
43 | struct srcfile_state *current_srcfile; /* = NULL */ | 44 | struct srcfile_state *current_srcfile; /* = NULL */ |
44 | 45 | ||
45 | /* Detect infinite include recursion. */ | 46 | /* Detect infinite include recursion. */ |
@@ -67,6 +68,9 @@ FILE *srcfile_relative_open(const char *fname, char **fullnamep) | |||
67 | strerror(errno)); | 68 | strerror(errno)); |
68 | } | 69 | } |
69 | 70 | ||
71 | if (depfile) | ||
72 | fprintf(depfile, " %s", fullname); | ||
73 | |||
70 | if (fullnamep) | 74 | if (fullnamep) |
71 | *fullnamep = fullname; | 75 | *fullnamep = fullname; |
72 | else | 76 | else |
diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h index bd7966e56a53..ce980cafe588 100644 --- a/scripts/dtc/srcpos.h +++ b/scripts/dtc/srcpos.h | |||
@@ -30,6 +30,7 @@ struct srcfile_state { | |||
30 | struct srcfile_state *prev; | 30 | struct srcfile_state *prev; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | extern FILE *depfile; /* = NULL */ | ||
33 | extern struct srcfile_state *current_srcfile; /* = NULL */ | 34 | extern struct srcfile_state *current_srcfile; /* = NULL */ |
34 | 35 | ||
35 | FILE *srcfile_relative_open(const char *fname, char **fullnamep); | 36 | FILE *srcfile_relative_open(const char *fname, char **fullnamep); |
diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile index a5510903e874..aca33b98bf63 100644 --- a/scripts/genksyms/Makefile +++ b/scripts/genksyms/Makefile | |||
@@ -11,3 +11,4 @@ HOSTCFLAGS_lex.lex.o := -I$(src) | |||
11 | # dependencies on generated files need to be listed explicitly | 11 | # dependencies on generated files need to be listed explicitly |
12 | $(obj)/lex.lex.o: $(obj)/keywords.hash.c $(obj)/parse.tab.h | 12 | $(obj)/lex.lex.o: $(obj)/keywords.hash.c $(obj)/parse.tab.h |
13 | 13 | ||
14 | clean-files := keywords.hash.c lex.lex.c parse.tab.c parse.tab.h | ||
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 4594f3341051..f32a04c4c5bc 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl | |||
@@ -95,7 +95,7 @@ my %VCS_cmds_git = ( | |||
95 | "execute_cmd" => \&git_execute_cmd, | 95 | "execute_cmd" => \&git_execute_cmd, |
96 | "available" => '(which("git") ne "") && (-d ".git")', | 96 | "available" => '(which("git") ne "") && (-d ".git")', |
97 | "find_signers_cmd" => | 97 | "find_signers_cmd" => |
98 | "git log --no-color --since=\$email_git_since " . | 98 | "git log --no-color --follow --since=\$email_git_since " . |
99 | '--format="GitCommit: %H%n' . | 99 | '--format="GitCommit: %H%n' . |
100 | 'GitAuthor: %an <%ae>%n' . | 100 | 'GitAuthor: %an <%ae>%n' . |
101 | 'GitDate: %aD%n' . | 101 | 'GitDate: %aD%n' . |
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 914833d99b06..79662658fb91 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile | |||
@@ -50,9 +50,8 @@ localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf | |||
50 | 50 | ||
51 | # Create new linux.pot file | 51 | # Create new linux.pot file |
52 | # Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files | 52 | # Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files |
53 | # The symlink is used to repair a deficiency in arch/um | ||
54 | update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h | 53 | update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h |
55 | $(Q)echo " GEN config" | 54 | $(Q)echo " GEN config.pot" |
56 | $(Q)xgettext --default-domain=linux \ | 55 | $(Q)xgettext --default-domain=linux \ |
57 | --add-comments --keyword=_ --keyword=N_ \ | 56 | --add-comments --keyword=_ --keyword=N_ \ |
58 | --from-code=UTF-8 \ | 57 | --from-code=UTF-8 \ |
@@ -63,10 +62,11 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h | |||
63 | $(Q)(for i in `ls $(srctree)/arch/*/Kconfig \ | 62 | $(Q)(for i in `ls $(srctree)/arch/*/Kconfig \ |
64 | $(srctree)/arch/*/um/Kconfig`; \ | 63 | $(srctree)/arch/*/um/Kconfig`; \ |
65 | do \ | 64 | do \ |
66 | echo " GEN $$i"; \ | 65 | echo " GEN $$i"; \ |
67 | $(obj)/kxgettext $$i \ | 66 | $(obj)/kxgettext $$i \ |
68 | >> $(obj)/config.pot; \ | 67 | >> $(obj)/config.pot; \ |
69 | done ) | 68 | done ) |
69 | $(Q)echo " GEN linux.pot" | ||
70 | $(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \ | 70 | $(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \ |
71 | --output $(obj)/linux.pot | 71 | --output $(obj)/linux.pot |
72 | $(Q)rm -f $(obj)/config.pot | 72 | $(Q)rm -f $(obj)/config.pot |
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 5a58965d8800..7c7a5a6cc3f5 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
@@ -464,7 +464,7 @@ kconfig_print_comment(FILE *fp, const char *value, void *arg) | |||
464 | fprintf(fp, "#"); | 464 | fprintf(fp, "#"); |
465 | if (l) { | 465 | if (l) { |
466 | fprintf(fp, " "); | 466 | fprintf(fp, " "); |
467 | fwrite(p, l, 1, fp); | 467 | xfwrite(p, l, 1, fp); |
468 | p += l; | 468 | p += l; |
469 | } | 469 | } |
470 | fprintf(fp, "\n"); | 470 | fprintf(fp, "\n"); |
@@ -537,7 +537,7 @@ header_print_comment(FILE *fp, const char *value, void *arg) | |||
537 | fprintf(fp, " *"); | 537 | fprintf(fp, " *"); |
538 | if (l) { | 538 | if (l) { |
539 | fprintf(fp, " "); | 539 | fprintf(fp, " "); |
540 | fwrite(p, l, 1, fp); | 540 | xfwrite(p, l, 1, fp); |
541 | p += l; | 541 | p += l; |
542 | } | 542 | } |
543 | fprintf(fp, "\n"); | 543 | fprintf(fp, "\n"); |
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 80fce57080cc..d4ecce8bc3a6 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h | |||
@@ -10,6 +10,7 @@ | |||
10 | extern "C" { | 10 | extern "C" { |
11 | #endif | 11 | #endif |
12 | 12 | ||
13 | #include <assert.h> | ||
13 | #include <stdio.h> | 14 | #include <stdio.h> |
14 | #ifndef __cplusplus | 15 | #ifndef __cplusplus |
15 | #include <stdbool.h> | 16 | #include <stdbool.h> |
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 9f4438027df4..adc230638c5b 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c | |||
@@ -683,7 +683,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) | |||
683 | dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), | 683 | dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), |
684 | GTK_DIALOG_DESTROY_WITH_PARENT, | 684 | GTK_DIALOG_DESTROY_WITH_PARENT, |
685 | GTK_MESSAGE_INFO, | 685 | GTK_MESSAGE_INFO, |
686 | GTK_BUTTONS_CLOSE, intro_text); | 686 | GTK_BUTTONS_CLOSE, "%s", intro_text); |
687 | g_signal_connect_swapped(GTK_OBJECT(dialog), "response", | 687 | g_signal_connect_swapped(GTK_OBJECT(dialog), "response", |
688 | G_CALLBACK(gtk_widget_destroy), | 688 | G_CALLBACK(gtk_widget_destroy), |
689 | GTK_OBJECT(dialog)); | 689 | GTK_OBJECT(dialog)); |
@@ -701,7 +701,7 @@ void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data) | |||
701 | dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), | 701 | dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), |
702 | GTK_DIALOG_DESTROY_WITH_PARENT, | 702 | GTK_DIALOG_DESTROY_WITH_PARENT, |
703 | GTK_MESSAGE_INFO, | 703 | GTK_MESSAGE_INFO, |
704 | GTK_BUTTONS_CLOSE, about_text); | 704 | GTK_BUTTONS_CLOSE, "%s", about_text); |
705 | g_signal_connect_swapped(GTK_OBJECT(dialog), "response", | 705 | g_signal_connect_swapped(GTK_OBJECT(dialog), "response", |
706 | G_CALLBACK(gtk_widget_destroy), | 706 | G_CALLBACK(gtk_widget_destroy), |
707 | GTK_OBJECT(dialog)); | 707 | GTK_OBJECT(dialog)); |
@@ -720,7 +720,7 @@ void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data) | |||
720 | dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), | 720 | dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), |
721 | GTK_DIALOG_DESTROY_WITH_PARENT, | 721 | GTK_DIALOG_DESTROY_WITH_PARENT, |
722 | GTK_MESSAGE_INFO, | 722 | GTK_MESSAGE_INFO, |
723 | GTK_BUTTONS_CLOSE, license_text); | 723 | GTK_BUTTONS_CLOSE, "%s", license_text); |
724 | g_signal_connect_swapped(GTK_OBJECT(dialog), "response", | 724 | g_signal_connect_swapped(GTK_OBJECT(dialog), "response", |
725 | G_CALLBACK(gtk_widget_destroy), | 725 | G_CALLBACK(gtk_widget_destroy), |
726 | GTK_OBJECT(dialog)); | 726 | GTK_OBJECT(dialog)); |
@@ -830,7 +830,7 @@ static void renderer_edited(GtkCellRendererText * cell, | |||
830 | static void change_sym_value(struct menu *menu, gint col) | 830 | static void change_sym_value(struct menu *menu, gint col) |
831 | { | 831 | { |
832 | struct symbol *sym = menu->sym; | 832 | struct symbol *sym = menu->sym; |
833 | tristate oldval, newval; | 833 | tristate newval; |
834 | 834 | ||
835 | if (!sym) | 835 | if (!sym) |
836 | return; | 836 | return; |
@@ -847,7 +847,6 @@ static void change_sym_value(struct menu *menu, gint col) | |||
847 | switch (sym_get_type(sym)) { | 847 | switch (sym_get_type(sym)) { |
848 | case S_BOOLEAN: | 848 | case S_BOOLEAN: |
849 | case S_TRISTATE: | 849 | case S_TRISTATE: |
850 | oldval = sym_get_tristate_value(sym); | ||
851 | if (!sym_tristate_within_range(sym, newval)) | 850 | if (!sym_tristate_within_range(sym, newval)) |
852 | newval = yes; | 851 | newval = yes; |
853 | sym_set_tristate_value(sym, newval); | 852 | sym_set_tristate_value(sym, newval); |
@@ -1278,7 +1277,6 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) | |||
1278 | gboolean valid; | 1277 | gboolean valid; |
1279 | GtkTreeIter *sibling; | 1278 | GtkTreeIter *sibling; |
1280 | struct symbol *sym; | 1279 | struct symbol *sym; |
1281 | struct property *prop; | ||
1282 | struct menu *menu1, *menu2; | 1280 | struct menu *menu1, *menu2; |
1283 | 1281 | ||
1284 | if (src == &rootmenu) | 1282 | if (src == &rootmenu) |
@@ -1287,7 +1285,6 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) | |||
1287 | valid = gtk_tree_model_iter_children(model2, child2, dst); | 1285 | valid = gtk_tree_model_iter_children(model2, child2, dst); |
1288 | for (child1 = src->list; child1; child1 = child1->next) { | 1286 | for (child1 = src->list; child1; child1 = child1->next) { |
1289 | 1287 | ||
1290 | prop = child1->prompt; | ||
1291 | sym = child1->sym; | 1288 | sym = child1->sym; |
1292 | 1289 | ||
1293 | reparse: | 1290 | reparse: |
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index b633bdb9f3d4..c18f2bd9c095 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h | |||
@@ -90,8 +90,10 @@ struct conf_printer { | |||
90 | /* confdata.c and expr.c */ | 90 | /* confdata.c and expr.c */ |
91 | static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) | 91 | static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) |
92 | { | 92 | { |
93 | if (fwrite(str, len, count, out) < count) | 93 | assert(len != 0); |
94 | fprintf(stderr, "\nError in writing or end of file.\n"); | 94 | |
95 | if (fwrite(str, len, count, out) != count) | ||
96 | fprintf(stderr, "Error in writing or end of file.\n"); | ||
95 | } | 97 | } |
96 | 98 | ||
97 | /* menu.c */ | 99 | /* menu.c */ |
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 19e200d91120..2c6286c0bc1a 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c | |||
@@ -830,6 +830,8 @@ static int handle_exit(void) | |||
830 | fprintf(stderr, _("\n\n" | 830 | fprintf(stderr, _("\n\n" |
831 | "Your configuration changes were NOT saved." | 831 | "Your configuration changes were NOT saved." |
832 | "\n\n")); | 832 | "\n\n")); |
833 | if (res != KEY_ESC) | ||
834 | res = 0; | ||
833 | } | 835 | } |
834 | 836 | ||
835 | return res; | 837 | return res; |
diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh new file mode 100644 index 000000000000..ceadf0e150cf --- /dev/null +++ b/scripts/kconfig/merge_config.sh | |||
@@ -0,0 +1,117 @@ | |||
1 | #!/bin/sh | ||
2 | # merge_config.sh - Takes a list of config fragment values, and merges | ||
3 | # them one by one. Provides warnings on overridden values, and specified | ||
4 | # values that did not make it to the resulting .config file (due to missed | ||
5 | # dependencies or config symbol removal). | ||
6 | # | ||
7 | # Portions reused from kconf_check and generate_cfg: | ||
8 | # http://git.yoctoproject.org/cgit/cgit.cgi/yocto-kernel-tools/tree/tools/kconf_check | ||
9 | # http://git.yoctoproject.org/cgit/cgit.cgi/yocto-kernel-tools/tree/tools/generate_cfg | ||
10 | # | ||
11 | # Copyright (c) 2009-2010 Wind River Systems, Inc. | ||
12 | # Copyright 2011 Linaro | ||
13 | # | ||
14 | # This program is free software; you can redistribute it and/or modify | ||
15 | # it under the terms of the GNU General Public License version 2 as | ||
16 | # published by the Free Software Foundation. | ||
17 | # | ||
18 | # This program is distributed in the hope that it will be useful, | ||
19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
21 | # See the GNU General Public License for more details. | ||
22 | |||
23 | clean_up() { | ||
24 | rm -f $TMP_FILE | ||
25 | exit | ||
26 | } | ||
27 | trap clean_up HUP INT TERM | ||
28 | |||
29 | usage() { | ||
30 | echo "Usage: $0 [OPTIONS] [CONFIG [...]]" | ||
31 | echo " -h display this help text" | ||
32 | echo " -m only merge the fragments, do not execute the make command" | ||
33 | echo " -n use allnoconfig instead of alldefconfig" | ||
34 | } | ||
35 | |||
36 | MAKE=true | ||
37 | ALLTARGET=alldefconfig | ||
38 | |||
39 | while true; do | ||
40 | case $1 in | ||
41 | "-n") | ||
42 | ALLTARGET=allnoconfig | ||
43 | shift | ||
44 | continue | ||
45 | ;; | ||
46 | "-m") | ||
47 | MAKE=false | ||
48 | shift | ||
49 | continue | ||
50 | ;; | ||
51 | "-h") | ||
52 | usage | ||
53 | exit | ||
54 | ;; | ||
55 | *) | ||
56 | break | ||
57 | ;; | ||
58 | esac | ||
59 | done | ||
60 | |||
61 | |||
62 | |||
63 | MERGE_LIST=$* | ||
64 | SED_CONFIG_EXP="s/^\(# \)\{0,1\}\(CONFIG_[a-zA-Z0-9_]*\)[= ].*/\2/p" | ||
65 | TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) | ||
66 | |||
67 | # Merge files, printing warnings on overrided values | ||
68 | for MERGE_FILE in $MERGE_LIST ; do | ||
69 | echo "Merging $MERGE_FILE" | ||
70 | CFG_LIST=$(sed -n "$SED_CONFIG_EXP" $MERGE_FILE) | ||
71 | |||
72 | for CFG in $CFG_LIST ; do | ||
73 | grep -q -w $CFG $TMP_FILE | ||
74 | if [ $? -eq 0 ] ; then | ||
75 | PREV_VAL=$(grep -w $CFG $TMP_FILE) | ||
76 | NEW_VAL=$(grep -w $CFG $MERGE_FILE) | ||
77 | if [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then | ||
78 | echo Value of $CFG is redefined by fragment $MERGE_FILE: | ||
79 | echo Previous value: $PREV_VAL | ||
80 | echo New value: $NEW_VAL | ||
81 | echo | ||
82 | fi | ||
83 | sed -i "/$CFG[ =]/d" $TMP_FILE | ||
84 | fi | ||
85 | done | ||
86 | cat $MERGE_FILE >> $TMP_FILE | ||
87 | done | ||
88 | |||
89 | if [ "$MAKE" = "false" ]; then | ||
90 | cp $TMP_FILE .config | ||
91 | echo "#" | ||
92 | echo "# merged configuration written to .config (needs make)" | ||
93 | echo "#" | ||
94 | clean_up | ||
95 | exit | ||
96 | fi | ||
97 | |||
98 | # Use the merged file as the starting point for: | ||
99 | # alldefconfig: Fills in any missing symbols with Kconfig default | ||
100 | # allnoconfig: Fills in any missing symbols with # CONFIG_* is not set | ||
101 | make KCONFIG_ALLCONFIG=$TMP_FILE $ALLTARGET | ||
102 | |||
103 | |||
104 | # Check all specified config values took (might have missed-dependency issues) | ||
105 | for CFG in $(sed -n "$SED_CONFIG_EXP" $TMP_FILE); do | ||
106 | |||
107 | REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE) | ||
108 | ACTUAL_VAL=$(grep -w -e "$CFG" .config) | ||
109 | if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then | ||
110 | echo "Value requested for $CFG not in final .config" | ||
111 | echo "Requested value: $REQUESTED_VAL" | ||
112 | echo "Actual value: $ACTUAL_VAL" | ||
113 | echo "" | ||
114 | fi | ||
115 | done | ||
116 | |||
117 | clean_up | ||
diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index ec7afce4c88d..bccf07ddd0b6 100644 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl | |||
@@ -250,33 +250,61 @@ if ($kconfig) { | |||
250 | read_kconfig($kconfig); | 250 | read_kconfig($kconfig); |
251 | } | 251 | } |
252 | 252 | ||
253 | sub convert_vars { | ||
254 | my ($line, %vars) = @_; | ||
255 | |||
256 | my $process = ""; | ||
257 | |||
258 | while ($line =~ s/^(.*?)(\$\((.*?)\))//) { | ||
259 | my $start = $1; | ||
260 | my $variable = $2; | ||
261 | my $var = $3; | ||
262 | |||
263 | if (defined($vars{$var})) { | ||
264 | $process .= $start . $vars{$var}; | ||
265 | } else { | ||
266 | $process .= $start . $variable; | ||
267 | } | ||
268 | } | ||
269 | |||
270 | $process .= $line; | ||
271 | |||
272 | return $process; | ||
273 | } | ||
274 | |||
253 | # Read all Makefiles to map the configs to the objects | 275 | # Read all Makefiles to map the configs to the objects |
254 | foreach my $makefile (@makefiles) { | 276 | foreach my $makefile (@makefiles) { |
255 | 277 | ||
256 | my $cont = 0; | 278 | my $line = ""; |
279 | my %make_vars; | ||
257 | 280 | ||
258 | open(MIN,$makefile) || die "Can't open $makefile"; | 281 | open(MIN,$makefile) || die "Can't open $makefile"; |
259 | while (<MIN>) { | 282 | while (<MIN>) { |
283 | # if this line ends with a backslash, continue | ||
284 | chomp; | ||
285 | if (/^(.*)\\$/) { | ||
286 | $line .= $1; | ||
287 | next; | ||
288 | } | ||
289 | |||
290 | $line .= $_; | ||
291 | $_ = $line; | ||
292 | $line = ""; | ||
293 | |||
260 | my $objs; | 294 | my $objs; |
261 | 295 | ||
262 | # is this a line after a line with a backslash? | 296 | $_ = convert_vars($_, %make_vars); |
263 | if ($cont && /(\S.*)$/) { | ||
264 | $objs = $1; | ||
265 | } | ||
266 | $cont = 0; | ||
267 | 297 | ||
268 | # collect objects after obj-$(CONFIG_FOO_BAR) | 298 | # collect objects after obj-$(CONFIG_FOO_BAR) |
269 | if (/obj-\$\((CONFIG_[^\)]*)\)\s*[+:]?=\s*(.*)/) { | 299 | if (/obj-\$\((CONFIG_[^\)]*)\)\s*[+:]?=\s*(.*)/) { |
270 | $var = $1; | 300 | $var = $1; |
271 | $objs = $2; | 301 | $objs = $2; |
302 | |||
303 | # check if variables are set | ||
304 | } elsif (/^\s*(\S+)\s*[:]?=\s*(.*\S)/) { | ||
305 | $make_vars{$1} = $2; | ||
272 | } | 306 | } |
273 | if (defined($objs)) { | 307 | if (defined($objs)) { |
274 | # test if the line ends with a backslash | ||
275 | if ($objs =~ m,(.*)\\$,) { | ||
276 | $objs = $1; | ||
277 | $cont = 1; | ||
278 | } | ||
279 | |||
280 | foreach my $obj (split /\s+/,$objs) { | 308 | foreach my $obj (split /\s+/,$objs) { |
281 | $obj =~ s/-/_/g; | 309 | $obj =~ s/-/_/g; |
282 | if ($obj =~ /(.*)\.o$/) { | 310 | if ($obj =~ /(.*)\.o$/) { |
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index f936d1fa969d..c0e14b3f2306 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
@@ -28,6 +28,7 @@ typedef Elf64_Addr kernel_ulong_t; | |||
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | #include <ctype.h> | 30 | #include <ctype.h> |
31 | #include <stdbool.h> | ||
31 | 32 | ||
32 | typedef uint32_t __u32; | 33 | typedef uint32_t __u32; |
33 | typedef uint16_t __u16; | 34 | typedef uint16_t __u16; |
@@ -38,6 +39,35 @@ typedef unsigned char __u8; | |||
38 | * we handle those differences explicitly below */ | 39 | * we handle those differences explicitly below */ |
39 | #include "../../include/linux/mod_devicetable.h" | 40 | #include "../../include/linux/mod_devicetable.h" |
40 | 41 | ||
42 | /* This array collects all instances that use the generic do_table */ | ||
43 | struct devtable { | ||
44 | const char *device_id; /* name of table, __mod_<name>_device_table. */ | ||
45 | unsigned long id_size; | ||
46 | void *function; | ||
47 | }; | ||
48 | |||
49 | /* We construct a table of pointers in an ELF section (pointers generally | ||
50 | * go unpadded by gcc). ld creates boundary syms for us. */ | ||
51 | extern struct devtable *__start___devtable[], *__stop___devtable[]; | ||
52 | #define ___cat(a,b) a ## b | ||
53 | #define __cat(a,b) ___cat(a,b) | ||
54 | |||
55 | #if __GNUC__ == 3 && __GNUC_MINOR__ < 3 | ||
56 | # define __used __attribute__((__unused__)) | ||
57 | #else | ||
58 | # define __used __attribute__((__used__)) | ||
59 | #endif | ||
60 | |||
61 | /* Add a table entry. We test function type matches while we're here. */ | ||
62 | #define ADD_TO_DEVTABLE(device_id, type, function) \ | ||
63 | static struct devtable __cat(devtable,__LINE__) = { \ | ||
64 | device_id + 0*sizeof((function)((const char *)NULL, \ | ||
65 | (type *)NULL, \ | ||
66 | (char *)NULL)), \ | ||
67 | sizeof(type), (function) }; \ | ||
68 | static struct devtable *__attribute__((section("__devtable"))) \ | ||
69 | __used __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__) | ||
70 | |||
41 | #define ADD(str, sep, cond, field) \ | 71 | #define ADD(str, sep, cond, field) \ |
42 | do { \ | 72 | do { \ |
43 | strcat(str, sep); \ | 73 | strcat(str, sep); \ |
@@ -289,6 +319,7 @@ static int do_hid_entry(const char *filename, | |||
289 | 319 | ||
290 | return 1; | 320 | return 1; |
291 | } | 321 | } |
322 | ADD_TO_DEVTABLE("hid", struct hid_device_id, do_hid_entry); | ||
292 | 323 | ||
293 | /* Looks like: ieee1394:venNmoNspNverN */ | 324 | /* Looks like: ieee1394:venNmoNspNverN */ |
294 | static int do_ieee1394_entry(const char *filename, | 325 | static int do_ieee1394_entry(const char *filename, |
@@ -313,6 +344,7 @@ static int do_ieee1394_entry(const char *filename, | |||
313 | add_wildcard(alias); | 344 | add_wildcard(alias); |
314 | return 1; | 345 | return 1; |
315 | } | 346 | } |
347 | ADD_TO_DEVTABLE("ieee1394", struct ieee1394_device_id, do_ieee1394_entry); | ||
316 | 348 | ||
317 | /* Looks like: pci:vNdNsvNsdNbcNscNiN. */ | 349 | /* Looks like: pci:vNdNsvNsdNbcNscNiN. */ |
318 | static int do_pci_entry(const char *filename, | 350 | static int do_pci_entry(const char *filename, |
@@ -356,6 +388,7 @@ static int do_pci_entry(const char *filename, | |||
356 | add_wildcard(alias); | 388 | add_wildcard(alias); |
357 | return 1; | 389 | return 1; |
358 | } | 390 | } |
391 | ADD_TO_DEVTABLE("pci", struct pci_device_id, do_pci_entry); | ||
359 | 392 | ||
360 | /* looks like: "ccw:tNmNdtNdmN" */ | 393 | /* looks like: "ccw:tNmNdtNdmN" */ |
361 | static int do_ccw_entry(const char *filename, | 394 | static int do_ccw_entry(const char *filename, |
@@ -379,6 +412,7 @@ static int do_ccw_entry(const char *filename, | |||
379 | add_wildcard(alias); | 412 | add_wildcard(alias); |
380 | return 1; | 413 | return 1; |
381 | } | 414 | } |
415 | ADD_TO_DEVTABLE("ccw", struct ccw_device_id, do_ccw_entry); | ||
382 | 416 | ||
383 | /* looks like: "ap:tN" */ | 417 | /* looks like: "ap:tN" */ |
384 | static int do_ap_entry(const char *filename, | 418 | static int do_ap_entry(const char *filename, |
@@ -387,6 +421,7 @@ static int do_ap_entry(const char *filename, | |||
387 | sprintf(alias, "ap:t%02X*", id->dev_type); | 421 | sprintf(alias, "ap:t%02X*", id->dev_type); |
388 | return 1; | 422 | return 1; |
389 | } | 423 | } |
424 | ADD_TO_DEVTABLE("ap", struct ap_device_id, do_ap_entry); | ||
390 | 425 | ||
391 | /* looks like: "css:tN" */ | 426 | /* looks like: "css:tN" */ |
392 | static int do_css_entry(const char *filename, | 427 | static int do_css_entry(const char *filename, |
@@ -395,6 +430,7 @@ static int do_css_entry(const char *filename, | |||
395 | sprintf(alias, "css:t%01X", id->type); | 430 | sprintf(alias, "css:t%01X", id->type); |
396 | return 1; | 431 | return 1; |
397 | } | 432 | } |
433 | ADD_TO_DEVTABLE("css", struct css_device_id, do_css_entry); | ||
398 | 434 | ||
399 | /* Looks like: "serio:tyNprNidNexN" */ | 435 | /* Looks like: "serio:tyNprNidNexN" */ |
400 | static int do_serio_entry(const char *filename, | 436 | static int do_serio_entry(const char *filename, |
@@ -414,6 +450,7 @@ static int do_serio_entry(const char *filename, | |||
414 | add_wildcard(alias); | 450 | add_wildcard(alias); |
415 | return 1; | 451 | return 1; |
416 | } | 452 | } |
453 | ADD_TO_DEVTABLE("serio", struct serio_device_id, do_serio_entry); | ||
417 | 454 | ||
418 | /* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */ | 455 | /* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */ |
419 | static int do_acpi_entry(const char *filename, | 456 | static int do_acpi_entry(const char *filename, |
@@ -422,6 +459,7 @@ static int do_acpi_entry(const char *filename, | |||
422 | sprintf(alias, "acpi*:%s:*", id->id); | 459 | sprintf(alias, "acpi*:%s:*", id->id); |
423 | return 1; | 460 | return 1; |
424 | } | 461 | } |
462 | ADD_TO_DEVTABLE("acpi", struct acpi_device_id, do_acpi_entry); | ||
425 | 463 | ||
426 | /* looks like: "pnp:dD" */ | 464 | /* looks like: "pnp:dD" */ |
427 | static void do_pnp_device_entry(void *symval, unsigned long size, | 465 | static void do_pnp_device_entry(void *symval, unsigned long size, |
@@ -544,8 +582,7 @@ static int do_pcmcia_entry(const char *filename, | |||
544 | add_wildcard(alias); | 582 | add_wildcard(alias); |
545 | return 1; | 583 | return 1; |
546 | } | 584 | } |
547 | 585 | ADD_TO_DEVTABLE("pcmcia", struct pcmcia_device_id, do_pcmcia_entry); | |
548 | |||
549 | 586 | ||
550 | static int do_of_entry (const char *filename, struct of_device_id *of, char *alias) | 587 | static int do_of_entry (const char *filename, struct of_device_id *of, char *alias) |
551 | { | 588 | { |
@@ -568,6 +605,7 @@ static int do_of_entry (const char *filename, struct of_device_id *of, char *ali | |||
568 | add_wildcard(alias); | 605 | add_wildcard(alias); |
569 | return 1; | 606 | return 1; |
570 | } | 607 | } |
608 | ADD_TO_DEVTABLE("of", struct of_device_id, do_of_entry); | ||
571 | 609 | ||
572 | static int do_vio_entry(const char *filename, struct vio_device_id *vio, | 610 | static int do_vio_entry(const char *filename, struct vio_device_id *vio, |
573 | char *alias) | 611 | char *alias) |
@@ -585,6 +623,7 @@ static int do_vio_entry(const char *filename, struct vio_device_id *vio, | |||
585 | add_wildcard(alias); | 623 | add_wildcard(alias); |
586 | return 1; | 624 | return 1; |
587 | } | 625 | } |
626 | ADD_TO_DEVTABLE("vio", struct vio_device_id, do_vio_entry); | ||
588 | 627 | ||
589 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | 628 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) |
590 | 629 | ||
@@ -640,6 +679,7 @@ static int do_input_entry(const char *filename, struct input_device_id *id, | |||
640 | do_input(alias, id->swbit, 0, INPUT_DEVICE_ID_SW_MAX); | 679 | do_input(alias, id->swbit, 0, INPUT_DEVICE_ID_SW_MAX); |
641 | return 1; | 680 | return 1; |
642 | } | 681 | } |
682 | ADD_TO_DEVTABLE("input", struct input_device_id, do_input_entry); | ||
643 | 683 | ||
644 | static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa, | 684 | static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa, |
645 | char *alias) | 685 | char *alias) |
@@ -650,6 +690,7 @@ static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa, | |||
650 | strcat(alias, "*"); | 690 | strcat(alias, "*"); |
651 | return 1; | 691 | return 1; |
652 | } | 692 | } |
693 | ADD_TO_DEVTABLE("eisa", struct eisa_device_id, do_eisa_entry); | ||
653 | 694 | ||
654 | /* Looks like: parisc:tNhvNrevNsvN */ | 695 | /* Looks like: parisc:tNhvNrevNsvN */ |
655 | static int do_parisc_entry(const char *filename, struct parisc_device_id *id, | 696 | static int do_parisc_entry(const char *filename, struct parisc_device_id *id, |
@@ -669,6 +710,7 @@ static int do_parisc_entry(const char *filename, struct parisc_device_id *id, | |||
669 | add_wildcard(alias); | 710 | add_wildcard(alias); |
670 | return 1; | 711 | return 1; |
671 | } | 712 | } |
713 | ADD_TO_DEVTABLE("parisc", struct parisc_device_id, do_parisc_entry); | ||
672 | 714 | ||
673 | /* Looks like: sdio:cNvNdN. */ | 715 | /* Looks like: sdio:cNvNdN. */ |
674 | static int do_sdio_entry(const char *filename, | 716 | static int do_sdio_entry(const char *filename, |
@@ -685,6 +727,7 @@ static int do_sdio_entry(const char *filename, | |||
685 | add_wildcard(alias); | 727 | add_wildcard(alias); |
686 | return 1; | 728 | return 1; |
687 | } | 729 | } |
730 | ADD_TO_DEVTABLE("sdio", struct sdio_device_id, do_sdio_entry); | ||
688 | 731 | ||
689 | /* Looks like: ssb:vNidNrevN. */ | 732 | /* Looks like: ssb:vNidNrevN. */ |
690 | static int do_ssb_entry(const char *filename, | 733 | static int do_ssb_entry(const char *filename, |
@@ -701,6 +744,7 @@ static int do_ssb_entry(const char *filename, | |||
701 | add_wildcard(alias); | 744 | add_wildcard(alias); |
702 | return 1; | 745 | return 1; |
703 | } | 746 | } |
747 | ADD_TO_DEVTABLE("ssb", struct ssb_device_id, do_ssb_entry); | ||
704 | 748 | ||
705 | /* Looks like: bcma:mNidNrevNclN. */ | 749 | /* Looks like: bcma:mNidNrevNclN. */ |
706 | static int do_bcma_entry(const char *filename, | 750 | static int do_bcma_entry(const char *filename, |
@@ -719,6 +763,7 @@ static int do_bcma_entry(const char *filename, | |||
719 | add_wildcard(alias); | 763 | add_wildcard(alias); |
720 | return 1; | 764 | return 1; |
721 | } | 765 | } |
766 | ADD_TO_DEVTABLE("bcma", struct bcma_device_id, do_bcma_entry); | ||
722 | 767 | ||
723 | /* Looks like: virtio:dNvN */ | 768 | /* Looks like: virtio:dNvN */ |
724 | static int do_virtio_entry(const char *filename, struct virtio_device_id *id, | 769 | static int do_virtio_entry(const char *filename, struct virtio_device_id *id, |
@@ -734,6 +779,7 @@ static int do_virtio_entry(const char *filename, struct virtio_device_id *id, | |||
734 | add_wildcard(alias); | 779 | add_wildcard(alias); |
735 | return 1; | 780 | return 1; |
736 | } | 781 | } |
782 | ADD_TO_DEVTABLE("virtio", struct virtio_device_id, do_virtio_entry); | ||
737 | 783 | ||
738 | /* | 784 | /* |
739 | * Looks like: vmbus:guid | 785 | * Looks like: vmbus:guid |
@@ -755,6 +801,7 @@ static int do_vmbus_entry(const char *filename, struct hv_vmbus_device_id *id, | |||
755 | 801 | ||
756 | return 1; | 802 | return 1; |
757 | } | 803 | } |
804 | ADD_TO_DEVTABLE("vmbus", struct hv_vmbus_device_id, do_vmbus_entry); | ||
758 | 805 | ||
759 | /* Looks like: i2c:S */ | 806 | /* Looks like: i2c:S */ |
760 | static int do_i2c_entry(const char *filename, struct i2c_device_id *id, | 807 | static int do_i2c_entry(const char *filename, struct i2c_device_id *id, |
@@ -764,6 +811,7 @@ static int do_i2c_entry(const char *filename, struct i2c_device_id *id, | |||
764 | 811 | ||
765 | return 1; | 812 | return 1; |
766 | } | 813 | } |
814 | ADD_TO_DEVTABLE("i2c", struct i2c_device_id, do_i2c_entry); | ||
767 | 815 | ||
768 | /* Looks like: spi:S */ | 816 | /* Looks like: spi:S */ |
769 | static int do_spi_entry(const char *filename, struct spi_device_id *id, | 817 | static int do_spi_entry(const char *filename, struct spi_device_id *id, |
@@ -773,6 +821,17 @@ static int do_spi_entry(const char *filename, struct spi_device_id *id, | |||
773 | 821 | ||
774 | return 1; | 822 | return 1; |
775 | } | 823 | } |
824 | ADD_TO_DEVTABLE("spi", struct spi_device_id, do_spi_entry); | ||
825 | |||
826 | /* Looks like: mcp:S */ | ||
827 | static int do_mcp_entry(const char *filename, struct mcp_device_id *id, | ||
828 | char *alias) | ||
829 | { | ||
830 | sprintf(alias, MCP_MODULE_PREFIX "%s", id->name); | ||
831 | |||
832 | return 1; | ||
833 | } | ||
834 | ADD_TO_DEVTABLE("mcp", struct mcp_device_id, do_mcp_entry); | ||
776 | 835 | ||
777 | static const struct dmifield { | 836 | static const struct dmifield { |
778 | const char *prefix; | 837 | const char *prefix; |
@@ -827,6 +886,7 @@ static int do_dmi_entry(const char *filename, struct dmi_system_id *id, | |||
827 | strcat(alias, ":"); | 886 | strcat(alias, ":"); |
828 | return 1; | 887 | return 1; |
829 | } | 888 | } |
889 | ADD_TO_DEVTABLE("dmi", struct dmi_system_id, do_dmi_entry); | ||
830 | 890 | ||
831 | static int do_platform_entry(const char *filename, | 891 | static int do_platform_entry(const char *filename, |
832 | struct platform_device_id *id, char *alias) | 892 | struct platform_device_id *id, char *alias) |
@@ -834,6 +894,7 @@ static int do_platform_entry(const char *filename, | |||
834 | sprintf(alias, PLATFORM_MODULE_PREFIX "%s", id->name); | 894 | sprintf(alias, PLATFORM_MODULE_PREFIX "%s", id->name); |
835 | return 1; | 895 | return 1; |
836 | } | 896 | } |
897 | ADD_TO_DEVTABLE("platform", struct platform_device_id, do_platform_entry); | ||
837 | 898 | ||
838 | static int do_mdio_entry(const char *filename, | 899 | static int do_mdio_entry(const char *filename, |
839 | struct mdio_device_id *id, char *alias) | 900 | struct mdio_device_id *id, char *alias) |
@@ -856,6 +917,7 @@ static int do_mdio_entry(const char *filename, | |||
856 | 917 | ||
857 | return 1; | 918 | return 1; |
858 | } | 919 | } |
920 | ADD_TO_DEVTABLE("mdio", struct mdio_device_id, do_mdio_entry); | ||
859 | 921 | ||
860 | /* Looks like: zorro:iN. */ | 922 | /* Looks like: zorro:iN. */ |
861 | static int do_zorro_entry(const char *filename, struct zorro_device_id *id, | 923 | static int do_zorro_entry(const char *filename, struct zorro_device_id *id, |
@@ -866,6 +928,7 @@ static int do_zorro_entry(const char *filename, struct zorro_device_id *id, | |||
866 | ADD(alias, "i", id->id != ZORRO_WILDCARD, id->id); | 928 | ADD(alias, "i", id->id != ZORRO_WILDCARD, id->id); |
867 | return 1; | 929 | return 1; |
868 | } | 930 | } |
931 | ADD_TO_DEVTABLE("zorro", struct zorro_device_id, do_zorro_entry); | ||
869 | 932 | ||
870 | /* looks like: "pnp:dD" */ | 933 | /* looks like: "pnp:dD" */ |
871 | static int do_isapnp_entry(const char *filename, | 934 | static int do_isapnp_entry(const char *filename, |
@@ -879,16 +942,84 @@ static int do_isapnp_entry(const char *filename, | |||
879 | (id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f); | 942 | (id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f); |
880 | return 1; | 943 | return 1; |
881 | } | 944 | } |
945 | ADD_TO_DEVTABLE("isa", struct isapnp_device_id, do_isapnp_entry); | ||
882 | 946 | ||
883 | /* Ignore any prefix, eg. some architectures prepend _ */ | 947 | /* |
884 | static inline int sym_is(const char *symbol, const char *name) | 948 | * Append a match expression for a single masked hex digit. |
949 | * outp points to a pointer to the character at which to append. | ||
950 | * *outp is updated on return to point just after the appended text, | ||
951 | * to facilitate further appending. | ||
952 | */ | ||
953 | static void append_nibble_mask(char **outp, | ||
954 | unsigned int nibble, unsigned int mask) | ||
885 | { | 955 | { |
886 | const char *match; | 956 | char *p = *outp; |
957 | unsigned int i; | ||
887 | 958 | ||
888 | match = strstr(symbol, name); | 959 | switch (mask) { |
889 | if (!match) | 960 | case 0: |
890 | return 0; | 961 | *p++ = '?'; |
891 | return match[strlen(name)] == '\0'; | 962 | break; |
963 | |||
964 | case 0xf: | ||
965 | p += sprintf(p, "%X", nibble); | ||
966 | break; | ||
967 | |||
968 | default: | ||
969 | /* | ||
970 | * Dumbly emit a match pattern for all possible matching | ||
971 | * digits. This could be improved in some cases using ranges, | ||
972 | * but it has the advantage of being trivially correct, and is | ||
973 | * often optimal. | ||
974 | */ | ||
975 | *p++ = '['; | ||
976 | for (i = 0; i < 0x10; i++) | ||
977 | if ((i & mask) == nibble) | ||
978 | p += sprintf(p, "%X", i); | ||
979 | *p++ = ']'; | ||
980 | } | ||
981 | |||
982 | /* Ensure that the string remains NUL-terminated: */ | ||
983 | *p = '\0'; | ||
984 | |||
985 | /* Advance the caller's end-of-string pointer: */ | ||
986 | *outp = p; | ||
987 | } | ||
988 | |||
989 | /* | ||
990 | * looks like: "amba:dN" | ||
991 | * | ||
992 | * N is exactly 8 digits, where each is an upper-case hex digit, or | ||
993 | * a ? or [] pattern matching exactly one digit. | ||
994 | */ | ||
995 | static int do_amba_entry(const char *filename, | ||
996 | struct amba_id *id, char *alias) | ||
997 | { | ||
998 | unsigned int digit; | ||
999 | char *p = alias; | ||
1000 | |||
1001 | if ((id->id & id->mask) != id->id) | ||
1002 | fatal("%s: Masked-off bit(s) of AMBA device ID are non-zero: " | ||
1003 | "id=0x%08X, mask=0x%08X. Please fix this driver.\n", | ||
1004 | filename, id->id, id->mask); | ||
1005 | |||
1006 | p += sprintf(alias, "amba:d"); | ||
1007 | for (digit = 0; digit < 8; digit++) | ||
1008 | append_nibble_mask(&p, | ||
1009 | (id->id >> (4 * (7 - digit))) & 0xf, | ||
1010 | (id->mask >> (4 * (7 - digit))) & 0xf); | ||
1011 | |||
1012 | return 1; | ||
1013 | } | ||
1014 | ADD_TO_DEVTABLE("amba", struct amba_id, do_amba_entry); | ||
1015 | |||
1016 | /* Does namelen bytes of name exactly match the symbol? */ | ||
1017 | static bool sym_is(const char *name, unsigned namelen, const char *symbol) | ||
1018 | { | ||
1019 | if (namelen != strlen(symbol)) | ||
1020 | return false; | ||
1021 | |||
1022 | return memcmp(name, symbol, namelen) == 0; | ||
892 | } | 1023 | } |
893 | 1024 | ||
894 | static void do_table(void *symval, unsigned long size, | 1025 | static void do_table(void *symval, unsigned long size, |
@@ -921,11 +1052,25 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, | |||
921 | { | 1052 | { |
922 | void *symval; | 1053 | void *symval; |
923 | char *zeros = NULL; | 1054 | char *zeros = NULL; |
1055 | const char *name; | ||
1056 | unsigned int namelen; | ||
924 | 1057 | ||
925 | /* We're looking for a section relative symbol */ | 1058 | /* We're looking for a section relative symbol */ |
926 | if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections) | 1059 | if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections) |
927 | return; | 1060 | return; |
928 | 1061 | ||
1062 | /* All our symbols are of form <prefix>__mod_XXX_device_table. */ | ||
1063 | name = strstr(symname, "__mod_"); | ||
1064 | if (!name) | ||
1065 | return; | ||
1066 | name += strlen("__mod_"); | ||
1067 | namelen = strlen(name); | ||
1068 | if (namelen < strlen("_device_table")) | ||
1069 | return; | ||
1070 | if (strcmp(name + namelen - strlen("_device_table"), "_device_table")) | ||
1071 | return; | ||
1072 | namelen -= strlen("_device_table"); | ||
1073 | |||
929 | /* Handle all-NULL symbols allocated into .bss */ | 1074 | /* Handle all-NULL symbols allocated into .bss */ |
930 | if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) { | 1075 | if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) { |
931 | zeros = calloc(1, sym->st_size); | 1076 | zeros = calloc(1, sym->st_size); |
@@ -936,117 +1081,24 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, | |||
936 | + sym->st_value; | 1081 | + sym->st_value; |
937 | } | 1082 | } |
938 | 1083 | ||
939 | if (sym_is(symname, "__mod_pci_device_table")) | 1084 | /* First handle the "special" cases */ |
940 | do_table(symval, sym->st_size, | 1085 | if (sym_is(name, namelen, "usb")) |
941 | sizeof(struct pci_device_id), "pci", | ||
942 | do_pci_entry, mod); | ||
943 | else if (sym_is(symname, "__mod_usb_device_table")) | ||
944 | /* special case to handle bcdDevice ranges */ | ||
945 | do_usb_table(symval, sym->st_size, mod); | 1086 | do_usb_table(symval, sym->st_size, mod); |
946 | else if (sym_is(symname, "__mod_hid_device_table")) | 1087 | else if (sym_is(name, namelen, "pnp")) |
947 | do_table(symval, sym->st_size, | ||
948 | sizeof(struct hid_device_id), "hid", | ||
949 | do_hid_entry, mod); | ||
950 | else if (sym_is(symname, "__mod_ieee1394_device_table")) | ||
951 | do_table(symval, sym->st_size, | ||
952 | sizeof(struct ieee1394_device_id), "ieee1394", | ||
953 | do_ieee1394_entry, mod); | ||
954 | else if (sym_is(symname, "__mod_ccw_device_table")) | ||
955 | do_table(symval, sym->st_size, | ||
956 | sizeof(struct ccw_device_id), "ccw", | ||
957 | do_ccw_entry, mod); | ||
958 | else if (sym_is(symname, "__mod_ap_device_table")) | ||
959 | do_table(symval, sym->st_size, | ||
960 | sizeof(struct ap_device_id), "ap", | ||
961 | do_ap_entry, mod); | ||
962 | else if (sym_is(symname, "__mod_css_device_table")) | ||
963 | do_table(symval, sym->st_size, | ||
964 | sizeof(struct css_device_id), "css", | ||
965 | do_css_entry, mod); | ||
966 | else if (sym_is(symname, "__mod_serio_device_table")) | ||
967 | do_table(symval, sym->st_size, | ||
968 | sizeof(struct serio_device_id), "serio", | ||
969 | do_serio_entry, mod); | ||
970 | else if (sym_is(symname, "__mod_acpi_device_table")) | ||
971 | do_table(symval, sym->st_size, | ||
972 | sizeof(struct acpi_device_id), "acpi", | ||
973 | do_acpi_entry, mod); | ||
974 | else if (sym_is(symname, "__mod_pnp_device_table")) | ||
975 | do_pnp_device_entry(symval, sym->st_size, mod); | 1088 | do_pnp_device_entry(symval, sym->st_size, mod); |
976 | else if (sym_is(symname, "__mod_pnp_card_device_table")) | 1089 | else if (sym_is(name, namelen, "pnp_card")) |
977 | do_pnp_card_entries(symval, sym->st_size, mod); | 1090 | do_pnp_card_entries(symval, sym->st_size, mod); |
978 | else if (sym_is(symname, "__mod_pcmcia_device_table")) | 1091 | else { |
979 | do_table(symval, sym->st_size, | 1092 | struct devtable **p; |
980 | sizeof(struct pcmcia_device_id), "pcmcia", | 1093 | |
981 | do_pcmcia_entry, mod); | 1094 | for (p = __start___devtable; p < __stop___devtable; p++) { |
982 | else if (sym_is(symname, "__mod_of_device_table")) | 1095 | if (sym_is(name, namelen, (*p)->device_id)) { |
983 | do_table(symval, sym->st_size, | 1096 | do_table(symval, sym->st_size, (*p)->id_size, |
984 | sizeof(struct of_device_id), "of", | 1097 | (*p)->device_id, (*p)->function, mod); |
985 | do_of_entry, mod); | 1098 | break; |
986 | else if (sym_is(symname, "__mod_vio_device_table")) | 1099 | } |
987 | do_table(symval, sym->st_size, | 1100 | } |
988 | sizeof(struct vio_device_id), "vio", | 1101 | } |
989 | do_vio_entry, mod); | ||
990 | else if (sym_is(symname, "__mod_input_device_table")) | ||
991 | do_table(symval, sym->st_size, | ||
992 | sizeof(struct input_device_id), "input", | ||
993 | do_input_entry, mod); | ||
994 | else if (sym_is(symname, "__mod_eisa_device_table")) | ||
995 | do_table(symval, sym->st_size, | ||
996 | sizeof(struct eisa_device_id), "eisa", | ||
997 | do_eisa_entry, mod); | ||
998 | else if (sym_is(symname, "__mod_parisc_device_table")) | ||
999 | do_table(symval, sym->st_size, | ||
1000 | sizeof(struct parisc_device_id), "parisc", | ||
1001 | do_parisc_entry, mod); | ||
1002 | else if (sym_is(symname, "__mod_sdio_device_table")) | ||
1003 | do_table(symval, sym->st_size, | ||
1004 | sizeof(struct sdio_device_id), "sdio", | ||
1005 | do_sdio_entry, mod); | ||
1006 | else if (sym_is(symname, "__mod_ssb_device_table")) | ||
1007 | do_table(symval, sym->st_size, | ||
1008 | sizeof(struct ssb_device_id), "ssb", | ||
1009 | do_ssb_entry, mod); | ||
1010 | else if (sym_is(symname, "__mod_bcma_device_table")) | ||
1011 | do_table(symval, sym->st_size, | ||
1012 | sizeof(struct bcma_device_id), "bcma", | ||
1013 | do_bcma_entry, mod); | ||
1014 | else if (sym_is(symname, "__mod_virtio_device_table")) | ||
1015 | do_table(symval, sym->st_size, | ||
1016 | sizeof(struct virtio_device_id), "virtio", | ||
1017 | do_virtio_entry, mod); | ||
1018 | else if (sym_is(symname, "__mod_vmbus_device_table")) | ||
1019 | do_table(symval, sym->st_size, | ||
1020 | sizeof(struct hv_vmbus_device_id), "vmbus", | ||
1021 | do_vmbus_entry, mod); | ||
1022 | else if (sym_is(symname, "__mod_i2c_device_table")) | ||
1023 | do_table(symval, sym->st_size, | ||
1024 | sizeof(struct i2c_device_id), "i2c", | ||
1025 | do_i2c_entry, mod); | ||
1026 | else if (sym_is(symname, "__mod_spi_device_table")) | ||
1027 | do_table(symval, sym->st_size, | ||
1028 | sizeof(struct spi_device_id), "spi", | ||
1029 | do_spi_entry, mod); | ||
1030 | else if (sym_is(symname, "__mod_dmi_device_table")) | ||
1031 | do_table(symval, sym->st_size, | ||
1032 | sizeof(struct dmi_system_id), "dmi", | ||
1033 | do_dmi_entry, mod); | ||
1034 | else if (sym_is(symname, "__mod_platform_device_table")) | ||
1035 | do_table(symval, sym->st_size, | ||
1036 | sizeof(struct platform_device_id), "platform", | ||
1037 | do_platform_entry, mod); | ||
1038 | else if (sym_is(symname, "__mod_mdio_device_table")) | ||
1039 | do_table(symval, sym->st_size, | ||
1040 | sizeof(struct mdio_device_id), "mdio", | ||
1041 | do_mdio_entry, mod); | ||
1042 | else if (sym_is(symname, "__mod_zorro_device_table")) | ||
1043 | do_table(symval, sym->st_size, | ||
1044 | sizeof(struct zorro_device_id), "zorro", | ||
1045 | do_zorro_entry, mod); | ||
1046 | else if (sym_is(symname, "__mod_isapnp_device_table")) | ||
1047 | do_table(symval, sym->st_size, | ||
1048 | sizeof(struct isapnp_device_id), "isa", | ||
1049 | do_isapnp_entry, mod); | ||
1050 | free(zeros); | 1102 | free(zeros); |
1051 | } | 1103 | } |
1052 | 1104 | ||
diff --git a/scripts/package/Makefile b/scripts/package/Makefile index bc6aa003860e..87bf08076b11 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile | |||
@@ -141,7 +141,7 @@ perf-%pkg: FORCE | |||
141 | help: FORCE | 141 | help: FORCE |
142 | @echo ' rpm-pkg - Build both source and binary RPM kernel packages' | 142 | @echo ' rpm-pkg - Build both source and binary RPM kernel packages' |
143 | @echo ' binrpm-pkg - Build only the binary kernel package' | 143 | @echo ' binrpm-pkg - Build only the binary kernel package' |
144 | @echo ' deb-pkg - Build the kernel as an deb package' | 144 | @echo ' deb-pkg - Build the kernel as a deb package' |
145 | @echo ' tar-pkg - Build the kernel as an uncompressed tarball' | 145 | @echo ' tar-pkg - Build the kernel as an uncompressed tarball' |
146 | @echo ' targz-pkg - Build the kernel as a gzip compressed tarball' | 146 | @echo ' targz-pkg - Build the kernel as a gzip compressed tarball' |
147 | @echo ' tarbz2-pkg - Build the kernel as a bzip2 compressed tarball' | 147 | @echo ' tarbz2-pkg - Build the kernel as a bzip2 compressed tarball' |
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index f40a6af6bf40..54e35c1e5948 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h | |||
@@ -462,7 +462,7 @@ __has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */ | |||
462 | succeed_file(); | 462 | succeed_file(); |
463 | } | 463 | } |
464 | if (w(txthdr->sh_type) != SHT_PROGBITS || | 464 | if (w(txthdr->sh_type) != SHT_PROGBITS || |
465 | !(w(txthdr->sh_flags) & SHF_EXECINSTR)) | 465 | !(_w(txthdr->sh_flags) & SHF_EXECINSTR)) |
466 | return NULL; | 466 | return NULL; |
467 | return txtname; | 467 | return txtname; |
468 | } | 468 | } |
diff --git a/scripts/tags.sh b/scripts/tags.sh index 38f6617a2cb1..833813a99e7c 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh | |||
@@ -132,7 +132,28 @@ exuberant() | |||
132 | --regex-asm='/^(ENTRY|_GLOBAL)\(([^)]*)\).*/\2/' \ | 132 | --regex-asm='/^(ENTRY|_GLOBAL)\(([^)]*)\).*/\2/' \ |
133 | --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ | 133 | --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ |
134 | --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ | 134 | --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ |
135 | --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/' | 135 | --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/' \ |
136 | --regex-c++='/PAGEFLAG\(([^,)]*).*/Page\1/' \ | ||
137 | --regex-c++='/PAGEFLAG\(([^,)]*).*/SetPage\1/' \ | ||
138 | --regex-c++='/PAGEFLAG\(([^,)]*).*/ClearPage\1/' \ | ||
139 | --regex-c++='/TESTSETFLAG\(([^,)]*).*/TestSetPage\1/' \ | ||
140 | --regex-c++='/TESTPAGEFLAG\(([^,)]*).*/Page\1/' \ | ||
141 | --regex-c++='/SETPAGEFLAG\(([^,)]*).*/SetPage\1/' \ | ||
142 | --regex-c++='/__SETPAGEFLAG\(([^,)]*).*/__SetPage\1/' \ | ||
143 | --regex-c++='/TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \ | ||
144 | --regex-c++='/__TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \ | ||
145 | --regex-c++='/CLEARPAGEFLAG\(([^,)]*).*/ClearPage\1/' \ | ||
146 | --regex-c++='/__CLEARPAGEFLAG\(([^,)]*).*/__ClearPage\1/' \ | ||
147 | --regex-c++='/__PAGEFLAG\(([^,)]*).*/__SetPage\1/' \ | ||
148 | --regex-c++='/__PAGEFLAG\(([^,)]*).*/__ClearPage\1/' \ | ||
149 | --regex-c++='/PAGEFLAG_FALSE\(([^,)]*).*/Page\1/' \ | ||
150 | --regex-c++='/TESTSCFLAG\(([^,)]*).*/TestSetPage\1/' \ | ||
151 | --regex-c++='/TESTSCFLAG\(([^,)]*).*/TestClearPage\1/' \ | ||
152 | --regex-c++='/SETPAGEFLAG_NOOP\(([^,)]*).*/SetPage\1/' \ | ||
153 | --regex-c++='/CLEARPAGEFLAG_NOOP\(([^,)]*).*/ClearPage\1/' \ | ||
154 | --regex-c++='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \ | ||
155 | --regex-c++='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \ | ||
156 | --regex-c++='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' | ||
136 | 157 | ||
137 | all_kconfigs | xargs $1 -a \ | 158 | all_kconfigs | xargs $1 -a \ |
138 | --langdef=kconfig --language-force=kconfig \ | 159 | --langdef=kconfig --language-force=kconfig \ |
@@ -146,6 +167,8 @@ exuberant() | |||
146 | --langdef=dotconfig --language-force=dotconfig \ | 167 | --langdef=dotconfig --language-force=dotconfig \ |
147 | --regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/' | 168 | --regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/' |
148 | 169 | ||
170 | # Remove structure forward declarations. | ||
171 | LANG=C sed -i -e '/^\([a-zA-Z_][a-zA-Z0-9_]*\)\t.*\t\/\^struct \1;.*\$\/;"\tx$/d' tags | ||
149 | } | 172 | } |
150 | 173 | ||
151 | emacs() | 174 | emacs() |
@@ -154,7 +177,28 @@ emacs() | |||
154 | --regex='/^(ENTRY|_GLOBAL)(\([^)]*\)).*/\2/' \ | 177 | --regex='/^(ENTRY|_GLOBAL)(\([^)]*\)).*/\2/' \ |
155 | --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \ | 178 | --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \ |
156 | --regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \ | 179 | --regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \ |
157 | --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/' | 180 | --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/' \ |
181 | --regex='/PAGEFLAG\(([^,)]*).*/Page\1/' \ | ||
182 | --regex='/PAGEFLAG\(([^,)]*).*/SetPage\1/' \ | ||
183 | --regex='/PAGEFLAG\(([^,)]*).*/ClearPage\1/' \ | ||
184 | --regex='/TESTSETFLAG\(([^,)]*).*/TestSetPage\1/' \ | ||
185 | --regex='/TESTPAGEFLAG\(([^,)]*).*/Page\1/' \ | ||
186 | --regex='/SETPAGEFLAG\(([^,)]*).*/SetPage\1/' \ | ||
187 | --regex='/__SETPAGEFLAG\(([^,)]*).*/__SetPage\1/' \ | ||
188 | --regex='/TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \ | ||
189 | --regex='/__TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \ | ||
190 | --regex='/CLEARPAGEFLAG\(([^,)]*).*/ClearPage\1/' \ | ||
191 | --regex='/__CLEARPAGEFLAG\(([^,)]*).*/__ClearPage\1/' \ | ||
192 | --regex='/__PAGEFLAG\(([^,)]*).*/__SetPage\1/' \ | ||
193 | --regex='/__PAGEFLAG\(([^,)]*).*/__ClearPage\1/' \ | ||
194 | --regex='/PAGEFLAG_FALSE\(([^,)]*).*/Page\1/' \ | ||
195 | --regex='/TESTSCFLAG\(([^,)]*).*/TestSetPage\1/' \ | ||
196 | --regex='/TESTSCFLAG\(([^,)]*).*/TestClearPage\1/' \ | ||
197 | --regex='/SETPAGEFLAG_NOOP\(([^,)]*).*/SetPage\1/' \ | ||
198 | --regex='/CLEARPAGEFLAG_NOOP\(([^,)]*).*/ClearPage\1/' \ | ||
199 | --regex='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \ | ||
200 | --regex='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \ | ||
201 | --regex='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' | ||
158 | 202 | ||
159 | all_kconfigs | xargs $1 -a \ | 203 | all_kconfigs | xargs $1 -a \ |
160 | --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' | 204 | --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' |