diff options
Diffstat (limited to 'scripts')
54 files changed, 2009 insertions, 362 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index d897278b1f97..6a3ee981931d 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -104,7 +104,7 @@ as-option = $(call try-run,\ # Usage: cflags-y += $(call as-instr,instr,option1,option2) as-instr = $(call try-run,\ - /bin/echo -e "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3)) + printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3)) # cc-option # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index d2b366c16b64..ff1720d28d0c 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -69,6 +69,7 @@ warning-1 += -Wmissing-prototypes warning-1 += -Wold-style-definition warning-1 += $(call cc-option, -Wmissing-include-dirs) warning-1 += $(call cc-option, -Wunused-but-set-variable) +warning-1 += $(call cc-disable-warning, missing-field-initializers) warning-2 := -Waggregate-return warning-2 += -Wcast-align @@ -76,6 +77,7 @@ warning-2 += -Wdisabled-optimization warning-2 += -Wnested-externs warning-2 += -Wshadow warning-2 += $(call cc-option, -Wlogical-op) +warning-2 += $(call cc-option, -Wmissing-field-initializers) warning-3 := -Wbad-function-cast warning-3 += -Wcast-qual 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 @@ # header-y - list files to be installed. They are preprocessed # to remove __KERNEL__ section of the file # objhdr-y - Same as header-y but for generated files +# genhdr-y - Same as objhdr-y but in a generated/ directory # # ========================================================================== # called may set destination dir (when installing to asm/) _dst := $(if $(dst),$(dst),$(obj)) +# generated header directory +gen := $(if $(gen),$(gen),$(subst include/,include/generated/,$(obj))) + kbuild-file := $(srctree)/$(obj)/Kbuild include $(kbuild-file) @@ -33,9 +37,10 @@ wrapper-files := $(filter $(header-y), $(generic-y)) # all headers files for this dir header-y := $(filter-out $(generic-y), $(header-y)) -all-files := $(header-y) $(objhdr-y) $(wrapper-files) +all-files := $(header-y) $(objhdr-y) $(genhdr-y) $(wrapper-files) input-files := $(addprefix $(srctree)/$(obj)/,$(header-y)) \ - $(addprefix $(objtree)/$(obj)/,$(objhdr-y)) + $(addprefix $(objtree)/$(obj)/,$(objhdr-y)) \ + $(addprefix $(objtree)/$(gen)/,$(genhdr-y)) output-files := $(addprefix $(install)/, $(all-files)) # Work out what needs to be removed @@ -52,6 +57,7 @@ quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\ cmd_install = \ $(PERL) $< $(srctree)/$(obj) $(install) $(SRCARCH) $(header-y); \ $(PERL) $< $(objtree)/$(obj) $(install) $(SRCARCH) $(objhdr-y); \ + $(PERL) $< $(objtree)/$(gen) $(install) $(SRCARCH) $(genhdr-y); \ for F in $(wrapper-files); do \ echo "\#include <asm-generic/$$F>" > $(install)/$$F; \ done; \ diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 5d986d9adf1b..0be6f110cce7 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -93,9 +93,9 @@ obj-dirs := $(addprefix $(obj)/,$(obj-dirs)) # already # $(modname_flags) #defines KBUILD_MODNAME as the name of the module it will # end up in (or would, if it gets compiled in) -# Note: It's possible that one object gets potentially linked into more -# than one module. In that case KBUILD_MODNAME will be set to foo_bar, -# where foo and bar are the name of the modules. +# Note: Files that end up in two or more modules are compiled without the +# KBUILD_MODNAME definition. The reason is that any made-up name would +# differ in different configs. name-fix = $(subst $(comma),_,$(subst -,_,$1)) basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" modname_flags = $(if $(filter 1,$(words $(modname))),\ @@ -264,7 +264,7 @@ $(obj)/%.dtb.S: $(obj)/%.dtb $(call cmd,dt_S_dtb) quiet_cmd_dtc = DTC $@ -cmd_dtc = $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 $(DTC_FLAGS) $< +cmd_dtc = $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 $(DTC_FLAGS) -d $(depfile) $< # Bzip2 # --------------------------------------------------------------------------- @@ -304,6 +304,30 @@ cmd_lzo = (cat $(filter-out FORCE,$^) | \ lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ (rm -f $@ ; false) +# U-Boot mkimage +# --------------------------------------------------------------------------- + +MKIMAGE := $(srctree)/scripts/mkuboot.sh + +# SRCARCH just happens to match slightly more than ARCH (on sparc), so reduces +# the number of overrides in arch makefiles +UIMAGE_ARCH ?= $(SRCARCH) +UIMAGE_COMPRESSION ?= $(if $(2),$(2),none) +UIMAGE_OPTS-y ?= +UIMAGE_TYPE ?= kernel +UIMAGE_LOADADDR ?= arch_must_set_this +UIMAGE_ENTRYADDR ?= $(UIMAGE_LOADADDR) +UIMAGE_NAME ?= 'Linux-$(KERNELRELEASE)' +UIMAGE_IN ?= $< +UIMAGE_OUT ?= $@ + +quiet_cmd_uimage = UIMAGE $(UIMAGE_OUT) + cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(UIMAGE_ARCH) -O linux \ + -C $(UIMAGE_COMPRESSION) $(UIMAGE_OPTS-y) \ + -T $(UIMAGE_TYPE) \ + -a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR) \ + -n $(UIMAGE_NAME) -d $(UIMAGE_IN) $(UIMAGE_OUT) + # XZ # --------------------------------------------------------------------------- # Use xzkern to compress the kernel image and xzmisc to compress other things. diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index e3bfcbe8a520..de639eeeed50 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -323,17 +323,22 @@ sub build_types { }x; $Type = qr{ $NonptrType - (?:[\s\*]+\s*const|[\s\*]+|(?:\s*\[\s*\])+)? + (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)? (?:\s+$Inline|\s+$Modifier)* }x; $Declare = qr{(?:$Storage\s+)?$Type}; } build_types(); -our $match_balanced_parentheses = qr/(\((?:[^\(\)]+|(-1))*\))/; our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; -our $LvalOrFunc = qr{($Lval)\s*($match_balanced_parentheses{0,1})\s*}; + +# Using $balanced_parens, $LvalOrFunc, or $FuncArg +# requires at least perl version v5.10.0 +# Any use must be runtime checked with $^V + +our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; +our $LvalOrFunc = qr{($Lval)\s*($balanced_parens{0,1})\s*}; our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant)}; sub deparenthesize { @@ -1330,6 +1335,36 @@ sub check_absolute_file { } } +sub pos_last_openparen { + my ($line) = @_; + + my $pos = 0; + + my $opens = $line =~ tr/\(/\(/; + my $closes = $line =~ tr/\)/\)/; + + my $last_openparen = 0; + + if (($opens == 0) || ($closes >= $opens)) { + return -1; + } + + my $len = length($line); + + for ($pos = 0; $pos < $len; $pos++) { + my $string = substr($line, $pos); + if ($string =~ /^($FuncArg|$balanced_parens)/) { + $pos += length($1) - 1; + } elsif (substr($line, $pos, 1) eq '(') { + $last_openparen = $pos; + } elsif (index($string, '(') == -1) { + last; + } + } + + return $last_openparen + 1; +} + sub process { my $filename = shift; @@ -1737,6 +1772,21 @@ sub process { "line over 80 characters\n" . $herecurr); } +# Check for user-visible strings broken across lines, which breaks the ability +# to grep for the string. Limited to strings used as parameters (those +# following an open parenthesis), which almost completely eliminates false +# positives, as well as warning only once per parameter rather than once per +# line of the string. Make an exception when the previous string ends in a +# newline (multiple lines in one string constant) or \n\t (common in inline +# assembly to indent the instruction on the following line). + if ($line =~ /^\+\s*"/ && + $prevline =~ /"\s*$/ && + $prevline =~ /\(/ && + $prevrawline !~ /\\n(?:\\t)*"\s*$/) { + WARN("SPLIT_STRING", + "quoted string split across lines\n" . $hereprev); + } + # check for spaces before a quoted newline if ($rawline =~ /^.*\".*\s\\n/) { WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", @@ -1783,6 +1833,48 @@ sub process { "please, no space before tabs\n" . $herevet); } +# check for && or || at the start of a line + if ($rawline =~ /^\+\s*(&&|\|\|)/) { + CHK("LOGICAL_CONTINUATIONS", + "Logical continuations should be on the previous line\n" . $hereprev); + } + +# check multi-line statement indentation matches previous line + if ($^V && $^V ge 5.10.0 && + $prevline =~ /^\+(\t*)(if \(|$Ident\().*(\&\&|\|\||,)\s*$/) { + $prevline =~ /^\+(\t*)(.*)$/; + my $oldindent = $1; + my $rest = $2; + + my $pos = pos_last_openparen($rest); + if ($pos >= 0) { + $line =~ /^\+([ \t]*)/; + my $newindent = $1; + + my $goodtabindent = $oldindent . + "\t" x ($pos / 8) . + " " x ($pos % 8); + my $goodspaceindent = $oldindent . " " x $pos; + + if ($newindent ne $goodtabindent && + $newindent ne $goodspaceindent) { + CHK("PARENTHESIS_ALIGNMENT", + "Alignment should match open parenthesis\n" . $hereprev); + } + } + } + + if ($line =~ /^\+.*\*[ \t]*\)[ \t]+/) { + CHK("SPACING", + "No space is necessary after a cast\n" . $hereprev); + } + + if ($rawline =~ /^\+[ \t]*\/\*[ \t]*$/ && + $prevrawline =~ /^\+[ \t]*$/) { + CHK("BLOCK_COMMENT_STYLE", + "Don't begin block comments with only a /* line, use /* comment...\n" . $hereprev); + } + # check for spaces at the beginning of a line. # Exceptions: # 1) within comments @@ -1924,6 +2016,12 @@ sub process { my $pre_ctx = "$1$2"; my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); + + if ($line =~ /^\+\t{6,}/) { + WARN("DEEP_INDENTATION", + "Too many leading tabs - consider code refactoring\n" . $herecurr); + } + my $ctx_cnt = $realcnt - $#ctx - 1; my $ctx = join("\n", @ctx); @@ -2319,7 +2417,7 @@ sub process { my ($where, $prefix) = ($-[1], $1); if ($prefix !~ /$Type\s+$/ && ($where != 0 || $prefix !~ /^.\s+$/) && - $prefix !~ /{\s+$/) { + $prefix !~ /[{,]\s+$/) { ERROR("BRACKET_SPACE", "space prohibited before open square bracket '['\n" . $herecurr); } @@ -2822,6 +2920,12 @@ sub process { { } + # Flatten any obvious string concatentation. + while ($dstat =~ s/("X*")\s*$Ident/$1/ || + $dstat =~ s/$Ident\s*("X*")/$1/) + { + } + my $exceptions = qr{ $Declare| module_param_named| @@ -2838,7 +2942,8 @@ sub process { if ($dstat ne '' && $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); - $dstat !~ /^(?:$Ident|-?$Constant)$/ && # 10 // foo() + $dstat !~ /^[!~-]?(?:$Ident|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo + $dstat !~ /^'X'$/ && # character constants $dstat !~ /$exceptions/ && $dstat !~ /^\.$Ident\s*=/ && # .foo = $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) @@ -2882,7 +2987,8 @@ sub process { #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; if ($#chunks > 0 && $level == 0) { - my $allowed = 0; + my @allowed = (); + my $allow = 0; my $seen = 0; my $herectx = $here . "\n"; my $ln = $linenr - 1; @@ -2893,6 +2999,7 @@ sub process { my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); my $offset = statement_rawlines($whitespace) - 1; + $allowed[$allow] = 0; #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; # We have looked at and allowed this specific line. @@ -2905,23 +3012,34 @@ sub process { $seen++ if ($block =~ /^\s*{/); - #print "cond<$cond> block<$block> allowed<$allowed>\n"; + #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; if (statement_lines($cond) > 1) { #print "APW: ALLOWED: cond<$cond>\n"; - $allowed = 1; + $allowed[$allow] = 1; } if ($block =~/\b(?:if|for|while)\b/) { #print "APW: ALLOWED: block<$block>\n"; - $allowed = 1; + $allowed[$allow] = 1; } if (statement_block_size($block) > 1) { #print "APW: ALLOWED: lines block<$block>\n"; - $allowed = 1; + $allowed[$allow] = 1; } + $allow++; } - if ($seen && !$allowed) { - WARN("BRACES", - "braces {} are not necessary for any arm of this statement\n" . $herectx); + if ($seen) { + my $sum_allowed = 0; + foreach (@allowed) { + $sum_allowed += $_; + } + if ($sum_allowed == 0) { + WARN("BRACES", + "braces {} are not necessary for any arm of this statement\n" . $herectx); + } elsif ($sum_allowed != $allow && + $seen != $allow) { + CHK("BRACES", + "braces {} should be used on all arms of this statement\n" . $herectx); + } } } } @@ -3117,6 +3235,12 @@ sub process { "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr); } +# Check for __attribute__ format(scanf, prefer __scanf + if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { + WARN("PREFER_SCANF", + "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr); + } + # check for sizeof(&) if ($line =~ /\bsizeof\s*\(\s*\&/) { WARN("SIZEOF_ADDRESS", @@ -3130,12 +3254,13 @@ sub process { } # Check for misused memsets - if (defined $stat && + if ($^V && $^V ge 5.10.0 && + defined $stat && $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) { my $ms_addr = $2; - my $ms_val = $8; - my $ms_size = $14; + my $ms_val = $7; + my $ms_size = $12; if ($ms_size =~ /^(0x|)0$/i) { ERROR("MEMSET", @@ -3147,17 +3272,18 @@ sub process { } # typecasts on min/max could be min_t/max_t - if (defined $stat && + if ($^V && $^V ge 5.10.0 && + defined $stat && $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { - if (defined $2 || defined $8) { + if (defined $2 || defined $7) { my $call = $1; my $cast1 = deparenthesize($2); my $arg1 = $3; - my $cast2 = deparenthesize($8); - my $arg2 = $9; + my $cast2 = deparenthesize($7); + my $arg2 = $8; my $cast; - if ($cast1 ne "" && $cast2 ne "") { + if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { $cast = "$cast1 or $cast2"; } elsif ($cast1 ne "") { $cast = $cast1; @@ -3227,22 +3353,30 @@ sub process { "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr); } +# check for use of yield() + if ($line =~ /\byield\s*\(\s*\)/) { + WARN("YIELD", + "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); + } + # check for semaphores initialized locked if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { WARN("CONSIDER_COMPLETION", "consider using a completion\n" . $herecurr); - } + # recommend kstrto* over simple_strto* and strict_strto* if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { WARN("CONSIDER_KSTRTO", "$1 is obsolete, use k$3 instead\n" . $herecurr); } + # check for __initcall(), use device_initcall() explicitly please if ($line =~ /^.\s*__initcall\s*\(/) { WARN("USE_DEVICE_INITCALL", "please use device_initcall() instead of __initcall()\n" . $herecurr); } + # check for various ops structs, ensure they are const. my $struct_ops = qr{acpi_dock_ops| address_space_operations| @@ -3379,6 +3513,12 @@ sub process { } if ($quiet == 0) { + + if ($^V lt 5.10.0) { + print("NOTE: perl $^V is not modern enough to detect all possible issues.\n"); + print("An upgrade to at least perl v5.10.0 is suggested.\n\n"); + } + # If there were whitespace errors which cleanpatch can fix # then suggest that. if ($rpt_cleaners) { @@ -3388,13 +3528,12 @@ sub process { } } - if (keys %ignore_type) { + if ($quiet == 0 && keys %ignore_type) { print "NOTE: Ignored message types:"; foreach my $ignore (sort keys %ignore_type) { print " $ignore"; } - print "\n"; - print "\n" if ($quiet == 0); + print "\n\n"; } if ($clean == 1 && $quiet == 0) { 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 } syscall_list() { -sed -n -e '/^\#define/ s/[^_]*__NR_\([^[:space:]]*\).*/\ -\#if !defined \(__NR_\1\) \&\& !defined \(__IGNORE_\1\)\ -\#warning syscall \1 not implemented\ -\#endif/p' $1 + grep '^[0-9]' "$1" | sort -n | ( + while read nr abi name entry ; do + echo <<EOF +#if !defined(__NR_${name}) && !defined(__IGNORE_${name}) +#warning syscall ${name} not implemented +#endif +EOF + done + ) } -(ignore_list && syscall_list $(dirname $0)/../arch/x86/include/asm/unistd_32.h) | \ +(ignore_list && syscall_list $(dirname $0)/../arch/x86/syscalls/syscall_32.tbl) | \ $* -E -x c - > /dev/null diff --git a/scripts/coccicheck b/scripts/coccicheck index 1bb1a1bd2daa..823e972149e5 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -10,13 +10,17 @@ if [ "$C" = "1" -o "$C" = "2" ]; then # OPTIONS=$* # Workaround for Coccinelle < 0.2.3 - FLAGS="-I $srctree/include -very_quiet" - shift $(( $# - 1 )) - OPTIONS=$1 + FLAGS="-I $srctree/include -very_quiet" + shift $(( $# - 1 )) + OPTIONS=$1 else ONLINE=0 FLAGS="-very_quiet" - OPTIONS="-dir $srctree" + if [ "$KBUILD_EXTMOD" = "" ] ; then + OPTIONS="-dir $srctree" + else + OPTIONS="-dir $KBUILD_EXTMOD -patch $srctree -I $srctree/include -I $KBUILD_EXTMOD/include" + fi fi 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 @@ +/// Reimplement a call to devm_request_mem_region followed by a call to ioremap +/// or ioremap_nocache by a call to devm_request_and_ioremap. +/// Devm_request_and_ioremap was introduced in +/// 72f8c0bfa0de64c68ee59f40eb9b2683bffffbb0. It makes the code much more +/// concise. +/// +/// +// Confidence: High +// Copyright: (C) 2011 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2011 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual patch +virtual org +virtual report +virtual context + +@nm@ +expression myname; +identifier i; +@@ + +struct platform_driver i = { .driver = { .name = myname } }; + +@depends on patch@ +expression dev,res,size; +@@ + +-if (!devm_request_mem_region(dev, res->start, size, +- \(res->name\|dev_name(dev)\))) { +- ... +- return ...; +-} +... when != res->start +( +-devm_ioremap(dev,res->start,size) ++devm_request_and_ioremap(dev,res) +| +-devm_ioremap_nocache(dev,res->start,size) ++devm_request_and_ioremap(dev,res) +) +... when any + when != res->start + +// this rule is separate from the previous one, because a single file can +// have multiple values of myname +@depends on patch@ +expression dev,res,size; +expression nm.myname; +@@ + +-if (!devm_request_mem_region(dev, res->start, size,myname)) { +- ... +- return ...; +-} +... when != res->start +( +-devm_ioremap(dev,res->start,size) ++devm_request_and_ioremap(dev,res) +| +-devm_ioremap_nocache(dev,res->start,size) ++devm_request_and_ioremap(dev,res) +) +... when any + when != res->start + + +@pb depends on org || report || context@ +expression dev,res,size; +expression nm.myname; +position p1,p2; +@@ + +*if + (!devm_request_mem_region@p1(dev, res->start, size, + \(res->name\|dev_name(dev)\|myname\))) { + ... + return ...; +} +... when != res->start +( +*devm_ioremap@p2(dev,res->start,size) +| +*devm_ioremap_nocache@p2(dev,res->start,size) +) +... when any + when != res->start + +@script:python depends on org@ +p1 << pb.p1; +p2 << pb.p2; +@@ + +cocci.print_main("INFO: replace by devm_request_and_ioremap",p1) +cocci.print_secs("",p2) + +@script:python depends on report@ +p1 << pb.p1; +p2 << pb.p2; +@@ + +msg = "INFO: devm_request_mem_region followed by ioremap on line %s can be replaced by devm_request_and_ioremap" % (p2[0].line) +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 @@ /// Use kstrdup rather than duplicating its implementation /// // Confidence: High -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. // URL: http://coccinelle.lip6.fr/ // Comments: // Options: -no_includes -include_headers virtual patch +virtual context +virtual org +virtual report -@@ +@depends on patch@ expression from,to; expression flag,E1,E2; statement S; @@ -23,7 +26,7 @@ statement S; ... when != \(from = E2 \| to = E2 \) - strcpy(to, from); -@@ +@depends on patch@ expression x,from,to; expression flag,E1,E2,E3; statement S; @@ -37,3 +40,65 @@ statement S; if (to==NULL || ...) S ... when != \(x = E3 \| from = E3 \| to = E3 \) - memcpy(to, from, x); + +// --------------------------------------------------------------------- + +@r1 depends on !patch exists@ +expression from,to; +expression flag,E1,E2; +statement S; +position p1,p2; +@@ + +* to = kmalloc@p1(strlen(from) + 1,flag); + ... when != \(from = E1 \| to = E1 \) + if (to==NULL || ...) S + ... when != \(from = E2 \| to = E2 \) +* strcpy@p2(to, from); + +@r2 depends on !patch exists@ +expression x,from,to; +expression flag,E1,E2,E3; +statement S; +position p1,p2; +@@ + +* x = strlen(from) + 1; + ... when != \( x = E1 \| from = E1 \) +* to = \(kmalloc@p1\|kzalloc@p2\)(x,flag); + ... when != \(x = E2 \| from = E2 \| to = E2 \) + if (to==NULL || ...) S + ... when != \(x = E3 \| from = E3 \| to = E3 \) +* memcpy@p2(to, from, x); + +@script:python depends on org@ +p1 << r1.p1; +p2 << r1.p2; +@@ + +cocci.print_main("WARNING opportunity for kstrdep",p1) +cocci.print_secs("strcpy",p2) + +@script:python depends on org@ +p1 << r2.p1; +p2 << r2.p2; +@@ + +cocci.print_main("WARNING opportunity for kstrdep",p1) +cocci.print_secs("memcpy",p2) + +@script:python depends on report@ +p1 << r1.p1; +p2 << r1.p2; +@@ + +msg = "WARNING opportunity for kstrdep (strcpy on line %s)" % (p2[0].line) +coccilib.report.print_report(p1[0], msg) + +@script:python depends on report@ +p1 << r2.p1; +p2 << r2.p2; +@@ + +msg = "WARNING opportunity for kstrdep (memcpy on line %s)" % (p2[0].line) +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 @@ /// Use kmemdup rather than duplicating its implementation /// // Confidence: High -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. // URL: http://coccinelle.lip6.fr/ // Comments: // Options: -no_includes -include_headers virtual patch +virtual context +virtual org +virtual report @r1@ expression from,to; @@ -28,7 +31,7 @@ position p; ... when != \( x = E1 \| from = E1 \) to = \(kmalloc@p\|kzalloc@p\)(x,flag); -@@ +@depends on patch@ expression from,to,size,flag; position p != {r1.p,r2.p}; statement S; @@ -38,3 +41,26 @@ statement S; + to = kmemdup(from,size,flag); if (to==NULL || ...) S - memcpy(to, from, size); + +@r depends on !patch@ +expression from,to,size,flag; +position p != {r1.p,r2.p}; +statement S; +@@ + +* to = \(kmalloc@p\|kzalloc@p\)(size,flag); + to = kmemdup(from,size,flag); + if (to==NULL || ...) S +* memcpy(to, from, size); + +@script:python depends on org@ +p << r.p; +@@ + +coccilib.org.print_todo(p[0], "WARNING opportunity for kmemdep") + +@script:python depends on report@ +p << r.p; +@@ + +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 @@ -/// Use kmemdup_user rather than duplicating its implementation +/// Use memdup_user rather than duplicating its implementation /// This is a little bit restricted to reduce false positives /// // Confidence: High -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. // URL: http://coccinelle.lip6.fr/ // Comments: // Options: -no_includes -include_headers virtual patch +virtual context +virtual org +virtual report -@@ +@depends on patch@ expression from,to,size,flag; -position p; identifier l1,l2; @@ -- to = \(kmalloc@p\|kzalloc@p\)(size,flag); +- to = \(kmalloc\|kzalloc\)(size,flag); + to = memdup_user(from,size); if ( - to==NULL @@ -33,3 +35,26 @@ identifier l1,l2; - -EFAULT - ...+> - } + +@r depends on !patch@ +expression from,to,size,flag; +position p; +statement S1,S2; +@@ + +* to = \(kmalloc@p\|kzalloc@p\)(size,flag); + if (to==NULL || ...) S1 + if (copy_from_user(to, from, size) != 0) + S2 + +@script:python depends on org@ +p << r.p; +@@ + +coccilib.org.print_todo(p[0], "WARNING opportunity for memdep_user") + +@script:python depends on report@ +p << r.p; +@@ + +coccilib.report.print_report(p[0], "WARNING opportunity for memdep_user") diff --git a/scripts/coccinelle/api/ptr_ret.cocci b/scripts/coccinelle/api/ptr_ret.cocci new file mode 100644 index 000000000000..cbfd08c7d8c7 --- /dev/null +++ b/scripts/coccinelle/api/ptr_ret.cocci @@ -0,0 +1,70 @@ +/// +/// Use PTR_RET rather than if(IS_ERR(...)) + PTR_ERR +/// +// Confidence: High +// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Options: -no_includes -include_headers +// +// Keywords: ERR_PTR, PTR_ERR, PTR_RET +// Version min: 2.6.39 +// + +virtual context +virtual patch +virtual org +virtual report + +@depends on patch@ +expression ptr; +@@ + +- if (IS_ERR(ptr)) return PTR_ERR(ptr); else return 0; ++ return PTR_RET(ptr); + +@depends on patch@ +expression ptr; +@@ + +- if (IS_ERR(ptr)) return PTR_ERR(ptr); return 0; ++ return PTR_RET(ptr); + +@r1 depends on !patch@ +expression ptr; +position p1; +@@ + +* if@p1 (IS_ERR(ptr)) return PTR_ERR(ptr); else return 0; + +@r2 depends on !patch@ +expression ptr; +position p2; +@@ + +* if@p2 (IS_ERR(ptr)) return PTR_ERR(ptr); return 0; + +@script:python depends on org@ +p << r1.p1; +@@ + +coccilib.org.print_todo(p[0], "WARNING: PTR_RET can be used") + + +@script:python depends on org@ +p << r2.p2; +@@ + +coccilib.org.print_todo(p[0], "WARNING: PTR_RET can be used") + +@script:python depends on report@ +p << r1.p1; +@@ + +coccilib.report.print_report(p[0], "WARNING: PTR_RET can be used") + +@script:python depends on report@ +p << r2.p2; +@@ + +coccilib.report.print_report(p[0], "WARNING: PTR_RET can be used") diff --git a/scripts/coccinelle/api/simple_open.cocci b/scripts/coccinelle/api/simple_open.cocci new file mode 100644 index 000000000000..05962f7be155 --- /dev/null +++ b/scripts/coccinelle/api/simple_open.cocci @@ -0,0 +1,70 @@ +/// This removes an open coded simple_open() function +/// and replaces file operations references to the function +/// with simple_open() instead. +/// +// Confidence: High +// Comments: +// Options: -no_includes -include_headers + +virtual patch +virtual report + +@ open depends on patch @ +identifier open_f != simple_open; +identifier i, f; +@@ +-int open_f(struct inode *i, struct file *f) +-{ +( +-if (i->i_private) +-f->private_data = i->i_private; +| +-f->private_data = i->i_private; +) +-return 0; +-} + +@ has_open depends on open @ +identifier fops; +identifier open.open_f; +@@ +struct file_operations fops = { +..., +-.open = open_f, ++.open = simple_open, +... +}; + +@ openr depends on report @ +identifier open_f != simple_open; +identifier i, f; +position p; +@@ +int open_f@p(struct inode *i, struct file *f) +{ +( +if (i->i_private) +f->private_data = i->i_private; +| +f->private_data = i->i_private; +) +return 0; +} + +@ has_openr depends on openr @ +identifier fops; +identifier openr.open_f; +position p; +@@ +struct file_operations fops = { +..., +.open = open_f@p, +... +}; + +@script:python@ +pf << openr.p; +ps << has_openr.p; +@@ + +coccilib.report.print_report(pf[0],"WARNING opportunity for simple_open, see also structure on line %s"%(ps[0].line)) diff --git a/scripts/coccinelle/free/clk_put.cocci b/scripts/coccinelle/free/clk_put.cocci new file mode 100644 index 000000000000..46747adfd20a --- /dev/null +++ b/scripts/coccinelle/free/clk_put.cocci @@ -0,0 +1,67 @@ +/// Find missing clk_puts. +/// +//# This only signals a missing clk_put when there is a clk_put later +//# in the same function. +//# False positives can be due to loops. +// +// Confidence: Moderate +// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: + +virtual context +virtual org +virtual report + +@clk@ +expression e; +statement S,S1; +int ret; +position p1,p2,p3; +@@ + +e = clk_get@p1(...) +... when != clk_put(e) +if (<+...e...+>) S +... when any + when != clk_put(e) + when != if (...) { ... clk_put(e); ... } +( + if (ret == 0) S1 +| +if (...) + { ... + return 0; } +| +if (...) + { ... + return <+...e...+>; } +| +*if@p2 (...) + { ... when != clk_put(e) + when forall + return@p3 ...; } +) +... when any +clk_put(e); + +@script:python depends on org@ +p1 << clk.p1; +p2 << clk.p2; +p3 << clk.p3; +@@ + +cocci.print_main("clk_get",p1) +cocci.print_secs("if",p2) +cocci.print_secs("needed clk_put",p3) + +@script:python depends on report@ +p1 << clk.p1; +p2 << clk.p2; +p3 << clk.p3; +@@ + +msg = "ERROR: missing clk_put; clk_get on line %s and execution via conditional on line %s" % (p1[0].line,p2[0].line) +coccilib.report.print_report(p3[0],msg) 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 @@ +/// Find uses of standard freeing functons on values allocated using devm_ +/// functions. Values allocated using the devm_functions are freed when +/// the device is detached, and thus the use of the standard freeing +/// function would cause a double free. +/// See Documentation/driver-model/devres.txt for more information. +/// +/// A difficulty of detecting this problem is that the standard freeing +/// function might be called from a different function than the one +/// containing the allocation function. It is thus necessary to make the +/// connection between the allocation function and the freeing function. +/// Here this is done using the specific argument text, which is prone to +/// false positives. There is no rule for the request_region and +/// request_mem_region variants because this heuristic seems to be a bit +/// less reliable in these cases. +/// +// Confidence: Moderate +// Copyright: (C) 2011 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2011 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual org +virtual report +virtual context + +@r depends on context || org || report@ +expression x; +@@ + +( + x = devm_kzalloc(...) +| + x = devm_request_irq(...) +| + x = devm_ioremap(...) +| + x = devm_ioremap_nocache(...) +| + x = devm_ioport_map(...) +) + +@pb@ +expression r.x; +position p; +@@ + +( +* kfree@p(x) +| +* free_irq@p(x) +| +* iounmap@p(x) +| +* ioport_unmap@p(x) +) + +@script:python depends on org@ +p << pb.p; +@@ + +msg="WARNING: invalid free of devm_ allocated data" +coccilib.org.print_todo(p[0], msg) + +@script:python depends on report@ +p << pb.p; +@@ + +msg="WARNING: invalid free of devm_ allocated data" +coccilib.report.print_report(p[0], msg) + diff --git a/scripts/coccinelle/free/iounmap.cocci b/scripts/coccinelle/free/iounmap.cocci new file mode 100644 index 000000000000..5384f4ba1192 --- /dev/null +++ b/scripts/coccinelle/free/iounmap.cocci @@ -0,0 +1,67 @@ +/// Find missing iounmaps. +/// +//# This only signals a missing iounmap when there is an iounmap later +//# in the same function. +//# False positives can be due to loops. +// +// Confidence: Moderate +// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: + +virtual context +virtual org +virtual report + +@iom@ +expression e; +statement S,S1; +int ret; +position p1,p2,p3; +@@ + +e = \(ioremap@p1\|ioremap_nocache@p1\)(...) +... when != iounmap(e) +if (<+...e...+>) S +... when any + when != iounmap(e) + when != if (...) { ... iounmap(e); ... } +( + if (ret == 0) S1 +| +if (...) + { ... + return 0; } +| +if (...) + { ... + return <+...e...+>; } +| +*if@p2 (...) + { ... when != iounmap(e) + when forall + return@p3 ...; } +) +... when any +iounmap(e); + +@script:python depends on org@ +p1 << iom.p1; +p2 << iom.p2; +p3 << iom.p3; +@@ + +cocci.print_main("ioremap",p1) +cocci.print_secs("if",p2) +cocci.print_secs("needed iounmap",p3) + +@script:python depends on report@ +p1 << iom.p1; +p2 << iom.p2; +p3 << iom.p3; +@@ + +msg = "ERROR: missing iounmap; ioremap on line %s and execution via conditional on line %s" % (p1[0].line,p2[0].line) +coccilib.report.print_report(p3[0],msg) 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 @@ //# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument /// // Confidence: Moderate -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. // URL: http://coccinelle.lip6.fr/ // Comments: // Options: -no_includes -include_headers @@ -23,7 +23,7 @@ position p1; kfree@p1(E) @print expression@ -constant char *c; +constant char [] c; expression free.E,E2; type T; position p; @@ -37,6 +37,10 @@ identifier f; | E@p != E2 | + E2 == E@p +| + E2 != E@p +| !E@p | E@p || ... @@ -113,5 +117,5 @@ p1 << free.p1; p2 << r.p2; @@ -msg = "reference preceded by free on line %s" % (p1[0].line) +msg = "ERROR: reference preceded by free on line %s" % (p1[0].line) 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 @@ /// is no point to call of_node_put on the final value. /// // Confidence: High -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. // URL: http://coccinelle.lip6.fr/ // Comments: // Options: -no_includes -include_headers virtual patch +virtual context +virtual org +virtual report -@@ +@depends on patch@ iterator name for_each_node_by_name; expression np,E; identifier l; @@ -24,7 +27,7 @@ for_each_node_by_name(np,...) { ... when != np = E - of_node_put(np); -@@ +@depends on patch@ iterator name for_each_node_by_type; expression np,E; identifier l; @@ -37,7 +40,7 @@ for_each_node_by_type(np,...) { ... when != np = E - of_node_put(np); -@@ +@depends on patch@ iterator name for_each_compatible_node; expression np,E; identifier l; @@ -50,7 +53,7 @@ for_each_compatible_node(np,...) { ... when != np = E - of_node_put(np); -@@ +@depends on patch@ iterator name for_each_matching_node; expression np,E; identifier l; @@ -62,3 +65,59 @@ for_each_matching_node(np,...) { } ... when != np = E - of_node_put(np); + +// ---------------------------------------------------------------------- + +@r depends on !patch forall@ +//iterator name for_each_node_by_name; +//iterator name for_each_node_by_type; +//iterator name for_each_compatible_node; +//iterator name for_each_matching_node; +expression np,E; +identifier l; +position p1,p2; +@@ + +( +*for_each_node_by_name@p1(np,...) +{ + ... when != break; + when != goto l; +} +| +*for_each_node_by_type@p1(np,...) +{ + ... when != break; + when != goto l; +} +| +*for_each_compatible_node@p1(np,...) +{ + ... when != break; + when != goto l; +} +| +*for_each_matching_node@p1(np,...) +{ + ... when != break; + when != goto l; +} +) +... when != np = E +* of_node_put@p2(np); + +@script:python depends on org@ +p1 << r.p1; +p2 << r.p2; +@@ + +cocci.print_main("unneeded of_node_put",p2) +cocci.print_secs("iterator",p1) + +@script:python depends on report@ +p1 << r.p1; +p2 << r.p2; +@@ + +msg = "ERROR: of_node_put not needed after iterator on line %s" % (p1[0].line) +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 @@ /// Many iterators have the property that the first argument is always bound -/// to a real list element, never NULL. False positives arise for some -/// iterators that do not have this property, or in cases when the loop -/// cursor is reassigned. The latter should only happen when the matched -/// code is on the way to a loop exit (break, goto, or return). +/// to a real list element, never NULL. +//# False positives arise for some iterators that do not have this property, +//# or in cases when the loop cursor is reassigned. The latter should only +//# happen when the matched code is on the way to a loop exit (break, goto, +//# or return). /// // Confidence: Moderate -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. // URL: http://coccinelle.lip6.fr/ // Comments: // Options: -no_includes -include_headers virtual patch +virtual context +virtual org +virtual report -@@ +@depends on patch@ iterator I; expression x,E,E1,E2; statement S,S1,S2; @@ -55,4 +59,36 @@ I(x,...) { <... x != NULL + ) ) - ...> }
\ No newline at end of file + ...> } + +@r depends on !patch exists@ +iterator I; +expression x,E; +position p1,p2; +@@ + +*I@p1(x,...) +{ ... when != x = E +( +* x@p2 == NULL +| +* x@p2 != NULL +) + ... when any +} + +@script:python depends on org@ +p1 << r.p1; +p2 << r.p2; +@@ + +cocci.print_main("iterator-bound variable",p1) +cocci.print_secs("useless NULL test",p2) + +@script:python depends on report@ +p1 << r.p1; +p2 << r.p2; +@@ + +msg = "ERROR: iterator variable bound on line %s cannot be NULL" % (p1[0].line) +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 @@ /// Find functions that refer to GFP_KERNEL but are called with locks held. -/// The proposed change of converting the GFP_KERNEL is not necessarily the -/// correct one. It may be desired to unlock the lock, or to not call the -/// function under the lock in the first place. +//# The proposed change of converting the GFP_KERNEL is not necessarily the +//# correct one. It may be desired to unlock the lock, or to not call the +//# function under the lock in the first place. /// // Confidence: Moderate -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// Copyright: (C) 2012 Nicolas Palix. GPLv2. +// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. // URL: http://coccinelle.lip6.fr/ // Comments: // Options: -no_includes -include_headers virtual patch +virtual context +virtual org +virtual report @gfp exists@ identifier fn; @@ -32,28 +35,29 @@ fn(...) { ... when any } -@locked@ +@locked exists@ identifier gfp.fn; +position p1,p2; @@ ( -read_lock_irq +read_lock_irq@p1 | -write_lock_irq +write_lock_irq@p1 | -read_lock_irqsave +read_lock_irqsave@p1 | -write_lock_irqsave +write_lock_irqsave@p1 | -spin_lock +spin_lock@p1 | -spin_trylock +spin_trylock@p1 | -spin_lock_irq +spin_lock_irq@p1 | -spin_lock_irqsave +spin_lock_irqsave@p1 | -local_irq_disable +local_irq_disable@p1 ) (...) ... when != read_unlock_irq(...) @@ -64,11 +68,38 @@ local_irq_disable when != spin_unlock_irq(...) when != spin_unlock_irqrestore(...) when != local_irq_enable(...) -fn(...) +fn@p2(...) -@depends on locked@ +@depends on locked && patch@ position gfp.p; @@ - GFP_KERNEL@p + GFP_ATOMIC + +@depends on locked && !patch@ +position gfp.p; +@@ + +* GFP_KERNEL@p + +@script:python depends on !patch && org@ +p << gfp.p; +fn << gfp.fn; +p1 << locked.p1; +p2 << locked.p2; +@@ + +cocci.print_main("lock",p1) +cocci.print_secs("call",p2) +cocci.print_secs("GFP_KERNEL",p) + +@script:python depends on !patch && report@ +p << gfp.p; +fn << gfp.fn; +p1 << locked.p1; +p2 << locked.p2; +@@ + +msg = "ERROR: function %s called on line %s inside lock on line %s but uses GFP_KERNEL" % (fn,p2[0].line,p1[0].line) +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 @@ /// Find nested lock+irqsave functions that use the same flags variables /// // Confidence: High -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. // URL: http://coccinelle.lip6.fr/ // Comments: // Options: -no_includes -include_headers @@ -12,7 +12,7 @@ virtual context virtual org virtual report -@r@ +@r exists@ expression lock1,lock2,flags; position p1,p2; @@ @@ -39,7 +39,7 @@ read_lock_irqsave@p2(lock2,flags) write_lock_irqsave@p2(lock2,flags) ) -@d@ +@d exists@ expression f <= r.flags; expression lock1,lock2,flags; position r.p1, r.p2; @@ -76,5 +76,5 @@ p1 << r.p1; p2 << r.p2; @@ -msg="ERROR: nested lock+irqsave that reuses flags from %s." % (p1[0].line) +msg="ERROR: nested lock+irqsave that reuses flags from line %s." % (p1[0].line) 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 @@ /// function call that releases the lock. /// // Confidence: Moderate -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. // URL: http://coccinelle.lip6.fr/ // Comments: // Options: -no_includes -include_headers +virtual context virtual org virtual report @@ -57,7 +58,7 @@ position r; for(...;...;...) { <+... return@r ...; ...+> } -@err@ +@err exists@ expression E1; position prelocked.p; position up != prelocked.p1; @@ -65,14 +66,14 @@ position r!=looped.r; identifier lock,unlock; @@ -lock(E1@p,...); +*lock(E1@p,...); <+... when != E1 if (...) { ... when != E1 - return@r ...; +* return@r ...; } ...+> -unlock@up(E1,...); +*unlock@up(E1,...); @script:python depends on org@ p << prelocked.p1; diff --git a/scripts/coccinelle/misc/boolinit.cocci b/scripts/coccinelle/misc/boolinit.cocci new file mode 100644 index 000000000000..97ce41ce8135 --- /dev/null +++ b/scripts/coccinelle/misc/boolinit.cocci @@ -0,0 +1,178 @@ +/// Bool initializations should use true and false. Bool tests don't need +/// comparisons. Based on contributions from Joe Perches, Rusty Russell +/// and Bruce W Allan. +/// +// Confidence: High +// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Options: -include_headers + +virtual patch +virtual context +virtual org +virtual report + +@depends on patch@ +bool t; +symbol true; +symbol false; +@@ + +( +- t == true ++ t +| +- true == t ++ t +| +- t != true ++ !t +| +- true != t ++ !t +| +- t == false ++ !t +| +- false == t ++ !t +| +- t != false ++ t +| +- false != t ++ t +) + +@depends on patch disable is_zero, isnt_zero@ +bool t; +@@ + +( +- t == 1 ++ t +| +- t != 1 ++ !t +| +- t == 0 ++ !t +| +- t != 0 ++ t +) + +@depends on patch@ +bool b; +@@ +( + b = +- 0 ++ false +| + b = +- 1 ++ true +) + +// --------------------------------------------------------------------- + +@r1 depends on !patch@ +bool t; +position p; +@@ + +( +* t@p == true +| +* true == t@p +| +* t@p != true +| +* true != t@p +| +* t@p == false +| +* false == t@p +| +* t@p != false +| +* false != t@p +) + +@r2 depends on !patch disable is_zero, isnt_zero@ +bool t; +position p; +@@ + +( +* t@p == 1 +| +* t@p != 1 +| +* t@p == 0 +| +* t@p != 0 +) + +@r3 depends on !patch@ +bool b; +position p1,p2; +constant c; +@@ +( +*b@p1 = 0 +| +*b@p1 = 1 +| +*b@p2 = c +) + +@script:python depends on org@ +p << r1.p; +@@ + +cocci.print_main("WARNING: Comparison to bool",p) + +@script:python depends on org@ +p << r2.p; +@@ + +cocci.print_main("WARNING: Comparison of bool to 0/1",p) + +@script:python depends on org@ +p1 << r3.p1; +@@ + +cocci.print_main("WARNING: Assignment of bool to 0/1",p1) + +@script:python depends on org@ +p2 << r3.p2; +@@ + +cocci.print_main("ERROR: Assignment of bool to non-0/1 constant",p2) + +@script:python depends on report@ +p << r1.p; +@@ + +coccilib.report.print_report(p[0],"WARNING: Comparison to bool") + +@script:python depends on report@ +p << r2.p; +@@ + +coccilib.report.print_report(p[0],"WARNING: Comparison of bool to 0/1") + +@script:python depends on report@ +p1 << r3.p1; +@@ + +coccilib.report.print_report(p1[0],"WARNING: Assignment of bool to 0/1") + +@script:python depends on report@ +p2 << r3.p2; +@@ + +coccilib.report.print_report(p2[0],"ERROR: Assignment of bool to non-0/1 constant") diff --git a/scripts/coccinelle/misc/cstptr.cocci b/scripts/coccinelle/misc/cstptr.cocci new file mode 100644 index 000000000000..d42564484528 --- /dev/null +++ b/scripts/coccinelle/misc/cstptr.cocci @@ -0,0 +1,41 @@ +/// PTR_ERR should be applied before its argument is reassigned, typically +/// to NULL +/// +// Confidence: High +// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual org +virtual report +virtual context + +@r exists@ +expression e,e1; +constant c; +position p1,p2; +@@ + +*e@p1 = c +... when != e = e1 + when != &e + when != true IS_ERR(e) +*PTR_ERR@p2(e) + +@script:python depends on org@ +p1 << r.p1; +p2 << r.p2; +@@ + +cocci.print_main("PTR_ERR",p2) +cocci.print_secs("assignment",p1) + +@script:python depends on report@ +p1 << r.p1; +p2 << r.p2; +@@ + +msg = "ERROR: PTR_ERR applied after initialization to constant on line %s" % (p1[0].line) +coccilib.report.print_report(p2[0],msg) 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 @@ /// initialization. /// // Confidence: Low -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. // URL: http://coccinelle.lip6.fr/ // Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise // Options: -no_includes -include_headers @@ -49,5 +49,5 @@ pr << r.p; @@ 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)): - msg = "%s: first occurrence %s, second occurrence %s" % (fld,ps[0].line,pr[0].line) + msg = "%s: first occurrence line %s, second occurrence line %s" % (fld,ps[0].line,pr[0].line) coccilib.report.print_report(p0[0],msg) diff --git a/scripts/coccinelle/null/badzero.cocci b/scripts/coccinelle/null/badzero.cocci new file mode 100644 index 000000000000..d79baf7220e7 --- /dev/null +++ b/scripts/coccinelle/null/badzero.cocci @@ -0,0 +1,237 @@ +/// Compare pointer-typed values to NULL rather than 0 +/// +//# This makes an effort to choose between !x and x == NULL. !x is used +//# if it has previously been used with the function used to initialize x. +//# This relies on type information. More type information can be obtained +//# using the option -all_includes and the option -I to specify an +//# include path. +// +// Confidence: High +// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: + +virtual patch +virtual context +virtual org +virtual report + +@initialize:ocaml@ +let negtable = Hashtbl.create 101 + +@depends on patch@ +expression *E; +identifier f; +@@ + +( + (E = f(...)) == +- 0 ++ NULL +| + (E = f(...)) != +- 0 ++ NULL +| +- 0 ++ NULL + == (E = f(...)) +| +- 0 ++ NULL + != (E = f(...)) +) + + +@t1 depends on !patch@ +expression *E; +identifier f; +position p; +@@ + +( + (E = f(...)) == +* 0@p +| + (E = f(...)) != +* 0@p +| +* 0@p + == (E = f(...)) +| +* 0@p + != (E = f(...)) +) + +@script:python depends on org@ +p << t1.p; +@@ + +coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") + +@script:python depends on report@ +p << t1.p; +@@ + +coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") + +// Tests of returned values + +@s@ +identifier f; +expression E,E1; +@@ + + E = f(...) + ... when != E = E1 + !E + +@script:ocaml depends on s@ +f << s.f; +@@ + +try let _ = Hashtbl.find negtable f in () +with Not_found -> Hashtbl.add negtable f () + +@ r disable is_zero,isnt_zero exists @ +expression *E; +identifier f; +@@ + +E = f(...) +... +(E == 0 +|E != 0 +|0 == E +|0 != E +) + +@script:ocaml@ +f << r.f; +@@ + +try let _ = Hashtbl.find negtable f in () +with Not_found -> include_match false + +// This rule may lead to inconsistent path problems, if E is defined in two +// places +@ depends on patch disable is_zero,isnt_zero @ +expression *E; +expression E1; +identifier r.f; +@@ + +E = f(...) +<... +( +- E == 0 ++ !E +| +- E != 0 ++ E +| +- 0 == E ++ !E +| +- 0 != E ++ E +) +...> +?E = E1 + +@t2 depends on !patch disable is_zero,isnt_zero @ +expression *E; +expression E1; +identifier r.f; +position p1; +position p2; +@@ + +E = f(...) +<... +( +* E == 0@p1 +| +* E != 0@p2 +| +* 0@p1 == E +| +* 0@p1 != E +) +...> +?E = E1 + +@script:python depends on org@ +p << t2.p1; +@@ + +coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0, suggest !E") + +@script:python depends on org@ +p << t2.p2; +@@ + +coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") + +@script:python depends on report@ +p << t2.p1; +@@ + +coccilib.report.print_report(p[0], "WARNING comparing pointer to 0, suggest !E") + +@script:python depends on report@ +p << t2.p2; +@@ + +coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") + +@ depends on patch disable is_zero,isnt_zero @ +expression *E; +@@ + +( + E == +- 0 ++ NULL +| + E != +- 0 ++ NULL +| +- 0 ++ NULL + == E +| +- 0 ++ NULL + != E +) + +@ t3 depends on !patch disable is_zero,isnt_zero @ +expression *E; +position p; +@@ + +( +* E == 0@p +| +* E != 0@p +| +* 0@p == E +| +* 0@p != E +) + +@script:python depends on org@ +p << t3.p; +@@ + +coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") + +@script:python depends on report@ +p << t3.p; +@@ + +coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") 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 @@ /// The various basic memory allocation functions don't return ERR_PTR /// // Confidence: High -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. // URL: http://coccinelle.lip6.fr/ // Comments: // Options: -no_includes -include_headers virtual patch +virtual context +virtual org +virtual report -@@ +@depends on patch@ expression x,E; @@ @@ -18,3 +21,28 @@ x = \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache ... when != x = E - IS_ERR(x) + !x + +@r depends on !patch exists@ +expression x,E; +position p1,p2; +@@ + +*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\)(...) +... when != x = E +* IS_ERR@p2(x) + +@script:python depends on org@ +p1 << r.p1; +p2 << r.p2; +@@ + +cocci.print_main("alloc call",p1) +cocci.print_secs("IS_ERR that should be NULL tests",p2) + +@script:python depends on report@ +p1 << r.p1; +p2 << r.p2; +@@ + +msg = "ERROR: allocation function on line %s returns NULL not ERR_PTR on failure" % (p1[0].line) +coccilib.report.print_report(p2[0], msg) diff --git a/scripts/depmod.sh b/scripts/depmod.sh index a27235685949..2ae481703141 100755 --- a/scripts/depmod.sh +++ b/scripts/depmod.sh @@ -9,12 +9,6 @@ fi DEPMOD=$1 KERNELRELEASE=$2 -if ! "$DEPMOD" -V 2>/dev/null | grep -q module-init-tools; then - echo "Warning: you may need to install module-init-tools" >&2 - echo "See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt" >&2 - sleep 1 -fi - if ! test -r System.map -a -x "$DEPMOD"; then exit 0 fi diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c index cbc0193098e4..2ef5e2e3dd38 100644 --- a/scripts/dtc/dtc.c +++ b/scripts/dtc/dtc.c @@ -71,6 +71,7 @@ static void __attribute__ ((noreturn)) usage(void) fprintf(stderr, "\t\t\tasm - assembler source\n"); fprintf(stderr, "\t-V <output version>\n"); fprintf(stderr, "\t\tBlob version to produce, defaults to %d (relevant for dtb\n\t\tand asm output only)\n", DEFAULT_FDT_VERSION); + fprintf(stderr, "\t-d <output dependency file>\n"); fprintf(stderr, "\t-R <number>\n"); fprintf(stderr, "\t\tMake space for <number> reserve map entries (relevant for \n\t\tdtb and asm output only)\n"); fprintf(stderr, "\t-S <bytes>\n"); @@ -99,7 +100,8 @@ int main(int argc, char *argv[]) const char *inform = "dts"; const char *outform = "dts"; const char *outname = "-"; - int force = 0, check = 0, sort = 0; + const char *depname = NULL; + int force = 0, sort = 0; const char *arg; int opt; FILE *outf = NULL; @@ -111,7 +113,8 @@ int main(int argc, char *argv[]) minsize = 0; padsize = 0; - while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:vH:s")) != EOF) { + while ((opt = getopt(argc, argv, "hI:O:o:V:d:R:S:p:fcqb:vH:s")) + != EOF) { switch (opt) { case 'I': inform = optarg; @@ -125,6 +128,9 @@ int main(int argc, char *argv[]) case 'V': outversion = strtol(optarg, NULL, 0); break; + case 'd': + depname = optarg; + break; case 'R': reservenum = strtol(optarg, NULL, 0); break; @@ -137,9 +143,6 @@ int main(int argc, char *argv[]) case 'f': force = 1; break; - case 'c': - check = 1; - break; case 'q': quiet++; break; @@ -188,6 +191,14 @@ int main(int argc, char *argv[]) fprintf(stderr, "DTC: %s->%s on file \"%s\"\n", inform, outform, arg); + if (depname) { + depfile = fopen(depname, "w"); + if (!depfile) + die("Couldn't open dependency file %s: %s\n", depname, + strerror(errno)); + fprintf(depfile, "%s:", outname); + } + if (streq(inform, "dts")) bi = dt_from_source(arg); else if (streq(inform, "fs")) @@ -197,6 +208,11 @@ int main(int argc, char *argv[]) else die("Unknown input format \"%s\"\n", inform); + if (depfile) { + fputc('\n', depfile); + fclose(depfile); + } + if (cmdline_boot_cpuid != -1) bi->boot_cpuid_phys = cmdline_boot_cpuid; diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c index ead0332c87e1..28d0b2381df6 100644 --- a/scripts/dtc/flattree.c +++ b/scripts/dtc/flattree.c @@ -697,7 +697,6 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) { struct reserve_info *reservelist = NULL; struct reserve_info *new; - const char *p; struct fdt_reserve_entry re; /* @@ -706,7 +705,6 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) * * First pass, count entries. */ - p = inb->ptr; while (1) { flat_read_chunk(inb, &re, sizeof(re)); re.address = fdt64_to_cpu(re.address); 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) return NULL; } +FILE *depfile; /* = NULL */ struct srcfile_state *current_srcfile; /* = NULL */ /* Detect infinite include recursion. */ @@ -67,6 +68,9 @@ FILE *srcfile_relative_open(const char *fname, char **fullnamep) strerror(errno)); } + if (depfile) + fprintf(depfile, " %s", fullname); + if (fullnamep) *fullnamep = fullname; 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 { struct srcfile_state *prev; }; +extern FILE *depfile; /* = NULL */ extern struct srcfile_state *current_srcfile; /* = NULL */ FILE *srcfile_relative_open(const char *fname, char **fullnamep); diff --git a/scripts/gcc-goto.sh b/scripts/gcc-goto.sh index 98cffcb941ea..a2af2e88daf3 100644 --- a/scripts/gcc-goto.sh +++ b/scripts/gcc-goto.sh @@ -2,4 +2,20 @@ # Test for gcc 'asm goto' support # Copyright (C) 2010, Jason Baron <jbaron@redhat.com> -echo "int main(void) { entry: asm goto (\"\"::::entry); return 0; }" | $@ -x c - -c -o /dev/null >/dev/null 2>&1 && echo "y" +cat << "END" | $@ -x c - -c -o /dev/null >/dev/null 2>&1 && echo "y" +int main(void) +{ +#ifdef __arm__ + /* + * Not related to asm goto, but used by jump label + * and broken on some ARM GCC versions (see GCC Bug 48637). + */ + static struct { int dummy; int state; } tp; + asm (".long %c0" :: "i" (&tp.state)); +#endif + +entry: + asm goto ("" :::: entry); + return 0; +} +END 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) # dependencies on generated files need to be listed explicitly $(obj)/lex.lex.o: $(obj)/keywords.hash.c $(obj)/parse.tab.h +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 f32a04c4c5bc..0948c6b5a321 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -931,7 +931,7 @@ sub get_maintainer_role { my $start = find_starting_index($index); my $end = find_ending_index($index); - my $role; + my $role = "unknown"; my $subsystem = $typevalue[$start]; if (length($subsystem) > 20) { $subsystem = substr($subsystem, 0, 17); @@ -1027,8 +1027,13 @@ sub add_categories { if ($email_list) { if (!$hash_list_to{lc($list_address)}) { $hash_list_to{lc($list_address)} = 1; - push(@list_to, [$list_address, - "open list${list_role}"]); + if ($list_additional =~ m/moderated/) { + push(@list_to, [$list_address, + "moderated list${list_role}"]); + } else { + push(@list_to, [$list_address, + "open list${list_role}"]); + } } } } diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl index 7957e7a5166a..64ac2380e4d5 100644 --- a/scripts/headers_check.pl +++ b/scripts/headers_check.pl @@ -19,6 +19,7 @@ # 3) Check for leaked CONFIG_ symbols use strict; +use File::Basename; my ($dir, $arch, @files) = @ARGV; @@ -99,6 +100,39 @@ sub check_asm_types } my $linux_types; +my %import_stack = (); +sub check_include_typesh +{ + my $path = $_[0]; + my $import_path; + + my $fh; + my @file_paths = ($path, $dir . "/" . $path, dirname($filename) . "/" . $path); + for my $possible ( @file_paths ) { + if (not $import_stack{$possible} and open($fh, '<', $possible)) { + $import_path = $possible; + $import_stack{$import_path} = 1; + last; + } + } + if (eof $fh) { + return; + } + + my $line; + while ($line = <$fh>) { + if ($line =~ m/^\s*#\s*include\s+<linux\/types.h>/) { + $linux_types = 1; + last; + } + if (my $included = ($line =~ /^\s*#\s*include\s+[<"](\S+)[>"]/)[0]) { + check_include_typesh($included); + } + } + close $fh; + delete $import_stack{$import_path}; +} + sub check_sizetypes { if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) { @@ -113,6 +147,9 @@ sub check_sizetypes $linux_types = 1; return; } + if (my $included = ($line =~ /^\s*#\s*include\s+[<"](\S+)[>"]/)[0]) { + check_include_typesh($included); + } if ($line =~ m/__[us](8|16|32|64)\b/) { printf STDERR "$filename:$lineno: " . "found __[us]{8,16,32,64} type " . @@ -122,4 +159,3 @@ sub check_sizetypes #$ret = 1; } } - 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 # Create new linux.pot file # Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files -# The symlink is used to repair a deficiency in arch/um update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h - $(Q)echo " GEN config" + $(Q)echo " GEN config.pot" $(Q)xgettext --default-domain=linux \ --add-comments --keyword=_ --keyword=N_ \ --from-code=UTF-8 \ @@ -63,10 +62,11 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h $(Q)(for i in `ls $(srctree)/arch/*/Kconfig \ $(srctree)/arch/*/um/Kconfig`; \ do \ - echo " GEN $$i"; \ + echo " GEN $$i"; \ $(obj)/kxgettext $$i \ >> $(obj)/config.pot; \ done ) + $(Q)echo " GEN linux.pot" $(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \ --output $(obj)/linux.pot $(Q)rm -f $(obj)/config.pot diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 5a58965d8800..52577f052bc1 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -344,10 +344,8 @@ setsym: int conf_read(const char *name) { - struct symbol *sym, *choice_sym; - struct property *prop; - struct expr *e; - int i, flags; + struct symbol *sym; + int i; sym_set_change_count(0); @@ -357,7 +355,7 @@ int conf_read(const char *name) for_all_symbols(i, sym) { sym_calc_value(sym); if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO)) - goto sym_ok; + continue; if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { /* check that calculated value agrees with saved value */ switch (sym->type) { @@ -366,30 +364,18 @@ int conf_read(const char *name) if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym)) break; if (!sym_is_choice(sym)) - goto sym_ok; + continue; /* fall through */ default: if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) - goto sym_ok; + continue; break; } } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) /* no previous value and not saved */ - goto sym_ok; + continue; conf_unsaved++; /* maybe print value in verbose mode... */ - sym_ok: - if (!sym_is_choice(sym)) - continue; - /* The choice symbol only has a set value (and thus is not new) - * if all its visible childs have values. - */ - prop = sym_get_choice_prop(sym); - flags = sym->flags; - expr_list_for_each_sym(prop->expr, e, choice_sym) - if (choice_sym->visible != no) - flags &= choice_sym->flags; - sym->flags &= flags | ~SYMBOL_DEF_USER; } for_all_symbols(i, sym) { @@ -464,7 +450,7 @@ kconfig_print_comment(FILE *fp, const char *value, void *arg) fprintf(fp, "#"); if (l) { fprintf(fp, " "); - fwrite(p, l, 1, fp); + xfwrite(p, l, 1, fp); p += l; } fprintf(fp, "\n"); @@ -537,7 +523,7 @@ header_print_comment(FILE *fp, const char *value, void *arg) fprintf(fp, " *"); if (l) { fprintf(fp, " "); - fwrite(p, l, 1, fp); + xfwrite(p, l, 1, fp); p += l; } fprintf(fp, "\n"); @@ -554,35 +540,6 @@ static struct conf_printer header_printer_cb = }; /* - * Generate the __enabled_CONFIG_* and __enabled_CONFIG_*_MODULE macros for - * use by the IS_{ENABLED,BUILTIN,MODULE} macros. The _MODULE variant is - * generated even for booleans so that the IS_ENABLED() macro works. - */ -static void -header_print__enabled_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) -{ - - switch (sym->type) { - case S_BOOLEAN: - case S_TRISTATE: { - fprintf(fp, "#define __enabled_" CONFIG_ "%s %d\n", - sym->name, (*value == 'y')); - fprintf(fp, "#define __enabled_" CONFIG_ "%s_MODULE %d\n", - sym->name, (*value == 'm')); - break; - } - default: - break; - } -} - -static struct conf_printer header__enabled_printer_cb = -{ - .print_symbol = header_print__enabled_symbol, - .print_comment = header_print_comment, -}; - -/* * Tristate printer * * This printer is used when generating the `include/config/tristate.conf' file. @@ -963,16 +920,11 @@ int conf_write_autoconf(void) conf_write_heading(out_h, &header_printer_cb, NULL); for_all_symbols(i, sym) { - if (!sym->name) - continue; - sym_calc_value(sym); - - conf_write_symbol(out_h, sym, &header__enabled_printer_cb, NULL); - - if (!(sym->flags & SYMBOL_WRITE)) + if (!(sym->flags & SYMBOL_WRITE) || !sym->name) continue; + /* write symbol to auto.conf, tristate and header files */ conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1); conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1); 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 @@ extern "C" { #endif +#include <assert.h> #include <stdio.h> #ifndef __cplusplus #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) dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, - GTK_BUTTONS_CLOSE, intro_text); + GTK_BUTTONS_CLOSE, "%s", intro_text); g_signal_connect_swapped(GTK_OBJECT(dialog), "response", G_CALLBACK(gtk_widget_destroy), GTK_OBJECT(dialog)); @@ -701,7 +701,7 @@ void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data) dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, - GTK_BUTTONS_CLOSE, about_text); + GTK_BUTTONS_CLOSE, "%s", about_text); g_signal_connect_swapped(GTK_OBJECT(dialog), "response", G_CALLBACK(gtk_widget_destroy), GTK_OBJECT(dialog)); @@ -720,7 +720,7 @@ void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data) dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, - GTK_BUTTONS_CLOSE, license_text); + GTK_BUTTONS_CLOSE, "%s", license_text); g_signal_connect_swapped(GTK_OBJECT(dialog), "response", G_CALLBACK(gtk_widget_destroy), GTK_OBJECT(dialog)); @@ -830,7 +830,7 @@ static void renderer_edited(GtkCellRendererText * cell, static void change_sym_value(struct menu *menu, gint col) { struct symbol *sym = menu->sym; - tristate oldval, newval; + tristate newval; if (!sym) return; @@ -847,7 +847,6 @@ static void change_sym_value(struct menu *menu, gint col) switch (sym_get_type(sym)) { case S_BOOLEAN: case S_TRISTATE: - oldval = sym_get_tristate_value(sym); if (!sym_tristate_within_range(sym, newval)) newval = yes; sym_set_tristate_value(sym, newval); @@ -1278,7 +1277,6 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) gboolean valid; GtkTreeIter *sibling; struct symbol *sym; - struct property *prop; struct menu *menu1, *menu2; if (src == &rootmenu) @@ -1287,7 +1285,6 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) valid = gtk_tree_model_iter_children(model2, child2, dst); for (child1 = src->list; child1; child1 = child1->next) { - prop = child1->prompt; sym = child1->sym; 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 { /* confdata.c and expr.c */ static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) { - if (fwrite(str, len, count, out) < count) - fprintf(stderr, "\nError in writing or end of file.\n"); + assert(len != 0); + + if (fwrite(str, len, count, out) != count) + fprintf(stderr, "Error in writing or end of file.\n"); } /* 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) fprintf(stderr, _("\n\n" "Your configuration changes were NOT saved." "\n\n")); + if (res != KEY_ESC) + res = 0; } return res; diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh new file mode 100755 index 000000000000..974d5cb7e30a --- /dev/null +++ b/scripts/kconfig/merge_config.sh @@ -0,0 +1,130 @@ +#!/bin/sh +# merge_config.sh - Takes a list of config fragment values, and merges +# them one by one. Provides warnings on overridden values, and specified +# values that did not make it to the resulting .config file (due to missed +# dependencies or config symbol removal). +# +# Portions reused from kconf_check and generate_cfg: +# http://git.yoctoproject.org/cgit/cgit.cgi/yocto-kernel-tools/tree/tools/kconf_check +# http://git.yoctoproject.org/cgit/cgit.cgi/yocto-kernel-tools/tree/tools/generate_cfg +# +# Copyright (c) 2009-2010 Wind River Systems, Inc. +# Copyright 2011 Linaro +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. + +clean_up() { + rm -f $TMP_FILE + exit +} +trap clean_up HUP INT TERM + +usage() { + echo "Usage: $0 [OPTIONS] [CONFIG [...]]" + echo " -h display this help text" + echo " -m only merge the fragments, do not execute the make command" + echo " -n use allnoconfig instead of alldefconfig" + echo " -r list redundant entries when merging fragments" +} + +MAKE=true +ALLTARGET=alldefconfig +WARNREDUN=false + +while true; do + case $1 in + "-n") + ALLTARGET=allnoconfig + shift + continue + ;; + "-m") + MAKE=false + shift + continue + ;; + "-h") + usage + exit + ;; + "-r") + WARNREDUN=true + shift + continue + ;; + *) + break + ;; + esac +done + +INITFILE=$1 +shift; + +MERGE_LIST=$* +SED_CONFIG_EXP="s/^\(# \)\{0,1\}\(CONFIG_[a-zA-Z0-9_]*\)[= ].*/\2/p" +TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) + +echo "Using $INITFILE as base" +cat $INITFILE > $TMP_FILE + +# Merge files, printing warnings on overrided values +for MERGE_FILE in $MERGE_LIST ; do + echo "Merging $MERGE_FILE" + CFG_LIST=$(sed -n "$SED_CONFIG_EXP" $MERGE_FILE) + + for CFG in $CFG_LIST ; do + grep -q -w $CFG $TMP_FILE + if [ $? -eq 0 ] ; then + PREV_VAL=$(grep -w $CFG $TMP_FILE) + NEW_VAL=$(grep -w $CFG $MERGE_FILE) + if [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then + echo Value of $CFG is redefined by fragment $MERGE_FILE: + echo Previous value: $PREV_VAL + echo New value: $NEW_VAL + echo + elif [ "$WARNREDUN" = "true" ]; then + echo Value of $CFG is redundant by fragment $MERGE_FILE: + fi + sed -i "/$CFG[ =]/d" $TMP_FILE + fi + done + cat $MERGE_FILE >> $TMP_FILE +done + +if [ "$MAKE" = "false" ]; then + cp $TMP_FILE .config + echo "#" + echo "# merged configuration written to .config (needs make)" + echo "#" + clean_up + exit +fi + +# Use the merged file as the starting point for: +# alldefconfig: Fills in any missing symbols with Kconfig default +# allnoconfig: Fills in any missing symbols with # CONFIG_* is not set +make KCONFIG_ALLCONFIG=$TMP_FILE $ALLTARGET + + +# Check all specified config values took (might have missed-dependency issues) +for CFG in $(sed -n "$SED_CONFIG_EXP" $TMP_FILE); do + + REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE) + ACTUAL_VAL=$(grep -w -e "$CFG" .config) + if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then + echo "Value requested for $CFG not in final .config" + echo "Requested value: $REQUESTED_VAL" + echo "Actual value: $ACTUAL_VAL" + echo "" + fi +done + +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) { read_kconfig($kconfig); } +sub convert_vars { + my ($line, %vars) = @_; + + my $process = ""; + + while ($line =~ s/^(.*?)(\$\((.*?)\))//) { + my $start = $1; + my $variable = $2; + my $var = $3; + + if (defined($vars{$var})) { + $process .= $start . $vars{$var}; + } else { + $process .= $start . $variable; + } + } + + $process .= $line; + + return $process; +} + # Read all Makefiles to map the configs to the objects foreach my $makefile (@makefiles) { - my $cont = 0; + my $line = ""; + my %make_vars; open(MIN,$makefile) || die "Can't open $makefile"; while (<MIN>) { + # if this line ends with a backslash, continue + chomp; + if (/^(.*)\\$/) { + $line .= $1; + next; + } + + $line .= $_; + $_ = $line; + $line = ""; + my $objs; - # is this a line after a line with a backslash? - if ($cont && /(\S.*)$/) { - $objs = $1; - } - $cont = 0; + $_ = convert_vars($_, %make_vars); # collect objects after obj-$(CONFIG_FOO_BAR) if (/obj-\$\((CONFIG_[^\)]*)\)\s*[+:]?=\s*(.*)/) { $var = $1; $objs = $2; + + # check if variables are set + } elsif (/^\s*(\S+)\s*[:]?=\s*(.*\S)/) { + $make_vars{$1} = $2; } if (defined($objs)) { - # test if the line ends with a backslash - if ($objs =~ m,(.*)\\$,) { - $objs = $1; - $cont = 1; - } - foreach my $obj (split /\s+/,$objs) { $obj =~ s/-/_/g; if ($obj =~ /(.*)\.o$/) { diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 071f00c3046e..22a3c400fc41 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -262,11 +262,18 @@ static struct symbol *sym_calc_choice(struct symbol *sym) struct symbol *def_sym; struct property *prop; struct expr *e; + int flags; /* first calculate all choice values' visibilities */ + flags = sym->flags; prop = sym_get_choice_prop(sym); - expr_list_for_each_sym(prop->expr, e, def_sym) + expr_list_for_each_sym(prop->expr, e, def_sym) { sym_calc_visibility(def_sym); + if (def_sym->visible != no) + flags &= def_sym->flags; + } + + sym->flags &= flags | ~SYMBOL_DEF_USER; /* is the user choice visible? */ def_sym = sym->def[S_DEF_USER].val; diff --git a/scripts/kernel-doc b/scripts/kernel-doc index d793001929cf..9b0c0b8b4ab4 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -5,7 +5,7 @@ use strict; ## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ## ## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ## ## Copyright (C) 2001 Simon Huggins ## -## Copyright (C) 2005-2010 Randy Dunlap ## +## Copyright (C) 2005-2012 Randy Dunlap ## ## ## ## #define enhancements by Armin Kuster <akuster@mvista.com> ## ## Copyright (c) 2000 MontaVista Software, Inc. ## @@ -1785,6 +1785,7 @@ sub dump_function($$) { $prototype =~ s/__devinit +//; $prototype =~ s/__init +//; $prototype =~ s/__init_or_module +//; + $prototype =~ s/__must_check +//; $prototype =~ s/^#\s*define\s+//; #ak added $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//; diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 363ab4666b17..8e730ccc3f2b 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -28,6 +28,7 @@ typedef Elf64_Addr kernel_ulong_t; #endif #include <ctype.h> +#include <stdbool.h> typedef uint32_t __u32; typedef uint16_t __u16; @@ -38,6 +39,61 @@ typedef unsigned char __u8; * we handle those differences explicitly below */ #include "../../include/linux/mod_devicetable.h" +/* This array collects all instances that use the generic do_table */ +struct devtable { + const char *device_id; /* name of table, __mod_<name>_device_table. */ + unsigned long id_size; + void *function; +}; + +#define ___cat(a,b) a ## b +#define __cat(a,b) ___cat(a,b) + +/* we need some special handling for this host tool running eventually on + * Darwin. The Mach-O section handling is a bit different than ELF section + * handling. The differnces in detail are: + * a) we have segments which have sections + * b) we need a API call to get the respective section symbols */ +#if defined(__MACH__) +#include <mach-o/getsect.h> + +#define INIT_SECTION(name) do { \ + unsigned long name ## _len; \ + char *__cat(pstart_,name) = getsectdata("__TEXT", \ + #name, &__cat(name,_len)); \ + char *__cat(pstop_,name) = __cat(pstart_,name) + \ + __cat(name, _len); \ + __cat(__start_,name) = (void *)__cat(pstart_,name); \ + __cat(__stop_,name) = (void *)__cat(pstop_,name); \ + } while (0) +#define SECTION(name) __attribute__((section("__TEXT, " #name))) + +struct devtable **__start___devtable, **__stop___devtable; +#else +#define INIT_SECTION(name) /* no-op for ELF */ +#define SECTION(name) __attribute__((section(#name))) + +/* We construct a table of pointers in an ELF section (pointers generally + * go unpadded by gcc). ld creates boundary syms for us. */ +extern struct devtable *__start___devtable[], *__stop___devtable[]; +#endif /* __MACH__ */ + +#if __GNUC__ == 3 && __GNUC_MINOR__ < 3 +# define __used __attribute__((__unused__)) +#else +# define __used __attribute__((__used__)) +#endif + +/* Add a table entry. We test function type matches while we're here. */ +#define ADD_TO_DEVTABLE(device_id, type, function) \ + static struct devtable __cat(devtable,__LINE__) = { \ + device_id + 0*sizeof((function)((const char *)NULL, \ + (type *)NULL, \ + (char *)NULL)), \ + sizeof(type), (function) }; \ + static struct devtable *SECTION(__devtable) __used \ + __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__) + #define ADD(str, sep, cond, field) \ do { \ strcat(str, sep); \ @@ -289,6 +345,7 @@ static int do_hid_entry(const char *filename, return 1; } +ADD_TO_DEVTABLE("hid", struct hid_device_id, do_hid_entry); /* Looks like: ieee1394:venNmoNspNverN */ static int do_ieee1394_entry(const char *filename, @@ -313,6 +370,7 @@ static int do_ieee1394_entry(const char *filename, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("ieee1394", struct ieee1394_device_id, do_ieee1394_entry); /* Looks like: pci:vNdNsvNsdNbcNscNiN. */ static int do_pci_entry(const char *filename, @@ -356,6 +414,7 @@ static int do_pci_entry(const char *filename, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("pci", struct pci_device_id, do_pci_entry); /* looks like: "ccw:tNmNdtNdmN" */ static int do_ccw_entry(const char *filename, @@ -379,6 +438,7 @@ static int do_ccw_entry(const char *filename, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("ccw", struct ccw_device_id, do_ccw_entry); /* looks like: "ap:tN" */ static int do_ap_entry(const char *filename, @@ -387,6 +447,7 @@ static int do_ap_entry(const char *filename, sprintf(alias, "ap:t%02X*", id->dev_type); return 1; } +ADD_TO_DEVTABLE("ap", struct ap_device_id, do_ap_entry); /* looks like: "css:tN" */ static int do_css_entry(const char *filename, @@ -395,6 +456,7 @@ static int do_css_entry(const char *filename, sprintf(alias, "css:t%01X", id->type); return 1; } +ADD_TO_DEVTABLE("css", struct css_device_id, do_css_entry); /* Looks like: "serio:tyNprNidNexN" */ static int do_serio_entry(const char *filename, @@ -414,6 +476,7 @@ static int do_serio_entry(const char *filename, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("serio", struct serio_device_id, do_serio_entry); /* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */ static int do_acpi_entry(const char *filename, @@ -422,6 +485,7 @@ static int do_acpi_entry(const char *filename, sprintf(alias, "acpi*:%s:*", id->id); return 1; } +ADD_TO_DEVTABLE("acpi", struct acpi_device_id, do_acpi_entry); /* looks like: "pnp:dD" */ static void do_pnp_device_entry(void *symval, unsigned long size, @@ -544,8 +608,7 @@ static int do_pcmcia_entry(const char *filename, add_wildcard(alias); return 1; } - - +ADD_TO_DEVTABLE("pcmcia", struct pcmcia_device_id, do_pcmcia_entry); static int do_of_entry (const char *filename, struct of_device_id *of, char *alias) { @@ -568,6 +631,7 @@ static int do_of_entry (const char *filename, struct of_device_id *of, char *ali add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("of", struct of_device_id, do_of_entry); static int do_vio_entry(const char *filename, struct vio_device_id *vio, char *alias) @@ -585,6 +649,7 @@ static int do_vio_entry(const char *filename, struct vio_device_id *vio, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("vio", struct vio_device_id, do_vio_entry); #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) @@ -640,6 +705,7 @@ static int do_input_entry(const char *filename, struct input_device_id *id, do_input(alias, id->swbit, 0, INPUT_DEVICE_ID_SW_MAX); return 1; } +ADD_TO_DEVTABLE("input", struct input_device_id, do_input_entry); static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa, char *alias) @@ -650,6 +716,7 @@ static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa, strcat(alias, "*"); return 1; } +ADD_TO_DEVTABLE("eisa", struct eisa_device_id, do_eisa_entry); /* Looks like: parisc:tNhvNrevNsvN */ static int do_parisc_entry(const char *filename, struct parisc_device_id *id, @@ -669,6 +736,7 @@ static int do_parisc_entry(const char *filename, struct parisc_device_id *id, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("parisc", struct parisc_device_id, do_parisc_entry); /* Looks like: sdio:cNvNdN. */ static int do_sdio_entry(const char *filename, @@ -685,6 +753,7 @@ static int do_sdio_entry(const char *filename, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("sdio", struct sdio_device_id, do_sdio_entry); /* Looks like: ssb:vNidNrevN. */ static int do_ssb_entry(const char *filename, @@ -701,6 +770,7 @@ static int do_ssb_entry(const char *filename, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("ssb", struct ssb_device_id, do_ssb_entry); /* Looks like: bcma:mNidNrevNclN. */ static int do_bcma_entry(const char *filename, @@ -719,6 +789,7 @@ static int do_bcma_entry(const char *filename, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("bcma", struct bcma_device_id, do_bcma_entry); /* Looks like: virtio:dNvN */ static int do_virtio_entry(const char *filename, struct virtio_device_id *id, @@ -734,6 +805,7 @@ static int do_virtio_entry(const char *filename, struct virtio_device_id *id, add_wildcard(alias); return 1; } +ADD_TO_DEVTABLE("virtio", struct virtio_device_id, do_virtio_entry); /* * Looks like: vmbus:guid @@ -755,6 +827,7 @@ static int do_vmbus_entry(const char *filename, struct hv_vmbus_device_id *id, return 1; } +ADD_TO_DEVTABLE("vmbus", struct hv_vmbus_device_id, do_vmbus_entry); /* Looks like: i2c:S */ static int do_i2c_entry(const char *filename, struct i2c_device_id *id, @@ -764,6 +837,7 @@ static int do_i2c_entry(const char *filename, struct i2c_device_id *id, return 1; } +ADD_TO_DEVTABLE("i2c", struct i2c_device_id, do_i2c_entry); /* Looks like: spi:S */ static int do_spi_entry(const char *filename, struct spi_device_id *id, @@ -773,6 +847,7 @@ static int do_spi_entry(const char *filename, struct spi_device_id *id, return 1; } +ADD_TO_DEVTABLE("spi", struct spi_device_id, do_spi_entry); static const struct dmifield { const char *prefix; @@ -827,6 +902,7 @@ static int do_dmi_entry(const char *filename, struct dmi_system_id *id, strcat(alias, ":"); return 1; } +ADD_TO_DEVTABLE("dmi", struct dmi_system_id, do_dmi_entry); static int do_platform_entry(const char *filename, struct platform_device_id *id, char *alias) @@ -834,6 +910,7 @@ static int do_platform_entry(const char *filename, sprintf(alias, PLATFORM_MODULE_PREFIX "%s", id->name); return 1; } +ADD_TO_DEVTABLE("platform", struct platform_device_id, do_platform_entry); static int do_mdio_entry(const char *filename, struct mdio_device_id *id, char *alias) @@ -856,6 +933,7 @@ static int do_mdio_entry(const char *filename, return 1; } +ADD_TO_DEVTABLE("mdio", struct mdio_device_id, do_mdio_entry); /* Looks like: zorro:iN. */ static int do_zorro_entry(const char *filename, struct zorro_device_id *id, @@ -866,6 +944,7 @@ static int do_zorro_entry(const char *filename, struct zorro_device_id *id, ADD(alias, "i", id->id != ZORRO_WILDCARD, id->id); return 1; } +ADD_TO_DEVTABLE("zorro", struct zorro_device_id, do_zorro_entry); /* looks like: "pnp:dD" */ static int do_isapnp_entry(const char *filename, @@ -879,6 +958,7 @@ static int do_isapnp_entry(const char *filename, (id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f); return 1; } +ADD_TO_DEVTABLE("isapnp", struct isapnp_device_id, do_isapnp_entry); /* * Append a match expression for a single masked hex digit. @@ -947,16 +1027,40 @@ static int do_amba_entry(const char *filename, return 1; } +ADD_TO_DEVTABLE("amba", struct amba_id, do_amba_entry); -/* Ignore any prefix, eg. some architectures prepend _ */ -static inline int sym_is(const char *symbol, const char *name) +/* LOOKS like x86cpu:vendor:VVVV:family:FFFF:model:MMMM:feature:*,FEAT,* + * All fields are numbers. It would be nicer to use strings for vendor + * and feature, but getting those out of the build system here is too + * complicated. + */ + +static int do_x86cpu_entry(const char *filename, struct x86_cpu_id *id, + char *alias) { - const char *match; + id->feature = TO_NATIVE(id->feature); + id->family = TO_NATIVE(id->family); + id->model = TO_NATIVE(id->model); + id->vendor = TO_NATIVE(id->vendor); - match = strstr(symbol, name); - if (!match) - return 0; - return match[strlen(name)] == '\0'; + strcpy(alias, "x86cpu:"); + ADD(alias, "vendor:", id->vendor != X86_VENDOR_ANY, id->vendor); + ADD(alias, ":family:", id->family != X86_FAMILY_ANY, id->family); + ADD(alias, ":model:", id->model != X86_MODEL_ANY, id->model); + strcat(alias, ":feature:*"); + if (id->feature != X86_FEATURE_ANY) + sprintf(alias + strlen(alias), "%04X*", id->feature); + return 1; +} +ADD_TO_DEVTABLE("x86cpu", struct x86_cpu_id, do_x86cpu_entry); + +/* Does namelen bytes of name exactly match the symbol? */ +static bool sym_is(const char *name, unsigned namelen, const char *symbol) +{ + if (namelen != strlen(symbol)) + return false; + + return memcmp(name, symbol, namelen) == 0; } static void do_table(void *symval, unsigned long size, @@ -989,11 +1093,25 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, { void *symval; char *zeros = NULL; + const char *name; + unsigned int namelen; /* We're looking for a section relative symbol */ if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections) return; + /* All our symbols are of form <prefix>__mod_XXX_device_table. */ + name = strstr(symname, "__mod_"); + if (!name) + return; + name += strlen("__mod_"); + namelen = strlen(name); + if (namelen < strlen("_device_table")) + return; + if (strcmp(name + namelen - strlen("_device_table"), "_device_table")) + return; + namelen -= strlen("_device_table"); + /* Handle all-NULL symbols allocated into .bss */ if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) { zeros = calloc(1, sym->st_size); @@ -1004,121 +1122,25 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, + sym->st_value; } - if (sym_is(symname, "__mod_pci_device_table")) - do_table(symval, sym->st_size, - sizeof(struct pci_device_id), "pci", - do_pci_entry, mod); - else if (sym_is(symname, "__mod_usb_device_table")) - /* special case to handle bcdDevice ranges */ + /* First handle the "special" cases */ + if (sym_is(name, namelen, "usb")) do_usb_table(symval, sym->st_size, mod); - else if (sym_is(symname, "__mod_hid_device_table")) - do_table(symval, sym->st_size, - sizeof(struct hid_device_id), "hid", - do_hid_entry, mod); - else if (sym_is(symname, "__mod_ieee1394_device_table")) - do_table(symval, sym->st_size, - sizeof(struct ieee1394_device_id), "ieee1394", - do_ieee1394_entry, mod); - else if (sym_is(symname, "__mod_ccw_device_table")) - do_table(symval, sym->st_size, - sizeof(struct ccw_device_id), "ccw", - do_ccw_entry, mod); - else if (sym_is(symname, "__mod_ap_device_table")) - do_table(symval, sym->st_size, - sizeof(struct ap_device_id), "ap", - do_ap_entry, mod); - else if (sym_is(symname, "__mod_css_device_table")) - do_table(symval, sym->st_size, - sizeof(struct css_device_id), "css", - do_css_entry, mod); - else if (sym_is(symname, "__mod_serio_device_table")) - do_table(symval, sym->st_size, - sizeof(struct serio_device_id), "serio", - do_serio_entry, mod); - else if (sym_is(symname, "__mod_acpi_device_table")) - do_table(symval, sym->st_size, - sizeof(struct acpi_device_id), "acpi", - do_acpi_entry, mod); - else if (sym_is(symname, "__mod_pnp_device_table")) + else if (sym_is(name, namelen, "pnp")) do_pnp_device_entry(symval, sym->st_size, mod); - else if (sym_is(symname, "__mod_pnp_card_device_table")) + else if (sym_is(name, namelen, "pnp_card")) do_pnp_card_entries(symval, sym->st_size, mod); - else if (sym_is(symname, "__mod_pcmcia_device_table")) - do_table(symval, sym->st_size, - sizeof(struct pcmcia_device_id), "pcmcia", - do_pcmcia_entry, mod); - else if (sym_is(symname, "__mod_of_device_table")) - do_table(symval, sym->st_size, - sizeof(struct of_device_id), "of", - do_of_entry, mod); - else if (sym_is(symname, "__mod_vio_device_table")) - do_table(symval, sym->st_size, - sizeof(struct vio_device_id), "vio", - do_vio_entry, mod); - else if (sym_is(symname, "__mod_input_device_table")) - do_table(symval, sym->st_size, - sizeof(struct input_device_id), "input", - do_input_entry, mod); - else if (sym_is(symname, "__mod_eisa_device_table")) - do_table(symval, sym->st_size, - sizeof(struct eisa_device_id), "eisa", - do_eisa_entry, mod); - else if (sym_is(symname, "__mod_parisc_device_table")) - do_table(symval, sym->st_size, - sizeof(struct parisc_device_id), "parisc", - do_parisc_entry, mod); - else if (sym_is(symname, "__mod_sdio_device_table")) - do_table(symval, sym->st_size, - sizeof(struct sdio_device_id), "sdio", - do_sdio_entry, mod); - else if (sym_is(symname, "__mod_ssb_device_table")) - do_table(symval, sym->st_size, - sizeof(struct ssb_device_id), "ssb", - do_ssb_entry, mod); - else if (sym_is(symname, "__mod_bcma_device_table")) - do_table(symval, sym->st_size, - sizeof(struct bcma_device_id), "bcma", - do_bcma_entry, mod); - else if (sym_is(symname, "__mod_virtio_device_table")) - do_table(symval, sym->st_size, - sizeof(struct virtio_device_id), "virtio", - do_virtio_entry, mod); - else if (sym_is(symname, "__mod_vmbus_device_table")) - do_table(symval, sym->st_size, - sizeof(struct hv_vmbus_device_id), "vmbus", - do_vmbus_entry, mod); - else if (sym_is(symname, "__mod_i2c_device_table")) - do_table(symval, sym->st_size, - sizeof(struct i2c_device_id), "i2c", - do_i2c_entry, mod); - else if (sym_is(symname, "__mod_spi_device_table")) - do_table(symval, sym->st_size, - sizeof(struct spi_device_id), "spi", - do_spi_entry, mod); - else if (sym_is(symname, "__mod_dmi_device_table")) - do_table(symval, sym->st_size, - sizeof(struct dmi_system_id), "dmi", - do_dmi_entry, mod); - else if (sym_is(symname, "__mod_platform_device_table")) - do_table(symval, sym->st_size, - sizeof(struct platform_device_id), "platform", - do_platform_entry, mod); - else if (sym_is(symname, "__mod_mdio_device_table")) - do_table(symval, sym->st_size, - sizeof(struct mdio_device_id), "mdio", - do_mdio_entry, mod); - else if (sym_is(symname, "__mod_zorro_device_table")) - do_table(symval, sym->st_size, - sizeof(struct zorro_device_id), "zorro", - do_zorro_entry, mod); - else if (sym_is(symname, "__mod_isapnp_device_table")) - do_table(symval, sym->st_size, - sizeof(struct isapnp_device_id), "isa", - do_isapnp_entry, mod); - else if (sym_is(symname, "__mod_amba_device_table")) - do_table(symval, sym->st_size, - sizeof(struct amba_id), "amba", - do_amba_entry, mod); + else { + struct devtable **p; + INIT_SECTION(__devtable); + + for (p = __start___devtable; p < __stop___devtable; p++) { + if (sym_is(name, namelen, (*p)->device_id)) { + do_table(symval, sym->st_size, (*p)->id_size, + (*p)->device_id, (*p)->function, mod); + break; + } + } + } free(zeros); } diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 2bd594e6d1b4..c4e7d1510f9d 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -132,8 +132,10 @@ static struct module *new_module(char *modname) /* strip trailing .o */ s = strrchr(p, '.'); if (s != NULL) - if (strcmp(s, ".o") == 0) + if (strcmp(s, ".o") == 0) { *s = '\0'; + mod->is_dot_o = 1; + } /* add to list */ mod->name = p; @@ -587,7 +589,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info, unsigned int crc; enum export export; - if (!is_vmlinux(mod->name) && strncmp(symname, "__ksymtab", 9) == 0) + if ((!is_vmlinux(mod->name) || mod->is_dot_o) && + strncmp(symname, "__ksymtab", 9) == 0) export = export_from_secname(info, get_secindex(info, sym)); else export = export_from_sec(info, get_secindex(info, sym)); @@ -849,7 +852,7 @@ static void check_section(const char *modname, struct elf_info *elf, #define ALL_INIT_DATA_SECTIONS \ ".init.setup$", ".init.rodata$", \ - ".devinit.rodata$", ".cpuinit.rodata$", ".meminit.rodata$" \ + ".devinit.rodata$", ".cpuinit.rodata$", ".meminit.rodata$", \ ".init.data$", ".devinit.data$", ".cpuinit.data$", ".meminit.data$" #define ALL_EXIT_DATA_SECTIONS \ ".exit.data$", ".devexit.data$", ".cpuexit.data$", ".memexit.data$" @@ -1494,6 +1497,13 @@ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) return 0; } +#ifndef R_ARM_CALL +#define R_ARM_CALL 28 +#endif +#ifndef R_ARM_JUMP24 +#define R_ARM_JUMP24 29 +#endif + static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) { unsigned int r_typ = ELF_R_TYPE(r->r_info); @@ -1505,6 +1515,8 @@ static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) (elf->symtab_start + ELF_R_SYM(r->r_info)); break; case R_ARM_PC24: + case R_ARM_CALL: + case R_ARM_JUMP24: /* From ARM ABI: ((S + A) | T) - P */ r->r_addend = (int)(long)(elf->hdr + sechdr->sh_offset + diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 2031119080dc..51207e4d5f8b 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -113,6 +113,7 @@ struct module { int has_cleanup; struct buffer dev_table_buf; char srcversion[25]; + int is_dot_o; }; struct elf_info { diff --git a/scripts/package/builddeb b/scripts/package/builddeb index f6cbc3ddb68b..eee5f8ed2493 100644 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -97,6 +97,7 @@ mkdir -m 755 -p "$libc_headers_dir/DEBIAN" mkdir -p "$libc_headers_dir/usr/share/doc/$libc_headers_packagename" mkdir -m 755 -p "$kernel_headers_dir/DEBIAN" mkdir -p "$kernel_headers_dir/usr/share/doc/$kernel_headers_packagename" +mkdir -p "$kernel_headers_dir/lib/modules/$version/" if [ "$ARCH" = "um" ] ; then mkdir -p "$tmpdir/usr/lib/uml/modules/$version" "$tmpdir/usr/bin" fi @@ -120,15 +121,19 @@ else fi if grep -q '^CONFIG_MODULES=y' .config ; then - INSTALL_MOD_PATH="$tmpdir" make KBUILD_SRC= modules_install + INSTALL_MOD_PATH="$tmpdir" $MAKE KBUILD_SRC= modules_install + rm -f "$tmpdir/lib/modules/$version/build" + rm -f "$tmpdir/lib/modules/$version/source" if [ "$ARCH" = "um" ] ; then mv "$tmpdir/lib/modules/$version"/* "$tmpdir/usr/lib/uml/modules/$version/" rmdir "$tmpdir/lib/modules/$version" fi fi -make headers_check -make headers_install INSTALL_HDR_PATH="$libc_headers_dir/usr" +if [ "$ARCH" != "um" ]; then + $MAKE headers_check KBUILD_SRC= + $MAKE headers_install KBUILD_SRC= INSTALL_HDR_PATH="$libc_headers_dir/usr" +fi # Install the maintainer scripts # Note: hook scripts under /etc/kernel are also executed by official Debian @@ -238,14 +243,15 @@ EOF fi # Build header package -(cd $srctree; find . -name Makefile -o -name Kconfig\* -o -name \*.pl > /tmp/files$$) -(cd $srctree; find arch/$SRCARCH/include include scripts -type f >> /tmp/files$$) -(cd $objtree; find .config Module.symvers include scripts -type f >> /tmp/objfiles$$) +(cd $srctree; find . -name Makefile -o -name Kconfig\* -o -name \*.pl > "$objtree/debian/hdrsrcfiles") +(cd $srctree; find arch/$SRCARCH/include include scripts -type f >> "$objtree/debian/hdrsrcfiles") +(cd $objtree; find .config Module.symvers include scripts -type f >> "$objtree/debian/hdrobjfiles") destdir=$kernel_headers_dir/usr/src/linux-headers-$version mkdir -p "$destdir" -(cd $srctree; tar -c -f - -T /tmp/files$$) | (cd $destdir; tar -xf -) -(cd $objtree; tar -c -f - -T /tmp/objfiles$$) | (cd $destdir; tar -xf -) -rm -f /tmp/files$$ /tmp/objfiles$$ +(cd $srctree; tar -c -f - -T "$objtree/debian/hdrsrcfiles") | (cd $destdir; tar -xf -) +(cd $objtree; tar -c -f - -T "$objtree/debian/hdrobjfiles") | (cd $destdir; tar -xf -) +ln -sf "/usr/src/linux-headers-$version" "$kernel_headers_dir/lib/modules/$version/build" +rm -f "$objtree/debian/hdrsrcfiles" "$objtree/debian/hdrobjfiles" arch=$(dpkg --print-architecture) cat <<EOF >> debian/control @@ -259,8 +265,6 @@ Description: Linux kernel headers for $KERNELRELEASE on $arch This is useful for people who need to build external modules EOF -create_package "$kernel_headers_packagename" "$kernel_headers_dir" - # Do we have firmware? Move it out of the way and build it into a package. if [ -e "$tmpdir/lib/firmware" ]; then mv "$tmpdir/lib/firmware" "$fwdir/lib/" @@ -287,7 +291,11 @@ Description: Linux support headers for userspace development are used by the installed headers for GNU glibc and other system libraries. EOF -create_package "$libc_headers_packagename" "$libc_headers_dir" +if [ "$ARCH" != "um" ]; then + create_package "$kernel_headers_packagename" "$kernel_headers_dir" + create_package "$libc_headers_packagename" "$libc_headers_dir" +fi + create_package "$packagename" "$tmpdir" exit 0 diff --git a/scripts/patch-kernel b/scripts/patch-kernel index 20fb25c23382..d000ea3a41fd 100755 --- a/scripts/patch-kernel +++ b/scripts/patch-kernel @@ -116,6 +116,10 @@ findFile () { ext=".bz2" name="bzip2" uncomp="bunzip2 -dc" + elif [ -r ${filebase}.xz ]; then + ext=".xz" + name="xz" + uncomp="xz -dc" elif [ -r ${filebase}.zip ]; then ext=".zip" name="zip" 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 */ succeed_file(); } if (w(txthdr->sh_type) != SHT_PROGBITS || - !(w(txthdr->sh_flags) & SHF_EXECINSTR)) + !(_w(txthdr->sh_flags) & SHF_EXECINSTR)) return NULL; return txtname; } diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 4d403844e137..bd6dca8a0ab2 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -75,8 +75,7 @@ scm_version() [ -w . ] && git update-index --refresh --unmerged > /dev/null # Check for uncommitted changes - if git diff-index --name-only HEAD | grep -v "^scripts/package" \ - | read dummy; then + if git diff-index --name-only HEAD | grep -qv "^scripts/package"; then printf '%s' -dirty fi diff --git a/scripts/tags.sh b/scripts/tags.sh index 38f6617a2cb1..cf7b12fee573 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -116,7 +116,7 @@ docscope() dogtags() { - all_sources | gtags -f - + all_sources | gtags -i -f - } exuberant() @@ -132,7 +132,28 @@ exuberant() --regex-asm='/^(ENTRY|_GLOBAL)\(([^)]*)\).*/\2/' \ --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ - --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/' + --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/' \ + --regex-c++='/PAGEFLAG\(([^,)]*).*/Page\1/' \ + --regex-c++='/PAGEFLAG\(([^,)]*).*/SetPage\1/' \ + --regex-c++='/PAGEFLAG\(([^,)]*).*/ClearPage\1/' \ + --regex-c++='/TESTSETFLAG\(([^,)]*).*/TestSetPage\1/' \ + --regex-c++='/TESTPAGEFLAG\(([^,)]*).*/Page\1/' \ + --regex-c++='/SETPAGEFLAG\(([^,)]*).*/SetPage\1/' \ + --regex-c++='/__SETPAGEFLAG\(([^,)]*).*/__SetPage\1/' \ + --regex-c++='/TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex-c++='/__TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex-c++='/CLEARPAGEFLAG\(([^,)]*).*/ClearPage\1/' \ + --regex-c++='/__CLEARPAGEFLAG\(([^,)]*).*/__ClearPage\1/' \ + --regex-c++='/__PAGEFLAG\(([^,)]*).*/__SetPage\1/' \ + --regex-c++='/__PAGEFLAG\(([^,)]*).*/__ClearPage\1/' \ + --regex-c++='/PAGEFLAG_FALSE\(([^,)]*).*/Page\1/' \ + --regex-c++='/TESTSCFLAG\(([^,)]*).*/TestSetPage\1/' \ + --regex-c++='/TESTSCFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex-c++='/SETPAGEFLAG_NOOP\(([^,)]*).*/SetPage\1/' \ + --regex-c++='/CLEARPAGEFLAG_NOOP\(([^,)]*).*/ClearPage\1/' \ + --regex-c++='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \ + --regex-c++='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \ + --regex-c++='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' all_kconfigs | xargs $1 -a \ --langdef=kconfig --language-force=kconfig \ @@ -145,7 +166,6 @@ exuberant() all_defconfigs | xargs -r $1 -a \ --langdef=dotconfig --language-force=dotconfig \ --regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/' - } emacs() @@ -154,7 +174,28 @@ emacs() --regex='/^(ENTRY|_GLOBAL)(\([^)]*\)).*/\2/' \ --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \ --regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \ - --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/' + --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/' \ + --regex='/PAGEFLAG\(([^,)]*).*/Page\1/' \ + --regex='/PAGEFLAG\(([^,)]*).*/SetPage\1/' \ + --regex='/PAGEFLAG\(([^,)]*).*/ClearPage\1/' \ + --regex='/TESTSETFLAG\(([^,)]*).*/TestSetPage\1/' \ + --regex='/TESTPAGEFLAG\(([^,)]*).*/Page\1/' \ + --regex='/SETPAGEFLAG\(([^,)]*).*/SetPage\1/' \ + --regex='/__SETPAGEFLAG\(([^,)]*).*/__SetPage\1/' \ + --regex='/TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex='/__TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex='/CLEARPAGEFLAG\(([^,)]*).*/ClearPage\1/' \ + --regex='/__CLEARPAGEFLAG\(([^,)]*).*/__ClearPage\1/' \ + --regex='/__PAGEFLAG\(([^,)]*).*/__SetPage\1/' \ + --regex='/__PAGEFLAG\(([^,)]*).*/__ClearPage\1/' \ + --regex='/PAGEFLAG_FALSE\(([^,)]*).*/Page\1/' \ + --regex='/TESTSCFLAG\(([^,)]*).*/TestSetPage\1/' \ + --regex='/TESTSCFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex='/SETPAGEFLAG_NOOP\(([^,)]*).*/SetPage\1/' \ + --regex='/CLEARPAGEFLAG_NOOP\(([^,)]*).*/ClearPage\1/' \ + --regex='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \ + --regex='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \ + --regex='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' all_kconfigs | xargs $1 -a \ --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' @@ -189,6 +230,7 @@ if [ "${ARCH}" = "um" ]; then fi fi +remove_structs= case "$1" in "cscope") docscope @@ -201,10 +243,17 @@ case "$1" in "tags") rm -f tags xtags ctags + remove_structs=y ;; "TAGS") rm -f TAGS xtags etags + remove_structs=y ;; esac + +# Remove structure forward declarations. +if [ -n "$remove_structs" ]; then + LANG=C sed -i -e '/^\([a-zA-Z_][a-zA-Z0-9_]*\)\t.*\t\/\^struct \1;.*\$\/;"\tx$/d' $1 +fi |
