From 7b76bfc86757ca5e7b0a62f50003752da77c115b Mon Sep 17 00:00:00 2001 From: Dick Streefland Date: Tue, 6 Oct 2009 22:35:40 +0200 Subject: kconfig: simplification of scripts/extract-ikconfig I've rewritten the extract-ikconfig script to extract the kernel configuration from a kernel compiled with CONFIG_IKCONFIG. The main motivation for the rewrite was to remove the dependency on the external C program binoffset.c, which is compiled on the initial run. The binoffset executable is invoked with a relative path, which means that the old script can only be run from the top of the kernel tree, and only when you have write permission in the scripts directory. The new script uses tr/grep/tail/zcat only, and can be invoked from anywhere. The binoffset.c program has been removed. This script requires GNU grep 2.5 (released 2002-03-13) or higher, because the -o option was introduced in that version. Signed-off-by: Dick Streefland LKML-Reference: <20091006203540.GA14634@streefland.net> Tested-by: Steven Rostedt Cc: Sam Ravnborg Signed-off-by: Steven Rostedt --- scripts/.gitignore | 1 - scripts/binoffset.c | 163 ----------------------------------------------- scripts/extract-ikconfig | 127 +++++++++++++----------------------- 3 files changed, 44 insertions(+), 247 deletions(-) delete mode 100644 scripts/binoffset.c (limited to 'scripts') diff --git a/scripts/.gitignore b/scripts/.gitignore index 52cab46ae35a..c5d5db54c009 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -6,5 +6,4 @@ kallsyms pnmtologo bin2c unifdef -binoffset ihex2fw diff --git a/scripts/binoffset.c b/scripts/binoffset.c deleted file mode 100644 index 1a2e39b8e3e5..000000000000 --- a/scripts/binoffset.c +++ /dev/null @@ -1,163 +0,0 @@ -/*************************************************************************** - * binoffset.c - * (C) 2002 Randy Dunlap - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# 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. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -# binoffset.c: -# - searches a (binary) file for a specified (binary) pattern -# - returns the offset of the located pattern or ~0 if not found -# - exits with exit status 0 normally or non-0 if pattern is not found -# or any other error occurs. - -****************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define VERSION "0.1" -#define BUF_SIZE (16 * 1024) -#define PAT_SIZE 100 - -char *progname; -char *inputname; -int inputfd; -unsigned int bix; /* buf index */ -unsigned char patterns [PAT_SIZE] = {0}; /* byte-sized pattern array */ -int pat_len; /* actual number of pattern bytes */ -unsigned char *madr; /* mmap address */ -size_t filesize; -int num_matches = 0; -off_t firstloc = 0; - -void usage (void) -{ - fprintf (stderr, "%s ver. %s\n", progname, VERSION); - fprintf (stderr, "usage: %s filename pattern_bytes\n", - progname); - fprintf (stderr, " [prints location of pattern_bytes in file]\n"); - exit (1); -} - -void get_pattern (int pat_count, char *pats []) -{ - int ix, err, tmp; - -#ifdef DEBUG - fprintf (stderr,"get_pattern: count = %d\n", pat_count); - for (ix = 0; ix < pat_count; ix++) - fprintf (stderr, " pat # %d: [%s]\n", ix, pats[ix]); -#endif - - for (ix = 0; ix < pat_count; ix++) { - tmp = 0; - err = sscanf (pats[ix], "%5i", &tmp); - if (err != 1 || tmp > 0xff) { - fprintf (stderr, "pattern or value error in pattern # %d [%s]\n", - ix, pats[ix]); - usage (); - } - patterns [ix] = tmp; - } - pat_len = pat_count; -} - -void search_pattern (void) -{ - for (bix = 0; bix < filesize; bix++) { - if (madr[bix] == patterns[0]) { - if (memcmp (&madr[bix], patterns, pat_len) == 0) { - if (num_matches == 0) - firstloc = bix; - num_matches++; - } - } - } -} - -#ifdef NOTDEF -size_t get_filesize (int fd) -{ - off_t end_off = lseek (fd, 0, SEEK_END); - lseek (fd, 0, SEEK_SET); - return (size_t) end_off; -} -#endif - -size_t get_filesize (int fd) -{ - int err; - struct stat stat; - - err = fstat (fd, &stat); - fprintf (stderr, "filesize: %ld\n", err < 0 ? (long)err : stat.st_size); - if (err < 0) - return err; - return (size_t) stat.st_size; -} - -int main (int argc, char *argv []) -{ - progname = argv[0]; - - if (argc < 3) - usage (); - - get_pattern (argc - 2, argv + 2); - - inputname = argv[1]; - - inputfd = open (inputname, O_RDONLY); - if (inputfd == -1) { - fprintf (stderr, "%s: cannot open '%s'\n", - progname, inputname); - exit (3); - } - - filesize = get_filesize (inputfd); - - madr = mmap (0, filesize, PROT_READ, MAP_PRIVATE, inputfd, 0); - if (madr == MAP_FAILED) { - fprintf (stderr, "mmap error = %d\n", errno); - close (inputfd); - exit (4); - } - - search_pattern (); - - if (munmap (madr, filesize)) - fprintf (stderr, "munmap error = %d\n", errno); - - if (close (inputfd)) - fprintf (stderr, "%s: error %d closing '%s'\n", - progname, errno, inputname); - - fprintf (stderr, "number of pattern matches = %d\n", num_matches); - if (num_matches == 0) - firstloc = ~0; - printf ("%ld\n", firstloc); - fprintf (stderr, "%ld\n", firstloc); - - exit (num_matches ? 0 : 2); -} - -/* end binoffset.c */ diff --git a/scripts/extract-ikconfig b/scripts/extract-ikconfig index de233ff43c1c..37f30d36c944 100755 --- a/scripts/extract-ikconfig +++ b/scripts/extract-ikconfig @@ -1,92 +1,53 @@ #!/bin/sh -# extracts .config info from a [b]zImage file -# uses: binoffset (new), dd, zcat, strings, grep -# $arg1 is [b]zImage filename - -binoffset="./scripts/binoffset" -test -e $binoffset || cc -o $binoffset ./scripts/binoffset.c || exit 1 - -IKCFG_ST="0x49 0x4b 0x43 0x46 0x47 0x5f 0x53 0x54" -IKCFG_ED="0x49 0x4b 0x43 0x46 0x47 0x5f 0x45 0x44" -dump_config() { - file="$1" - - start=`$binoffset $file $IKCFG_ST 2>/dev/null` - [ "$?" != "0" ] && start="-1" - if [ "$start" -eq "-1" ]; then - return - fi - end=`$binoffset $file $IKCFG_ED 2>/dev/null` - [ "$?" != "0" ] && end="-1" - if [ "$end" -eq "-1" ]; then - return - fi - - start=`expr $start + 8` - size=`expr $end - $start` - - dd if="$file" ibs=1 skip="$start" count="$size" 2>/dev/null | zcat - - clean_up - exit 0 -} - - -usage() -{ - echo " usage: extract-ikconfig [b]zImage_filename" -} - -clean_up() +# ---------------------------------------------------------------------- +# extract-ikconfig - Extract the .config file from a kernel image +# +# This will only work when the kernel was compiled with CONFIG_IKCONFIG. +# +# The obscure use of the "tr" filter is to work around older versions of +# "grep" that report the byte offset of the line instead of the pattern. +# +# (c) 2009, Dick Streefland +# Licensed under the terms of the GNU General Public License. +# ---------------------------------------------------------------------- + +gz1='\037\213\010' +gz2='01' +cf1='IKCFG_ST\037\213\010' +cf2='0123456789' + +dump_config() { - if [ "$TMPFILE" != "" ]; then - rm -f $TMPFILE + if pos=`tr "$cf1\n$cf2" "\n$cf2=" < "$1" | grep -abo "^$cf2"` + then + pos=${pos%%:*} + tail -c+$(($pos+8)) "$1" | zcat -q + exit 0 fi } -if [ $# -lt 1 ] +# Check invocation: +me=${0##*/} +img=$1 +if [ $# -ne 1 -o ! -s "$img" ] then - usage - exit 1 + echo "Usage: $me " >&2 + exit 2 fi -TMPFILE=`mktemp -t ikconfig-XXXXXX` || exit 1 -image="$1" - -# vmlinux: Attempt to dump the configuration from the file directly -dump_config "$image" - -GZHDR1="0x1f 0x8b 0x08 0x00" -GZHDR2="0x1f 0x8b 0x08 0x08" - -ELFHDR="0x7f 0x45 0x4c 0x46" - -# vmlinux.gz: Check for a compressed images -off=`$binoffset "$image" $GZHDR1 2>/dev/null` -[ "$?" != "0" ] && off="-1" -if [ "$off" -eq "-1" ]; then - off=`$binoffset "$image" $GZHDR2 2>/dev/null` - [ "$?" != "0" ] && off="-1" -fi -if [ "$off" -eq "0" ]; then - zcat <"$image" >"$TMPFILE" - dump_config "$TMPFILE" -elif [ "$off" -ne "-1" ]; then - (dd ibs="$off" skip=1 count=0 && dd bs=512k) <"$image" 2>/dev/null | \ - zcat >"$TMPFILE" - dump_config "$TMPFILE" - -# check if this is simply an ELF file -else - off=`$binoffset "$image" $ELFHDR 2>/dev/null` - [ "$?" != "0" ] && off="-1" - if [ "$off" -eq "0" ]; then - dump_config "$image" - fi -fi - -echo "ERROR: Unable to extract kernel configuration information." -echo " This kernel image may not have the config info." - -clean_up +# Initial attempt for uncompressed images or objects: +dump_config "$img" + +# That didn't work, so decompress and try again: +tmp=/tmp/ikconfig$$ +trap "rm -f $tmp" 0 +for pos in `tr "$gz1\n$gz2" "\n$gz2=" < "$img" | grep -abo "^$gz2"` +do + pos=${pos%%:*} + tail -c+$pos "$img" | zcat 2> /dev/null > $tmp + dump_config $tmp +done + +# Bail out: +echo "$me: Cannot find kernel config." >&2 exit 1 -- cgit v1.2.3 From dc4f8845ee2ca39fe054a2d911729ffd269b4b66 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 5 Jan 2010 19:27:51 +0100 Subject: tracing: optimize recordmcount.pl for offsets-handling - move check for open file in front of the writing loop - use perl-constructs to access the array Signed-off-by: Wolfram Sang LKML-Reference: <1262716072-14414-2-git-send-email-w.sang@pengutronix.de> Signed-off-by: Steven Rostedt --- scripts/recordmcount.pl | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 92f09fe9639e..5de12c7b366f 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -432,14 +432,14 @@ sub update_funcs # Loop through all the mcount caller offsets and print a reference # to the caller based from the ref_func. - for (my $i=0; $i <= $#offsets; $i++) { - if (!$opened) { - open(FILE, ">$mcount_s") || die "can't create $mcount_s\n"; - $opened = 1; - print FILE "\t.section $mcount_section,\"a\",$section_type\n"; - print FILE "\t.align $alignment\n" if (defined($alignment)); - } - printf FILE "\t%s %s + %d\n", $type, $ref_func, $offsets[$i] - $offset; + if (!$opened) { + open(FILE, ">$mcount_s") || die "can't create $mcount_s\n"; + $opened = 1; + print FILE "\t.section $mcount_section,\"a\",$section_type\n"; + print FILE "\t.align $alignment\n" if (defined($alignment)); + } + foreach my $cur_offset (@offsets) { + printf FILE "\t%s %s + %d\n", $type, $ref_func, $cur_offset - $offset; } } @@ -514,7 +514,7 @@ while () { } # is this a call site to mcount? If so, record it to print later if ($text_found && /$mcount_regex/) { - $offsets[$#offsets + 1] = hex $1; + push(@offsets, hex $1); } } -- cgit v1.2.3 From 17263baf958b7ab1d8c60445f412a1080362c88c Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 6 Jan 2010 16:43:08 -0500 Subject: kconfig: Create include/generated for localmodconfig If someone downloads a brand new kernel and runs localmodconfig or localyesconfig, the ending result will report: *** Error during update of the kernel configuration. This is because localmodconfig and localyesconfig must create the include/generated directory to place the autoconf.h file. Signed-off-by: Steven Rostedt --- scripts/kconfig/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 999e8a7d5bf7..006c96f5fcb5 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -31,6 +31,7 @@ silentoldconfig: $(obj)/conf $< -s $(Kconfig) localmodconfig: $(obj)/streamline_config.pl $(obj)/conf + $(Q)mkdir -p include/generated $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config $(Q)if [ -f .config ]; then \ cmp -s .tmp.config .config || \ @@ -45,6 +46,7 @@ localmodconfig: $(obj)/streamline_config.pl $(obj)/conf $(Q)rm -f .tmp.config localyesconfig: $(obj)/streamline_config.pl $(obj)/conf + $(Q)mkdir -p include/generated $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config $(Q)sed -i s/=m/=y/ .tmp.config $(Q)if [ -f .config ]; then \ -- cgit v1.2.3 From 13d7e9385644d376a0816ad663ba3dfc45359f2f Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 6 Jan 2010 17:56:12 -0500 Subject: kconfig: Check for if conditions in Kconfig for localmodconfig The streamline_config.pl misses the if conditions for checking dependencies. For Kconfigs with the following construct: if MEDIA_SUPPORT config VIDEO_DEV [...] If VIDEO_DEV was enabled, the script will miss the fact that MEDIA_SUPPORT is also needed. This patch changes streamline_config.pl to include if conditions into the dependencies of configs. Reported-by: Anton Blanchard Tested-by: Anton Blanchard Signed-off-by: Steven Rostedt --- scripts/kconfig/streamline_config.pl | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index 0d800820c3cd..9e66fa8dc52e 100644 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -121,6 +121,8 @@ my %prompts; my %objects; my $var; my $cont = 0; +my $iflevel = 0; +my @ifdeps; # prevent recursion my %read_kconfigs; @@ -146,6 +148,15 @@ sub read_kconfig { $state = "NEW"; $config = $1; + for (my $i = 0; $i < $iflevel; $i++) { + if ($i) { + $depends{$config} .= " " . $ifdeps[$i]; + } else { + $depends{$config} = $ifdeps[$i]; + } + $state = "DEP"; + } + # collect the depends for the config } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { $state = "DEP"; @@ -166,6 +177,21 @@ sub read_kconfig { # note if the config has a prompt $prompt{$config} = 1; + # Check for if statements + } elsif (/^if\s+(.*\S)\s*$/) { + my $deps = $1; + # remove beginning and ending non text + $deps =~ s/^[^a-zA-Z0-9_]*//; + $deps =~ s/[^a-zA-Z0-9_]*$//; + + my @deps = split /[^a-zA-Z0-9_]+/, $deps; + + $ifdeps[$iflevel++] = join ':', @deps; + + } elsif (/^endif/) { + + $iflevel-- if ($iflevel); + # stop on "help" } elsif (/^\s*help\s*$/) { $state = "NONE"; -- cgit v1.2.3 From dfaa9e2c5707b2c217c0121aac796e0fa3051482 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 5 Jan 2010 21:41:22 +0100 Subject: tracing: Use appropriate perl constructs in recordmcount.pl Modified recordmcount.pl to use perl constructs that are still understandable by C hackers that are not perl programmers. Signed-off-by: Wolfram Sang LKML-Reference: <1262724082-9517-1-git-send-email-w.sang@pengutronix.de> Signed-off-by: Steven Rostedt --- scripts/recordmcount.pl | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 5de12c7b366f..545fe7154ced 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -136,13 +136,14 @@ my %text_sections = ( ".text.unlikely" => 1, ); -$objdump = "objdump" if ((length $objdump) == 0); -$objcopy = "objcopy" if ((length $objcopy) == 0); -$cc = "gcc" if ((length $cc) == 0); -$ld = "ld" if ((length $ld) == 0); -$nm = "nm" if ((length $nm) == 0); -$rm = "rm" if ((length $rm) == 0); -$mv = "mv" if ((length $mv) == 0); +# Note: we are nice to C-programmers here, thus we skip the '||='-idiom. +$objdump = 'objdump' if (!$objdump); +$objcopy = 'objcopy' if (!$objcopy); +$cc = 'gcc' if (!$cc); +$ld = 'ld' if (!$ld); +$nm = 'nm' if (!$nm); +$rm = 'rm' if (!$rm); +$mv = 'mv' if (!$mv); #print STDERR "running: $P '$arch' '$objdump' '$objcopy' '$cc' '$ld' " . # "'$nm' '$rm' '$mv' '$inputfile'\n"; @@ -194,12 +195,8 @@ sub check_objcopy } } -if ($arch eq "x86") { - if ($bits == 64) { - $arch = "x86_64"; - } else { - $arch = "i386"; - } +if ($arch eq 'x86') { + $arch = ($bits == 64) ? 'x86_64' : 'i386'; } # @@ -476,11 +473,7 @@ while () { $read_headers = 0; # Only record text sections that we know are safe - if (defined($text_sections{$1})) { - $read_function = 1; - } else { - $read_function = 0; - } + $read_function = defined($text_sections{$1}); # print out any recorded offsets update_funcs(); -- cgit v1.2.3 From 88f66ea98d7ae6a8b6a34e38b1b4fa51abc1c9ca Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 6 Jan 2010 18:49:44 -0500 Subject: kconfig: Look in both /bin and /sbin for lsmod in streamline_config.pl Distributions now have lsmod in /bin instead of /sbin. But to handle both cases, we look for it in /sbin /bin /usr/bin and /usr/sbin. If lsmod is not found in any of those paths, it defaults to use just lsmod and hopes that it lies in the path of the user. Tested-by: Xavier Chantry Signed-off-by: Steven Rostedt --- scripts/kconfig/streamline_config.pl | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index 9e66fa8dc52e..d7f7db73e587 100644 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -264,7 +264,20 @@ foreach my $makefile (@makefiles) { my %modules; # see what modules are loaded on this system -open(LIN,"/sbin/lsmod|") || die "Cant lsmod"; +my $lsmod; + +foreach $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) { + if ( -x "$dir/lsmod" ) { + $lsmod = "$dir/lsmod"; + last; + } +} +if (!defined($lsmod)) { + # try just the path + $lsmod = "lsmod"; +} + +open(LIN,"$lsmod|") || die "Can not call lsmod with $lsmod"; while () { next if (/^Module/); # Skip the first line. if (/^(\S+)/) { -- cgit v1.2.3 From 99cf611613f8826f52c156810bfb9e34c71d193a Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Tue, 2 Feb 2010 13:44:07 -0800 Subject: get_maintainer.pl: teach git log to use --no-color When git has been set to always use color in .gitconfig then I get the warning message Bad divisor in main::vcs_assign: 0 This is caused by vcs_file_signoffs not matching any commits due to the pattern not understand the colour codes. Fix this by telling git log to never use colour. Signed-off-by: Richard Kennedy Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 090f24839700..2f3230db7ffb 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -74,8 +74,8 @@ my %VCS_cmds; my %VCS_cmds_git = ( "execute_cmd" => \&git_execute_cmd, "available" => '(which("git") ne "") && (-d ".git")', - "find_signers_cmd" => "git log --since=\$email_git_since -- \$file", - "find_commit_signers_cmd" => "git log -1 \$commit", + "find_signers_cmd" => "git log --no-color --since=\$email_git_since -- \$file", + "find_commit_signers_cmd" => "git log --no-color -1 \$commit", "blame_range_cmd" => "git blame -l -L \$diff_start,+\$diff_length \$file", "blame_file_cmd" => "git blame -l \$file", "commit_pattern" => "^commit [0-9a-f]{40,40}", -- cgit v1.2.3 From ef2b9b054580ef835078d8aa411bd06542cd5c1c Mon Sep 17 00:00:00 2001 From: Hui Zhu Date: Tue, 2 Feb 2010 13:44:09 -0800 Subject: markup_oops.pl: fix $func_offset error with x86_64 When I use markup_oops.pl parse a x8664 oops, I got: objdump: --start-address: bad number: NaN No matching code found This is because: main::(./m.pl:228): open(FILE, "objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump"; DB<3> p $decodestart NaN This NaN is from: main::(./m.pl:176): my $decodestart = Math::BigInt->from_hex("0x$target") - Math::BigInt->from_hex("0x$func_offset"); DB<2> p $func_offset 0x175 There is already a "0x" in $func_offset, another 0x makes it a NaN. The $func_offset is from line: if ($line =~ /RIP: 0010:\[\<[0-9a-f]+\>\] \[\<[0-9a-f]+\>\] ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]/) { $function = $1; $func_offset = $2; } I make a patch to change "(0x[0-9a-f]+)\/0x[a-f0-9]/)" to "0x([0-9a-f]+)\/0x[a-f0-9]/)". Signed-off-by: Hui Zhu Cc: Arjan van de Ven Cc: Michal Marek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/markup_oops.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl index ce3e40b01e48..e950f9cde019 100644 --- a/scripts/markup_oops.pl +++ b/scripts/markup_oops.pl @@ -158,7 +158,7 @@ while () { $function = $1; $func_offset = $2; } - if ($line =~ /RIP: 0010:\[\<[0-9a-f]+\>\] \[\<[0-9a-f]+\>\] ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]/) { + if ($line =~ /RIP: 0010:\[\<[0-9a-f]+\>\] \[\<[0-9a-f]+\>\] ([a-zA-Z0-9\_]+)\+0x([0-9a-f]+)\/0x[a-f0-9]/) { $function = $1; $func_offset = $2; } -- cgit v1.2.3 From 615f0833aa4c4aa944ceb78895bbffa8bd1884df Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Feb 2010 21:51:27 -0500 Subject: kconfig: Add LSMOD=file to override the lsmod for localmodconfig Doing the following: make LSMOD=file localmodconfig Will make the streamline-config code use the given file instead of lsmod. If the file is an executable, it will execute it, otherwise it will read it as text. make LSMOD=/my/local/path/lsmod localmodconfig The above will execute the lsmod in /my/local/path instead of the lsmods that may be located elsewhere. make LSMOD=embedded_board_lsmod localmodconfig The above will read the "embedded_board_lsmod" as a text file. This is useful if you are doing a cross compile and need to run the config against modules that exist on an embedded device. Note, if the LSMOD= file does is not a path, it will add the path to the object directory. That is, the above example will look for "embedded_board_lsmod" in the directory that the binary will be built in (the O=dir directory). Signed-off-by: Steven Rostedt On branch config/linus --- scripts/kconfig/Makefile | 13 ++++++++++-- scripts/kconfig/streamline_config.pl | 38 +++++++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 006c96f5fcb5..85b906547845 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -30,9 +30,18 @@ silentoldconfig: $(obj)/conf $(Q)mkdir -p include/generated $< -s $(Kconfig) +# if no path is given, then use src directory to find file +ifdef LSMOD +LSMOD_F = $(shell if [ `basename $(LSMOD)` == $(LSMOD) ]; then \ + echo $(objtree)/$(LSMOD); \ + else \ + echo $(LSMOD); \ + fi) +endif + localmodconfig: $(obj)/streamline_config.pl $(obj)/conf $(Q)mkdir -p include/generated - $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config + $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config $(Q)if [ -f .config ]; then \ cmp -s .tmp.config .config || \ (mv -f .config .config.old.1; \ @@ -47,7 +56,7 @@ localmodconfig: $(obj)/streamline_config.pl $(obj)/conf localyesconfig: $(obj)/streamline_config.pl $(obj)/conf $(Q)mkdir -p include/generated - $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config + $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config $(Q)sed -i s/=m/=y/ .tmp.config $(Q)if [ -f .config ]; then \ cmp -s .tmp.config .config || \ diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index d7f7db73e587..afbd54ac1d83 100644 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -113,6 +113,7 @@ find_config; # Get the build source and top level Kconfig file (passed in) my $ksource = $ARGV[0]; my $kconfig = $ARGV[1]; +my $lsmod_file = $ARGV[2]; my @makefiles = `find $ksource -name Makefile`; my %depends; @@ -263,21 +264,36 @@ foreach my $makefile (@makefiles) { my %modules; -# see what modules are loaded on this system -my $lsmod; - -foreach $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) { - if ( -x "$dir/lsmod" ) { - $lsmod = "$dir/lsmod"; - last; +if (defined($lsmod_file)) { + if ( ! -f $lsmod_file) { + die "$lsmod_file not found"; + } + if ( -x $lsmod_file) { + # the file is executable, run it + open(LIN, "$lsmod_file|"); + } else { + # Just read the contents + open(LIN, "$lsmod_file"); } +} else { + + # see what modules are loaded on this system + my $lsmod; + + foreach $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) { + if ( -x "$dir/lsmod" ) { + $lsmod = "$dir/lsmod"; + last; + } } -if (!defined($lsmod)) { - # try just the path - $lsmod = "lsmod"; + if (!defined($lsmod)) { + # try just the path + $lsmod = "lsmod"; + } + + open(LIN,"$lsmod|") || die "Can not call lsmod with $lsmod"; } -open(LIN,"$lsmod|") || die "Can not call lsmod with $lsmod"; while () { next if (/^Module/); # Skip the first line. if (/^(\S+)/) { -- cgit v1.2.3 From 3cebbb81c7e75321e25cc586d07a25a3d98278fc Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Wed, 3 Feb 2010 17:20:14 +0100 Subject: kconfig: Simplify LSMOD= handling Signed-off-by: Michal Marek LKML-Reference: <20100203162014.GA10956@sepie.suse.cz> Signed-off-by: Steven Rostedt --- scripts/kconfig/Makefile | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 85b906547845..186c46604d06 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -32,11 +32,10 @@ silentoldconfig: $(obj)/conf # if no path is given, then use src directory to find file ifdef LSMOD -LSMOD_F = $(shell if [ `basename $(LSMOD)` == $(LSMOD) ]; then \ - echo $(objtree)/$(LSMOD); \ - else \ - echo $(LSMOD); \ - fi) +LSMOD_F := $(LSMOD) +ifeq ($(findstring /,$(LSMOD)),) + LSMOD_F := $(objtree)/$(LSMOD) +endif endif localmodconfig: $(obj)/streamline_config.pl $(obj)/conf -- cgit v1.2.3 From 3ad2f3fbb961429d2aa627465ae4829758bc7e07 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 3 Feb 2010 08:01:28 +0800 Subject: tree-wide: Assorted spelling fixes In particular, several occurances of funny versions of 'success', 'unknown', 'therefore', 'acknowledge', 'argument', 'achieve', 'address', 'beginning', 'desirable', 'separate' and 'necessary' are fixed. Signed-off-by: Daniel Mack Cc: Joe Perches Cc: Junio C Hamano Signed-off-by: Jiri Kosina --- scripts/gfp-translate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/gfp-translate b/scripts/gfp-translate index 073cb6d152a0..d81b968d864e 100644 --- a/scripts/gfp-translate +++ b/scripts/gfp-translate @@ -19,7 +19,7 @@ usage() { exit 0 } -# Parse command-line arguements +# Parse command-line arguments while [ $# -gt 0 ]; do case $1 in --source) -- cgit v1.2.3 From a9e7314b7940cee00b80995b360dbc06f995cc6e Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Fri, 26 Feb 2010 13:05:47 -0800 Subject: kernel-doc: track line numbers for each file separately The problem is that $. keeps track of the current record number (which is line number by default). But if you pass it multiple files, it does not wrap at the end of file, and therefore contains the *total* number of processed lines. I suppose we can fix line numbering by introducing a simple assignment $. = 1 before processing every new file. Signed-off-by: Ilya Dryomov Signed-off-by: Randy Dunlap Signed-off-by: Linus Torvalds --- scripts/kernel-doc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 241310e59cd6..8018f6a1dd04 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -2023,6 +2023,8 @@ sub process_file($) { return; } + $. = 1; + $section_counter = 0; while () { if ($state == 0) { -- cgit v1.2.3 From 1c32fd0c5ac1ccbdc37a1a392a5d75cbe059b401 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Fri, 26 Feb 2010 13:06:03 -0800 Subject: kernel-doc: drop the -filelist option, it doesn't work I also found the -filelist option, but apparently the implementation is broken, and it was broken from the very first git commit. For the -filelist option I suggest the removal (I wasn't able to find any users of it, moreover it's not even listed in the usage() output, so presumably nobody knows about it). Signed-off-by: Ilya Dryomov Signed-off-by: Randy Dunlap Signed-off-by: Linus Torvalds --- scripts/kernel-doc | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 8018f6a1dd04..208ad3b0ca51 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -13,8 +13,6 @@ use strict; ## This software falls under the GNU General Public License. ## ## Please read the COPYING file for more information ## -# w.o. 03-11-2000: added the '-filelist' option. - # 18/01/2001 - Cleanups # Functions prototyped as foo(void) same as foo() # Stop eval'ing where we don't need to. @@ -245,7 +243,7 @@ my $man_date = ('January', 'February', 'March', 'April', 'May', 'June', # could cause "use of undefined value" or other bugs. my ($function, %function_table, %parametertypes, $declaration_purpose); my ($type, $declaration_name, $return_type); -my ($newsection, $newcontents, $prototype, $filelist, $brcount, %source_map); +my ($newsection, $newcontents, $prototype, $brcount, %source_map); if (defined($ENV{'KBUILD_VERBOSE'})) { $verbose = "$ENV{'KBUILD_VERBOSE'}"; @@ -338,8 +336,6 @@ while ($ARGV[0] =~ m/^-(.*)/) { $verbose = 1; } elsif (($cmd eq "-h") || ($cmd eq "--help")) { usage(); - } elsif ($cmd eq '-filelist') { - $filelist = shift @ARGV; } elsif ($cmd eq '-no-doc-sections') { $no_doc_sections = 1; } @@ -1811,14 +1807,6 @@ if (open(SOURCE_MAP, "<.tmp_filelist.txt")) { close(SOURCE_MAP); } -if ($filelist) { - open(FLIST,"<$filelist") or die "Can't open file list $filelist"; - while() { - chop; - process_file($_); - } -} - foreach (@ARGV) { chomp; process_file($_); -- cgit v1.2.3 From 03372dbbe618bfcd02f9c8cdbfe78e97e3aad43b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 5 Mar 2010 13:43:00 -0800 Subject: scripts/get_maintainer.pl: add --file-emails, find embedded email addresses Add an imperfect option to search a source file for email addresses. New option: --file-emails or --fe email addresses in files are freeform text and are nearly impossible to parse. Still, might as well try to do a somewhat acceptable job of finding them. This code should find all addresses that are in the form addr@domain.tld The code assumes that up to 3 alphabetic words along with dashes, commas, and periods that preceed the email address are a name. If 3 words are found for the name, and one of the first two words are a single letter and period, or just a single letter then the 3 words are use as name otherwise the last 2 words are used. Some variants that are shown correctly: John Smith Random J. Developer Random J. Developer (rjd@tld.com) J. Random Developer rjd@tld.com Variants that are shown nominally correctly: Written by First Last (funny-addr@somecompany.com) is shown as: First Last Variants that are shown incorrectly: Some Really Long Name MontaVista Software, Inc. are returned as: Long Name "Software, Inc" --roles and --rolestats show "(in file)" for matches. For instance: Without -file-emails: $ ./scripts/get_maintainer.pl -f -nogit -roles net/core/netpoll.c David S. Miller (maintainer:NETWORKING [GENERAL]) linux-kernel@vger.kernel.org (open list) With -fe: $ ./scripts/get_maintainer.pl -f -fe -nogit -roles net/core/netpoll.c David S. Miller (maintainer:NETWORKING [GENERAL]) Matt Mackall (in file) Ingo Molnar (in file) linux-kernel@vger.kernel.org (open list) netdev@vger.kernel.org (open list:NETWORKING [GENERAL]) The number of email addresses in the file in not limited. Neither is the number of returned email addresses. Signed-off-by: Joe Perches Cc: Matt Mackall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 83 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 2f3230db7ffb..bff2390652c2 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -41,6 +41,7 @@ my $web = 0; my $subsystem = 0; my $status = 0; my $keywords = 1; +my $file_emails = 0; my $from_filename = 0; my $pattern_depth = 0; my $version = 0; @@ -120,6 +121,7 @@ if (!GetOptions( 'web!' => \$web, 'pattern-depth=i' => \$pattern_depth, 'k|keywords!' => \$keywords, + 'fe|file-emails!' => \$file_emails, 'f|file' => \$from_filename, 'v|version' => \$version, 'h|help' => \$help, @@ -232,6 +234,7 @@ if ($email_remove_duplicates) { my @files = (); my @range = (); my @keyword_tvi = (); +my @file_emails = (); foreach my $file (@ARGV) { ##if $file is a directory and it lacks a trailing slash, add one @@ -242,15 +245,21 @@ foreach my $file (@ARGV) { } if ($from_filename) { push(@files, $file); - if (-f $file && $keywords) { + if (-f $file && ($keywords || $file_emails)) { open(FILE, "<$file") or die "$P: Can't open ${file}\n"; my $text = do { local($/) ; }; - foreach my $line (keys %keyword_hash) { - if ($text =~ m/$keyword_hash{$line}/x) { - push(@keyword_tvi, $line); + close(FILE); + if ($keywords) { + foreach my $line (keys %keyword_hash) { + if ($text =~ m/$keyword_hash{$line}/x) { + push(@keyword_tvi, $line); + } } } - close(FILE); + if ($file_emails) { + my @poss_addr = $text =~ m$[A-Za-zÀ-ÿ\"\' \,\.\+-]*\s*[\,]*\s*[\(\<\{]{0,1}[A-Za-z0-9_\.\+-]+\@[A-Za-z0-9\.-]+\.[A-Za-z0-9]+[\)\>\}]{0,1}$g; + push(@file_emails, clean_file_emails(@poss_addr)); + } } } else { my $file_cnt = @files; @@ -285,6 +294,8 @@ foreach my $file (@ARGV) { } } +@file_emails = uniq(@file_emails); + my @email_to = (); my @list_to = (); my @scm = (); @@ -377,6 +388,14 @@ if ($email) { } } } + + foreach my $email (@file_emails) { + my ($name, $address) = parse_email($email); + + my $tmp_email = format_email($name, $address, $email_usename); + push_email_address($tmp_email, ''); + add_role($tmp_email, 'in file'); + } } if ($email || $email_list) { @@ -453,6 +472,7 @@ MAINTAINER field selection options: --remove-duplicates => minimize duplicate email names/addresses --roles => show roles (status:subsystem, git-signer, list, etc...) --rolestats => show roles and statistics (commits/total_commits, %) + --file-emails => add email addresses found in -f file (default: 0 (off)) --scm => print SCM tree(s) if any --status => print status if any --subsystem => print subsystem name if any @@ -811,7 +831,9 @@ sub add_role { foreach my $entry (@email_to) { if ($email_remove_duplicates) { my ($entry_name, $entry_address) = parse_email($entry->[0]); - if ($name eq $entry_name || $address eq $entry_address) { + if (($name eq $entry_name || $address eq $entry_address) + && ($role eq "" || !($entry->[1] =~ m/$role/)) + ) { if ($entry->[1] eq "") { $entry->[1] = "$role"; } else { @@ -819,7 +841,9 @@ sub add_role { } } } else { - if ($email eq $entry->[0]) { + if ($email eq $entry->[0] + && ($role eq "" || !($entry->[1] =~ m/$role/)) + ) { if ($entry->[1] eq "") { $entry->[1] = "$role"; } else { @@ -1099,6 +1123,51 @@ sub sort_and_uniq { return @parms; } +sub clean_file_emails { + my (@file_emails) = @_; + my @fmt_emails = (); + + foreach my $email (@file_emails) { + $email =~ s/[\(\<\{]{0,1}([A-Za-z0-9_\.\+-]+\@[A-Za-z0-9\.-]+)[\)\>\}]{0,1}/\<$1\>/g; + my ($name, $address) = parse_email($email); + if ($name eq '"[,\.]"') { + $name = ""; + } + + my @nw = split(/[^A-Za-zÀ-ÿ\'\,\.\+-]/, $name); + if (@nw > 2) { + my $first = $nw[@nw - 3]; + my $middle = $nw[@nw - 2]; + my $last = $nw[@nw - 1]; + + if (((length($first) == 1 && $first =~ m/[A-Za-z]/) || + (length($first) == 2 && substr($first, -1) eq ".")) || + (length($middle) == 1 || + (length($middle) == 2 && substr($middle, -1) eq "."))) { + $name = "$first $middle $last"; + } else { + $name = "$middle $last"; + } + } + + if (substr($name, -1) =~ /[,\.]/) { + $name = substr($name, 0, length($name) - 1); + } elsif (substr($name, -2) =~ /[,\.]"/) { + $name = substr($name, 0, length($name) - 2) . '"'; + } + + if (substr($name, 0, 1) =~ /[,\.]/) { + $name = substr($name, 1, length($name) - 1); + } elsif (substr($name, 0, 2) =~ /"[,\.]/) { + $name = '"' . substr($name, 2, length($name) - 2); + } + + my $fmt_email = format_email($name, $address, $email_usename); + push(@fmt_emails, $fmt_email); + } + return @fmt_emails; +} + sub merge_email { my @lines; my %saw; -- cgit v1.2.3 From 4b76c9da611593eed6a13527c5ebd00c173624ad Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 5 Mar 2010 13:43:03 -0800 Subject: scripts/get_maintainer.pl: add --sections, print entire matched subsystem Print the complete contents of the matched subsystems in pattern match depth order. Sample output: $ ./scripts/get_maintainer.pl --sections -f drivers/net/usb/smsc95xx.c USB SMSC95XX ETHERNET DRIVER M:Steve Glendinning L:netdev@vger.kernel.org S:Supported F:drivers/net/usb/smsc95xx.* USB SUBSYSTEM M:Greg Kroah-Hartman L:linux-usb@vger.kernel.org W:http://www.linux-usb.org T:quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ S:Supported F:Documentation/usb/ F:drivers/net/usb/ F:drivers/usb/ F:include/linux/usb.h F:include/linux/usb/ NETWORKING DRIVERS L:netdev@vger.kernel.org W:http://www.linuxfoundation.org/en/Net T:git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git S:Odd Fixes F:drivers/net/ F:include/linux/if_* F:include/linux/*device.h THE REST M:Linus Torvalds L:linux-kernel@vger.kernel.org Q:http://patchwork.kernel.org/project/LKML/list/ T:git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git S:Buried alive in reporters F:* F:*/ Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index bff2390652c2..e54f72f6c341 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -41,6 +41,7 @@ my $web = 0; my $subsystem = 0; my $status = 0; my $keywords = 1; +my $sections = 0; my $file_emails = 0; my $from_filename = 0; my $pattern_depth = 0; @@ -121,6 +122,7 @@ if (!GetOptions( 'web!' => \$web, 'pattern-depth=i' => \$pattern_depth, 'k|keywords!' => \$keywords, + 'sections!' => \$sections, 'fe|file-emails!' => \$file_emails, 'f|file' => \$from_filename, 'v|version' => \$version, @@ -152,10 +154,20 @@ if ($output_rolestats) { $output_roles = 1; } -my $selections = $email + $scm + $status + $subsystem + $web; -if ($selections == 0) { - usage(); - die "$P: Missing required option: email, scm, status, subsystem or web\n"; +if ($sections) { + $email = 0; + $email_list = 0; + $scm = 0; + $status = 0; + $subsystem = 0; + $web = 0; + $keywords = 0; +} else { + my $selections = $email + $scm + $status + $subsystem + $web; + if ($selections == 0) { + usage(); + die "$P: Missing required option: email, scm, status, subsystem or web\n"; + } } if ($email && @@ -357,6 +369,21 @@ foreach my $file (@files) { foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) { add_categories($line); + if ($sections) { + my $i; + my $start = find_starting_index($line); + my $end = find_ending_index($line); + for ($i = $start; $i < $end; $i++) { + my $line = $typevalue[$i]; + if ($line =~ /^[FX]:/) { ##Restore file patterns + $line =~ s/([^\\])\.([^\*])/$1\?$2/g; + $line =~ s/([^\\])\.$/$1\?/g; ##Convert . back to ? + $line =~ s/\\\./\./g; ##Convert \. to . + $line =~ s/\.\*/\*/g; ##Convert .* to * + } + print("$line\n"); + } + } } if ($email && $email_git) { @@ -486,6 +513,7 @@ Output type options: Other options: --pattern-depth => Number of pattern directory traversals (default: 0 (all)) --keywords => scan patch for keywords (default: 1 (on)) + --sections => print the entire subsystem sections with pattern matches --version => show version --help => show this help information -- cgit v1.2.3 From f11e9a1534c5e9dd4be97b30e6b24902e0ec325b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 5 Mar 2010 13:43:03 -0800 Subject: scripts/get_maintainer.pl: change --sections to print in the same style as MAINTAINERS Signed-off-by: Joe Perches Cc: Stefan Richter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index e54f72f6c341..4cd83fae87ca 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -381,8 +381,10 @@ foreach my $file (@files) { $line =~ s/\\\./\./g; ##Convert \. to . $line =~ s/\.\*/\*/g; ##Convert .* to * } + $line =~ s/^([A-Z]):/$1:\t/g; print("$line\n"); } + print("\n"); } } -- cgit v1.2.3 From 64f77f312b15f101bf6c4c65d5359ccc16e3f82b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 5 Mar 2010 13:43:04 -0800 Subject: scripts/get_maintainer.pl: add ability to read from STDIN Doesn't need or accept '-' as a trailing option to read stdin. Doesn't print usage() after bad options. Adds --usage as command line equivalent of --help Suggested-by: Borislav Petkov Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 4cd83fae87ca..f8baeeb8c3f7 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -126,7 +126,7 @@ if (!GetOptions( 'fe|file-emails!' => \$file_emails, 'f|file' => \$from_filename, 'v|version' => \$version, - 'h|help' => \$help, + 'h|help|usage' => \$help, )) { die "$P: invalid argument - use --help if necessary\n"; } @@ -141,9 +141,9 @@ if ($version != 0) { exit 0; } -if ($#ARGV < 0) { - usage(); - die "$P: argument missing: patchfile or -f file please\n"; +if (-t STDIN && !@ARGV) { + # We're talking to a terminal, but have no command line arguments. + die "$P: missing patchfile or -f file - use --help if necessary\n"; } if ($output_separator ne ", ") { @@ -165,7 +165,6 @@ if ($sections) { } else { my $selections = $email + $scm + $status + $subsystem + $web; if ($selections == 0) { - usage(); die "$P: Missing required option: email, scm, status, subsystem or web\n"; } } @@ -173,7 +172,6 @@ if ($sections) { if ($email && ($email_maintainer + $email_list + $email_subscriber_list + $email_git + $email_git_penguin_chiefs + $email_git_blame) == 0) { - usage(); die "$P: Please select at least 1 email option\n"; } @@ -248,12 +246,18 @@ my @range = (); my @keyword_tvi = (); my @file_emails = (); +if (!@ARGV) { + push(@ARGV, "&STDIN"); +} + foreach my $file (@ARGV) { - ##if $file is a directory and it lacks a trailing slash, add one - if ((-d $file)) { - $file =~ s@([^/])$@$1/@; - } elsif (!(-f $file)) { - die "$P: file '${file}' not found\n"; + if ($file ne "&STDIN") { + ##if $file is a directory and it lacks a trailing slash, add one + if ((-d $file)) { + $file =~ s@([^/])$@$1/@; + } elsif (!(-f $file)) { + die "$P: file '${file}' not found\n"; + } } if ($from_filename) { push(@files, $file); -- cgit v1.2.3 From 22dd5b0cba50a197aaa3bd2790a29ee2e8e4e372 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 5 Mar 2010 13:43:06 -0800 Subject: get_maintainer: fix perlcritic warnings perlcritic is a standard checker for Perl Best Practices. This patch fixes most of the warnings in the get_maintainer script. If kernel programmers are going to have checkpatch they should write clean scripts as well... Bareword file handle opened at line 176, column 1. See pages 202,204 of PBP. (Severity: 5) Two-argument "open" used at line 176, column 1. See page 207 of PBP. (Severity: 5) Bareword file handle opened at line 207, column 5. See pages 202,204 of PBP. (Severity: 5) Two-argument "open" used at line 207, column 5. See page 207 of PBP. (Severity: 5) Bareword file handle opened at line 246, column 6. See pages 202,204 of PBP. (Severity: 5) Two-argument "open" used at line 246, column 6. See page 207 of PBP. (Severity: 5) Bareword file handle opened at line 258, column 2. See pages 202,204 of PBP. (Severity: 5) Two-argument "open" used at line 258, column 2. See page 207 of PBP. (Severity: 5) Expression form of "eval" at line 983, column 17. See page 161 of PBP. (Severity: 5) Expression form of "eval" at line 985, column 17. See page 161 of PBP. (Severity: 5) Subroutine prototypes used at line 1186, column 1. See page 194 of PBP. (Severity: 5) Subroutine prototypes used at line 1206, column 1. See page 194 of PBP. (Severity: 5) Signed-off-by: Stephen Hemminger Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index f8baeeb8c3f7..9bb094138dd8 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -185,8 +185,9 @@ if (!top_of_kernel_tree($lk_path)) { my @typevalue = (); my %keyword_hash; -open(MAINT, "<${lk_path}MAINTAINERS") || die "$P: Can't open MAINTAINERS\n"; -while () { +open (my $maint, '<', "${lk_path}MAINTAINERS") + or die "$P: Can't open MAINTAINERS: $!\n"; +while (<$maint>) { my $line = $_; if ($line =~ m/^(\C):\s*(.*)/) { @@ -211,13 +212,14 @@ while () { push(@typevalue, $line); } } -close(MAINT); +close($maint); my %mailmap; if ($email_remove_duplicates) { - open(MAILMAP, "<${lk_path}.mailmap") || warn "$P: Can't open .mailmap\n"; - while () { + open(my $mailmap, '<', "${lk_path}.mailmap") + or warn "$P: Can't open .mailmap: $!\n"; + while (<$mailmap>) { my $line = $_; next if ($line =~ m/^\s*#/); @@ -236,7 +238,7 @@ if ($email_remove_duplicates) { $mailmap{$name} = \@arr; } } - close(MAILMAP); + close($mailmap); } ## use the filenames on the command line or find the filenames in the patchfiles @@ -262,9 +264,10 @@ foreach my $file (@ARGV) { if ($from_filename) { push(@files, $file); if (-f $file && ($keywords || $file_emails)) { - open(FILE, "<$file") or die "$P: Can't open ${file}\n"; - my $text = do { local($/) ; }; - close(FILE); + open(my $f, '<', $file) + or die "$P: Can't open $file: $!\n"; + my $text = do { local($/) ; <$f> }; + close($f); if ($keywords) { foreach my $line (keys %keyword_hash) { if ($text =~ m/$keyword_hash{$line}/x) { @@ -280,8 +283,10 @@ foreach my $file (@ARGV) { } else { my $file_cnt = @files; my $lastfile; - open(PATCH, "<$file") or die "$P: Can't open ${file}\n"; - while () { + + open(my $patch, '<', $file) + or die "$P: Can't open $file: $!\n"; + while (<$patch>) { my $patch_line = $_; if (m/^\+\+\+\s+(\S+)/) { my $filename = $1; @@ -301,7 +306,8 @@ foreach my $file (@ARGV) { } } } - close(PATCH); + close($patch); + if ($file_cnt == @files) { warn "$P: file '${file}' doesn't appear to be a patch. " . "Add -f to options?\n"; @@ -1286,7 +1292,7 @@ sub rfc822_strip_comments { # valid: returns true if the parameter is an RFC822 valid address # -sub rfc822_valid ($) { +sub rfc822_valid { my $s = rfc822_strip_comments(shift); if (!$rfc822re) { @@ -1306,7 +1312,7 @@ sub rfc822_valid ($) { # from success with no addresses found, because an empty string is # a valid list. -sub rfc822_validlist ($) { +sub rfc822_validlist { my $s = rfc822_strip_comments(shift); if (!$rfc822re) { -- cgit v1.2.3 From a63ceb4c36a7674f7efa90e8ba96b44a3989d717 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 5 Mar 2010 13:43:06 -0800 Subject: get_maintainer: quote email address with period Picky mail systems won't accept email addresses where recipient has period in name; ie. David S. Miller will not work. Signed-off-by: Stephen Hemminger Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 9bb094138dd8..b61002dceaba 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -605,7 +605,7 @@ sub parse_email { $name =~ s/^\"|\"$//g; $address =~ s/^\s+|\s+$//g; - if ($name =~ /[^a-z0-9 \.\-]/i) { ##has "must quote" chars + if ($name =~ /[^\w \-]/i) { ##has "must quote" chars $name =~ s/(? Date: Fri, 5 Mar 2010 13:43:07 -0800 Subject: scripts/get_maintainer.pl: fix possible infinite loop If MAINTAINERS section entries are misformatted, it was possible to have an infinite loop. Correct the defect by always moving the index to the end of section + 1 Also, exit check for exclude as soon as possible. Signed-off-by: Joe Perches Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index b61002dceaba..f76f3d13276d 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -347,6 +347,7 @@ foreach my $file (@files) { if ($type eq 'X') { if (file_match_pattern($file, $value)) { $exclude = 1; + last; } } } @@ -373,8 +374,7 @@ foreach my $file (@files) { } } - $tvi += ($end - $start); - + $tvi = $end + 1; } foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) { -- cgit v1.2.3 From 8f53a9b80f011080555c498d2ca2dc6b1a77c42c Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 5 Mar 2010 13:43:48 -0800 Subject: scripts/checkpatch.pl: add WARN on sizeof(&foo) sizeof(&foo) is frequently an error. Warn on its use. Signed-off-by: Joe Perches Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 3257d3d96767..309050f30874 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2572,6 +2572,11 @@ sub process { WARN("plain inline is preferred over $1\n" . $herecurr); } +# check for sizeof(&) + if ($line =~ /\bsizeof\s*\(\s*\&/) { + WARN("sizeof(& should be avoided\n" . $herecurr); + } + # check for new externs in .c files. if ($realfile =~ /\.c$/ && defined $stat && $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) -- cgit v1.2.3 From 42bdf74c95b6935f3c09a09ba4bead6cad11b540 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Fri, 5 Mar 2010 13:43:50 -0800 Subject: checkpatch: trivial fix for trailing statements check In case if the statement and the conditional are in one line, the line appears in the report doubly. And items of this check have no blank line before the next item. This patch fixes these trivial problems, to improve readability of the report. [sample.c] > if (cond1 > && cond2 > && cond3) func_foo(); > > if (cond4) func_bar(); Before: > ERROR: trailing statements should be on next line > #1: FILE: sample.c:1: > +if (cond1 > [...] > + && cond3) func_foo(); > ERROR: trailing statements should be on next line > #5: FILE: sample.c:5: > +if (cond4) func_bar(); > +if (cond4) func_bar(); > total: 2 errors, 0 warnings, 5 lines checked After: > ERROR: trailing statements should be on next line > #1: FILE: sample.c:1: > +if (cond1 > [...] > + && cond3) func_foo(); > > ERROR: trailing statements should be on next line > #5: FILE: sample.c:5: > +if (cond4) func_bar(); > > total: 2 errors, 0 warnings, 5 lines checked Signed-off-by: Hidetoshi Seto Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 309050f30874..3e4099a6df51 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2182,8 +2182,10 @@ sub process { # Find out how long the conditional actually is. my @newlines = ($c =~ /\n/gs); my $cond_lines = 1 + $#newlines; + my $stat_real = ''; - my $stat_real = raw_line($linenr, $cond_lines); + $stat_real = raw_line($linenr, $cond_lines) + . "\n" if ($cond_lines); if (defined($stat_real) && $cond_lines > 1) { $stat_real = "[...]\n$stat_real"; } -- cgit v1.2.3 From 691e669ba8c64d31ac08d87b1751e6acfa3ff65e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 5 Mar 2010 13:43:51 -0800 Subject: checkpatch.pl: allow > 80 char lines for logging functions not just printk Signed-off-by: Joe Perches Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 3e4099a6df51..9a3894dbf752 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -189,6 +189,14 @@ our $typeTypedefs = qr{(?x: atomic_t )}; +our $logFunctions = qr{(?x: + printk| + pr_(debug|dbg|vdbg|devel|info|warning|err|notice|alert|crit|emerg|cont)| + dev_(printk|dbg|vdbg|info|warn|err|notice|alert|crit|emerg|WARN)| + WARN| + panic +)}; + our @typeList = ( qr{void}, qr{(?:unsigned\s+)?char}, @@ -1377,7 +1385,7 @@ sub process { #80 column limit if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && $rawline !~ /^.\s*\*\s*\@$Ident\s/ && - $line !~ /^\+\s*printk\s*\(\s*(?:KERN_\S+\s*)?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ && + $line !~ /^\+\s*$logFunctions\s*\(\s*(?:KERN_\S+\s*)?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ && $length > 80) { WARN("line over 80 characters\n" . $herecurr); -- cgit v1.2.3 From 52131292c069b74f4b5f3c786ff66ff6e82b0e69 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 5 Mar 2010 13:43:51 -0800 Subject: checkpatch: fix false positive on __initconst checkpatch falsely complained about '__initconst' because it thought the 'const' needed a space before. Fix this by changing the list of attributes: - add '__initconst' - force plain 'init' to contain a word-boundary at the end Signed-off-by: Wolfram Sang Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 9a3894dbf752..1530dbf1dab5 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -145,11 +145,14 @@ our $Sparse = qr{ __kprobes| __ref }x; + +# Notes to $Attribute: +# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check our $Attribute = qr{ const| __read_mostly| __kprobes| - __(?:mem|cpu|dev|)(?:initdata|init)| + __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)| ____cacheline_aligned| ____cacheline_aligned_in_smp| ____cacheline_internodealigned_in_smp| -- cgit v1.2.3 From 22fd2d3e4f75a2596ccdfdcbdfd505c9c60bf346 Mon Sep 17 00:00:00 2001 From: Stefani Seibold Date: Fri, 5 Mar 2010 13:43:52 -0800 Subject: checkpatch.pl: add union and struct to the exceptions list Here is a small code snippet, which will be complained about by checkpatch.pl: #define __STRUCT_KFIFO_COMMON(recsize, ptrtype) \ union { \ struct { \ unsigned int in; \ unsigned int out; \ }; \ char rectype[recsize]; \ ptrtype *ptr; \ const ptrtype *ptr_const; \ }; This construct is legal and safe, so checkpatch.pl should accept this. It should be also true for struct defined in a macro. Add the `struct' and `union' keywords to the exceptions list of the checkpatch.pl script, to prevent error message "Macros with multiple statements should be enclosed in a do - while loop". Otherwise it is not possible to build a struct or union with a macro. Signed-off-by: Stefani Seibold Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 1530dbf1dab5..623d07b97727 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2361,6 +2361,8 @@ sub process { DECLARE_PER_CPU| DEFINE_PER_CPU| __typeof__\(| + union| + struct| \.$Ident\s*=\s*| ^\"|\"$ }x; -- cgit v1.2.3 From 79404849e90a41ea2109bd0e2f7c7164b0c4ce73 Mon Sep 17 00:00:00 2001 From: Emese Revfy Date: Fri, 5 Mar 2010 13:43:53 -0800 Subject: checkpatch.pl: extend list of expected-to-be-const structures Based on Arjan's suggestion, extend the list of ops structures that should be const. Signed-off-by: Emese Revfy Cc: Andy Whitcroft Cc: Arjan van de Ven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 623d07b97727..1a93ac265c31 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2654,9 +2654,46 @@ sub process { if ($line =~ /^.\s*__initcall\s*\(/) { WARN("please use device_initcall() instead of __initcall()\n" . $herecurr); } -# check for struct file_operations, ensure they are const. +# check for various ops structs, ensure they are const. + my $struct_ops = qr{acpi_dock_ops| + address_space_operations| + backlight_ops| + block_device_operations| + dentry_operations| + dev_pm_ops| + dma_map_ops| + extent_io_ops| + file_lock_operations| + file_operations| + hv_ops| + ide_dma_ops| + intel_dvo_dev_ops| + item_operations| + iwl_ops| + kgdb_arch| + kgdb_io| + kset_uevent_ops| + lock_manager_operations| + microcode_ops| + mtrr_ops| + neigh_ops| + nlmsvc_binding| + pci_raw_ops| + pipe_buf_operations| + platform_hibernation_ops| + platform_suspend_ops| + proto_ops| + rpc_pipe_ops| + seq_operations| + snd_ac97_build_ops| + soc_pcmcia_socket_ops| + stacktrace_ops| + sysfs_ops| + tty_operations| + usb_mon_operations| + wd_ops}x; if ($line !~ /\bconst\b/ && - $line =~ /\bstruct\s+(file_operations|seq_operations)\b/) { + $line =~ /\bstruct\s+($struct_ops)\b/) { WARN("struct $1 should normally be const\n" . $herecurr); } -- cgit v1.2.3 From 08e4436566250cb98b3f3ac37643b1cf09481256 Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Fri, 5 Mar 2010 13:43:54 -0800 Subject: checkpatch.pl: warn if an adding line introduce spaces before tabs. Signed-off-by: Alberto Panizzo Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 1a93ac265c31..cf4e44cf3c27 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1422,6 +1422,12 @@ sub process { ERROR("code indent should use tabs where possible\n" . $herevet); } +# check for space before tabs. + if ($rawline =~ /^\+/ && $rawline =~ / \t/) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + WARN("please, no space before tabs\n" . $herevet); + } + # check we are in a valid C source file if not then ignore this hunk next if ($realfile !~ /\.(h|c)$/); -- cgit v1.2.3 From 5e79d96eed306a8b4af67b3f35f6867edfabeebc Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 5 Mar 2010 13:43:55 -0800 Subject: checkpatch: warn on unnecessary spaces before quoted newlines Signed-off-by: Joe Perches Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index cf4e44cf3c27..a4d74344d805 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1394,6 +1394,11 @@ sub process { WARN("line over 80 characters\n" . $herecurr); } +# check for spaces before a quoted newline + if ($rawline =~ /^.*\".*\s\\n/) { + WARN("unnecessary whitespace before a quoted newline\n" . $herecurr); + } + # check for adding lines without a newline. if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { WARN("adding a line without newline at end of file\n" . $herecurr); -- cgit v1.2.3 From ef8ff89b58546055e238c3b521f83b440dfe8ef2 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Tue, 9 Mar 2010 16:00:20 +0100 Subject: kbuild: Really don't clean bounds.h and asm-offsets.h Commit 7d3cc8b tried to keep bounds.h and asm-offsets.h during make clean by filtering these out of $(clean-files), but they are listed in $(targets) and $(always) and thus removed automatically. Introduce a new $(no-clean-files) variable to really skip such files in Makefile.clean. Signed-off-by: Michal Marek --- scripts/Makefile.clean | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index 6f89fbb56256..686cb0d31c7c 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -45,6 +45,8 @@ __clean-files := $(extra-y) $(always) \ $(host-progs) \ $(hostprogs-y) $(hostprogs-m) $(hostprogs-) +__clean-files := $(filter-out $(no-clean-files), $(__clean-files)) + # as clean-files is given relative to the current directory, this adds # a $(obj) prefix, except for absolute paths -- cgit v1.2.3 From 4c98ecaf350737cd424eb94140e9e9f1a3408956 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 10 Mar 2010 15:22:02 -0800 Subject: scripts/kernel-doc: fix empty function description section scripts/kernel-doc mishandles a function that has a multi-line function short description and no function parameters. The observed problem was from drivers/scsi/scsi_netlink.c: /** * scsi_netlink_init - Called by SCSI subsystem to intialize * the SCSI transport netlink interface * **/ kernel-doc treated the " * " line as a Description: section with only a newline character in the Description contents. This caused output_highlight() to complain: "output_highlight got called with no args?", plus produce a perl call stack backtrace. The fix is just to ignore Description sections if they only contain "\n". Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/kernel-doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 208ad3b0ca51..c7865c362d28 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -2103,7 +2103,7 @@ sub process_file($) { $section = $newsection; } elsif (/$doc_end/) { - if ($contents ne "") { + if (($contents ne "") && ($contents ne "\n")) { dump_section($file, $section, xml_escape($contents)); $section = $section_default; $contents = ""; -- cgit v1.2.3 From 31a2d31dbd01a7d530a748e6f708ba047c37fb90 Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Fri, 19 Feb 2010 12:43:44 +0100 Subject: kconfig: util: Fix typo in comment sting replaced with string Signed-off-by: Thomas Weber Signed-off-by: Jiri Kosina --- scripts/kconfig/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c index b6b2a46af14c..25d1ec4ca28a 100644 --- a/scripts/kconfig/util.c +++ b/scripts/kconfig/util.c @@ -72,7 +72,7 @@ int file_write_dep(const char *name) } -/* Allocate initial growable sting */ +/* Allocate initial growable string */ struct gstr str_new(void) { struct gstr gs; -- cgit v1.2.3 From 310de047eef6685274045db1e6b39c9f313df428 Mon Sep 17 00:00:00 2001 From: James Morris Date: Tue, 16 Mar 2010 08:47:36 +1100 Subject: selinux: fix warning in genheaders Fix const warning in the genheaders script as a result of changes to the headers, as noted here: http://linux.derkeiler.com/Mailing-Lists/Kernel/2010-03/msg03977.html Reported-by: Stephen Rothwell Signed-off-by: James Morris --- scripts/selinux/genheaders/genheaders.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/selinux/genheaders/genheaders.c b/scripts/selinux/genheaders/genheaders.c index 24626968055d..58a12c278706 100644 --- a/scripts/selinux/genheaders/genheaders.c +++ b/scripts/selinux/genheaders/genheaders.c @@ -81,7 +81,7 @@ int main(int argc, char *argv[]) fprintf(fout, "\n"); for (i = 1; i < isids_len; i++) { - char *s = initial_sid_to_string[i]; + const char *s = initial_sid_to_string[i]; fprintf(fout, "#define SECINITSID_%s", s); for (j = 0; j < max(1, 40 - strlen(s)); j++) fprintf(fout, " "); -- cgit v1.2.3 From ef5da59f12602815baa8fad98241b77dedea3b31 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 23 Mar 2010 13:35:14 -0700 Subject: scripts/kernel-doc: handle struct member __aligned scripts/kernel-doc erroneously says: Warning(include/linux/skbuff.h:410): Excess struct/union/enum/typedef member 'cb' description in 'sk_buff' on this line in struct sk_buff: char cb[48] __aligned(8); due to treating the last field as the struct member name, so teach kernel-doc to ignore __aligned(x) in structs. Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/kernel-doc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index c7865c362d28..c297eb4785d6 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1424,6 +1424,8 @@ sub dump_struct($$) { $nested =~ s/\/\*.*?\*\///gos; # strip kmemcheck_bitfield_{begin,end}.*; $members =~ s/kmemcheck_bitfield_.*?;//gos; + # strip attributes + $members =~ s/__aligned\s*\(\d+\)//gos; create_parameterlist($members, ';', $file); check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested); -- cgit v1.2.3 From 3a4df13d2420ae1998e5c7d26275f8714e84da30 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 23 Mar 2010 13:35:18 -0700 Subject: get_maintainer: repair STDIN usage Commit 22dd5b0cba50a197aaa3bd2790a29ee2e8e4e372 (fix perlcritic warnings) broke the ability to handle STDIN because the three argument version of open() cannot handle standard IO-streams (which is mentioned in PerlBestPractices, too). Signed-off-by: Wolfram Sang Cc: Stephen Hemminger Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index f76f3d13276d..6f97a13bcee4 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -284,7 +284,7 @@ foreach my $file (@ARGV) { my $file_cnt = @files; my $lastfile; - open(my $patch, '<', $file) + open(my $patch, "< $file") or die "$P: Can't open $file: $!\n"; while (<$patch>) { my $patch_line = $_; -- cgit v1.2.3 From 20072205fcdf7d85cd3101f1f11dfab333c5fd0c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 23 Mar 2010 13:35:24 -0700 Subject: scripts/kernel-doc: fix fatal error on function prototype Fix a fatal error in scripts/kernel-doc when a function signature uses __init_or_module (just ignore that string): Error(drivers/base/platform.c:568): cannot understand prototype: 'struct platform_device * __init_or_module platform_create_bundle(struct platform_driver *driver, int (*probe)(struct platform_device *), struct resource *res, unsigned int n_res, const void *data, size_t size) ' Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/kernel-doc | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index c297eb4785d6..fcdfb245a575 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1730,6 +1730,7 @@ sub dump_function($$) { $prototype =~ s/^noinline +//; $prototype =~ s/__devinit +//; $prototype =~ s/__init +//; + $prototype =~ s/__init_or_module +//; $prototype =~ s/^#\s*define\s+//; #ak added $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//; -- cgit v1.2.3 From f77f13e22df4a40d237697df496152c8c37f3f2b Mon Sep 17 00:00:00 2001 From: Gilles Espinasse Date: Mon, 29 Mar 2010 15:41:47 +0200 Subject: Fix comment and Kconfig typos for 'require' and 'fragment' Signed-off-by: Gilles Espinasse Signed-off-by: Jiri Kosina --- scripts/package/mkspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/package/mkspec b/scripts/package/mkspec index 47bdd2f99b78..fa27f3dac769 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -1,6 +1,6 @@ #!/bin/sh # -# Output a simple RPM spec file that uses no fancy features requring +# Output a simple RPM spec file that uses no fancy features requiring # RPM v4. This is intended to work with any RPM distro. # # The only gothic bit here is redefining install_post to avoid -- cgit v1.2.3 From 8626d3b4328061f5b82b11ae1d6918a0c3602f42 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 2 Apr 2010 01:05:27 +0000 Subject: phylib: Support phy module autoloading We don't use the normal hotplug mechanism because it doesn't work. It will load the module some time after the device appears, but that's not good enough for us -- we need the driver loaded _immediately_ because otherwise the NIC driver may just abort and then the phy 'device' goes away. [bwh: s/phy/mdio/ in module alias, kerneldoc for struct mdio_device_id] Signed-off-by: David Woodhouse Signed-off-by: Ben Hutchings Acked-by: Andy Fleming Signed-off-by: David S. Miller --- scripts/mod/file2alias.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 220213e603db..36a60a853173 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -796,6 +796,28 @@ static int do_platform_entry(const char *filename, return 1; } +static int do_mdio_entry(const char *filename, + struct mdio_device_id *id, char *alias) +{ + int i; + + alias += sprintf(alias, MDIO_MODULE_PREFIX); + + for (i = 0; i < 32; i++) { + if (!((id->phy_id_mask >> (31-i)) & 1)) + *(alias++) = '?'; + else if ((id->phy_id >> (31-i)) & 1) + *(alias++) = '1'; + else + *(alias++) = '0'; + } + + /* Terminate the string */ + *alias = 0; + + return 1; +} + /* Ignore any prefix, eg. some architectures prepend _ */ static inline int sym_is(const char *symbol, const char *name) { @@ -943,6 +965,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, 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); free(zeros); } -- cgit v1.2.3 From d61931d89be506372d01a90d1755f6d0a9fafe2d Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 5 Mar 2010 17:34:46 +0100 Subject: x86: Add optimized popcnt variants Add support for the hardware version of the Hamming weight function, popcnt, present in CPUs which advertize it under CPUID, Function 0x0000_0001_ECX[23]. On CPUs which don't support it, we fallback to the default lib/hweight.c sw versions. A synthetic benchmark comparing popcnt with __sw_hweight64 showed almost a 3x speedup on a F10h machine. Signed-off-by: Borislav Petkov LKML-Reference: <20100318112015.GC11152@aftab> Signed-off-by: H. Peter Anvin --- scripts/Makefile.lib | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index f9bdf264473d..cbcd654215e6 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -245,3 +245,7 @@ quiet_cmd_lzo = LZO $@ cmd_lzo = (cat $(filter-out FORCE,$^) | \ lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ (rm -f $@ ; false) + +# misc stuff +# --------------------------------------------------------------------------- +quote:=" -- cgit v1.2.3 From bf54a2b3c0dbf76136f00ff785bf6d8f6291311d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 18 Nov 2008 21:13:53 +0100 Subject: m68k: amiga - Zorro bus modalias support Add Amiga Zorro bus modalias and uevent support Signed-off-by: Geert Uytterhoeven --- scripts/mod/file2alias.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 220213e603db..df90f31d14bf 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -796,6 +796,16 @@ static int do_platform_entry(const char *filename, return 1; } +/* Looks like: zorro:iN. */ +static int do_zorro_entry(const char *filename, struct zorro_device_id *id, + char *alias) +{ + id->id = TO_NATIVE(id->id); + strcpy(alias, "zorro:"); + ADD(alias, "i", id->id != ZORRO_WILDCARD, id->id); + return 1; +} + /* Ignore any prefix, eg. some architectures prepend _ */ static inline int sym_is(const char *symbol, const char *name) { @@ -943,6 +953,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, do_table(symval, sym->st_size, sizeof(struct platform_device_id), "platform", do_platform_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); free(zeros); } -- cgit v1.2.3 From fedb3d27d9e8606b3867b5ae49d6258458a07a72 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Fri, 18 Dec 2009 20:52:39 +0100 Subject: MODULE_DEVICE_TABLE(isapnp, ...) does nothing On Monday 23 November 2009 04:29:53 Rusty Russell wrote: > On Mon, 23 Nov 2009 07:31:57 am Ondrej Zary wrote: > > The problem is that > > scripts/mod/file2alias.c simply ignores isapnp. > > AFAICT it always has, and noone has complained until now. Perhaps > something was still reading /lib/modules/`uname -r`/modules.isapnpmap? The patch below works fine (at least with Debian). It needs your first patch that moves the definitions to mod_devicetable.h. Verified that aliases for these modules are generated correctly: drivers/media/radio/radio-sf16fmi.c drivers/net/ne.c drivers/net/3c515.c drivers/net/smc-ultra.c drivers/pcmcia/i82365.c drivers/scsi/aha1542.c drivers/scsi/aha152x.c drivers/scsi/sym53c416.c drivers/scsi/g_NCR5380.c Tested with RTL8019AS (ne), AVA-1505AE (aha152x) and dtc436e (g_NCR5380) cards - they now work automatically. Generate pnp:d aliases for isapnp_device_tables. This allows udev to load these modules automatically. Signed-off-by: Ondrej Zary Signed-off-by: Rusty Russell --- scripts/mod/file2alias.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index df90f31d14bf..808c20d81f8d 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -806,6 +806,19 @@ static int do_zorro_entry(const char *filename, struct zorro_device_id *id, return 1; } +/* looks like: "pnp:dD" */ +static int do_isapnp_entry(const char *filename, + struct isapnp_device_id *id, char *alias) +{ + sprintf(alias, "pnp:d%c%c%c%x%x%x%x*", + 'A' + ((id->vendor >> 2) & 0x3f) - 1, + 'A' + (((id->vendor & 3) << 3) | ((id->vendor >> 13) & 7)) - 1, + 'A' + ((id->vendor >> 8) & 0x1f) - 1, + (id->function >> 4) & 0x0f, id->function & 0x0f, + (id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f); + return 1; +} + /* Ignore any prefix, eg. some architectures prepend _ */ static inline int sym_is(const char *symbol, const char *name) { @@ -957,6 +970,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, 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); free(zeros); } -- cgit v1.2.3 From 1704f47b50b5d9e1b825e43e1baaf2c5897baf03 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 19 Mar 2010 01:37:42 +0100 Subject: lockdep: Add novalidate class for dev->mutex conversion The conversion of device->sem to device->mutex resulted in lockdep warnings. Create a novalidate class for now until the driver folks come up with separate classes. That way we have at least the basic mutex debugging coverage. Add a checkpatch error so the usage is reserved for device->mutex. [ tglx: checkpatch and compile fix for LOCKDEP=n ] Signed-off-by: Peter Zijlstra Signed-off-by: Thomas Gleixner Signed-off-by: Greg Kroah-Hartman --- scripts/checkpatch.pl | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index a4d74344d805..f2bbea900700 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2656,6 +2656,7 @@ sub process { # check for semaphores used as mutexes if ($line =~ /^.\s*init_MUTEX_LOCKED\s*\(/) { WARN("consider using a completion\n" . $herecurr); + } # recommend strict_strto* over simple_strto* if ($line =~ /\bsimple_(strto.*?)\s*\(/) { @@ -2740,6 +2741,16 @@ sub process { WARN("use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); } } + +# check for lockdep_set_novalidate_class + if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || + $line =~ /__lockdep_no_validate__\s*\)/ ) { + if ($realfile !~ m@^kernel/lockdep@ && + $realfile !~ m@^include/linux/lockdep@ && + $realfile !~ m@^drivers/base/core@) { + ERROR("lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); + } + } } # If we have no input at all, then there is nothing to report on -- cgit v1.2.3 From e4d26b027a0b7e289fdc542fe06535329b457dd5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 24 May 2010 14:33:17 -0700 Subject: scripts/get_maintainer.pl: optionally ignore non-maintainer signatures When using --git to determine who to send a patch to, get_maintainers will currently include all signatures. This can include signers that simply report an issue or test a patch. Signers that use this tag are not necessarily good candidates to review new patches. This patch allows get_maintainers to optionally restrict output to only signatures that use Signed-off-by:, Acked-by:, or Reviewed-by:. Signed-off-by: is included because those are people who are responsible for the code. Acked-by: is questionable, but as signers that use this tag tend to be active linux gatekeepers, false positives are tolerable. Reviewed-by: is included because signers responsible for the code thought that the review feedback for a changeset by that signer was valuable. This patch has been modified from Florian's original submission to change the supported signature types to the canonical forms and use slightly different spacing. A couple of spacing issues were also corrected in the original source. The command line argument was also renamed. Original-patch-by: Florian Mickler Signed-off-by: Florian Mickler Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 6f97a13bcee4..f66018d1d5ee 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -25,6 +25,7 @@ my $email_list = 1; my $email_subscriber_list = 0; my $email_git_penguin_chiefs = 0; my $email_git = 1; +my $email_git_all_signature_types = 1; my $email_git_blame = 0; my $email_git_min_signatures = 1; my $email_git_max_maintainers = 5; @@ -51,9 +52,9 @@ my $help = 0; my $exit = 0; my @penguin_chief = (); -push(@penguin_chief,"Linus Torvalds:torvalds\@linux-foundation.org"); +push(@penguin_chief, "Linus Torvalds:torvalds\@linux-foundation.org"); #Andrew wants in on most everything - 2009/01/14 -#push(@penguin_chief,"Andrew Morton:akpm\@linux-foundation.org"); +#push(@penguin_chief, "Andrew Morton:akpm\@linux-foundation.org"); my @penguin_chief_names = (); foreach my $chief (@penguin_chief) { @@ -63,7 +64,16 @@ foreach my $chief (@penguin_chief) { push(@penguin_chief_names, $chief_name); } } -my $penguin_chiefs = "\(" . join("|",@penguin_chief_names) . "\)"; +my $penguin_chiefs = "\(" . join("|", @penguin_chief_names) . "\)"; + +# Signature types of people who are either +# a) responsible for the code in question, or +# b) familiar enough with it to give relevant feedback +my @signature_tags = (); +push(@signature_tags, "Signed-off-by:"); +push(@signature_tags, "Reviewed-by:"); +push(@signature_tags, "Acked-by:"); +my $signaturePattern = "\(" . join("|", @signature_tags) . "\)"; # rfc822 email address - preloaded methods go here. my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])"; @@ -100,6 +110,7 @@ my %VCS_cmds_hg = ( if (!GetOptions( 'email!' => \$email, 'git!' => \$email_git, + 'git-all-signature-types!' => \$email_git_all_signature_types, 'git-blame!' => \$email_git_blame, 'git-chief-penguins!' => \$email_git_penguin_chiefs, 'git-min-signatures=i' => \$email_git_min_signatures, @@ -180,6 +191,10 @@ if (!top_of_kernel_tree($lk_path)) { . "a linux kernel source tree.\n"; } +if ($email_git_all_signature_types) { + $signaturePattern = "(.+?)[Bb][Yy]:"; +} + ## Read MAINTAINERS for type/value pairs my @typevalue = (); @@ -497,13 +512,15 @@ version: $V MAINTAINER field selection options: --email => print email address(es) if any --git => include recent git \*-by: signers + --git-all-signature-types => include signers regardless of signature type + or use only ${signaturePattern} signers (default: $email_git_all_signature_types) --git-chief-penguins => include ${penguin_chiefs} - --git-min-signatures => number of signatures required (default: 1) - --git-max-maintainers => maximum maintainers to add (default: 5) - --git-min-percent => minimum percentage of commits required (default: 5) + --git-min-signatures => number of signatures required (default: $email_git_min_signatures) + --git-max-maintainers => maximum maintainers to add (default: $email_git_max_maintainers) + --git-min-percent => minimum percentage of commits required (default: $email_git_min_percent) --git-blame => use git blame to find modified commits for patch or file - --git-since => git history to use (default: 1-year-ago) - --hg-since => hg history to use (default: -365) + --git-since => git history to use (default: $email_git_since) + --hg-since => hg history to use (default: $email_hg_since) --m => include maintainer(s) if any --n => include name 'Full Name ' --l => include list(s) if any @@ -964,7 +981,7 @@ sub vcs_find_signers { $commits = grep(/$pattern/, @lines); # of commits - @lines = grep(/^[-_ a-z]+by:.*\@.*$/i, @lines); + @lines = grep(/^[ \t]*${signaturePattern}.*\@.*$/, @lines); if (!$email_git_penguin_chiefs) { @lines = grep(!/${penguin_chiefs}/i, @lines); } -- cgit v1.2.3 From 368669da205cd7aac33a2c75f4c81b5ad28efd67 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 24 May 2010 14:33:19 -0700 Subject: scripts/get_maintainer.pl: add .get_maintainer.conf default options file Allow the use of a .get_maintainer.conf file to control the default options applied when scripts/get_maintainer.pl is run. .get_maintainer.conf can contain any valid command-line argument. File contents are prepended to any additional command line arguments. Multiple lines may be used, blank lines ignored, # is a comment. Updated scripts/get_maintainer.pl version to 0.24 Signed-off-by: Joe Perches Reviewed-by: Florian Mickler Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index f66018d1d5ee..b82ac95ef2fc 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -13,7 +13,7 @@ use strict; my $P = $0; -my $V = '0.23'; +my $V = '0.24'; use Getopt::Long qw(:config no_auto_abbrev); @@ -107,6 +107,30 @@ my %VCS_cmds_hg = ( "blame_commit_pattern" => "^([0-9a-f]+):" ); +if (-f "${lk_path}.get_maintainer.conf") { + my @conf_args; + open(my $conffile, '<', "${lk_path}.get_maintainer.conf") + or warn "$P: Can't open .get_maintainer.conf: $!\n"; + while (<$conffile>) { + my $line = $_; + + $line =~ s/\s*\n?$//g; + $line =~ s/^\s*//g; + $line =~ s/\s+/ /g; + + next if ($line =~ m/^\s*#/); + next if ($line =~ m/^\s*$/); + + my @words = split(" ", $line); + foreach my $word (@words) { + last if ($word =~ m/^#/); + push (@conf_args, $word); + } + } + close($conffile); + unshift(@ARGV, @conf_args) if @conf_args; +} + if (!GetOptions( 'email!' => \$email, 'git!' => \$email_git, @@ -573,6 +597,11 @@ Notes: --git-min-signatures, --git-max-maintainers, --git-min-percent, and --git-blame Use --hg-since not --git-since to control date selection + File ".get_maintainer.conf", if it exists in the linux kernel source root + directory, can change whatever get_maintainer defaults are desired. + Entries in this file can be any command line argument. + This file is prepended to any additional command line arguments. + Multiple lines and # comments are allowed. EOT } -- cgit v1.2.3 From 0fa05599009ed36304d490064888d0252d656add Mon Sep 17 00:00:00 2001 From: Florian Mickler Date: Mon, 24 May 2010 14:33:20 -0700 Subject: scripts/get_maintainer.pl: default to not include unspecified tags This changes the default of the option --git-all-signature-types to be disabled by default. The effect being, that only certain (currently Signed-Off-By:, Acked-by: and Reviewed-By:) tags are used to get adresses of potential maintainers. Motivated is this change by the desire to not 'spam' people unnecessary: A Tested-By or a Reported-By is not ment as a hint that those people want to/are able to review patches to the code in question. In a quest to find resilient statistics for this i came up with this: I produced a list of all the tag-signers not already covered with a signed-off/acked/reviewed tag somewhere in the last year of git history. Those were 650 addresses of "assumed non-developers". And to check if those "assumed non-developers" are professional testers/reporters worth cc'ing, i then counted their total appearences in the git log: 469 were mentioned only once. 123 were mentioned twice. 38 three times 8 four times 5 six times 5 five times 1 eight times 1 fourteen times I believe this supports my thesis, that the ''non-maintainer-tags'' are not actively useful for patch-review. (except probably the guy mentioned fourteen times...) But of course one could also find arguments to poke holes in this statistics, for example does this statistic not include code-locality: A tested-by on a patch that touches some specific piece of code can be more worth than a signed-off in another part of the tree. But... let's play it safe and let's err on the "safe" side meaning to not spam those people when in doubt. We already have the signed-off's and Maintainers file. So this should be ok. And if need be, the maintainers can always forward the patch. [i probably could make a diploma thesis out of this changelog :)] Signed-off-by: Florian Mickler Acked-by: Wolfram Sang Cc: Joe Perches Cc: Stefan Richter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index b82ac95ef2fc..b2281982f52f 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -25,7 +25,7 @@ my $email_list = 1; my $email_subscriber_list = 0; my $email_git_penguin_chiefs = 0; my $email_git = 1; -my $email_git_all_signature_types = 1; +my $email_git_all_signature_types = 0; my $email_git_blame = 0; my $email_git_min_signatures = 1; my $email_git_max_maintainers = 5; -- cgit v1.2.3 From 3354957a4f8b9bb4b43625232acdf0626851c82f Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 24 May 2010 14:33:29 -0700 Subject: checkpatch: add check for too short Kconfig descriptions I've seen various new Kconfigs with rather unhelpful one liner descriptions. Add a Kconfig warning for a minimum length of the Kconfig help section. Right now I arbitarily chose 4. The exact value can be debated. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Andi Kleen Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index f2bbea900700..de0f4672cb74 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1382,6 +1382,21 @@ sub process { ERROR("trailing whitespace\n" . $herevet); } +# check for Kconfig help text having a real description + if ($realfile =~ /Kconfig/ && + $line =~ /\+?\s*(---)?help(---)?$/) { + my $length = 0; + for (my $l = $linenr; defined($lines[$l]); $l++) { + my $f = $lines[$l]; + $f =~ s/#.*//; + $f =~ s/^\s+//; + next if ($f =~ /^$/); + last if ($f =~ /^\s*config\s/); + $length++; + } + WARN("please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($length < 4); + } + # check we are in a valid source file if not then ignore this hunk next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/); -- cgit v1.2.3 From d4977c78e9c7dd042f96f4a21d957bc25a561333 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 24 May 2010 14:33:30 -0700 Subject: checkpatch: warn on declaration with storage class not at the beginning The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser Acked-by: Jean Delvare Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index de0f4672cb74..bd88f11b0953 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2601,6 +2601,11 @@ sub process { CHK("architecture specific defines should be avoided\n" . $herecurr); } +# Check that the storage class is at the beginning of a declaration + if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) { + WARN("storage class should be at the beginning of the declaration\n" . $herecurr) + } + # check the location of the inline attribute, that it is between # storage class and type. if ($line =~ /\b$Type\s+$Inline\b/ || -- cgit v1.2.3 From 2a2a400f66e9e23eba960905c36dd37904bd9970 Mon Sep 17 00:00:00 2001 From: Albin Tonnerre Date: Wed, 26 May 2010 14:44:28 -0700 Subject: initramfs: add support for in-kernel initramfs compressed with LZO Add the necessary parts to be enable the use of LZO-compressed initramfs build into the kernel. Signed-off-by: Albin Tonnerre Cc: "H. Peter Anvin" Cc: Michal Marek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/gen_initramfs_list.sh | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh index 76af5f9623e3..a932ae52f921 100644 --- a/scripts/gen_initramfs_list.sh +++ b/scripts/gen_initramfs_list.sh @@ -242,6 +242,7 @@ case "$arg" in echo "$output_file" | grep -q "\.gz$" && compr="gzip -9 -f" echo "$output_file" | grep -q "\.bz2$" && compr="bzip2 -9 -f" echo "$output_file" | grep -q "\.lzma$" && compr="lzma -9 -f" + echo "$output_file" | grep -q "\.lzo$" && compr="lzop -9 -f" echo "$output_file" | grep -q "\.cpio$" && compr="cat" shift ;; -- cgit v1.2.3 From e5199edb9e1b17792743d76bf10601ec7d6ef513 Mon Sep 17 00:00:00 2001 From: Toralf Foerster Date: Fri, 28 May 2010 10:24:59 +0200 Subject: kconfig: Make a variable local in streamline_config.pl Proper perl requires that local variables should be declared with 'my', otherwise this may produce errors. Signed-off-by: Toralf Foerster LKML-Reference: <201005281025.00358.toralf.foerster@gmx.de> Signed-off-by: Steven Rostedt --- scripts/kconfig/streamline_config.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index afbd54ac1d83..9726946472fd 100644 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -307,7 +307,7 @@ close (LIN); my %configs; foreach my $module (keys(%modules)) { if (defined($objects{$module})) { - @arr = @{$objects{$module}}; + my @arr = @{$objects{$module}}; foreach my $conf (@arr) { $configs{$conf} = $module; } -- cgit v1.2.3 From 1d1d1feafd5d42e9e1312d42973e661582e51704 Mon Sep 17 00:00:00 2001 From: Toralf Foerster Date: Fri, 28 May 2010 10:25:52 +0200 Subject: kconfig: Fix typo in comment in streamline_config.pl Signed-off-by: Toralf Foerster LKML-Reference: <201005281025.52753.toralf.foerster@gmx.de> Signed-off-by: Steven Rostedt --- scripts/kconfig/streamline_config.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index 9726946472fd..2f8bde809711 100644 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -242,7 +242,7 @@ foreach my $makefile (@makefiles) { foreach my $obj (split /\s+/,$objs) { $obj =~ s/-/_/g; if ($obj =~ /(.*)\.o$/) { - # Objects may bes enabled by more than one config. + # Objects may be enabled by more than one config. # Store configs in an array. my @arr; -- cgit v1.2.3 From 17431928194b36a0f88082df875e2e036da7fddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toralf=20F=C3=B6rster?= Date: Wed, 26 May 2010 20:22:02 +0200 Subject: kconfig: Hide error output in find command in streamline_config.pl Finding the list of Makefiles in streamline-config should not report errors. Also move the "chomp" to the @makefiles array instead of doing it in the for loop. This is more efficient, and does not make it any less readable by C programmers. Signed-off-by: Toralf Foerster LKML-Reference: <201005262022.02928.toralf.foerster@gmx.de> Signed-off-by: Steven Rostedt --- scripts/kconfig/streamline_config.pl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index 2f8bde809711..c70a27d924f0 100644 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -115,7 +115,9 @@ my $ksource = $ARGV[0]; my $kconfig = $ARGV[1]; my $lsmod_file = $ARGV[2]; -my @makefiles = `find $ksource -name Makefile`; +my @makefiles = `find $ksource -name Makefile 2>/dev/null`; +chomp @makefiles; + my %depends; my %selects; my %prompts; @@ -215,7 +217,6 @@ if ($kconfig) { # Read all Makefiles to map the configs to the objects foreach my $makefile (@makefiles) { - chomp $makefile; open(MIN,$makefile) || die "Can't open $makefile"; while () { -- cgit v1.2.3 From f0778c8c41001783d4074e34efc7d3e632d87ee3 Mon Sep 17 00:00:00 2001 From: Aristeu Rozanski Date: Thu, 6 May 2010 12:48:34 -0400 Subject: kconfig: introduce nonint_oldconfig and loose_nonint_oldconfig This patch has been around for a long time in Fedora and Red Hat Enterprise Linux kernels and it may be useful for others. The nonint_oldconfig target will fail and print the unset config options while loose_nonint_oldconfig will simply let the config option unset. They're useful in distro kernel packages where the config files are built using a combination of smaller config files. Arjan van de Ven wrote the initial nonint_config and Roland McGrath added the loose_nonint_oldconfig. Signed-off-by: Arjan van de Ven [defunct email] Whatevered-by: Kyle McMartin Acked-by: Arjan van de Ven Acked-by: Randy Dunlap Signed-off-by: Aristeu Rozanski [mmarek: whitespace fixes] Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 10 +++++++++ scripts/kconfig/conf.c | 53 ++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 54 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 75bdf5ae202c..f8d1ee3a372e 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -62,6 +62,12 @@ localyesconfig: $(obj)/streamline_config.pl $(obj)/conf fi $(Q)rm -f .tmp.config +nonint_oldconfig: $(obj)/conf + $< -b $(Kconfig) + +loose_nonint_oldconfig: $(obj)/conf + $< -B $(Kconfig) + # 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 @@ -126,6 +132,10 @@ help: @echo ' allmodconfig - New config selecting modules when possible' @echo ' allyesconfig - New config where all options are accepted with yes' @echo ' allnoconfig - New config where all options are answered with no' + @echo ' nonint_oldconfig - Checks the current configuration and fails if an option is ' + @echo ' not set' + @echo ' loose_nonint_oldconfig - Same as nonint_oldconfig, but updates the config file with ' + @echo ' missing config options as unset' # lxdialog stuff check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 9960d1c303f8..3fa4abf3b084 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -16,6 +16,10 @@ #define LKC_DIRECT_LINK #include "lkc.h" +/* Return codes */ +#define EUNSETOPT 2 /* if -B and -b are used and unset config + * options were found */ + static void conf(struct menu *menu); static void check_conf(struct menu *menu); @@ -23,6 +27,8 @@ enum { ask_all, ask_new, ask_silent, + dont_ask, + dont_ask_dont_tell, set_default, set_yes, set_mod, @@ -37,6 +43,7 @@ static int sync_kconfig; static int conf_cnt; static char line[128]; static struct menu *rootEntry; +static int unset_variables; static void print_help(struct menu *menu) { @@ -360,7 +367,10 @@ static void conf(struct menu *menu) switch (prop->type) { case P_MENU: - if (input_mode == ask_silent && rootEntry != menu) { + if ((input_mode == ask_silent || + input_mode == dont_ask || + input_mode == dont_ask_dont_tell) && + rootEntry != menu) { check_conf(menu); return; } @@ -418,10 +428,23 @@ static void check_conf(struct menu *menu) if (sym && !sym_has_value(sym)) { if (sym_is_changable(sym) || (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { - if (!conf_cnt++) - printf(_("*\n* Restart config...\n*\n")); - rootEntry = menu_get_parent_menu(menu); - conf(rootEntry); + if (input_mode == dont_ask || + input_mode == dont_ask_dont_tell) { + if (input_mode == dont_ask && + sym->name && !sym_is_choice_value(sym)) { + if (!unset_variables) + fprintf(stderr, "The following" + " variables are not set:\n"); + fprintf(stderr, "CONFIG_%s\n", + sym->name); + unset_variables++; + } + } else { + if (!conf_cnt++) + printf(_("*\n* Restart config...\n*\n")); + rootEntry = menu_get_parent_menu(menu); + conf(rootEntry); + } } } @@ -439,7 +462,7 @@ int main(int ac, char **av) bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) { + while ((opt = getopt(ac, av, "osbBdD:nmyrh")) != -1) { switch (opt) { case 'o': input_mode = ask_silent; @@ -448,6 +471,12 @@ int main(int ac, char **av) input_mode = ask_silent; sync_kconfig = 1; break; + case 'b': + input_mode = dont_ask; + break; + case 'B': + input_mode = dont_ask_dont_tell; + break; case 'd': input_mode = set_default; break; @@ -525,6 +554,8 @@ int main(int ac, char **av) case ask_silent: case ask_all: case ask_new: + case dont_ask: + case dont_ask_dont_tell: conf_read(NULL); break; case set_no: @@ -586,12 +617,16 @@ int main(int ac, char **av) conf(&rootmenu); input_mode = ask_silent; /* fall through */ + case dont_ask: + case dont_ask_dont_tell: case ask_silent: /* Update until a loop caused no more changes */ do { conf_cnt = 0; check_conf(&rootmenu); - } while (conf_cnt); + } while (conf_cnt && + (input_mode != dont_ask && + input_mode != dont_ask_dont_tell)); break; } @@ -607,11 +642,11 @@ int main(int ac, char **av) fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n")); return 1; } - } else { + } else if (!unset_variables || input_mode != dont_ask) { if (conf_write(NULL)) { fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); exit(1); } } - return 0; + return unset_variables ? EUNSETOPT : 0; } -- cgit v1.2.3 From b040b44c35c251882da8488a5f038435a531312c Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 7 May 2010 13:56:33 +0800 Subject: kconfig: print symbol type in help text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Randy suggested to print out the symbol type in gconfig. Note this change does more than Randy's suggestion, that it also affects menuconfig and "make config". │ Symbol: BLOCK [=y] │ Type : boolean │ Prompt: Enable the block layer │ Defined at block/Kconfig:4 │ Depends on: EMBEDDED [=n] Signed-off-by: Li Zefan Acked-by: Randy Dunlap Signed-off-by: Michal Marek --- scripts/kconfig/menu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 203632cc30bd..187caa9142fd 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -501,9 +501,11 @@ void get_symbol_str(struct gstr *r, struct symbol *sym) bool hit; struct property *prop; - if (sym && sym->name) + if (sym && sym->name) { str_printf(r, "Symbol: %s [=%s]\n", sym->name, sym_get_string_value(sym)); + str_printf(r, "Type : %s\n", sym_type_name(sym->type)); + } for_all_prompts(sym, prop) get_prompt_str(r, prop); hit = false; -- cgit v1.2.3 From 70ed074718a6704ac2f82d014f372ba25c42ba12 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 7 May 2010 13:56:50 +0800 Subject: kconfig: print the range of integer/hex symbol in help text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this patch, one has to refer to the Kconfig file to find out the range of an integer/hex symbol. │ Symbol: NR_CPUS [=4] │ Type : integer │ Range : [2 8] │ Prompt: Maximum number of CPUs │ Defined at arch/x86/Kconfig:761 │ Depends on: SMP [=y] && !MAXSMP [=n] │ Location: │ -> Processor type and features Signed-off-by: Li Zefan Signed-off-by: Michal Marek --- scripts/kconfig/expr.c | 2 +- scripts/kconfig/menu.c | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index d83f2322893a..8f18e37892cb 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -1121,7 +1121,7 @@ static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *s } str_append(gs, str); - if (sym) + if (sym && sym->type != S_UNKNOWN) str_printf(gs, " [=%s]", sym_str); } diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 187caa9142fd..9d1f2adf2289 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -505,6 +505,14 @@ void get_symbol_str(struct gstr *r, struct symbol *sym) str_printf(r, "Symbol: %s [=%s]\n", sym->name, sym_get_string_value(sym)); str_printf(r, "Type : %s\n", sym_type_name(sym->type)); + if (sym->type == S_INT || sym->type == S_HEX) { + prop = sym_get_range_prop(sym); + if (prop) { + str_printf(r, "Range : "); + expr_gstr_print(prop->expr, r); + str_append(r, "\n"); + } + } } for_all_prompts(sym, prop) get_prompt_str(r, prop); -- cgit v1.2.3 From 3fb9acb3297f5e1170f3e45a18cc3f8b1fd1901a Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 7 May 2010 13:57:07 +0800 Subject: kconfig: fix to tag NEW symbols correctly Those configs are not new: $ cat .config ... CONFIG_NAMESPACES=y ... CONFIG_BLOCK=y ... But are tagged as NEW: $ yes "" | make config > myconf $ cat myconf | grep '(NEW)' Namespaces support (NAMESPACES) [Y/?] (NEW) y ... Enable the block layer (BLOCK) [Y/?] (NEW) y ... You can also notice this bug when using gconfig/xconfig. It's because the SYMBOL_DEF_USER bit of an invisible symbol is cleared when the config file is read: int conf_read(const char *name) { ... for_all_symbols(i, sym) { if (sym_has_value(sym) && !sym_is_choice_value(sym)) { /* Reset values of generates values, so they'll appear * as new, if they should become visible, but that * doesn't quite work if the Kconfig and the saved * configuration disagree. */ if (sym->visible == no && !conf_unsaved) sym->flags &= ~SYMBOL_DEF_USER; ... } But a menu item which represents an invisible symbol is still visible, if it's sub-menu is visible, so its SYMBOL_DEF_USER bit should be set to indicate it's not NEW. Signed-off-by: Li Zefan Signed-off-by: Michal Marek --- scripts/kconfig/menu.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 9d1f2adf2289..eef17bacb6bc 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -419,9 +419,13 @@ bool menu_is_visible(struct menu *menu) if (!sym || sym_get_tristate_value(menu->sym) == no) return false; - for (child = menu->list; child; child = child->next) - if (menu_is_visible(child)) + for (child = menu->list; child; child = child->next) { + if (menu_is_visible(child)) { + if (sym) + sym->flags |= SYMBOL_DEF_USER; return true; + } + } return false; } -- cgit v1.2.3 From f9447c49390f4935e19e89c88ce4a1311c080dbc Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 7 May 2010 13:57:22 +0800 Subject: menuconfig: improive help text a bit Suggested-by: Randy Dunlap Signed-off-by: Li Zefan Acked-by: Randy Dunlap Signed-off-by: Michal Marek --- scripts/kconfig/mconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 2c83d3234d30..d2f6e056c058 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -74,7 +74,7 @@ static const char mconf_readme[] = N_( "\n" " Shortcut: Press or .\n" "\n" -"o To show hidden options, press .\n" +"o To toggle the display of hidden options, press .\n" "\n" "\n" "Radiolists (Choice lists)\n" -- cgit v1.2.3 From e0bb7fe2d7e6d7cfa6135fa9ca5634343fff63b5 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 7 May 2010 13:57:35 +0800 Subject: gconfig: fix to tag NEW symbols correctly The logic should be reversed. Signed-off-by: Li Zefan Signed-off-by: Michal Marek --- scripts/kconfig/gconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index bef10411837f..1b1832943d7a 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -1114,7 +1114,7 @@ static gchar **fill_row(struct menu *menu) row[COL_OPTION] = g_strdup_printf("%s %s", _(menu_get_prompt(menu)), - sym && sym_has_value(sym) ? "(NEW)" : ""); + sym && !sym_has_value(sym) ? "(NEW)" : ""); if (opt_mode == OPT_ALL && !menu_is_visible(menu)) row[COL_COLOR] = g_strdup("DarkGray"); -- cgit v1.2.3 From c10d03caf303d91da07c7f093a4822453c13f9b1 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 7 May 2010 13:57:49 +0800 Subject: gconfig: fix null pointer warning In gconfig if you enable "Show all options", you'll see some "(null)" config options, and clicking those options triggers a warning: (gconf:9368): Gtk-CRITICAL **: gtk_text_buffer_insert_with_tags: assertion `text != NULL' failed Signed-off-by: Li Zefan Acked-by: Randy Dunlap Signed-off-by: Michal Marek --- scripts/kconfig/gconf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 1b1832943d7a..d66988265f89 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -1343,7 +1343,8 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) #endif if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) || - (opt_mode == OPT_PROMPT && !menu_has_prompt(child1))) { + (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) || + (opt_mode == OPT_ALL && !menu_get_prompt(child1))) { /* remove node */ if (gtktree_iter_find_node(dst, menu1) != NULL) { @@ -1425,7 +1426,7 @@ static void display_tree(struct menu *menu) if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) || (opt_mode == OPT_PROMPT && menu_has_prompt(child)) || - (opt_mode == OPT_ALL)) + (opt_mode == OPT_ALL && menu_get_prompt(child))) place_node(child, fill_row(child)); #ifdef DEBUG printf("%*c%s: ", indent, ' ', menu_get_prompt(child)); -- cgit v1.2.3 From c1f96f091ee146836dd73ecce531f8e0a170cfca Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 7 May 2010 13:58:04 +0800 Subject: xconfig: clean up @ok is a pointer to a bool var, so we should check the value of *ok. But actually we don't need to check it, so just remove the if statement. Signed-off-by: Li Zefan Signed-off-by: Michal Marek --- scripts/kconfig/qconf.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 00c51507cfcc..47cdeae8378c 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -58,11 +58,10 @@ QValueList ConfigSettings::readSizes(const QString& key, bool *ok) { QValueList result; QStringList entryList = readListEntry(key, ok); - if (ok) { - QStringList::Iterator it; - for (it = entryList.begin(); it != entryList.end(); ++it) - result.push_back((*it).toInt()); - } + QStringList::Iterator it; + + for (it = entryList.begin(); it != entryList.end(); ++it) + result.push_back((*it).toInt()); return result; } -- cgit v1.2.3 From 120d63e63319aceea5d127f0de93bd7fe1cbaba1 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 7 May 2010 13:58:21 +0800 Subject: xconfig: remove unused function Remove ConfigInfoView::setSource(). Signed-off-by: Li Zefan Signed-off-by: Michal Marek --- scripts/kconfig/qconf.cc | 28 ---------------------------- scripts/kconfig/qconf.h | 1 - 2 files changed, 29 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 47cdeae8378c..5e01af2f41ac 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -963,34 +963,6 @@ void ConfigInfoView::setInfo(struct menu *m) menuInfo(); } -void ConfigInfoView::setSource(const QString& name) -{ - const char *p = name.latin1(); - - menu = NULL; - sym = NULL; - - switch (p[0]) { - case 'm': - struct menu *m; - - if (sscanf(p, "m%p", &m) == 1 && menu != m) { - menu = m; - menuInfo(); - emit menuSelected(menu); - } - break; - case 's': - struct symbol *s; - - if (sscanf(p, "s%p", &s) == 1 && sym != s) { - sym = s; - symbolInfo(); - } - break; - } -} - void ConfigInfoView::symbolInfo(void) { QString str; diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index b3b5657b6b35..54775ae38250 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -254,7 +254,6 @@ public: public slots: void setInfo(struct menu *menu); void saveSettings(void); - void setSource(const QString& name); void setShowDebug(bool); signals: -- cgit v1.2.3 From 39a4897c1bb66e8a36043c105d7fd73d8b32b480 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Mon, 10 May 2010 16:33:41 +0800 Subject: xconfig: add support to show hidden options which have prompts This feature has been supported in menuconfig and gconfig, so here add it to xconfig. Signed-off-by: Li Zefan Signed-off-by: Michal Marek --- scripts/kconfig/qconf.cc | 69 +++++++++++++++++++++++++++++++++++------------- scripts/kconfig/qconf.h | 16 ++++++++--- 2 files changed, 62 insertions(+), 23 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 5e01af2f41ac..820df2d1217b 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -148,7 +148,7 @@ void ConfigItem::updateMenu(void) case S_TRISTATE: char ch; - if (!sym_is_changable(sym) && !list->showAll) { + if (!sym_is_changable(sym) && list->optMode == normalOpt) { setPixmap(promptColIdx, 0); setText(noColIdx, QString::null); setText(modColIdx, QString::null); @@ -319,7 +319,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name) symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void), - showAll(false), showName(false), showRange(false), showData(false), + showName(false), showRange(false), showData(false), optMode(normalOpt), rootEntry(0), headerPopup(0) { int i; @@ -336,10 +336,10 @@ ConfigList::ConfigList(ConfigView* p, const char *name) if (name) { configSettings->beginGroup(name); - showAll = configSettings->readBoolEntry("/showAll", false); showName = configSettings->readBoolEntry("/showName", false); showRange = configSettings->readBoolEntry("/showRange", false); showData = configSettings->readBoolEntry("/showData", false); + optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false); configSettings->endGroup(); connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); } @@ -351,6 +351,17 @@ ConfigList::ConfigList(ConfigView* p, const char *name) reinit(); } +bool ConfigList::menuSkip(struct menu *menu) +{ + if (optMode == normalOpt && menu_is_visible(menu)) + return false; + if (optMode == promptOpt && menu_has_prompt(menu)) + return false; + if (optMode == allOpt) + return false; + return true; +} + void ConfigList::reinit(void) { removeColumn(dataColIdx); @@ -379,7 +390,7 @@ void ConfigList::saveSettings(void) configSettings->writeEntry("/showName", showName); configSettings->writeEntry("/showRange", showRange); configSettings->writeEntry("/showData", showData); - configSettings->writeEntry("/showAll", showAll); + configSettings->writeEntry("/optionMode", (int)optMode); configSettings->endGroup(); } } @@ -605,7 +616,7 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu) } visible = menu_is_visible(child); - if (showAll || visible) { + if (!menuSkip(child)) { if (!child->sym && !child->list && !child->prompt) continue; if (!item || item->menu != child) @@ -834,7 +845,10 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) e->ignore(); } -ConfigView* ConfigView::viewList; +ConfigView*ConfigView::viewList; +QAction *ConfigView::showNormalAction; +QAction *ConfigView::showAllAction; +QAction *ConfigView::showPromptAction; ConfigView::ConfigView(QWidget* parent, const char *name) : Parent(parent, name) @@ -859,13 +873,16 @@ ConfigView::~ConfigView(void) } } -void ConfigView::setShowAll(bool b) +void ConfigView::setOptionMode(QAction *act) { - if (list->showAll != b) { - list->showAll = b; - list->updateListAll(); - emit showAllChanged(b); - } + if (act == showNormalAction) + list->optMode = normalOpt; + else if (act == showAllAction) + list->optMode = allOpt; + else + list->optMode = promptOpt; + + list->updateListAll(); } void ConfigView::setShowName(bool b) @@ -1320,11 +1337,24 @@ ConfigMainWindow::ConfigMainWindow(void) connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool))); connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool))); showDataAction->setOn(configList->showData); - QAction *showAllAction = new QAction(NULL, _("Show All Options"), 0, this); - showAllAction->setToggleAction(TRUE); - connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool))); - connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool))); - showAllAction->setOn(configList->showAll); + + QActionGroup *optGroup = new QActionGroup(this); + optGroup->setExclusive(TRUE); + connect(optGroup, SIGNAL(selected(QAction *)), configView, + SLOT(setOptionMode(QAction *))); + connect(optGroup, SIGNAL(selected(QAction *)), menuView, + SLOT(setOptionMode(QAction *))); + + configView->showNormalAction = new QAction(NULL, _("Show Normal Options"), 0, optGroup); + configView->showAllAction = new QAction(NULL, _("Show All Options"), 0, optGroup); + configView->showPromptAction = new QAction(NULL, _("Show Prompt Options"), 0, optGroup); + configView->showNormalAction->setToggleAction(TRUE); + configView->showNormalAction->setOn(configList->optMode == normalOpt); + configView->showAllAction->setToggleAction(TRUE); + configView->showAllAction->setOn(configList->optMode == allOpt); + configView->showPromptAction->setToggleAction(TRUE); + configView->showPromptAction->setOn(configList->optMode == promptOpt); + QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this); showDebugAction->setToggleAction(TRUE); connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool))); @@ -1367,7 +1397,8 @@ ConfigMainWindow::ConfigMainWindow(void) showRangeAction->addTo(optionMenu); showDataAction->addTo(optionMenu); optionMenu->insertSeparator(); - showAllAction->addTo(optionMenu); + optGroup->addTo(optionMenu); + optionMenu->insertSeparator(); showDebugAction->addTo(optionMenu); // create help menu @@ -1462,7 +1493,7 @@ void ConfigMainWindow::setMenuLink(struct menu *menu) ConfigList* list = NULL; ConfigItem* item; - if (!menu_is_visible(menu) && !configView->showAll()) + if (configList->menuSkip(menu)) return; switch (configList->mode) { diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index 54775ae38250..636a74b23bf9 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -44,6 +44,9 @@ enum colIdx { enum listMode { singleMode, menuMode, symbolMode, fullMode, listMode }; +enum optionMode { + normalOpt = 0, allOpt, promptOpt +}; class ConfigList : public QListView { Q_OBJECT @@ -115,6 +118,8 @@ public: void setAllOpen(bool open); void setParentMenu(void); + bool menuSkip(struct menu *); + template void updateMenuList(P*, struct menu*); @@ -124,8 +129,9 @@ public: QPixmap choiceYesPix, choiceNoPix; QPixmap menuPix, menuInvPix, menuBackPix, voidPix; - bool showAll, showName, showRange, showData; + bool showName, showRange, showData; enum listMode mode; + enum optionMode optMode; struct menu *rootEntry; QColorGroup disabledColorGroup; QColorGroup inactivedColorGroup; @@ -222,17 +228,15 @@ public: static void updateList(ConfigItem* item); static void updateListAll(void); - bool showAll(void) const { return list->showAll; } bool showName(void) const { return list->showName; } bool showRange(void) const { return list->showRange; } bool showData(void) const { return list->showData; } public slots: - void setShowAll(bool); void setShowName(bool); void setShowRange(bool); void setShowData(bool); + void setOptionMode(QAction *); signals: - void showAllChanged(bool); void showNameChanged(bool); void showRangeChanged(bool); void showDataChanged(bool); @@ -242,6 +246,10 @@ public: static ConfigView* viewList; ConfigView* nextView; + + static QAction *showNormalAction; + static QAction *showAllAction; + static QAction *showPromptAction; }; class ConfigInfoView : public QTextBrowser { -- cgit v1.2.3 From cbab05f041a4cff6ca15856bdd35238b282b64eb Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Thu, 27 May 2010 10:22:28 +0100 Subject: gconfig: fix build failure on fedora 13 Making gconfig fails on fedora 13 as the linker cannot resolve dlsym. Adding libdl to the link command fixes this. make shows this error :- /usr/bin/ld: scripts/kconfig/kconfig_load.o: undefined reference to symbol 'dlsym@@GLIBC_2.2.5' /usr/bin/ld: note: 'dlsym@@GLIBC_2.2.5' is defined in DSO /lib64/libdl.so.2 so try adding it to the linker command line /lib64/libdl.so.2: could not read symbols: Invalid operation tested on x86_64 fedora 13. Signed-off-by: Richard Kennedy Reviewed-by: WANG Cong Cc: Signed-off-by: Andrew Morton Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 999e8a7d5bf7..25a518310038 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -198,7 +198,7 @@ HOSTCFLAGS_zconf.tab.o := -I$(src) HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK -HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` +HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` -ldl HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ -D LKC_DIRECT_LINK -- cgit v1.2.3 From 073ed10363a89cfcc04b7c4d9a9626c5ed48852c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Am=C3=A9rico=20Wang?= Date: Thu, 3 Jun 2010 10:50:39 +0800 Subject: scripts: add nconf into gitignore file scripts/kconfig/nconf is generated by 'make nconfig', add it into .gitignore. Signed-off-by: WANG Cong Signed-off-by: Michal Marek --- scripts/kconfig/.gitignore | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore index 6a36a76e6606..624f6502e03e 100644 --- a/scripts/kconfig/.gitignore +++ b/scripts/kconfig/.gitignore @@ -17,6 +17,7 @@ gconf.glade.h # conf mconf +nconf qconf gconf kxgettext -- cgit v1.2.3 From 03b550d3f9faf912d935ea310363e8e96d3aeeea Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 2 Jun 2010 13:56:36 -0700 Subject: checkkconfigsymbols.sh: Kconfig symbols sometimes have lowercase letters Quite a few Kconfig symbols contain lowercase letters. The current checkkconfigsymbols.sh code only contains A-Z in the regexp it uses to find config symbols in source code, so it comes up with the wrong symbol to look for in Kconfig files and then generates false positives when it doesn't find that wrong symbol. For example checking drivers/net generates a false positive for MAC89 because the the actual config option is MAC89x0. Fix this by also adding a-z to the regexp. Signed-off-by: Roland Dreier Signed-off-by: Andrew Morton Signed-off-by: Michal Marek --- scripts/checkkconfigsymbols.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkkconfigsymbols.sh b/scripts/checkkconfigsymbols.sh index 46be3c5a62b7..2ca49bb31efc 100755 --- a/scripts/checkkconfigsymbols.sh +++ b/scripts/checkkconfigsymbols.sh @@ -14,7 +14,7 @@ find $paths -name '*.[chS]' -o -name 'Makefile' -o -name 'Makefile*[^~]'| while do # Output the bare Kconfig variable and the filename; the _MODULE part at # the end is not removed here (would need perl an not-hungry regexp for that). - sed -ne 's!^.*\<\(UML_\)\?CONFIG_\([0-9A-Z_]\+\).*!\2 '$i'!p' < $i + sed -ne 's!^.*\<\(UML_\)\?CONFIG_\([0-9A-Za-z_]\+\).*!\2 '$i'!p' < $i done | \ # Smart "sort|uniq" implemented in awk and tuned to collect the names of all # files which use a given symbol -- cgit v1.2.3 From 42ef223c4a0f6e34e13ccb503b423ebdc04878e1 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Thu, 3 Jun 2010 15:24:39 +0800 Subject: menuconfig: fix to center checklist correctly in a corner case Run: make ARCH=arm menuconfig And then select "System Type" -> "ARM system type". The kconfig "choice" menu at this point looks empty. It's because config ARCH_S3C2410 has a long prompt: config ARCH_S3C2410 bool "Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443, S3C2450" ... menuconfig centers the checklist according to this prompt without considering the width of the list, and then things get wrong. Reported-by: Nobin Mathew Signed-off-by: Li Zefan Signed-off-by: Michal Marek --- scripts/kconfig/lxdialog/checklist.c | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c index bcc6f19c3a35..c92a05a2de17 100644 --- a/scripts/kconfig/lxdialog/checklist.c +++ b/scripts/kconfig/lxdialog/checklist.c @@ -175,6 +175,7 @@ do_resize: check_x = 0; item_foreach() check_x = MAX(check_x, strlen(item_str()) + 4); + check_x = MIN(check_x, list_width); check_x = (list_width - check_x) / 2; item_x = check_x + 4; -- cgit v1.2.3 From e7401d8321f89a3785a395ba307c720e2b390f96 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Thu, 3 Jun 2010 15:24:57 +0800 Subject: menuconfig: truncate list items Truncate list items to fit in a single line, otherwise those items which have long prompts will cover some other items. This follows the behavior of menubox. Signed-off-by: Li Zefan Signed-off-by: Michal Marek --- scripts/kconfig/lxdialog/checklist.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c index c92a05a2de17..a2eb80fbc896 100644 --- a/scripts/kconfig/lxdialog/checklist.c +++ b/scripts/kconfig/lxdialog/checklist.c @@ -31,6 +31,10 @@ static int list_width, check_x, item_x; static void print_item(WINDOW * win, int choice, int selected) { int i; + char *list_item = malloc(list_width + 1); + + strncpy(list_item, item_str(), list_width - item_x); + list_item[list_width - item_x] = '\0'; /* Clear 'residue' of last item */ wattrset(win, dlg.menubox.atr); @@ -45,13 +49,14 @@ static void print_item(WINDOW * win, int choice, int selected) wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' '); wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr); - mvwaddch(win, choice, item_x, item_str()[0]); + mvwaddch(win, choice, item_x, list_item[0]); wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); - waddstr(win, (char *)item_str() + 1); + waddstr(win, list_item + 1); if (selected) { wmove(win, choice, check_x + 1); wrefresh(win); } + free(list_item); } /* -- cgit v1.2.3 From b396aa03084b51f6822052a8070703287f198360 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Thu, 3 Jun 2010 22:48:12 +0530 Subject: scripts: decodecode: remove bashisms Remove bashisms to make scripts/decodecode work with other shells. Signed-off-by: Rabin Vincent Reviewed-by: WANG Cong Signed-off-by: Michal Marek --- scripts/decodecode | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/decodecode b/scripts/decodecode index 8b30cc36744f..18ba881c3415 100755 --- a/scripts/decodecode +++ b/scripts/decodecode @@ -40,7 +40,7 @@ echo $code code=`echo $code | sed -e 's/.*Code: //'` width=`expr index "$code" ' '` -width=$[($width-1)/2] +width=$((($width-1)/2)) case $width in 1) type=byte ;; 2) type=2byte ;; @@ -48,10 +48,10 @@ case $width in esac disas() { - ${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s &> /dev/null + ${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s > /dev/null 2>&1 - if [ "$ARCH" == "arm" ]; then - if [ $width == 2 ]; then + if [ "$ARCH" = "arm" ]; then + if [ $width -eq 2 ]; then OBJDUMPFLAGS="-M force-thumb" fi @@ -59,7 +59,7 @@ disas() { fi ${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \ - grep -v "/tmp\|Disassembly\|\.text\|^$" &> $1.dis + grep -v "/tmp\|Disassembly\|\.text\|^$" > $1.dis 2>&1 } marker=`expr index "$code" "\<"` -- cgit v1.2.3 From e26d6b834cc4a68adeb82abbdce7205df7599118 Mon Sep 17 00:00:00 2001 From: Don Zickus Date: Mon, 24 May 2010 17:07:24 -0400 Subject: Makefile.build: make KBUILD_SYMTYPES work again commit 37a8d9f67f18de1e2cbc7387311ce22d4dbff518 tried to combine some duplicate code and accidentally broke how KBUILD_SYMTYPES worked This fixes the code to match the original intention by the author who originally added the code I believe. The fixes include: - removing extra whitespaces in the if-statements - moving the if-statement from around the -r to the -T - adding a second arg to cmd_gensymtypes to simplify the options passed to genksyms. Tested by instrumenting genksyms and seeing what options were passed in during a make, KBUILD_SYMTYPES make, and when a foo.symref was created. Everything compiled and looked ok. Signed-off-by: Don Zickus Signed-off-by: Michal Marek --- scripts/Makefile.build | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index e4deb73e9a84..390aae4bb222 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -156,14 +156,14 @@ $(obj)/%.i: $(src)/%.c FORCE cmd_gensymtypes = \ $(CPP) -D__GENKSYMS__ $(c_flags) $< | \ - $(GENKSYMS) -T $@ -a $(ARCH) \ + $(GENKSYMS) $(if $(1), -T $(2)) -a $(ARCH) \ $(if $(KBUILD_PRESERVE),-p) \ - $(if $(1),-r $(firstword $(wildcard $(@:.symtypes=.symref) /dev/null))) + -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null)) quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ cmd_cc_symtypes_c = \ set -e; \ - $(call cmd_gensymtypes, true) >/dev/null; \ + $(call cmd_gensymtypes,true,$@) >/dev/null; \ test -s $@ || rm -f $@ $(obj)/%.symtypes : $(src)/%.c FORCE @@ -192,16 +192,16 @@ else # the actual value of the checksum generated by genksyms cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< -cmd_modversions = \ - if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ - $(call cmd_gensymtypes, $(KBUILD_SYMTYPES)) \ - > $(@D)/.tmp_$(@F:.o=.ver); \ - \ - $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ - -T $(@D)/.tmp_$(@F:.o=.ver); \ - rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \ - else \ - mv -f $(@D)/.tmp_$(@F) $@; \ +cmd_modversions = \ + if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ + $(call cmd_gensymtypes,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ + > $(@D)/.tmp_$(@F:.o=.ver); \ + \ + $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ + -T $(@D)/.tmp_$(@F:.o=.ver); \ + rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \ + else \ + mv -f $(@D)/.tmp_$(@F) $@; \ fi; endif -- cgit v1.2.3 From 8e5564e6c7554902301543e731354ad2ad58ae53 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 31 May 2010 11:13:21 -0300 Subject: perf tools: Make target to generate self contained source tarball MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Useful for when people want to try some version of the perf tools and don't wants to download the kernel tarball. Here is a session using this new target: [root@emilia linux-2.6-tip]# make help | grep -i perf perf-tar-src-pkg - Build perf-2.6.35-rc1.tar source tarball perf-targz-src-pkg - Build perf-2.6.35-rc1.tar.gz source tarball perf-tarbz2-src-pkg - Build perf-2.6.35-rc1.tar.bz2 source tarball [root@emilia linux-2.6-tip]# make perf-tarbz2-src-pkg TAR [root@emilia linux-2.6-tip]# ls -la perf-2.6.35-rc1.tar.bz2 -rw-r--r-- 1 root root 295731 May 31 11:18 perf-2.6.35-rc1.tar.bz2 [root@emilia linux-2.6-tip]# tar xf perf-2.6.35-rc1.tar.bz2 [root@emilia linux-2.6-tip]# cd perf-2.6.35-rc1 [root@emilia perf-2.6.35-rc1]# ls arch HEAD include lib tools [root@emilia perf-2.6.35-rc1]# cd tools/perf [root@emilia perf]# make -j9 2>&1 | tail CC arch/x86/util/dwarf-regs.o CC util/probe-finder.o CC util/newt.o CC util/scripting-engines/trace-event-perl.o CC scripts/perl/Perf-Trace-Util/Context.o CC perf.o CC builtin-help.o AR libperf.a LINK perf rm .perf.dev.null [root@emilia perf]# ./perf record -a sleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.262 MB perf.data (~11457 samples) ] [root@emilia perf]# ./perf report | head -12 # Events: 6K cycles # # Overhead Command Shared Object Symbol # ........ ............... .................. ...... # 4.73% perf [kernel.kallsyms] [k] format_decode 4.49% perf libc-2.12.so [.] _IO_file_underflow_internal 4.38% init [kernel.kallsyms] [k] mwait_idle 3.29% perf [kernel.kallsyms] [k] vsnprintf 2.38% init [kernel.kallsyms] [k] sched_clock_local 2.35% init [kernel.kallsyms] [k] apic_timer_interrupt 1.86% sirq-timer/5 [kernel.kallsyms] [k] find_busiest_group [root@emilia perf]# Acked-by: Michal Marek Acked-by: Sam Ravnborg Cc: David S. Miller Cc: Frédéric Weisbecker Cc: Ingo Molnar Cc: Michal Marek Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Sam Ravnborg Cc: Stephane Eranian Cc: Tom Zanussi LKML-Reference: <20100528185357.GA28009@ghostprotocols.net> Signed-off-by: Arnaldo Carvalho de Melo --- scripts/package/Makefile | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/package/Makefile b/scripts/package/Makefile index 62fcc3a7f4d3..18513b0191db 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -111,13 +111,38 @@ tar%pkg: FORCE clean-dirs += $(objtree)/tar-install/ +# perf-pkg - generate a source tarball with perf source +# --------------------------------------------------------------------------- + +perf-tar=perf-$(KERNELVERSION) + +quiet_cmd_perf_tar = TAR + cmd_perf_tar = \ +git archive --prefix=$(perf-tar)/ HEAD^{tree} \ + $$(cat $(srctree)/tools/perf/MANIFEST) -o $(perf-tar).tar; \ +mkdir -p $(perf-tar); \ +git rev-parse HEAD > $(perf-tar)/HEAD; \ +tar rf $(perf-tar).tar $(perf-tar)/HEAD; \ +rm -r $(perf-tar); \ +$(if $(findstring tar-src,$@),, \ +$(if $(findstring bz2,$@),bzip2, \ +$(if $(findstring gz,$@),gzip, \ +$(error unknown target $@))) \ + -f -9 $(perf-tar).tar) + +perf-%pkg: FORCE + $(call cmd,perf_tar) + # Help text displayed when executing 'make help' # --------------------------------------------------------------------------- help: FORCE - @echo ' rpm-pkg - Build both source and binary RPM kernel packages' - @echo ' binrpm-pkg - Build only the binary kernel package' - @echo ' deb-pkg - Build the kernel as an deb package' - @echo ' tar-pkg - Build the kernel as an uncompressed tarball' - @echo ' targz-pkg - Build the kernel as a gzip compressed tarball' - @echo ' tarbz2-pkg - Build the kernel as a bzip2 compressed tarball' + @echo ' rpm-pkg - Build both source and binary RPM kernel packages' + @echo ' binrpm-pkg - Build only the binary kernel package' + @echo ' deb-pkg - Build the kernel as an deb package' + @echo ' tar-pkg - Build the kernel as an uncompressed tarball' + @echo ' targz-pkg - Build the kernel as a gzip compressed tarball' + @echo ' tarbz2-pkg - Build the kernel as a bzip2 compressed tarball' + @echo ' perf-tar-src-pkg - Build $(perf-tar).tar source tarball' + @echo ' perf-targz-src-pkg - Build $(perf-tar).tar.gz source tarball' + @echo ' perf-tarbz2-src-pkg - Build $(perf-tar).tar.bz2 source tarball' -- cgit v1.2.3 From 607b30fcf20c6e5339591692db6ffa0b15e041a0 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Thu, 10 Jun 2010 12:23:08 +0200 Subject: kbuild: Create output directory in Makefile.modbuiltin Reported-by: Stephen Rothwell Signed-off-by: Michal Marek --- scripts/Makefile.modbuiltin | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'scripts') diff --git a/scripts/Makefile.modbuiltin b/scripts/Makefile.modbuiltin index 102a276f6eea..1adb974e6950 100644 --- a/scripts/Makefile.modbuiltin +++ b/scripts/Makefile.modbuiltin @@ -14,6 +14,11 @@ __modbuiltin: include scripts/Kbuild.include +ifneq ($(KBUILD_SRC),) +# Create output directory if not already present +_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj)) +endif + # The filename Kbuild has precedence over Makefile kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile) -- cgit v1.2.3 From 74425eee71eb44c9f370bd922f72282b69bb0eab Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Sun, 6 Jun 2010 17:15:01 +0200 Subject: Add a target to use the Coccinelle checker A 'coccicheck' target is added. It can be called with four different modes. Each one generates a different kind of output, i.e. context, patch, org, report, according to the corresponding mode to be activated. The new target calls the 'coccicheck' front-end in the 'scripts' directory with the MODE argument. Every SmPL file in the subdirectories of 'scripts/coccinelle' is then given to the front-end and applied to the entire source tree. The four modes behave as follows: 'report' generates a list in the following format: file:line:column-column: message 'patch' proposes a fix, when possible. 'context' highlights lines of interest and their context in a diff-like style. Lines of interest are indicated with '-'. 'org' generates a report in the Org mode format of Emacs. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Acked-by: Sam Ravnborg Acked-by: Joerg Roedel Signed-off-by: Michal Marek --- scripts/Makefile.help | 3 +++ scripts/coccicheck | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 scripts/Makefile.help create mode 100755 scripts/coccicheck (limited to 'scripts') diff --git a/scripts/Makefile.help b/scripts/Makefile.help new file mode 100644 index 000000000000..d03608f5db04 --- /dev/null +++ b/scripts/Makefile.help @@ -0,0 +1,3 @@ + +checker-help: + @echo ' coccicheck - Check with Coccinelle.' diff --git a/scripts/coccicheck b/scripts/coccicheck new file mode 100755 index 000000000000..037424b9ede5 --- /dev/null +++ b/scripts/coccicheck @@ -0,0 +1,54 @@ +#!/bin/sh + +SPATCH="`which ${SPATCH:=spatch}`" + +if [ ! -x "$SPATCH" ]; then + echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/' + exit 1 +fi + +if [ "$MODE" = "" ] ; then + echo 'You have not explicitly specify the mode to use. Fallback to "report".' + echo 'You can specify the mode with "make coccicheck MODE="' + echo 'Available modes are: report, patch, context, org' + MODE="report" +fi + +echo '' +echo 'Please check for false positives in the output before submitting a patch.' +echo 'When using "patch" mode, carefully review the patch before submitting it.' +echo '' + +function coccinelle { + COCCI="$1" + DIR="$2" + + OPT=`grep "Option" $COCCI | cut -d':' -f2` + FILE=`echo $COCCI | sed "s|$DIR/||"` + + echo "Processing `basename $COCCI` with option(s) \"$OPT\"" + echo 'Message example to submit a patch:' + + sed -e '/\/\/\//!d' -e 's|^///||' $COCCI + + echo ' The semantic patch that makes this change is available' + echo " in $FILE." + echo '' + echo ' More information about semantic patching is available at' + echo ' http://coccinelle.lip6.fr/' + echo '' + +# The option '-parse_cocci' can be used to syntaxically check the SmPL files. +# +# $SPATCH -D $MODE -very_quiet -parse_cocci $COCCI $OPT > /dev/null + + $SPATCH -D $MODE -very_quiet -sp_file $COCCI $OPT -dir $DIR +} + +if [ "$COCCI" = "" ] ; then + for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do + coccinelle $f $srctree; + done +else + coccinelle $COCCI $srctree +fi -- cgit v1.2.3 From 51169c801518bf0a250f208362593e7250e7d2c1 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Sun, 6 Jun 2010 17:15:03 +0200 Subject: Add scripts/coccinelle/alloc/drop_kmalloc_cast.cocci The purpose of this semantic patch is to remove useless casts, as mentioned in the Linux documentation. See Chapter 14 in Documentation/CodingStyle for more information. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/alloc/drop_kmalloc_cast.cocci | 67 ++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 scripts/coccinelle/alloc/drop_kmalloc_cast.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci b/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci new file mode 100644 index 000000000000..7d4771d449c3 --- /dev/null +++ b/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci @@ -0,0 +1,67 @@ +/// +/// Casting (void *) value returned by kmalloc is useless +/// as mentioned in Documentation/CodingStyle, Chap 14. +/// +// Confidence: High +// Copyright: 2009,2010 Nicolas Palix, DIKU. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Options: -no_includes -include_headers +// +// Keywords: kmalloc, kzalloc, kcalloc +// Version min: < 2.6.12 kmalloc +// Version min: < 2.6.12 kcalloc +// Version min: 2.6.14 kzalloc +// + +virtual context +virtual patch +virtual org +virtual report + +//---------------------------------------------------------- +// For context mode +//---------------------------------------------------------- + +@depends on context@ +type T; +@@ + +* (T *) + \(kmalloc\|kzalloc\|kcalloc\)(...) + +//---------------------------------------------------------- +// For patch mode +//---------------------------------------------------------- + +@depends on patch@ +type T; +@@ + +- (T *) + \(kmalloc\|kzalloc\|kcalloc\)(...) + +//---------------------------------------------------------- +// For org and report mode +//---------------------------------------------------------- + +@r depends on org || report@ +type T; +position p; +@@ + + (T@p *)\(kmalloc\|kzalloc\|kcalloc\)(...) + +@script:python depends on org@ +p << r.p; +t << r.T; +@@ + +coccilib.org.print_safe_todo(p[0], t) + +@script:python depends on report@ +p << r.p; +t << r.T; +@@ + +msg="WARNING: casting value returned by k[cmz]alloc to (%s *) is useless." % (t) +coccilib.report.print_report(p[0], msg) -- cgit v1.2.3 From cf5842de75e9fb8044ff5ca73050e361daa6aae4 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Sun, 6 Jun 2010 17:15:04 +0200 Subject: Add scripts/coccinelle/alloc/kzalloc-simple.cocci This semantic patch replaces a pair of calls to kmalloc and memset by a single call to kzalloc. It only looks for simple cases to avoid false positives. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/alloc/kzalloc-simple.cocci | 82 +++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 scripts/coccinelle/alloc/kzalloc-simple.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/alloc/kzalloc-simple.cocci b/scripts/coccinelle/alloc/kzalloc-simple.cocci new file mode 100644 index 000000000000..2eae828fc657 --- /dev/null +++ b/scripts/coccinelle/alloc/kzalloc-simple.cocci @@ -0,0 +1,82 @@ +/// +/// kzalloc should be used rather than kmalloc followed by memset 0 +/// +// Confidence: High +// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/rules/kzalloc.html +// Options: -no_includes -include_headers +// +// Keywords: kmalloc, kzalloc +// Version min: < 2.6.12 kmalloc +// Version min: 2.6.14 kzalloc +// + +virtual context +virtual patch +virtual org +virtual report + +//---------------------------------------------------------- +// For context mode +//---------------------------------------------------------- + +@depends on context@ +type T, T2; +expression x; +expression E1,E2; +statement S; +@@ + +* x = (T)kmalloc(E1,E2); + if ((x==NULL) || ...) S +* memset((T2)x,0,E1); + +//---------------------------------------------------------- +// For patch mode +//---------------------------------------------------------- + +@depends on patch@ +type T, T2; +expression x; +expression E1,E2; +statement S; +@@ + +- x = (T)kmalloc(E1,E2); ++ x = kzalloc(E1,E2); + if ((x==NULL) || ...) S +- memset((T2)x,0,E1); + +//---------------------------------------------------------- +// For org mode +//---------------------------------------------------------- + +@r depends on org || report@ +type T, T2; +expression x; +expression E1,E2; +statement S; +position p; +@@ + + x = (T)kmalloc@p(E1,E2); + if ((x==NULL) || ...) S + memset((T2)x,0,E1); + +@script:python depends on org@ +p << r.p; +x << r.x; +@@ + +msg="%s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << r.p; +x << r.x; +@@ + +msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x) +coccilib.report.print_report(p[0], msg) -- cgit v1.2.3 From 09c35396ecadceb13f0b3fb77da200b6da6a0e37 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Sun, 6 Jun 2010 17:15:05 +0200 Subject: Add scripts/coccinelle/resource_size.cocci This semantic patch replaces explicit computations of resource size by a call to resource_size. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/resource_size.cocci | 93 ++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 scripts/coccinelle/resource_size.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/resource_size.cocci b/scripts/coccinelle/resource_size.cocci new file mode 100644 index 000000000000..1935a58b39d9 --- /dev/null +++ b/scripts/coccinelle/resource_size.cocci @@ -0,0 +1,93 @@ +/// +/// Use resource_size function on resource object +/// instead of explicit computation. +/// +// Confidence: High +// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Options: +// +// Keywords: resource_size +// Version min: 2.6.27 resource_size +// + +virtual context +virtual patch +virtual org +virtual report + +//---------------------------------------------------------- +// For context mode +//---------------------------------------------------------- + +@r_context depends on context && !patch && !org@ +struct resource *res; +@@ + +* (res->end - res->start) + 1 + +//---------------------------------------------------------- +// For patch mode +//---------------------------------------------------------- + +@r_patch depends on !context && patch && !org@ +struct resource *res; +@@ + +- (res->end - res->start) + 1 ++ resource_size(res) + +//---------------------------------------------------------- +// For org mode +//---------------------------------------------------------- + + +@r_org depends on !context && !patch && (org || report)@ +struct resource *res; +position p; +@@ + + (res->end@p - res->start) + 1 + +@rbad_org depends on !context && !patch && (org || report)@ +struct resource *res; +position p != r_org.p; +@@ + + res->end@p - res->start + +@script:python depends on org@ +p << r_org.p; +x << r_org.res; +@@ + +msg="ERROR with %s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << r_org.p; +x << r_org.res; +@@ + +msg="ERROR: Missing resource_size with %s" % (x) +coccilib.report.print_report(p[0], msg) + +@script:python depends on org@ +p << rbad_org.p; +x << rbad_org.res; +@@ + +msg="WARNING with %s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << rbad_org.p; +x << rbad_org.res; +@@ + +msg="WARNING: Suspicious code. resource_size is maybe missing with %s" % (x) +coccilib.report.print_report(p[0], msg) -- cgit v1.2.3 From f853f8305bc2ab24a2f5fb24c4635c645cc7f9d1 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Sun, 6 Jun 2010 17:15:06 +0200 Subject: Add scripts/coccinelle/err_cast.cocci Add a Coccinelle file to use the ERR_CAST function Before the release 2.6.25, one had to use ERR_PTR(PTR_ERR(...)) to convert the pointer type of an error. Since then, the function ERR_CAST has been available for that purpose. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/err_cast.cocci | 56 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 scripts/coccinelle/err_cast.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/err_cast.cocci b/scripts/coccinelle/err_cast.cocci new file mode 100644 index 000000000000..2ce115000af6 --- /dev/null +++ b/scripts/coccinelle/err_cast.cocci @@ -0,0 +1,56 @@ +/// +/// Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(...)) +/// +// Confidence: High +// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Options: +// +// Keywords: ERR_PTR, PTR_ERR, ERR_CAST +// Version min: 2.6.25 +// + +virtual context +virtual patch +virtual org +virtual report + + +@ depends on context && !patch && !org && !report@ +expression x; +@@ + +* ERR_PTR(PTR_ERR(x)) + +@ depends on !context && patch && !org && !report @ +expression x; +@@ + +- ERR_PTR(PTR_ERR(x)) ++ ERR_CAST(x) + +@r depends on !context && !patch && (org || report)@ +expression x; +position p; +@@ + + ERR_PTR@p(PTR_ERR(x)) + +@script:python depends on org@ +p << r.p; +x << r.x; +@@ + +msg="WARNING ERR_CAST can be used with %s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << r.p; +x << r.x; +@@ + +msg="WARNING: ERR_CAST can be used with %s" % (x) +coccilib.report.print_report(p[0], msg) -- cgit v1.2.3 From 82c4340b0a3ccf090ef38fa111363018cf0594c8 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Sun, 6 Jun 2010 17:15:07 +0200 Subject: Add scripts/coccinelle/deref_null.cocci Add a Coccinelle file to identify the dereferences of NULL variables This semantic patch identifies when a variable is known to be NULL after a test, but it is still dereferenced later. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/deref_null.cocci | 293 ++++++++++++++++++++++++++++++++++++ 1 file changed, 293 insertions(+) create mode 100644 scripts/coccinelle/deref_null.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/deref_null.cocci b/scripts/coccinelle/deref_null.cocci new file mode 100644 index 000000000000..9969d76d0f4b --- /dev/null +++ b/scripts/coccinelle/deref_null.cocci @@ -0,0 +1,293 @@ +/// +/// A variable is dereference under a NULL test. +/// Even though it is know to be NULL. +/// +// Confidence: Moderate +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: -I ... -all_includes can give more complete results +// Options: + +virtual context +virtual patch +virtual org +virtual report + +@initialize:python depends on !context && patch && !org && !report@ + +import sys +print >> sys.stderr, "This semantic patch does not support the 'patch' mode." + +@depends on patch@ +@@ + +this_rule_should_never_matches(); + +@ifm depends on !patch@ +expression *E; +statement S1,S2; +position p1; +@@ + +if@p1 ((E == NULL && ...) || ...) S1 else S2 + +// The following two rules are separate, because both can match a single +// expression in different ways +@pr1 depends on !patch expression@ +expression *ifm.E; +identifier f; +position p1; +@@ + + (E != NULL && ...) ? <+...E->f@p1...+> : ... + +@pr2 depends on !patch expression@ +expression *ifm.E; +identifier f; +position p2; +@@ + +( + (E != NULL) && ... && <+...E->f@p2...+> +| + (E == NULL) || ... || <+...E->f@p2...+> +| + sizeof(<+...E->f@p2...+>) +) + +// For org and report modes + +@r depends on !context && !patch && (org || report) exists@ +expression subE <= ifm.E; +expression *ifm.E; +expression E1,E2; +identifier f; +statement S1,S2,S3,S4; +iterator iter; +position p!={pr1.p1,pr2.p2}; +position ifm.p1; +@@ + +if@p1 ((E == NULL && ...) || ...) +{ + ... when != if (...) S1 else S2 +( + iter(subE,...) S4 // no use +| + list_remove_head(E2,subE,...) +| + subE = E1 +| + for(subE = E1;...;...) S4 +| + subE++ +| + ++subE +| + --subE +| + subE-- +| + &subE +| + E->f@p // bad use +) + ... when any + return ...; +} +else S3 + +@script:python depends on !context && !patch && !org && report@ +p << r.p; +p1 << ifm.p1; +x << ifm.E; +@@ + +msg="ERROR: %s is NULL but dereferenced." % (x) +coccilib.report.print_report(p[0], msg) +cocci.include_match(False) + +@script:python depends on !context && !patch && org && !report@ +p << r.p; +p1 << ifm.p1; +x << ifm.E; +@@ + +msg="ERROR: %s is NULL but dereferenced." % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +cocci.print_main(msg_safe,p) +cocci.include_match(False) + +@s depends on !context && !patch && (org || report) exists@ +expression subE <= ifm.E; +expression *ifm.E; +expression E1,E2; +identifier f; +statement S1,S2,S3,S4; +iterator iter; +position p!={pr1.p1,pr2.p2}; +position ifm.p1; +@@ + +if@p1 ((E == NULL && ...) || ...) +{ + ... when != if (...) S1 else S2 +( + iter(subE,...) S4 // no use +| + list_remove_head(E2,subE,...) +| + subE = E1 +| + for(subE = E1;...;...) S4 +| + subE++ +| + ++subE +| + --subE +| + subE-- +| + &subE +| + E->f@p // bad use +) + ... when any +} +else S3 + +@script:python depends on !context && !patch && !org && report@ +p << s.p; +p1 << ifm.p1; +x << ifm.E; +@@ + +msg="ERROR: %s is NULL but dereferenced." % (x) +coccilib.report.print_report(p[0], msg) + +@script:python depends on !context && !patch && org && !report@ +p << s.p; +p1 << ifm.p1; +x << ifm.E; +@@ + +msg="ERROR: %s is NULL but dereferenced." % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +cocci.print_main(msg_safe,p) + +// For context mode + +@depends on context && !patch && !org && !report exists@ +expression subE <= ifm.E; +expression *ifm.E; +expression E1,E2; +identifier f; +statement S1,S2,S3,S4; +iterator iter; +position p!={pr1.p1,pr2.p2}; +position ifm.p1; +@@ + +if@p1 ((E == NULL && ...) || ...) +{ + ... when != if (...) S1 else S2 +( + iter(subE,...) S4 // no use +| + list_remove_head(E2,subE,...) +| + subE = E1 +| + for(subE = E1;...;...) S4 +| + subE++ +| + ++subE +| + --subE +| + subE-- +| + &subE +| +* E->f@p // bad use +) + ... when any + return ...; +} +else S3 + +// The following three rules are duplicates of ifm, pr1 and pr2 respectively. +// It is need because the previous rule as already made a "change". + +@ifm1 depends on !patch@ +expression *E; +statement S1,S2; +position p1; +@@ + +if@p1 ((E == NULL && ...) || ...) S1 else S2 + +@pr11 depends on !patch expression@ +expression *ifm1.E; +identifier f; +position p1; +@@ + + (E != NULL && ...) ? <+...E->f@p1...+> : ... + +@pr12 depends on !patch expression@ +expression *ifm1.E; +identifier f; +position p2; +@@ + +( + (E != NULL) && ... && <+...E->f@p2...+> +| + (E == NULL) || ... || <+...E->f@p2...+> +| + sizeof(<+...E->f@p2...+>) +) + +@depends on context && !patch && !org && !report exists@ +expression subE <= ifm1.E; +expression *ifm1.E; +expression E1,E2; +identifier f; +statement S1,S2,S3,S4; +iterator iter; +position p!={pr11.p1,pr12.p2}; +position ifm1.p1; +@@ + +if@p1 ((E == NULL && ...) || ...) +{ + ... when != if (...) S1 else S2 +( + iter(subE,...) S4 // no use +| + list_remove_head(E2,subE,...) +| + subE = E1 +| + for(subE = E1;...;...) S4 +| + subE++ +| + ++subE +| + --subE +| + subE-- +| + &subE +| +* E->f@p // bad use +) + ... when any +} +else S3 -- cgit v1.2.3 From 60c8eca69f7fb2820677a635d921866f66727fcb Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Fri, 11 Jun 2010 13:41:04 -0700 Subject: scripts:conf.c Fix warning: variable 'type' set but not used Not sure if this is correct or not, but with make menuconfig HOSTCC scripts/kconfig/conf.o scripts/kconfig/conf.c: In function 'conf_sym': scripts/kconfig/conf.c:159:6: warning: variable 'type' set but not used scripts/kconfig/conf.c: In function 'conf_choice': scripts/kconfig/conf.c:231:6: warning: variable 'type' set but not used HOSTLD scripts/kconfig/mconf I get this using gcc 4.6.0 the below change fixes this form me. Signed-off-by: Justin P. Mattock Signed-off-by: Michal Marek --- scripts/kconfig/conf.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 3fa4abf3b084..bde01b4200ee 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -163,14 +163,12 @@ static int conf_string(struct menu *menu) static int conf_sym(struct menu *menu) { struct symbol *sym = menu->sym; - int type; tristate oldval, newval; while (1) { printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); if (sym->name) printf("(%s) ", sym->name); - type = sym_get_type(sym); putchar('['); oldval = sym_get_tristate_value(sym); switch (oldval) { @@ -235,11 +233,9 @@ static int conf_choice(struct menu *menu) { struct symbol *sym, *def_sym; struct menu *child; - int type; bool is_new; sym = menu->sym; - type = sym_get_type(sym); is_new = !sym_has_value(sym); if (sym_is_changable(sym)) { conf_sym(menu); -- cgit v1.2.3 From 1c938663d58b5b2965976a6f54cc51b5d6f691aa Mon Sep 17 00:00:00 2001 From: Krzysztof Halasa Date: Fri, 11 Jun 2010 01:08:20 +0200 Subject: kbuild: Fix modpost segfault MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Alan writes: > program: /home/alan/GitTrees/linux-2.6-mid-ref/scripts/mod/modpost -o > Module.symvers -S vmlinux.o > > Program received signal SIGSEGV, Segmentation fault. It just hit me. It's the offset calculation in reloc_location() which overflows: return (void *)elf->hdr + sechdrs[section].sh_offset + (r->r_offset - sechdrs[section].sh_addr); E.g. for the first rodata r entry: r->r_offset < sechdrs[section].sh_addr and the expression in the parenthesis produces 0xFFFFFFE0 or something equally wise. Reported-by: Alan Signed-off-by: Krzysztof Hałasa Tested-by: Alan Signed-off-by: Michal Marek --- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 3318692e4e76..f8779006986d 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1342,7 +1342,7 @@ static unsigned int *reloc_location(struct elf_info *elf, int section = sechdr->sh_info; return (void *)elf->hdr + sechdrs[section].sh_offset + - (r->r_offset - sechdrs[section].sh_addr); + r->r_offset - sechdrs[section].sh_addr; } static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) -- cgit v1.2.3 From 09155120cf0ffe6f0c8aba3aa625831405b65996 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Thu, 17 Jun 2010 15:14:58 +0200 Subject: kbuild: Clean up and speed up the localversion logic Now that we run scripts/setlocalversion during every build, it makes sense to move all the localversion logic there. This cleans up the toplevel Makefile and also makes sure that the script is called only once in 'make prepare' (previously, it would be called every time due to a variable expansion in an ifneq statement). No user-visible change is intended, unless one runs the setlocalversion script directly. Reported-by: Dmitry Torokhov Cc: David Rientjes Cc: Greg Thelen Cc: Nico Schottelius Signed-off-by: Michal Marek --- scripts/package/Makefile | 2 +- scripts/setlocalversion | 179 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 133 insertions(+), 48 deletions(-) (limited to 'scripts') diff --git a/scripts/package/Makefile b/scripts/package/Makefile index 62fcc3a7f4d3..3a681ef25306 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -44,7 +44,7 @@ rpm-pkg rpm: $(objtree)/kernel.spec FORCE fi $(MAKE) clean $(PREV) ln -sf $(srctree) $(KERNELPATH) - $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion > $(objtree)/.scmversion + $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion --scm-only > $(objtree)/.scmversion $(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. $(PREV) rm $(KERNELPATH) rm -f $(objtree)/.scmversion diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 46989b88d734..d6a866ed1835 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -10,73 +10,158 @@ # usage() { - echo "Usage: $0 [srctree]" >&2 + echo "Usage: $0 [--scm-only] [srctree]" >&2 exit 1 } -cd "${1:-.}" || usage +scm_only=false +srctree=. +if test "$1" = "--scm-only"; then + scm_only=true + shift +fi +if test $# -gt 0; then + srctree=$1 + shift +fi +if test $# -gt 0 -o ! -d "$srctree"; then + usage +fi -# Check for git and a git repo. -if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then +scm_version() +{ + local short=false - # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore it, - # because this version is defined in the top level Makefile. - if [ -z "`git describe --exact-match 2>/dev/null`" ]; then + cd "$srctree" + if test -e .scmversion; then + cat "$_" + return + fi + if test "$1" = "--short"; then + short=true + fi - # If we are past a tagged commit (like "v2.6.30-rc5-302-g72357d5"), - # we pretty print it. - if atag="`git describe 2>/dev/null`"; then - echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' + # Check for git and a git repo. + if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then + + # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore + # it, because this version is defined in the top level Makefile. + if [ -z "`git describe --exact-match 2>/dev/null`" ]; then + + # If only the short version is requested, don't bother + # running further git commands + if $short; then + echo "+" + return + fi + # If we are past a tagged commit (like + # "v2.6.30-rc5-302-g72357d5"), we pretty print it. + if atag="`git describe 2>/dev/null`"; then + echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' + + # If we don't have a tag at all we print -g{commitish}. + else + printf '%s%s' -g $head + fi + fi - # If we don't have a tag at all we print -g{commitish}. - else - printf '%s%s' -g $head + # Is this git on svn? + if git config --get svn-remote.svn.url >/dev/null; then + printf -- '-svn%s' "`git svn find-rev $head`" fi - fi - # Is this git on svn? - if git config --get svn-remote.svn.url >/dev/null; then - printf -- '-svn%s' "`git svn find-rev $head`" - fi + # Update index only on r/w media + [ -w . ] && git update-index --refresh --unmerged > /dev/null - # Update index only on r/w media - [ -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 + printf '%s' -dirty + fi - # Check for uncommitted changes - if git diff-index --name-only HEAD | grep -v "^scripts/package" \ - | read dummy; then - printf '%s' -dirty + # All done with git + return fi - # All done with git - exit -fi + # Check for mercurial and a mercurial repo. + if hgid=`hg id 2>/dev/null`; then + tag=`printf '%s' "$hgid" | cut -d' ' -f2` + + # Do we have an untagged version? + if [ -z "$tag" -o "$tag" = tip ]; then + id=`printf '%s' "$hgid" | sed 's/[+ ].*//'` + printf '%s%s' -hg "$id" + fi -# Check for mercurial and a mercurial repo. -if hgid=`hg id 2>/dev/null`; then - tag=`printf '%s' "$hgid" | cut -d' ' -f2` + # Are there uncommitted changes? + # These are represented by + after the changeset id. + case "$hgid" in + *+|*+\ *) printf '%s' -dirty ;; + esac - # Do we have an untagged version? - if [ -z "$tag" -o "$tag" = tip ]; then - id=`printf '%s' "$hgid" | sed 's/[+ ].*//'` - printf '%s%s' -hg "$id" + # All done with mercurial + return fi - # Are there uncommitted changes? - # These are represented by + after the changeset id. - case "$hgid" in - *+|*+\ *) printf '%s' -dirty ;; - esac + # Check for svn and a svn repo. + if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then + rev=`echo $rev | awk '{print $NF}'` + printf -- '-svn%s' "$rev" - # All done with mercurial + # All done with svn + return + fi +} + +collect_files() +{ + local file res + + for file; do + case "$file" in + *\~*) + continue + ;; + esac + if test -e "$file"; then + res="$res$(cat "$file")" + fi + done + echo "$res" +} + +if $scm_only; then + scm_version exit fi -# Check for svn and a svn repo. -if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then - rev=`echo $rev | awk '{print $NF}'` - printf -- '-svn%s' "$rev" +if test -e include/config/auto.conf; then + source "$_" +else + echo "Error: kernelrelease not valid - run 'make prepare' to update it" + exit 1 +fi - # All done with svn - exit +# localversion* files in the build and source directory +res="$(collect_files localversion*)" +if test ! "$srctree" -ef .; then + res="$res$(collect_files "$srctree"/localversion*)" +fi + +# CONFIG_LOCALVERSION and LOCALVERSION (if set) +res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}" + +# scm version string if not at a tagged commit +if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then + # full scm version string + res="$res$(scm_version)" +else + # apped a plus sign if the repository is not in a clean tagged + # state and LOCALVERSION= is not specified + if test "${LOCALVERSION+set}" != "set"; then + scm=$(scm_version --short) + res="$res${scm:++}" + fi fi + +echo "$res" -- cgit v1.2.3 From b51cae21ee66f77a368428e6bdf75a0c012c9fd7 Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Fri, 25 Jun 2010 14:54:16 -0400 Subject: Add wait4() back to the set of syscalls. The initial pass at the generic ABI assumed that wait4() could be easily expressed using waitid(). Although it's true that wait4() can be built on waitid(), it's awkward enough that it makes more sense to continue to include wait4 in the generic syscall ABI. Since there is already a deprecated wait4 in the ABI, this change converts that wait4 into old_wait, and puts wait4 in the next available slot for new supported syscalls, after the platform-specific syscalls at number 260. Signed-off-by: Chris Metcalf Acked-by: Arnd Bergmann --- scripts/checksyscalls.sh | 1 - 1 file changed, 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh index 66ad375612f2..6bb42e72e0e5 100755 --- a/scripts/checksyscalls.sh +++ b/scripts/checksyscalls.sh @@ -183,7 +183,6 @@ cat << EOF #define __IGNORE_ustat /* statfs */ #define __IGNORE_utime /* utimes */ #define __IGNORE_vfork /* clone */ -#define __IGNORE_wait4 /* waitid */ /* sync_file_range had a stupid ABI. Allow sync_file_range2 instead */ #ifdef __NR_sync_file_range2 -- cgit v1.2.3 From 1e9dea2a60b71ea7a9ac2936bed920d39f662e52 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Sun, 13 Jun 2010 09:26:34 +0200 Subject: Add support for the C variable in the coccicheck script This patch makes it possible to use the Coccinelle checker with the C variable of the build system. To check only newly edited code, the following command may be used: 'make C={1,2} CHECK="scripts/coccicheck"' This runs every semantic patch in scripts/coccinelle by default. The COCCI variable may additionally be used to only apply a single semantic patch. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccicheck | 76 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 25 deletions(-) (limited to 'scripts') diff --git a/scripts/coccicheck b/scripts/coccicheck index 037424b9ede5..b8bcf1f7bed7 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -2,53 +2,79 @@ SPATCH="`which ${SPATCH:=spatch}`" +if [ "$C" = "1" -o "$C" = "2" ]; then + ONLINE=1 + +# This requires Coccinelle >= 0.2.3 +# FLAGS="-ignore_unknown_options -very_quiet" +# OPTIONS=$* + +# Workaround for Coccinelle < 0.2.3 + FLAGS="-I $srctree/include -very_quiet" + shift $(( $# - 1 )) + OPTIONS=$1 +else + ONLINE=0 + FLAGS="-very_quiet" +fi + if [ ! -x "$SPATCH" ]; then echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/' exit 1 fi if [ "$MODE" = "" ] ; then - echo 'You have not explicitly specify the mode to use. Fallback to "report".' - echo 'You can specify the mode with "make coccicheck MODE="' - echo 'Available modes are: report, patch, context, org' + if [ "$ONLINE" = "0" ] ; then + echo 'You have not explicitly specify the mode to use. Fallback to "report".' + echo 'You can specify the mode with "make coccicheck MODE="' + echo 'Available modes are: report, patch, context, org' + fi MODE="report" fi -echo '' -echo 'Please check for false positives in the output before submitting a patch.' -echo 'When using "patch" mode, carefully review the patch before submitting it.' -echo '' +if [ "$ONLINE" = "0" ] ; then + echo '' + echo 'Please check for false positives in the output before submitting a patch.' + echo 'When using "patch" mode, carefully review the patch before submitting it.' + echo '' +fi -function coccinelle { +coccinelle () { COCCI="$1" - DIR="$2" OPT=`grep "Option" $COCCI | cut -d':' -f2` - FILE=`echo $COCCI | sed "s|$DIR/||"` - echo "Processing `basename $COCCI` with option(s) \"$OPT\"" - echo 'Message example to submit a patch:' +# The option '-parse_cocci' can be used to syntaxically check the SmPL files. +# +# $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null - sed -e '/\/\/\//!d' -e 's|^///||' $COCCI + if [ "$ONLINE" = "0" ] ; then - echo ' The semantic patch that makes this change is available' - echo " in $FILE." - echo '' - echo ' More information about semantic patching is available at' - echo ' http://coccinelle.lip6.fr/' - echo '' + FILE=`echo $COCCI | sed "s|$srctree/||"` -# The option '-parse_cocci' can be used to syntaxically check the SmPL files. -# -# $SPATCH -D $MODE -very_quiet -parse_cocci $COCCI $OPT > /dev/null + echo "Processing `basename $COCCI` with option(s) \"$OPT\"" + echo 'Message example to submit a patch:' + + sed -e '/\/\/\//!d' -e 's|^///||' $COCCI + + echo ' The semantic patch that makes this change is available' + echo " in $FILE." + echo '' + echo ' More information about semantic patching is available at' + echo ' http://coccinelle.lip6.fr/' + echo '' + + $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT -dir $srctree || exit 1 + else + $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1 + fi - $SPATCH -D $MODE -very_quiet -sp_file $COCCI $OPT -dir $DIR } if [ "$COCCI" = "" ] ; then for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do - coccinelle $f $srctree; + coccinelle $f done else - coccinelle $COCCI $srctree + coccinelle $COCCI fi -- cgit v1.2.3 From 5e8e1cc0a1c36c8ff156ac1f04a16422bd4ed3ac Mon Sep 17 00:00:00 2001 From: Martin Ettl Date: Sun, 21 Feb 2010 09:31:44 +0100 Subject: scripts/dtc: Fix a resource leak during a check of the current git head of the linux kernel with the static code analysis tool cppcheck (http://sourceforge.net/apps/mediawiki/cppcheck/index.php?title=Main_Page) the tool discovered a resource leak in linux-2.6/scripts/dtc/fstree.c. Please refer the attached patch, that fixes the issue. Fixes https://bugzilla.kernel.org/show_bug.cgi?id=15363 Signed-off-by: Martin Ettl Cc: David Gibson Signed-off-by: Michal Marek --- scripts/dtc/fstree.c | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/dtc/fstree.c b/scripts/dtc/fstree.c index 766b2694d935..8fe1bdf239f0 100644 --- a/scripts/dtc/fstree.c +++ b/scripts/dtc/fstree.c @@ -77,6 +77,7 @@ static struct node *read_fstree(const char *dirname) free(tmpnam); } + closedir(d); return tree; } -- cgit v1.2.3 From 246cf9c26bf11f2bffbecea6e5bd222eee7b1df8 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Tue, 8 Jun 2010 17:25:57 +0100 Subject: kbuild: Warn on selecting symbols with unmet direct dependencies The "select" statement in Kconfig files allows the enabling of options even if they have unmet direct dependencies (i.e. "depends on" expands to "no"). Currently, the "depends on" clauses are used in calculating the visibility but they do not affect the reverse dependencies in any way. The patch introduces additional tracking of the "depends on" statements and prints a warning on selecting an option if its direct dependencies are not met. Signed-off-by: Catalin Marinas Cc: Sam Ravnborg Cc: Arnd Bergmann Cc: Andrew Morton Cc: Linus Torvalds Signed-off-by: Michal Marek --- scripts/kconfig/expr.h | 2 ++ scripts/kconfig/menu.c | 5 +++++ scripts/kconfig/symbol.c | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 891cd9ce9ba2..75a31e4552f3 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -83,6 +83,7 @@ struct symbol { tristate visible; int flags; struct property *prop; + struct expr_value dir_dep; struct expr_value rev_dep; }; @@ -163,6 +164,7 @@ struct menu { struct symbol *sym; struct property *prompt; struct expr *dep; + struct expr *dir_dep; unsigned int flags; char *help; struct file *file; diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index eef17bacb6bc..11799894f3bd 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -105,6 +105,7 @@ static struct expr *menu_check_dep(struct expr *e) void menu_add_dep(struct expr *dep) { current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); + current_entry->dir_dep = current_entry->dep; } void menu_set_type(int type) @@ -288,6 +289,10 @@ void menu_finalize(struct menu *parent) for (menu = parent->list; menu; menu = menu->next) menu_finalize(menu); } else if (sym) { + /* ignore inherited dependencies for dir_dep */ + sym->dir_dep.expr = expr_transform(expr_copy(parent->dir_dep)); + sym->dir_dep.expr = expr_eliminate_dups(sym->dir_dep.expr); + basedep = parent->prompt ? parent->prompt->visible.expr : NULL; basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); basedep = expr_eliminate_dups(expr_transform(basedep)); diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 2e7a048e0cfc..174b230a52b0 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -205,6 +205,16 @@ static void sym_calc_visibility(struct symbol *sym) } if (sym_is_choice_value(sym)) return; + /* defaulting to "yes" if no explicit "depends on" are given */ + tri = yes; + if (sym->dir_dep.expr) + tri = expr_calc_value(sym->dir_dep.expr); + if (tri == mod) + tri = yes; + if (sym->dir_dep.tri != tri) { + sym->dir_dep.tri = tri; + sym_set_changed(sym); + } tri = no; if (sym->rev_dep.expr) tri = expr_calc_value(sym->rev_dep.expr); @@ -321,6 +331,14 @@ void sym_calc_value(struct symbol *sym) } } calc_newval: + if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { + fprintf(stderr, "warning: ("); + expr_fprint(sym->rev_dep.expr, stderr); + fprintf(stderr, ") selects %s which has unmet direct dependencies (", + sym->name); + expr_fprint(sym->dir_dep.expr, stderr); + fprintf(stderr, ")\n"); + } newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); } if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) -- cgit v1.2.3 From 7fca5dc8aa7aaa6a1023bd3587901b88ebfe8154 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 29 Jun 2010 20:08:42 +0000 Subject: powerpc: Fix module building for gcc 4.5 and 64 bit Gcc 4.5 is now generating out of line register save and restore in the function prefix and postfix when we use -Os. Signed-off-by: Stephen Rothwell Signed-off-by: Benjamin Herrenschmidt --- scripts/mod/modpost.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index f8779006986d..f6127b9f5aca 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -503,6 +503,11 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname) strncmp(symname, "_rest32gpr_", sizeof("_rest32gpr_") - 1) == 0 || strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0) return 1; + if (info->hdr->e_machine == EM_PPC64) + /* Special register function linked on all modules during final link of .ko */ + if (strncmp(symname, "_restgpr0_", sizeof("_restgpr0_") - 1) == 0 || + strncmp(symname, "_savegpr0_", sizeof("_savegpr0_") - 1) == 0) + return 1; /* Do not ignore this symbol */ return 0; } -- cgit v1.2.3 From 0a28c47b8db8ff74d1bfbc5c5ad0100cea472351 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 30 Jun 2010 13:11:01 +0100 Subject: kconfig: Don't write invisible choice values This makes it so "make oldconfig" really prompts for any choice where options that previously weren't visible just became so. Previously one would have to remember to go over all choice values and check whether some that previously couldn't be selected now can be. Signed-off-by: Jan Beulich Signed-off-by: Michal Marek --- scripts/kconfig/symbol.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 174b230a52b0..c127fa342f1d 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -232,13 +232,15 @@ static struct symbol *sym_calc_choice(struct symbol *sym) struct property *prop; struct expr *e; + /* first calculate all choice values' visibilities */ + prop = sym_get_choice_prop(sym); + expr_list_for_each_sym(prop->expr, e, def_sym) + sym_calc_visibility(def_sym); + /* is the user choice visible? */ def_sym = sym->def[S_DEF_USER].val; - if (def_sym) { - sym_calc_visibility(def_sym); - if (def_sym->visible != no) - return def_sym; - } + if (def_sym && def_sym->visible != no) + return def_sym; /* any of the defaults visible? */ for_all_defaults(sym, prop) { @@ -246,18 +248,15 @@ static struct symbol *sym_calc_choice(struct symbol *sym) if (prop->visible.tri == no) continue; def_sym = prop_get_symbol(prop); - sym_calc_visibility(def_sym); if (def_sym->visible != no) return def_sym; } /* just get the first visible value */ prop = sym_get_choice_prop(sym); - expr_list_for_each_sym(prop->expr, e, def_sym) { - sym_calc_visibility(def_sym); + expr_list_for_each_sym(prop->expr, e, def_sym) if (def_sym->visible != no) return def_sym; - } /* no choice? reset tristate value */ sym->curr.tri = no; @@ -383,12 +382,13 @@ void sym_calc_value(struct symbol *sym) if (sym_is_choice(sym)) { struct symbol *choice_sym; - int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); prop = sym_get_choice_prop(sym); expr_list_for_each_sym(prop->expr, e, choice_sym) { - choice_sym->flags |= flags; - if (flags & SYMBOL_CHANGED) + if ((sym->flags & SYMBOL_WRITE) && + choice_sym->visible != no) + choice_sym->flags |= SYMBOL_WRITE; + if (sym->flags & SYMBOL_CHANGED) sym_set_changed(choice_sym); } } -- cgit v1.2.3 From 6dc0c2f3384fe543a805922c6a314c7ad25a92fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Sun, 18 Jul 2010 10:26:40 +0200 Subject: kbuild: Make the setlocalversion script POSIX-compliant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'source' builtin is a bash alias to the '.' (dot) builtin. While the former is supported only by bash, the latter is specified in POSIX and works fine with all POSIX-compliant shells I am aware of. The '$_' special parameter is specific to bash. It is partially supported in dash too but it always evaluates to the current script path (which causes the script to enter a loop recursively re-executing itself). This is why I have replaced the two occurences of '$_' with the explicit parameter. The 'local' builtin is another example of bash-specific code. Although it is supported by all POSIX-compliant shells I am aware of, it is not part of POSIX specification and thus the code should not rely on it assigning a specific value to the local variable. Moreover, the 'posh' shell has a limited version of 'local' builtin not supporting direct variable assignments. Thus, I have broken one of the 'local' declarations down into a (non-POSIX) 'local' declaration and a plain (POSIX-compliant) variable assignment. Signed-off-by: Michał Górny Signed-off-by: Michal Marek --- scripts/setlocalversion | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/setlocalversion b/scripts/setlocalversion index d6a866ed1835..a7b9f7607e13 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -30,11 +30,12 @@ fi scm_version() { - local short=false + local short + short=false cd "$srctree" if test -e .scmversion; then - cat "$_" + cat .scmversion return fi if test "$1" = "--short"; then @@ -136,7 +137,7 @@ if $scm_only; then fi if test -e include/config/auto.conf; then - source "$_" + . include/config/auto.conf else echo "Error: kernelrelease not valid - run 'make prepare' to update it" exit 1 -- cgit v1.2.3 From b003afe32f608b8d9f9a898b36514dfbf374fd3a Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Thu, 15 Jul 2010 10:36:37 +0200 Subject: kbuild: Fix make rpm make rpm was broken by commit 0915512: make clean set -e; cd ..; ln -sf /usr/src/iwlwifi-2.6 kernel-2.6.35rc4wl /bin/sh /usr/src/iwlwifi-2.6/scripts/setlocalversion --scm-only > /usr/src/iwlwifi-2.6/.scmversion cat: .scmversion: input file is output file make[1]: *** [rpm] Error 1 Reported-and-tested-by: "Zheng, Jiajia" Signed-off-by: Michal Marek --- scripts/package/Makefile | 2 +- scripts/setlocalversion | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/package/Makefile b/scripts/package/Makefile index 3a681ef25306..d2c29b63adda 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -44,7 +44,7 @@ rpm-pkg rpm: $(objtree)/kernel.spec FORCE fi $(MAKE) clean $(PREV) ln -sf $(srctree) $(KERNELPATH) - $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion --scm-only > $(objtree)/.scmversion + $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion --save-scmversion $(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. $(PREV) rm $(KERNELPATH) rm -f $(objtree)/.scmversion diff --git a/scripts/setlocalversion b/scripts/setlocalversion index a7b9f7607e13..64a9cb5556cd 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -10,13 +10,13 @@ # usage() { - echo "Usage: $0 [--scm-only] [srctree]" >&2 + echo "Usage: $0 [--save-scmversion] [srctree]" >&2 exit 1 } scm_only=false srctree=. -if test "$1" = "--scm-only"; then +if test "$1" = "--save-scmversion"; then scm_only=true shift fi @@ -132,7 +132,10 @@ collect_files() } if $scm_only; then - scm_version + if test ! -e .scmversion; then + res=$(scm_version) + echo "$res" >.scmversion + fi exit fi -- cgit v1.2.3 From a484e54fae891703cbe1c9ec1b536605f11f5482 Mon Sep 17 00:00:00 2001 From: David Daney Date: Fri, 9 Jul 2010 14:52:05 -0700 Subject: tracing: Fix $mcount_regex for MIPS in recordmcount.pl I found this issue in a locally patched 2.6.32.x, current kernels have moved the offending code to an __init function which is skipped by recordmcount.pl, so the bug is not currently being exercised. However, I think the patch is still a good idea, to avoid future problems if _mcount were to ever have its address taken in normal code. This is what I originally saw: Although arch/mips/kernel/ftrace.c is built without -pg, and thus contains no calls to _mcount, it does use the address of _mcount in ftrace_make_nop(). This was causing relocations to be emitted for _mcount which recordmcount.pl erronously took to be _mcount call sites. The result was that the text of ftrace_make_nop() would be patched with garbage leading to a system crash. In non-module code, all _mcount call sites will have R_MIPS_26 relocations, so we restrict $mcount_regex to only match on these. Acked-by: Ralf Baechle Acked-by: Wu Zhangjin Signed-off-by: David Daney LKML-Reference: <1278712325-12050-1-git-send-email-ddaney@caviumnetworks.com> Cc: Li Hong Cc: Ingo Molnar Cc: Matt Fleming Signed-off-by: Steven Rostedt --- scripts/recordmcount.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index f3c9c0a90b98..0171060b5fd6 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -326,7 +326,7 @@ if ($arch eq "x86_64") { # 14: R_MIPS_NONE *ABS* # 18: 00020021 nop if ($is_module eq "0") { - $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; + $mcount_regex = "^\\s*([0-9a-fA-F]+): R_MIPS_26\\s+_mcount\$"; } else { $mcount_regex = "^\\s*([0-9a-fA-F]+): R_MIPS_HI16\\s+_mcount\$"; } -- cgit v1.2.3 From 58f915a311c1eac464e0e1caca2f85a05b66c930 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 23 Jul 2010 00:04:14 -0700 Subject: nconfig: Fix segfault when help contains special characters nconfig segfaults when help text contains the character '%'. For a quick example, navigate to the kernel compression options and get the help for bzip2. Doing so triggers a call to mvwprintw() with a string containing '%' and no extra arguments to fill in the specifier's value. Fix this case by printing the literal string retrieved from the kconfig. #0 0x00002b52b6b11d83 in vfprintf () from /lib/libc.so.6 #1 0x00002b52b6bad010 in __vsnprintf_chk () from /lib/libc.so.6 #2 0x00002b52b623991b in _nc_printf_string () from /lib/libncursesw.so.5 #3 0x00002b52b6234cff in vwprintw () from /lib/libncursesw.so.5 #4 0x00002b52b6234db9 in mvwprintw () from /lib/libncursesw.so.5 #5 0x00000000004151d8 in fill_window (win=0x21b64c0, text=0x21b62b0 "CONFIG_KERNEL_BZIP2:\n\nIts compression ratio and speed is intermediate.\nDecompression speed is slowest among the three. The kernel\nsize is about 10% smaller with bzip2, in comparison to gzip.\nBzip2 us"...) at scripts/kconfig/nconf.gui.c:229 #6 0x0000000000416335 in show_scroll_win (main_window=0x21a5630, title=0x157fa30 "Bzip2", text=0x21b62b0 "CONFIG_KERNEL_BZIP2:\n\nIts compression ratio and speed is intermediate.\nDecompression speed is slowest among the three. The kernel\nsize is about 10% smaller with bzip2, in comparison to gzip.\nBzip2 us"...) at scripts/kconfig/nconf.gui.c:535 #7 0x00000000004055b2 in show_help (menu=0x157f9d0) at scripts/kconfig/nconf.c:1257 #8 0x0000000000405897 in conf_choice (menu=0x157f130) at scripts/kconfig/nconf.c:1321 #9 0x0000000000405326 in conf (menu=0x157d130) at scripts/kconfig/nconf.c:1208 #10 0x00000000004052e8 in conf (menu=0xb434a0) at scripts/kconfig/nconf.c:1203 #11 0x0000000000406092 in main (ac=2, av=0x7fff96a93c38) Cc: Michal Marek Cc: Nir Tzachar Signed-off-by: Stephen Boyd Signed-off-by: Michal Marek --- scripts/kconfig/nconf.gui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index 115edb437fb1..a9d9344e1365 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -226,7 +226,7 @@ void fill_window(WINDOW *win, const char *text) int len = get_line_length(line); strncpy(tmp, line, min(len, x)); tmp[len] = '\0'; - mvwprintw(win, i, 0, tmp); + mvwprintw(win, i, 0, "%s", tmp); } } -- cgit v1.2.3 From 1244b41d00eb60cb3d05220383bc9d15b9045fb4 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Thu, 22 Jul 2010 14:24:57 +0200 Subject: kconfig: make randconfig fair for booleans Give boolean symbols a 50% chance of getting enabled, rather than 67%. Signed-off-by: Peter Korsgaard Acked-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index c4dec80cfd8e..210a49e27d47 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -862,7 +862,8 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) sym->def[S_DEF_USER].tri = no; break; case def_random: - sym->def[S_DEF_USER].tri = (tristate)(rand() % 3); + cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2; + sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt); break; default: continue; -- cgit v1.2.3 From ac1ffde1ba053db0266f886a15ed845a6628fcb0 Mon Sep 17 00:00:00 2001 From: Ulf Magnusson Date: Tue, 27 Jul 2010 21:57:43 +0200 Subject: kconfig: fix MODULES-related bug in case of no .config There seems to be a kconfig bug due to MODULES not always being evaluated if no .config is found. Take the following Kconfig as an example: config MODULES def_bool y config FOO def_tristate m With no .config, the following configuration is generated: CONFIG_MODULES=y CONFIG_FOO=y With an empty .config, the following: CONFIG_MODULES=y CONFIG_FOO=m Tristate choice statements can also exhibit the problem, due to having an implicit rev_dep (select) containing "m". The problem is that MODULES is never evaluted in conf_read_simple() unless there's a .config. The following patch fixes this. Signed-off-by: Ulf Magnusson Reviewed-by: WANG Cong Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 210a49e27d47..8dce5862550d 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -170,8 +170,11 @@ int conf_read_simple(const char *name, int def) if (in) goto load; sym_add_change_count(1); - if (!sym_defconfig_list) + if (!sym_defconfig_list) { + if (modules_sym) + sym_calc_value(modules_sym); return 1; + } for_all_defaults(sym_defconfig_list, prop) { if (expr_calc_value(prop->visible.expr) == no || -- cgit v1.2.3 From 4062f1a4c030157216dc8932e27131975cf7253c Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 31 Jul 2010 23:35:26 +0200 Subject: kconfig: use long options in conf The list of options supported by conf is growing and their abbreviation did not resemble anything usefull. So drop the single letter options in favour of long options. The long options are named equal to what we know from the make target. The internal implmentation was changed to match this, resulting in much more readable code. Support for short options is dropped - no one is supposed to call this program direct anyway. Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 70 +++++++++------------ scripts/kconfig/conf.c | 161 ++++++++++++++++++++++------------------------- 2 files changed, 105 insertions(+), 126 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index f8d1ee3a372e..549e50e49cbf 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -21,53 +21,47 @@ menuconfig: $(obj)/mconf $< $(Kconfig) config: $(obj)/conf - $< $(Kconfig) + $< --oldaskconfig $(Kconfig) nconfig: $(obj)/nconf $< $(Kconfig) oldconfig: $(obj)/conf - $< -o $(Kconfig) + $< --$@ $(Kconfig) silentoldconfig: $(obj)/conf $(Q)mkdir -p include/generated - $< -s $(Kconfig) + $< --$@ $(Kconfig) localmodconfig: $(obj)/streamline_config.pl $(obj)/conf $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config - $(Q)if [ -f .config ]; then \ - cmp -s .tmp.config .config || \ - (mv -f .config .config.old.1; \ - mv -f .tmp.config .config; \ - $(obj)/conf -s $(Kconfig); \ - mv -f .config.old.1 .config.old) \ - else \ - mv -f .tmp.config .config; \ - $(obj)/conf -s $(Kconfig); \ + $(Q)if [ -f .config ]; then \ + cmp -s .tmp.config .config || \ + (mv -f .config .config.old.1; \ + mv -f .tmp.config .config; \ + $(obj)/conf --silentoldconfig $(Kconfig); \ + mv -f .config.old.1 .config.old) \ + else \ + mv -f .tmp.config .config; \ + $(obj)/conf --silentoldconfig $(Kconfig); \ fi $(Q)rm -f .tmp.config localyesconfig: $(obj)/streamline_config.pl $(obj)/conf $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config $(Q)sed -i s/=m/=y/ .tmp.config - $(Q)if [ -f .config ]; then \ - cmp -s .tmp.config .config || \ - (mv -f .config .config.old.1; \ - mv -f .tmp.config .config; \ - $(obj)/conf -s $(Kconfig); \ - mv -f .config.old.1 .config.old) \ - else \ - mv -f .tmp.config .config; \ - $(obj)/conf -s $(Kconfig); \ + $(Q)if [ -f .config ]; then \ + cmp -s .tmp.config .config || \ + (mv -f .config .config.old.1; \ + mv -f .tmp.config .config; \ + $(obj)/conf --silentoldconfig $(Kconfig); \ + mv -f .config.old.1 .config.old) \ + else \ + mv -f .tmp.config .config; \ + $(obj)/conf --silentoldconfig $(Kconfig); \ fi $(Q)rm -f .tmp.config -nonint_oldconfig: $(obj)/conf - $< -b $(Kconfig) - -loose_nonint_oldconfig: $(obj)/conf - $< -B $(Kconfig) - # 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 @@ -91,30 +85,26 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h $(Q)rm -f arch/um/Kconfig.arch $(Q)rm -f $(obj)/config.pot -PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig - -randconfig: $(obj)/conf - $< -r $(Kconfig) +PHONY += allnoconfig allyesconfig allmodconfig randconfig -allyesconfig: $(obj)/conf - $< -y $(Kconfig) +allnoconfig allyesconfig allmodconfig randconfig: $(obj)/conf + $< --$@ $(Kconfig) -allnoconfig: $(obj)/conf - $< -n $(Kconfig) +PHONY += nonint_oldconfig loose_nonint_oldconfig defconfig -allmodconfig: $(obj)/conf - $< -m $(Kconfig) +nonint_oldconfig loose_nonint_oldconfig: $(obj)/conf + $< --$@ $(Kconfig) defconfig: $(obj)/conf ifeq ($(KBUILD_DEFCONFIG),) - $< -d $(Kconfig) + $< --defconfig $(Kconfig) else @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" - $(Q)$< -D arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) + $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) endif %_defconfig: $(obj)/conf - $(Q)$< -D arch/$(SRCARCH)/configs/$@ $(Kconfig) + $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) # Help text used by make help help: diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index bde01b4200ee..2dec584f1268 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -23,18 +24,19 @@ static void conf(struct menu *menu); static void check_conf(struct menu *menu); -enum { - ask_all, - ask_new, - ask_silent, - dont_ask, - dont_ask_dont_tell, - set_default, - set_yes, - set_mod, - set_no, - set_random -} input_mode = ask_all; +enum input_mode { + oldaskconfig, + silentoldconfig, + oldconfig, + allnoconfig, + allyesconfig, + allmodconfig, + randconfig, + defconfig, + nonint_oldconfig, + loose_nonint_oldconfig, +} input_mode = oldaskconfig; + char *defconfig_file; static int indent = 1; @@ -100,14 +102,14 @@ static int conf_askvalue(struct symbol *sym, const char *def) } switch (input_mode) { - case ask_new: - case ask_silent: + case oldconfig: + case silentoldconfig: if (sym_has_value(sym)) { printf("%s\n", def); return 0; } check_stdin(); - case ask_all: + case oldaskconfig: fflush(stdout); fgets(line, 128, stdin); return 1; @@ -297,15 +299,15 @@ static int conf_choice(struct menu *menu) printf("?"); printf("]: "); switch (input_mode) { - case ask_new: - case ask_silent: + case oldconfig: + case silentoldconfig: if (!is_new) { cnt = def; printf("%d\n", cnt); break; } check_stdin(); - case ask_all: + case oldaskconfig: fflush(stdout); fgets(line, 128, stdin); strip(line); @@ -363,9 +365,9 @@ static void conf(struct menu *menu) switch (prop->type) { case P_MENU: - if ((input_mode == ask_silent || - input_mode == dont_ask || - input_mode == dont_ask_dont_tell) && + if ((input_mode == silentoldconfig || + input_mode == nonint_oldconfig || + input_mode == loose_nonint_oldconfig) && rootEntry != menu) { check_conf(menu); return; @@ -424,9 +426,9 @@ static void check_conf(struct menu *menu) if (sym && !sym_has_value(sym)) { if (sym_is_changable(sym) || (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { - if (input_mode == dont_ask || - input_mode == dont_ask_dont_tell) { - if (input_mode == dont_ask && + if (input_mode == nonint_oldconfig || + input_mode == loose_nonint_oldconfig) { + if (input_mode == nonint_oldconfig && sym->name && !sym_is_choice_value(sym)) { if (!unset_variables) fprintf(stderr, "The following" @@ -448,6 +450,20 @@ static void check_conf(struct menu *menu) check_conf(child); } +static struct option long_opts[] = { + {"oldaskconfig", no_argument, NULL, oldaskconfig}, + {"oldconfig", no_argument, NULL, oldconfig}, + {"silentoldconfig", no_argument, NULL, silentoldconfig}, + {"defconfig", optional_argument, NULL, defconfig}, + {"allnoconfig", no_argument, NULL, allnoconfig}, + {"allyesconfig", no_argument, NULL, allyesconfig}, + {"allmodconfig", no_argument, NULL, allmodconfig}, + {"randconfig", no_argument, NULL, randconfig}, + {"nonint_oldconfig", no_argument, NULL, nonint_oldconfig}, + {"loose_nonint_oldconfig", no_argument, NULL, loose_nonint_oldconfig}, + {NULL, 0, NULL, 0} +}; + int main(int ac, char **av) { int opt; @@ -458,38 +474,16 @@ int main(int ac, char **av) bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - while ((opt = getopt(ac, av, "osbBdD:nmyrh")) != -1) { + while ((opt = getopt_long_only(ac, av, "", long_opts, NULL)) != -1) { + input_mode = (enum input_mode)opt; switch (opt) { - case 'o': - input_mode = ask_silent; - break; - case 's': - input_mode = ask_silent; + case silentoldconfig: sync_kconfig = 1; break; - case 'b': - input_mode = dont_ask; - break; - case 'B': - input_mode = dont_ask_dont_tell; - break; - case 'd': - input_mode = set_default; - break; - case 'D': - input_mode = set_default; + case defconfig: defconfig_file = optarg; break; - case 'n': - input_mode = set_no; - break; - case 'm': - input_mode = set_mod; - break; - case 'y': - input_mode = set_yes; - break; - case 'r': + case randconfig: { struct timeval now; unsigned int seed; @@ -502,17 +496,12 @@ int main(int ac, char **av) seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1)); srand(seed); - - input_mode = set_random; break; } - case 'h': - printf(_("See README for usage info\n")); - exit(0); - break; - default: + case '?': fprintf(stderr, _("See README for usage info\n")); exit(1); + break; } } if (ac == optind) { @@ -537,7 +526,7 @@ int main(int ac, char **av) } switch (input_mode) { - case set_default: + case defconfig: if (!defconfig_file) defconfig_file = conf_get_default_confname(); if (conf_read(defconfig_file)) { @@ -547,27 +536,27 @@ int main(int ac, char **av) exit(1); } break; - case ask_silent: - case ask_all: - case ask_new: - case dont_ask: - case dont_ask_dont_tell: + case silentoldconfig: + case oldaskconfig: + case oldconfig: + case nonint_oldconfig: + case loose_nonint_oldconfig: conf_read(NULL); break; - case set_no: - case set_mod: - case set_yes: - case set_random: + case allnoconfig: + case allyesconfig: + case allmodconfig: + case randconfig: name = getenv("KCONFIG_ALLCONFIG"); if (name && !stat(name, &tmpstat)) { conf_read_simple(name, S_DEF_USER); break; } switch (input_mode) { - case set_no: name = "allno.config"; break; - case set_mod: name = "allmod.config"; break; - case set_yes: name = "allyes.config"; break; - case set_random: name = "allrandom.config"; break; + case allnoconfig: name = "allno.config"; break; + case allyesconfig: name = "allyes.config"; break; + case allmodconfig: name = "allmod.config"; break; + case randconfig: name = "allrandom.config"; break; default: break; } if (!stat(name, &tmpstat)) @@ -592,37 +581,37 @@ int main(int ac, char **av) } switch (input_mode) { - case set_no: + case allnoconfig: conf_set_all_new_symbols(def_no); break; - case set_yes: + case allyesconfig: conf_set_all_new_symbols(def_yes); break; - case set_mod: + case allmodconfig: conf_set_all_new_symbols(def_mod); break; - case set_random: + case randconfig: conf_set_all_new_symbols(def_random); break; - case set_default: + case defconfig: conf_set_all_new_symbols(def_default); break; - case ask_new: - case ask_all: + case oldconfig: + case oldaskconfig: rootEntry = &rootmenu; conf(&rootmenu); - input_mode = ask_silent; + input_mode = silentoldconfig; /* fall through */ - case dont_ask: - case dont_ask_dont_tell: - case ask_silent: + case nonint_oldconfig: + case loose_nonint_oldconfig: + case silentoldconfig: /* Update until a loop caused no more changes */ do { conf_cnt = 0; check_conf(&rootmenu); } while (conf_cnt && - (input_mode != dont_ask && - input_mode != dont_ask_dont_tell)); + (input_mode != nonint_oldconfig && + input_mode != loose_nonint_oldconfig)); break; } @@ -638,7 +627,7 @@ int main(int ac, char **av) fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n")); return 1; } - } else if (!unset_variables || input_mode != dont_ask) { + } else if (!unset_variables || input_mode != nonint_oldconfig) { if (conf_write(NULL)) { fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); exit(1); -- cgit v1.2.3 From ef61ca88c511154d6bead23c08f9a021cfdfeb01 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 31 Jul 2010 23:35:27 +0200 Subject: kconfig: rename loose_nonint_oldconfig => oldnoconfig Rename target to something that fall more in line with the other kconfig targets. oldnoconfig shall read as: - read the old configuration and set all new options to no Signed-off-by: Sam Ravnborg Cc: Aristeu Rozanski Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 7 +++---- scripts/kconfig/conf.c | 14 +++++++------- 2 files changed, 10 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 549e50e49cbf..2142afb0a13b 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -90,9 +90,9 @@ PHONY += allnoconfig allyesconfig allmodconfig randconfig allnoconfig allyesconfig allmodconfig randconfig: $(obj)/conf $< --$@ $(Kconfig) -PHONY += nonint_oldconfig loose_nonint_oldconfig defconfig +PHONY += nonint_oldconfig oldnoconfig defconfig -nonint_oldconfig loose_nonint_oldconfig: $(obj)/conf +nonint_oldconfig oldnoconfig: $(obj)/conf $< --$@ $(Kconfig) defconfig: $(obj)/conf @@ -124,8 +124,7 @@ help: @echo ' allnoconfig - New config where all options are answered with no' @echo ' nonint_oldconfig - Checks the current configuration and fails if an option is ' @echo ' not set' - @echo ' loose_nonint_oldconfig - Same as nonint_oldconfig, but updates the config file with ' - @echo ' missing config options as unset' + @echo ' oldnoconfig - Same as silentoldconfig but set new symbols to n (unset)' # lxdialog stuff check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 2dec584f1268..1f86fca6b07f 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -34,7 +34,7 @@ enum input_mode { randconfig, defconfig, nonint_oldconfig, - loose_nonint_oldconfig, + oldnoconfig, } input_mode = oldaskconfig; char *defconfig_file; @@ -367,7 +367,7 @@ static void conf(struct menu *menu) case P_MENU: if ((input_mode == silentoldconfig || input_mode == nonint_oldconfig || - input_mode == loose_nonint_oldconfig) && + input_mode == oldnoconfig) && rootEntry != menu) { check_conf(menu); return; @@ -427,7 +427,7 @@ static void check_conf(struct menu *menu) if (sym_is_changable(sym) || (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { if (input_mode == nonint_oldconfig || - input_mode == loose_nonint_oldconfig) { + input_mode == oldnoconfig) { if (input_mode == nonint_oldconfig && sym->name && !sym_is_choice_value(sym)) { if (!unset_variables) @@ -460,7 +460,7 @@ static struct option long_opts[] = { {"allmodconfig", no_argument, NULL, allmodconfig}, {"randconfig", no_argument, NULL, randconfig}, {"nonint_oldconfig", no_argument, NULL, nonint_oldconfig}, - {"loose_nonint_oldconfig", no_argument, NULL, loose_nonint_oldconfig}, + {"oldnoconfig", no_argument, NULL, oldnoconfig}, {NULL, 0, NULL, 0} }; @@ -540,7 +540,7 @@ int main(int ac, char **av) case oldaskconfig: case oldconfig: case nonint_oldconfig: - case loose_nonint_oldconfig: + case oldnoconfig: conf_read(NULL); break; case allnoconfig: @@ -603,7 +603,7 @@ int main(int ac, char **av) input_mode = silentoldconfig; /* fall through */ case nonint_oldconfig: - case loose_nonint_oldconfig: + case oldnoconfig: case silentoldconfig: /* Update until a loop caused no more changes */ do { @@ -611,7 +611,7 @@ int main(int ac, char **av) check_conf(&rootmenu); } while (conf_cnt && (input_mode != nonint_oldconfig && - input_mode != loose_nonint_oldconfig)); + input_mode != oldnoconfig)); break; } -- cgit v1.2.3 From 861b4ea4cc0eade661480f1ce197ae747f22a918 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 31 Jul 2010 23:35:28 +0200 Subject: kconfig: change nonint_oldconfig to listnewconfig Rename to a name that better match the other kconfig targets. listnewconfig shall read as: - list new options compared to current configuration New options are now written to stdout so one can redirect the output. Do not exit with an error code if there is new options. These are feature changes compared to the original nonint_oldconfig - but as this feature has not yet been in a released kernel it should not matter. It is still possible to do: make listnewconfig lookup new config options in Kconfig* edit .config Signed-off-by: Sam Ravnborg Cc: Aristeu Rozanski Acked-by: Aristeu Rozanski Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 7 +++---- scripts/kconfig/conf.c | 34 +++++++++++----------------------- 2 files changed, 14 insertions(+), 27 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 2142afb0a13b..01bad1bd2550 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -90,9 +90,9 @@ PHONY += allnoconfig allyesconfig allmodconfig randconfig allnoconfig allyesconfig allmodconfig randconfig: $(obj)/conf $< --$@ $(Kconfig) -PHONY += nonint_oldconfig oldnoconfig defconfig +PHONY += listnewconfig oldnoconfig defconfig -nonint_oldconfig oldnoconfig: $(obj)/conf +listnewconfig oldnoconfig: $(obj)/conf $< --$@ $(Kconfig) defconfig: $(obj)/conf @@ -122,8 +122,7 @@ help: @echo ' allmodconfig - New config selecting modules when possible' @echo ' allyesconfig - New config where all options are accepted with yes' @echo ' allnoconfig - New config where all options are answered with no' - @echo ' nonint_oldconfig - Checks the current configuration and fails if an option is ' - @echo ' not set' + @echo ' listnewconfig - List new options' @echo ' oldnoconfig - Same as silentoldconfig but set new symbols to n (unset)' # lxdialog stuff diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 1f86fca6b07f..ff5c914c0e5c 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -17,10 +17,6 @@ #define LKC_DIRECT_LINK #include "lkc.h" -/* Return codes */ -#define EUNSETOPT 2 /* if -B and -b are used and unset config - * options were found */ - static void conf(struct menu *menu); static void check_conf(struct menu *menu); @@ -33,7 +29,7 @@ enum input_mode { allmodconfig, randconfig, defconfig, - nonint_oldconfig, + listnewconfig, oldnoconfig, } input_mode = oldaskconfig; @@ -45,7 +41,6 @@ static int sync_kconfig; static int conf_cnt; static char line[128]; static struct menu *rootEntry; -static int unset_variables; static void print_help(struct menu *menu) { @@ -366,7 +361,7 @@ static void conf(struct menu *menu) switch (prop->type) { case P_MENU: if ((input_mode == silentoldconfig || - input_mode == nonint_oldconfig || + input_mode == listnewconfig || input_mode == oldnoconfig) && rootEntry != menu) { check_conf(menu); @@ -426,16 +421,9 @@ static void check_conf(struct menu *menu) if (sym && !sym_has_value(sym)) { if (sym_is_changable(sym) || (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { - if (input_mode == nonint_oldconfig || - input_mode == oldnoconfig) { - if (input_mode == nonint_oldconfig && - sym->name && !sym_is_choice_value(sym)) { - if (!unset_variables) - fprintf(stderr, "The following" - " variables are not set:\n"); - fprintf(stderr, "CONFIG_%s\n", - sym->name); - unset_variables++; + if (input_mode == listnewconfig) { + if (sym->name && !sym_is_choice_value(sym)) { + printf("CONFIG_%s\n", sym->name); } } else { if (!conf_cnt++) @@ -459,7 +447,7 @@ static struct option long_opts[] = { {"allyesconfig", no_argument, NULL, allyesconfig}, {"allmodconfig", no_argument, NULL, allmodconfig}, {"randconfig", no_argument, NULL, randconfig}, - {"nonint_oldconfig", no_argument, NULL, nonint_oldconfig}, + {"listnewconfig", no_argument, NULL, listnewconfig}, {"oldnoconfig", no_argument, NULL, oldnoconfig}, {NULL, 0, NULL, 0} }; @@ -539,7 +527,7 @@ int main(int ac, char **av) case silentoldconfig: case oldaskconfig: case oldconfig: - case nonint_oldconfig: + case listnewconfig: case oldnoconfig: conf_read(NULL); break; @@ -602,7 +590,7 @@ int main(int ac, char **av) conf(&rootmenu); input_mode = silentoldconfig; /* fall through */ - case nonint_oldconfig: + case listnewconfig: case oldnoconfig: case silentoldconfig: /* Update until a loop caused no more changes */ @@ -610,7 +598,7 @@ int main(int ac, char **av) conf_cnt = 0; check_conf(&rootmenu); } while (conf_cnt && - (input_mode != nonint_oldconfig && + (input_mode != listnewconfig && input_mode != oldnoconfig)); break; } @@ -627,11 +615,11 @@ int main(int ac, char **av) fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n")); return 1; } - } else if (!unset_variables || input_mode != nonint_oldconfig) { + } else if (input_mode != listnewconfig) { if (conf_write(NULL)) { fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); exit(1); } } - return unset_variables ? EUNSETOPT : 0; + return 0; } -- cgit v1.2.3 From 59e89e3ddf8523be39a8e0a66bacbbdd6a72d069 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 31 Jul 2010 23:35:29 +0200 Subject: kconfig: save location of config symbols When we add a new config symbol save the file/line so we later can refer to their location. The information is saved as a property to a config symbol because we may have multiple definitions of the same symbol. This has the side-effect that a symbol always has at least one property. Signed-off-by: Sam Ravnborg Cc: Roman Zippel Signed-off-by: Michal Marek --- scripts/kconfig/expr.h | 1 + scripts/kconfig/menu.c | 2 ++ scripts/kconfig/symbol.c | 2 ++ 3 files changed, 5 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 75a31e4552f3..6ee2e4fb1481 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -132,6 +132,7 @@ enum prop_type { P_SELECT, /* select BAR */ P_RANGE, /* range 7..100 (for a symbol) */ P_ENV, /* value from environment variable */ + P_SYMBOL, /* where a symbol is defined */ }; struct property { diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 11799894f3bd..4fb590247f33 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -58,6 +58,8 @@ void menu_add_entry(struct symbol *sym) *last_entry_ptr = menu; last_entry_ptr = &menu->next; current_entry = menu; + if (sym) + menu_add_symbol(P_SYMBOL, sym, NULL); } void menu_end_entry(void) diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index c127fa342f1d..9f180ab7698d 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -961,6 +961,8 @@ const char *prop_get_type_name(enum prop_type type) return "select"; case P_RANGE: return "range"; + case P_SYMBOL: + return "symbol"; case P_UNKNOWN: break; } -- cgit v1.2.3 From d595cea62403db4e65b98a8bb96ff2b5205c7b82 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Sat, 31 Jul 2010 23:35:30 +0200 Subject: kconfig: print more info when we see a recursive dependency Consider following kconfig file: config TEST1 bool "test 1" depends on TEST2 config TEST2 bool "test 2" depends on TEST1 Previously kconfig would report: foo:6:error: found recursive dependency: TEST2 -> TEST1 -> TEST2 With the following patch kconfig reports: foo:5:error: recursive dependency detected! foo:5: symbol TEST2 depends on TEST1 foo:1: symbol TEST1 depends on TEST2 Note that we now report where the offending symbols are defined. This can be a great help for complex situations involving several files. Patch is originally from Roman Zippel with a few adjustments by Sam. Signed-off-by: Sam Ravnborg Cc: Roman Zippel Signed-off-by: Michal Marek --- scripts/kconfig/symbol.c | 142 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 127 insertions(+), 15 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 9f180ab7698d..bc1e1584e2da 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -783,6 +783,110 @@ struct symbol **sym_re_search(const char *pattern) return sym_arr; } +/* + * When we check for recursive dependencies we use a stack to save + * current state so we can print out relevant info to user. + * The entries are located on the call stack so no need to free memory. + * Note inser() remove() must always match to properly clear the stack. + */ +static struct dep_stack { + struct dep_stack *prev, *next; + struct symbol *sym; + struct property *prop; + struct expr *expr; +} *check_top; + +static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym) +{ + memset(stack, 0, sizeof(*stack)); + if (check_top) + check_top->next = stack; + stack->prev = check_top; + stack->sym = sym; + check_top = stack; +} + +static void dep_stack_remove(void) +{ + check_top = check_top->prev; + if (check_top) + check_top->next = NULL; +} + +/* + * Called when we have detected a recursive dependency. + * check_top point to the top of the stact so we use + * the ->prev pointer to locate the bottom of the stack. + */ +static void sym_check_print_recursive(struct symbol *last_sym) +{ + struct dep_stack *stack; + struct symbol *sym, *next_sym; + struct menu *menu = NULL; + struct property *prop; + struct dep_stack cv_stack; + + if (sym_is_choice_value(last_sym)) { + dep_stack_insert(&cv_stack, last_sym); + last_sym = prop_get_symbol(sym_get_choice_prop(last_sym)); + } + + for (stack = check_top; stack != NULL; stack = stack->prev) + if (stack->sym == last_sym) + break; + if (!stack) { + fprintf(stderr, "unexpected recursive dependency error\n"); + return; + } + + for (; stack; stack = stack->next) { + sym = stack->sym; + next_sym = stack->next ? stack->next->sym : last_sym; + prop = stack->prop; + + /* for choice values find the menu entry (used below) */ + if (sym_is_choice(sym) || sym_is_choice_value(sym)) { + for (prop = sym->prop; prop; prop = prop->next) { + menu = prop->menu; + if (prop->menu) + break; + } + } + if (stack->sym == last_sym) + fprintf(stderr, "%s:%d:error: recursive dependency detected!\n", + prop->file->name, prop->lineno); + if (stack->expr) { + fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", + prop->file->name, prop->lineno, + sym->name ? sym->name : "", + prop_get_type_name(prop->type), + next_sym->name ? next_sym->name : ""); + } else if (stack->prop) { + fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n", + prop->file->name, prop->lineno, + sym->name ? sym->name : "", + next_sym->name ? next_sym->name : ""); + } else if (sym_is_choice(sym)) { + fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", + menu->file->name, menu->lineno, + sym->name ? sym->name : "", + next_sym->name ? next_sym->name : ""); + } else if (sym_is_choice_value(sym)) { + fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n", + menu->file->name, menu->lineno, + sym->name ? sym->name : "", + next_sym->name ? next_sym->name : ""); + } else { + fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n", + prop->file->name, prop->lineno, + sym->name ? sym->name : "", + next_sym->name ? next_sym->name : ""); + } + } + + if (check_top == &cv_stack) + dep_stack_remove(); +} static struct symbol *sym_check_expr_deps(struct expr *e) { @@ -819,24 +923,33 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym) { struct symbol *sym2; struct property *prop; + struct dep_stack stack; + + dep_stack_insert(&stack, sym); sym2 = sym_check_expr_deps(sym->rev_dep.expr); if (sym2) - return sym2; + goto out; for (prop = sym->prop; prop; prop = prop->next) { if (prop->type == P_CHOICE || prop->type == P_SELECT) continue; + stack.prop = prop; sym2 = sym_check_expr_deps(prop->visible.expr); if (sym2) break; if (prop->type != P_DEFAULT || sym_is_choice(sym)) continue; + stack.expr = prop->expr; sym2 = sym_check_expr_deps(prop->expr); if (sym2) break; + stack.expr = NULL; } +out: + dep_stack_remove(); + return sym2; } @@ -845,6 +958,9 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice) struct symbol *sym, *sym2; struct property *prop; struct expr *e; + struct dep_stack stack; + + dep_stack_insert(&stack, choice); prop = sym_get_choice_prop(choice); expr_list_for_each_sym(prop->expr, e, sym) @@ -858,10 +974,8 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice) expr_list_for_each_sym(prop->expr, e, sym) { sym2 = sym_check_sym_deps(sym); - if (sym2) { - fprintf(stderr, " -> %s", sym->name); + if (sym2) break; - } } out: expr_list_for_each_sym(prop->expr, e, sym) @@ -871,6 +985,8 @@ out: prop_get_symbol(sym_get_choice_prop(sym2)) == choice) sym2 = choice; + dep_stack_remove(); + return sym2; } @@ -880,18 +996,20 @@ struct symbol *sym_check_deps(struct symbol *sym) struct property *prop; if (sym->flags & SYMBOL_CHECK) { - fprintf(stderr, "%s:%d:error: found recursive dependency: %s", - sym->prop->file->name, sym->prop->lineno, - sym->name ? sym->name : ""); + sym_check_print_recursive(sym); return sym; } if (sym->flags & SYMBOL_CHECKED) return NULL; if (sym_is_choice_value(sym)) { + struct dep_stack stack; + /* for choice groups start the check with main choice symbol */ + dep_stack_insert(&stack, sym); prop = sym_get_choice_prop(sym); sym2 = sym_check_deps(prop_get_symbol(prop)); + dep_stack_remove(); } else if (sym_is_choice(sym)) { sym2 = sym_check_choice_deps(sym); } else { @@ -900,14 +1018,8 @@ struct symbol *sym_check_deps(struct symbol *sym) sym->flags &= ~SYMBOL_CHECK; } - if (sym2) { - fprintf(stderr, " -> %s", sym->name ? sym->name : ""); - if (sym2 == sym) { - fprintf(stderr, "\n"); - zconfnerrs++; - sym2 = NULL; - } - } + if (sym2 && sym2 == sym) + sym2 = NULL; return sym2; } -- cgit v1.2.3 From 0748cb3e1fbd89c03a98c15e91ad65797981de77 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 31 Jul 2010 23:35:31 +0200 Subject: kconfig: add alldefconfig alldefconfig create a configuration with all values set to their default value (form the Kconfig files). This may be useful when we try to use more sensible default values and may also be used in combination with the minimal defconfigs. Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 13 +++++++------ scripts/kconfig/conf.c | 7 +++++++ 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 01bad1bd2550..72973591c0f1 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -85,9 +85,9 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h $(Q)rm -f arch/um/Kconfig.arch $(Q)rm -f $(obj)/config.pot -PHONY += allnoconfig allyesconfig allmodconfig randconfig +PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig -allnoconfig allyesconfig allmodconfig randconfig: $(obj)/conf +allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf $< --$@ $(Kconfig) PHONY += listnewconfig oldnoconfig defconfig @@ -117,11 +117,12 @@ help: @echo ' localmodconfig - Update current config disabling modules not loaded' @echo ' localyesconfig - Update current config converting local mods to core' @echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps' - @echo ' randconfig - New config with random answer to all options' - @echo ' defconfig - New config with default answer to all options' - @echo ' allmodconfig - New config selecting modules when possible' - @echo ' allyesconfig - New config where all options are accepted with yes' + @echo ' defconfig - New config with default from ARCH supplied defconfig' @echo ' allnoconfig - New config where all options are answered with no' + @echo ' allyesconfig - New config where all options are accepted with yes' + @echo ' allmodconfig - New config selecting modules when possible' + @echo ' alldefconfig - New config with all symbols set to default' + @echo ' randconfig - New config with random answer to all options' @echo ' listnewconfig - List new options' @echo ' oldnoconfig - Same as silentoldconfig but set new symbols to n (unset)' diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index ff5c914c0e5c..c8bd33cb3bf7 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -27,6 +27,7 @@ enum input_mode { allnoconfig, allyesconfig, allmodconfig, + alldefconfig, randconfig, defconfig, listnewconfig, @@ -446,6 +447,7 @@ static struct option long_opts[] = { {"allnoconfig", no_argument, NULL, allnoconfig}, {"allyesconfig", no_argument, NULL, allyesconfig}, {"allmodconfig", no_argument, NULL, allmodconfig}, + {"alldefconfig", no_argument, NULL, alldefconfig}, {"randconfig", no_argument, NULL, randconfig}, {"listnewconfig", no_argument, NULL, listnewconfig}, {"oldnoconfig", no_argument, NULL, oldnoconfig}, @@ -534,6 +536,7 @@ int main(int ac, char **av) case allnoconfig: case allyesconfig: case allmodconfig: + case alldefconfig: case randconfig: name = getenv("KCONFIG_ALLCONFIG"); if (name && !stat(name, &tmpstat)) { @@ -544,6 +547,7 @@ int main(int ac, char **av) case allnoconfig: name = "allno.config"; break; case allyesconfig: name = "allyes.config"; break; case allmodconfig: name = "allmod.config"; break; + case alldefconfig: name = "alldef.config"; break; case randconfig: name = "allrandom.config"; break; default: break; } @@ -578,6 +582,9 @@ int main(int ac, char **av) case allmodconfig: conf_set_all_new_symbols(def_mod); break; + case alldefconfig: + conf_set_all_new_symbols(def_default); + break; case randconfig: conf_set_all_new_symbols(def_random); break; -- cgit v1.2.3 From c252147de68cf58ba601278481e473dab432cee4 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 31 Jul 2010 23:35:32 +0200 Subject: kconfig: refactor code in symbol.c Move logic to determine default for a choice to a separate function. No functional changes. Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/kconfig/lkc.h | 1 + scripts/kconfig/symbol.c | 46 +++++++++++++++++++++++++++++++++------------- 2 files changed, 34 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index ce6549cdaccf..755b8190eb64 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -126,6 +126,7 @@ void sym_init(void); void sym_clear_all_valid(void); void sym_set_all_changed(void); void sym_set_changed(struct symbol *sym); +struct symbol *sym_choice_default(struct symbol *sym); struct symbol *sym_check_deps(struct symbol *sym); struct property *prop_alloc(enum prop_type type, struct symbol *sym); struct symbol *prop_get_symbol(struct property *prop); diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index bc1e1584e2da..0a013ab3ae27 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -226,22 +226,18 @@ static void sym_calc_visibility(struct symbol *sym) } } -static struct symbol *sym_calc_choice(struct symbol *sym) +/* + * Find the default symbol for a choice. + * First try the default values for the choice symbol + * Next locate the first visible choice value + * Return NULL if none was found + */ +struct symbol *sym_choice_default(struct symbol *sym) { struct symbol *def_sym; struct property *prop; struct expr *e; - /* first calculate all choice values' visibilities */ - prop = sym_get_choice_prop(sym); - expr_list_for_each_sym(prop->expr, e, def_sym) - sym_calc_visibility(def_sym); - - /* is the user choice visible? */ - def_sym = sym->def[S_DEF_USER].val; - if (def_sym && def_sym->visible != no) - return def_sym; - /* any of the defaults visible? */ for_all_defaults(sym, prop) { prop->visible.tri = expr_calc_value(prop->visible.expr); @@ -258,11 +254,35 @@ static struct symbol *sym_calc_choice(struct symbol *sym) if (def_sym->visible != no) return def_sym; - /* no choice? reset tristate value */ - sym->curr.tri = no; + /* failed to locate any defaults */ return NULL; } +static struct symbol *sym_calc_choice(struct symbol *sym) +{ + struct symbol *def_sym; + struct property *prop; + struct expr *e; + + /* first calculate all choice values' visibilities */ + prop = sym_get_choice_prop(sym); + expr_list_for_each_sym(prop->expr, e, def_sym) + sym_calc_visibility(def_sym); + + /* is the user choice visible? */ + def_sym = sym->def[S_DEF_USER].val; + if (def_sym && def_sym->visible != no) + return def_sym; + + def_sym = sym_choice_default(sym); + + if (def_sym == NULL) + /* no choice? reset tristate value */ + sym->curr.tri = no; + + return def_sym; +} + void sym_calc_value(struct symbol *sym) { struct symbol_value newval, oldval; -- cgit v1.2.3 From 49192f266ffa187bd7adaf5c2d881f85bd53e0ed Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 31 Jul 2010 23:35:33 +0200 Subject: kconfig: code refactoring in confdata.c Add a a few local functions to avoid some code duplication No functional changes. Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 137 +++++++++++++++++++++++---------------------- 1 file changed, 70 insertions(+), 67 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 8dce5862550d..583f6405f01d 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -399,15 +399,73 @@ int conf_read(const char *name) return 0; } +/* Write a S_STRING */ +static void conf_write_string(bool headerfile, const char *name, + const char *str, FILE *out) +{ + int l; + if (headerfile) + fprintf(out, "#define CONFIG_%s \"", name); + else + fprintf(out, "CONFIG_%s=\"", name); + + while (1) { + l = strcspn(str, "\"\\"); + if (l) { + fwrite(str, l, 1, out); + str += l; + } + if (!*str) + break; + fprintf(out, "\\%c", *str++); + } + fputs("\"\n", out); +} + +static void conf_write_symbol(struct symbol *sym, enum symbol_type type, + FILE *out, bool write_no) +{ + const char *str; + + switch (type) { + case S_BOOLEAN: + case S_TRISTATE: + switch (sym_get_tristate_value(sym)) { + case no: + if (write_no) + fprintf(out, "# CONFIG_%s is not set\n", sym->name); + break; + case mod: + fprintf(out, "CONFIG_%s=m\n", sym->name); + break; + case yes: + fprintf(out, "CONFIG_%s=y\n", sym->name); + break; + } + break; + case S_STRING: + conf_write_string(false, sym->name, sym_get_string_value(sym), out); + break; + case S_HEX: + case S_INT: + str = sym_get_string_value(sym); + fprintf(out, "CONFIG_%s=%s\n", sym->name, str); + break; + case S_OTHER: + case S_UNKNOWN: + break; + } +} + int conf_write(const char *name) { FILE *out; struct symbol *sym; struct menu *menu; const char *basename; - char dirname[128], tmpname[128], newname[128]; - int type, l; const char *str; + char dirname[128], tmpname[128], newname[128]; + enum symbol_type type; time_t now; int use_timestamp = 1; char *env; @@ -487,50 +545,11 @@ int conf_write(const char *name) if (modules_sym->curr.tri == no) type = S_BOOLEAN; } - switch (type) { - case S_BOOLEAN: - case S_TRISTATE: - switch (sym_get_tristate_value(sym)) { - case no: - fprintf(out, "# CONFIG_%s is not set\n", sym->name); - break; - case mod: - fprintf(out, "CONFIG_%s=m\n", sym->name); - break; - case yes: - fprintf(out, "CONFIG_%s=y\n", sym->name); - break; - } - break; - case S_STRING: - str = sym_get_string_value(sym); - fprintf(out, "CONFIG_%s=\"", sym->name); - while (1) { - l = strcspn(str, "\"\\"); - if (l) { - fwrite(str, l, 1, out); - str += l; - } - if (!*str) - break; - fprintf(out, "\\%c", *str++); - } - fputs("\"\n", out); - break; - case S_HEX: - str = sym_get_string_value(sym); - if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { - fprintf(out, "CONFIG_%s=%s\n", sym->name, str); - break; - } - case S_INT: - str = sym_get_string_value(sym); - fprintf(out, "CONFIG_%s=%s\n", sym->name, str); - break; - } + /* Write config symbol to file */ + conf_write_symbol(sym, type, out, true); } - next: +next: if (menu->list) { menu = menu->list; continue; @@ -682,7 +701,7 @@ int conf_write_autoconf(void) const char *name; FILE *out, *tristate, *out_h; time_t now; - int i, l; + int i; sym_clear_all_valid(); @@ -732,6 +751,11 @@ int conf_write_autoconf(void) sym_calc_value(sym); if (!(sym->flags & SYMBOL_WRITE) || !sym->name) continue; + + /* write symbol to config file */ + conf_write_symbol(sym, sym->type, out, false); + + /* update autoconf and tristate files */ switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: @@ -739,12 +763,10 @@ int conf_write_autoconf(void) case no: break; case mod: - fprintf(out, "CONFIG_%s=m\n", sym->name); fprintf(tristate, "CONFIG_%s=M\n", sym->name); fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); break; case yes: - fprintf(out, "CONFIG_%s=y\n", sym->name); if (sym->type == S_TRISTATE) fprintf(tristate, "CONFIG_%s=Y\n", sym->name); @@ -753,35 +775,16 @@ int conf_write_autoconf(void) } break; case S_STRING: - str = sym_get_string_value(sym); - fprintf(out, "CONFIG_%s=\"", sym->name); - fprintf(out_h, "#define CONFIG_%s \"", sym->name); - while (1) { - l = strcspn(str, "\"\\"); - if (l) { - fwrite(str, l, 1, out); - fwrite(str, l, 1, out_h); - str += l; - } - if (!*str) - break; - fprintf(out, "\\%c", *str); - fprintf(out_h, "\\%c", *str); - str++; - } - fputs("\"\n", out); - fputs("\"\n", out_h); + conf_write_string(true, sym->name, sym_get_string_value(sym), out_h); break; case S_HEX: str = sym_get_string_value(sym); if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { - fprintf(out, "CONFIG_%s=%s\n", sym->name, str); fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); break; } case S_INT: str = sym_get_string_value(sym); - fprintf(out, "CONFIG_%s=%s\n", sym->name, str); fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); break; default: -- cgit v1.2.3 From 7cf3d73b4360e91b14326632ab1aeda4cb26308d Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 31 Jul 2010 23:35:34 +0200 Subject: kconfig: add savedefconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit savedefconfig will save a minimal config to a file named "defconfig". The config symbols are saved in the same order as they appear in the menu structure so it should be possible to map them to the relevant menus if desired. The implementation was tested against several minimal configs for arm which was created using brute-force. There was one regression related to default numbers which had their valid range further limited by another symbol. Sample: config FOO int "foo" default 4 config BAR int "bar" range 0 FOO If FOO is set to 3 then BAR cannot take a value higher than 3. But the current implementation will set BAR equal to 4. This is seldomly used and the final configuration is OK, and the fix was non-trivial. So it was documented in the code and left as is. Signed-off-by: Sam Ravnborg Acked-by: Uwe Kleine-König Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 6 +++- scripts/kconfig/conf.c | 14 +++++++++ scripts/kconfig/confdata.c | 76 +++++++++++++++++++++++++++++++++++++++++++++ scripts/kconfig/lkc.h | 1 + scripts/kconfig/lkc_proto.h | 1 + scripts/kconfig/symbol.c | 74 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 171 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 72973591c0f1..c0e459e2b014 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -90,11 +90,14 @@ PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf $< --$@ $(Kconfig) -PHONY += listnewconfig oldnoconfig defconfig +PHONY += listnewconfig oldnoconfig savedefconfig defconfig listnewconfig oldnoconfig: $(obj)/conf $< --$@ $(Kconfig) +savedefconfig: $(obj)/conf + $< --$@=defconfig $(Kconfig) + defconfig: $(obj)/conf ifeq ($(KBUILD_DEFCONFIG),) $< --defconfig $(Kconfig) @@ -118,6 +121,7 @@ help: @echo ' localyesconfig - Update current config converting local mods to core' @echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps' @echo ' defconfig - New config with default from ARCH supplied defconfig' + @echo ' savedefconfig - Save current config as ./defconfig (minimal config)' @echo ' allnoconfig - New config where all options are answered with no' @echo ' allyesconfig - New config where all options are accepted with yes' @echo ' allmodconfig - New config selecting modules when possible' diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index c8bd33cb3bf7..010600ef58c0 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -30,6 +30,7 @@ enum input_mode { alldefconfig, randconfig, defconfig, + savedefconfig, listnewconfig, oldnoconfig, } input_mode = oldaskconfig; @@ -444,6 +445,7 @@ static struct option long_opts[] = { {"oldconfig", no_argument, NULL, oldconfig}, {"silentoldconfig", no_argument, NULL, silentoldconfig}, {"defconfig", optional_argument, NULL, defconfig}, + {"savedefconfig", required_argument, NULL, savedefconfig}, {"allnoconfig", no_argument, NULL, allnoconfig}, {"allyesconfig", no_argument, NULL, allyesconfig}, {"allmodconfig", no_argument, NULL, allmodconfig}, @@ -471,6 +473,7 @@ int main(int ac, char **av) sync_kconfig = 1; break; case defconfig: + case savedefconfig: defconfig_file = optarg; break; case randconfig: @@ -526,6 +529,9 @@ int main(int ac, char **av) exit(1); } break; + case savedefconfig: + conf_read(NULL); + break; case silentoldconfig: case oldaskconfig: case oldconfig: @@ -591,6 +597,8 @@ int main(int ac, char **av) case defconfig: conf_set_all_new_symbols(def_default); break; + case savedefconfig: + break; case oldconfig: case oldaskconfig: rootEntry = &rootmenu; @@ -622,6 +630,12 @@ int main(int ac, char **av) fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n")); return 1; } + } else if (input_mode == savedefconfig) { + if (conf_write_defconfig(defconfig_file)) { + fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"), + defconfig_file); + return 1; + } } else if (input_mode != listnewconfig) { if (conf_write(NULL)) { fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 583f6405f01d..f81f263b64f2 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -457,6 +457,82 @@ static void conf_write_symbol(struct symbol *sym, enum symbol_type type, } } +/* + * Write out a minimal config. + * All values that has default values are skipped as this is redundant. + */ +int conf_write_defconfig(const char *filename) +{ + struct symbol *sym; + struct menu *menu; + FILE *out; + + out = fopen(filename, "w"); + if (!out) + return 1; + + sym_clear_all_valid(); + + /* Traverse all menus to find all relevant symbols */ + menu = rootmenu.list; + + while (menu != NULL) + { + sym = menu->sym; + if (sym == NULL) { + if (!menu_is_visible(menu)) + goto next_menu; + } else if (!sym_is_choice(sym)) { + sym_calc_value(sym); + if (!(sym->flags & SYMBOL_WRITE)) + goto next_menu; + sym->flags &= ~SYMBOL_WRITE; + /* If we cannot change the symbol - skip */ + if (!sym_is_changable(sym)) + goto next_menu; + /* If symbol equals to default value - skip */ + if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0) + goto next_menu; + + /* + * If symbol is a choice value and equals to the + * default for a choice - skip. + * But only if value equal to "y". + */ + if (sym_is_choice_value(sym)) { + struct symbol *cs; + struct symbol *ds; + + cs = prop_get_symbol(sym_get_choice_prop(sym)); + ds = sym_choice_default(cs); + if (sym == ds) { + if ((sym->type == S_BOOLEAN || + sym->type == S_TRISTATE) && + sym_get_tristate_value(sym) == yes) + goto next_menu; + } + } + conf_write_symbol(sym, sym->type, out, true); + } +next_menu: + if (menu->list != NULL) { + menu = menu->list; + } + else if (menu->next != NULL) { + menu = menu->next; + } else { + while ((menu = menu->parent)) { + if (menu->next != NULL) { + menu = menu->next; + break; + } + } + } + } + fclose(out); + return 0; +} + int conf_write(const char *name) { FILE *out; diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 755b8190eb64..76db065ed72c 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -127,6 +127,7 @@ void sym_clear_all_valid(void); void sym_set_all_changed(void); void sym_set_changed(struct symbol *sym); struct symbol *sym_choice_default(struct symbol *sym); +const char *sym_get_string_default(struct symbol *sym); struct symbol *sym_check_deps(struct symbol *sym); struct property *prop_alloc(enum prop_type type, struct symbol *sym); struct symbol *prop_get_symbol(struct property *prop); diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 7cadcad8233b..9a948c9ce44e 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -3,6 +3,7 @@ P(conf_parse,void,(const char *name)); P(conf_read,int,(const char *name)); P(conf_read_simple,int,(const char *name, int)); +P(conf_write_defconfig,int,(const char *name)); P(conf_write,int,(const char *name)); P(conf_write_autoconf,int,(void)); P(conf_get_changed,bool,(void)); diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 0a013ab3ae27..e95718fea355 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -661,6 +661,80 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) return true; } +/* + * Find the default value associated to a symbol. + * For tristate symbol handle the modules=n case + * in which case "m" becomes "y". + * If the symbol does not have any default then fallback + * to the fixed default values. + */ +const char *sym_get_string_default(struct symbol *sym) +{ + struct property *prop; + struct symbol *ds; + const char *str; + tristate val; + + sym_calc_visibility(sym); + sym_calc_value(modules_sym); + val = symbol_no.curr.tri; + str = symbol_empty.curr.val; + + /* If symbol has a default value look it up */ + prop = sym_get_default_prop(sym); + if (prop != NULL) { + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + /* The visibility imay limit the value from yes => mod */ + val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri); + break; + default: + /* + * The following fails to handle the situation + * where a default value is further limited by + * the valid range. + */ + ds = prop_get_symbol(prop); + if (ds != NULL) { + sym_calc_value(ds); + str = (const char *)ds->curr.val; + } + } + } + + /* Handle select statements */ + val = EXPR_OR(val, sym->rev_dep.tri); + + /* transpose mod to yes if modules are not enabled */ + if (val == mod) + if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no) + val = yes; + + /* transpose mod to yes if type is bool */ + if (sym->type == S_BOOLEAN && val == mod) + val = yes; + + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + switch (val) { + case no: return "n"; + case mod: return "m"; + case yes: return "y"; + } + case S_INT: + case S_HEX: + return str; + case S_STRING: + return str; + case S_OTHER: + case S_UNKNOWN: + break; + } + return ""; +} + const char *sym_get_string_value(struct symbol *sym) { tristate val; -- cgit v1.2.3 From 6588169d516560f68672e2928680b71c647b7806 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Wed, 28 Jul 2010 17:33:09 +0200 Subject: kbuild: allow assignment to {A,C,LD}FLAGS_MODULE on the command line It is now possible to assign options to AS, CC and LD on the command line - which is only used when building modules. {A,C,LD}FLAGS_MODULE was all used both in the top-level Makefile in the arch makefiles, thus users had no way to specify additional options to AS, CC, LD when building modules without overriding the original value. Introduce a new set of variables KBUILD_{A,C,LD}FLAGS_MODULE that is used by arch specific files and free up {A,C,LD}FLAGS_MODULE so they can be assigned on the command line. All arch Makefiles that used the old variables has been updated. Note: Previously we had a MODFLAGS variable for both AS and CC. But in favour of consistency this was dropped. So in some cases arch Makefile has one assignmnet replaced by two assignmnets. Note2: MODFLAGS was not documented and is dropped without any notice. I do not expect much/any breakage from this. Signed-off-by: Sam Ravnborg Cc: Denys Vlasenko Cc: Haavard Skinnemoen Cc: Mike Frysinger Cc: Tony Luck Cc: Geert Uytterhoeven Cc: Ralf Baechle Cc: Benjamin Herrenschmidt Cc: Martin Schwidefsky Cc: Chen Liqin Acked-by: Mike Frysinger [blackfin] Acked-by: Haavard Skinnemoen [avr32] Signed-off-by: Michal Marek --- scripts/Makefile.build | 9 ++++++--- scripts/Makefile.modpost | 7 ++++--- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 390aae4bb222..5e7c40e16545 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -115,7 +115,10 @@ endif # --------------------------------------------------------------------------- # Default is built-in, unless we know otherwise -modkern_cflags = $(if $(part-of-module), $(CFLAGS_MODULE), $(CFLAGS_KERNEL)) +modkern_cflags = \ + $(if $(part-of-module), \ + $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \ + $(CFLAGS_KERNEL)) quiet_modtag := $(empty) $(empty) $(real-objs-m) : part-of-module := y @@ -250,8 +253,8 @@ $(obj)/%.lst: $(src)/%.c FORCE modkern_aflags := $(AFLAGS_KERNEL) -$(real-objs-m) : modkern_aflags := $(AFLAGS_MODULE) -$(real-objs-m:.o=.s): modkern_aflags := $(AFLAGS_MODULE) +$(real-objs-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) +$(real-objs-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) quiet_cmd_as_s_S = CPP $(quiet_modtag) $@ cmd_as_s_S = $(CPP) $(a_flags) -o $@ $< diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 8f14c81abbc7..3e3f02409bbd 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -107,7 +107,7 @@ $(modules:.ko=.mod.c): __modpost ; modname = $(notdir $(@:.mod.o=)) quiet_cmd_cc_o_c = CC $@ - cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE) \ + cmd_cc_o_c = $(CC) $(c_flags) $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE) \ -c -o $@ $< $(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE @@ -117,8 +117,9 @@ targets += $(modules:.ko=.mod.o) # Step 6), final link of the modules quiet_cmd_ld_ko_o = LD [M] $@ - cmd_ld_ko_o = $(LD) -r $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \ - $(filter-out FORCE,$^) + cmd_ld_ko_o = $(LD) -r $(LDFLAGS) \ + $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ + -o $@ $(filter-out FORCE,$^) $(modules): %.ko :%.o %.mod.o FORCE $(call if_changed,ld_ko_o) -- cgit v1.2.3 From 80c00ba942ee39c9a95c06959223560400bbb86e Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Wed, 28 Jul 2010 19:11:27 +0200 Subject: kbuild: allow assignment to {A,C}FLAGS_KERNEL on the command line It is now possible to assign options to AS and CC on the command line - which is only used for built-in code. {A,C}FLAGS_KERNEL was used both in the top-level Makefile in the arch makefiles, thus users had no way to specify additional options to AS, CC without overriding the original value. Introduce a new set of variables KBUILD_{A,C}FLAGS_KERNEL that is used by arch specific files and free up {A,C}FLAGS_KERNEL so they can be assigned on the command line. All arch Makefiles that used the old variables has been updated. Signed-off-by: Sam Ravnborg Cc: Tony Luck Cc: Hirokazu Takata Signed-off-by: Michal Marek --- scripts/Makefile.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 5e7c40e16545..a1a5cf95a68d 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -118,7 +118,7 @@ endif modkern_cflags = \ $(if $(part-of-module), \ $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \ - $(CFLAGS_KERNEL)) + $(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL)) quiet_modtag := $(empty) $(empty) $(real-objs-m) : part-of-module := y @@ -251,7 +251,7 @@ $(obj)/%.lst: $(src)/%.c FORCE # Compile assembler sources (.S) # --------------------------------------------------------------------------- -modkern_aflags := $(AFLAGS_KERNEL) +modkern_aflags := $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL) $(real-objs-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) $(real-objs-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) -- cgit v1.2.3 From 4696e2958b345189afebcb52e365d16ca6e403ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 30 Jul 2010 20:43:20 +0200 Subject: trivial: fix a typo in a filename MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Michal Marek --- scripts/Makefile.modpost | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 3e3f02409bbd..7d22056582c1 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -30,7 +30,7 @@ # - See include/linux/module.h for more details # Step 4 is solely used to allow module versioning in external modules, -# where the CRC of each module is retrieved from the Module.symers file. +# where the CRC of each module is retrieved from the Module.symvers file. # KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined # symbols in the final module linking stage -- cgit v1.2.3 From 1ce53adf13a54375d2a5c7cdbe341b2558389615 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 29 Jul 2010 01:47:53 +0200 Subject: modpost: support objects with more than 64k sections This patch makes modpost able to process object files with more than 64k sections. Needed for huge kernel builds (allyesconfig, for example) with -ffunction-sections. 64k sections handling is covered, for example, by this document: "IA-64 gABI Proposal 74: Section Indexes" http://www.codesourcery.com/public/cxx-abi/abi/prop-74-sindex.html Signed-off-by: Denys Vlasenko Signed-off-by: Anders Kaseorg Acked-by: Sam Ravnborg Cc: Rusty Russell Cc: Andi Kleen Signed-off-by: Michal Marek --- scripts/mod/file2alias.c | 6 +-- scripts/mod/modpost.c | 102 +++++++++++++++++++++++++++++++++++------------ scripts/mod/modpost.h | 43 ++++++++++++++++++++ 3 files changed, 122 insertions(+), 29 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 220213e603db..33f436328f9a 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -839,16 +839,16 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, char *zeros = NULL; /* We're looking for a section relative symbol */ - if (!sym->st_shndx || sym->st_shndx >= info->hdr->e_shnum) + if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections) return; /* Handle all-NULL symbols allocated into .bss */ - if (info->sechdrs[sym->st_shndx].sh_type & SHT_NOBITS) { + if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) { zeros = calloc(1, sym->st_size); symval = zeros; } else { symval = (void *)info->hdr - + info->sechdrs[sym->st_shndx].sh_offset + + info->sechdrs[get_secindex(info, sym)].sh_offset + sym->st_value; } diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 3318692e4e76..7249ab44f44c 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -253,7 +253,7 @@ static enum export export_no(const char *s) return export_unknown; } -static enum export export_from_sec(struct elf_info *elf, Elf_Section sec) +static enum export export_from_sec(struct elf_info *elf, unsigned int sec) { if (sec == elf->export_sec) return export_plain; @@ -373,6 +373,8 @@ static int parse_elf(struct elf_info *info, const char *filename) Elf_Ehdr *hdr; Elf_Shdr *sechdrs; Elf_Sym *sym; + const char *secstrings; + unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U; hdr = grab_file(filename, &info->size); if (!hdr) { @@ -417,8 +419,27 @@ static int parse_elf(struct elf_info *info, const char *filename) return 0; } + if (hdr->e_shnum == 0) { + /* + * There are more than 64k sections, + * read count from .sh_size. + * note: it doesn't need shndx2secindex() + */ + info->num_sections = TO_NATIVE(sechdrs[0].sh_size); + } + else { + info->num_sections = hdr->e_shnum; + } + if (hdr->e_shstrndx == SHN_XINDEX) { + info->secindex_strings = + shndx2secindex(TO_NATIVE(sechdrs[0].sh_link)); + } + else { + info->secindex_strings = hdr->e_shstrndx; + } + /* Fix endianness in section headers */ - for (i = 0; i < hdr->e_shnum; i++) { + for (i = 0; i < info->num_sections; i++) { sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type); sechdrs[i].sh_flags = TO_NATIVE(sechdrs[i].sh_flags); @@ -431,9 +452,8 @@ static int parse_elf(struct elf_info *info, const char *filename) sechdrs[i].sh_entsize = TO_NATIVE(sechdrs[i].sh_entsize); } /* Find symbol table. */ - for (i = 1; i < hdr->e_shnum; i++) { - const char *secstrings - = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; + secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset; + for (i = 1; i < info->num_sections; i++) { const char *secname; int nobits = sechdrs[i].sh_type == SHT_NOBITS; @@ -461,14 +481,26 @@ static int parse_elf(struct elf_info *info, const char *filename) else if (strcmp(secname, "__ksymtab_gpl_future") == 0) info->export_gpl_future_sec = i; - if (sechdrs[i].sh_type != SHT_SYMTAB) - continue; + if (sechdrs[i].sh_type == SHT_SYMTAB) { + unsigned int sh_link_idx; + symtab_idx = i; + info->symtab_start = (void *)hdr + + sechdrs[i].sh_offset; + info->symtab_stop = (void *)hdr + + sechdrs[i].sh_offset + sechdrs[i].sh_size; + sh_link_idx = shndx2secindex(sechdrs[i].sh_link); + info->strtab = (void *)hdr + + sechdrs[sh_link_idx].sh_offset; + } - info->symtab_start = (void *)hdr + sechdrs[i].sh_offset; - info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset - + sechdrs[i].sh_size; - info->strtab = (void *)hdr + - sechdrs[sechdrs[i].sh_link].sh_offset; + /* 32bit section no. table? ("more than 64k sections") */ + if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) { + symtab_shndx_idx = i; + info->symtab_shndx_start = (void *)hdr + + sechdrs[i].sh_offset; + info->symtab_shndx_stop = (void *)hdr + + sechdrs[i].sh_offset + sechdrs[i].sh_size; + } } if (!info->symtab_start) fatal("%s has no symtab?\n", filename); @@ -480,6 +512,21 @@ static int parse_elf(struct elf_info *info, const char *filename) sym->st_value = TO_NATIVE(sym->st_value); sym->st_size = TO_NATIVE(sym->st_size); } + + if (symtab_shndx_idx != ~0U) { + Elf32_Word *p; + if (symtab_idx != + shndx2secindex(sechdrs[symtab_shndx_idx].sh_link)) + fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n", + filename, + shndx2secindex(sechdrs[symtab_shndx_idx].sh_link), + symtab_idx); + /* Fix endianness */ + for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop; + p++) + *p = TO_NATIVE(*p); + } + return 1; } @@ -514,7 +561,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, Elf_Sym *sym, const char *symname) { unsigned int crc; - enum export export = export_from_sec(info, sym->st_shndx); + enum export export = export_from_sec(info, get_secindex(info, sym)); switch (sym->st_shndx) { case SHN_COMMON: @@ -656,19 +703,19 @@ static const char *sym_name(struct elf_info *elf, Elf_Sym *sym) return "(unknown)"; } -static const char *sec_name(struct elf_info *elf, int shndx) +static const char *sec_name(struct elf_info *elf, int secindex) { Elf_Shdr *sechdrs = elf->sechdrs; return (void *)elf->hdr + - elf->sechdrs[elf->hdr->e_shstrndx].sh_offset + - sechdrs[shndx].sh_name; + elf->sechdrs[elf->secindex_strings].sh_offset + + sechdrs[secindex].sh_name; } static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr) { return (void *)elf->hdr + - elf->sechdrs[elf->hdr->e_shstrndx].sh_offset + - sechdr->sh_name; + elf->sechdrs[elf->secindex_strings].sh_offset + + sechdr->sh_name; } /* if sym is empty or point to a string @@ -1047,11 +1094,14 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr, Elf_Sym *near = NULL; Elf64_Sword distance = 20; Elf64_Sword d; + unsigned int relsym_secindex; if (relsym->st_name != 0) return relsym; + + relsym_secindex = get_secindex(elf, relsym); for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { - if (sym->st_shndx != relsym->st_shndx) + if (get_secindex(elf, sym) != relsym_secindex) continue; if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) continue; @@ -1113,9 +1163,9 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr, for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { const char *symsec; - if (sym->st_shndx >= SHN_LORESERVE) + if (is_shndx_special(sym->st_shndx)) continue; - symsec = sec_name(elf, sym->st_shndx); + symsec = sec_name(elf, get_secindex(elf, sym)); if (strcmp(symsec, sec) != 0) continue; if (!is_valid_name(elf, sym)) @@ -1311,7 +1361,7 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf, const char *tosec; const struct sectioncheck *mismatch; - tosec = sec_name(elf, sym->st_shndx); + tosec = sec_name(elf, get_secindex(elf, sym)); mismatch = section_mismatch(fromsec, tosec); if (mismatch) { Elf_Sym *to; @@ -1339,7 +1389,7 @@ static unsigned int *reloc_location(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) { Elf_Shdr *sechdrs = elf->sechdrs; - int section = sechdr->sh_info; + int section = shndx2secindex(sechdr->sh_info); return (void *)elf->hdr + sechdrs[section].sh_offset + (r->r_offset - sechdrs[section].sh_addr); @@ -1447,7 +1497,7 @@ static void section_rela(const char *modname, struct elf_info *elf, r.r_addend = TO_NATIVE(rela->r_addend); sym = elf->symtab_start + r_sym; /* Skip special sections */ - if (sym->st_shndx >= SHN_LORESERVE) + if (is_shndx_special(sym->st_shndx)) continue; check_section_mismatch(modname, elf, &r, sym, fromsec); } @@ -1505,7 +1555,7 @@ static void section_rel(const char *modname, struct elf_info *elf, } sym = elf->symtab_start + r_sym; /* Skip special sections */ - if (sym->st_shndx >= SHN_LORESERVE) + if (is_shndx_special(sym->st_shndx)) continue; check_section_mismatch(modname, elf, &r, sym, fromsec); } @@ -1530,7 +1580,7 @@ static void check_sec_ref(struct module *mod, const char *modname, Elf_Shdr *sechdrs = elf->sechdrs; /* Walk through all sections */ - for (i = 0; i < elf->hdr->e_shnum; i++) { + for (i = 0; i < elf->num_sections; i++) { check_section(modname, elf, &elf->sechdrs[i]); /* We want to process only relocation sections and not .init */ if (sechdrs[i].sh_type == SHT_RELA) diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index be987a44f250..0388cfccac8d 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -129,8 +129,51 @@ struct elf_info { const char *strtab; char *modinfo; unsigned int modinfo_len; + + /* support for 32bit section numbers */ + + unsigned int num_sections; /* max_secindex + 1 */ + unsigned int secindex_strings; + /* if Nth symbol table entry has .st_shndx = SHN_XINDEX, + * take shndx from symtab_shndx_start[N] instead */ + Elf32_Word *symtab_shndx_start; + Elf32_Word *symtab_shndx_stop; }; +static inline int is_shndx_special(unsigned int i) +{ + return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE; +} + +/* shndx is in [0..SHN_LORESERVE) U (SHN_HIRESERVE, 0xfffffff], thus: + * shndx == 0 <=> sechdrs[0] + * ...... + * shndx == SHN_LORESERVE-1 <=> sechdrs[SHN_LORESERVE-1] + * shndx == SHN_HIRESERVE+1 <=> sechdrs[SHN_LORESERVE] + * shndx == SHN_HIRESERVE+2 <=> sechdrs[SHN_LORESERVE+1] + * ...... + * fyi: sym->st_shndx is uint16, SHN_LORESERVE = ff00, SHN_HIRESERVE = ffff, + * so basically we map 0000..feff -> 0000..feff + * ff00..ffff -> (you are a bad boy, dont do it) + * 10000..xxxx -> ff00..(xxxx-0x100) + */ +static inline unsigned int shndx2secindex(unsigned int i) +{ + if (i <= SHN_HIRESERVE) + return i; + return i - (SHN_HIRESERVE + 1 - SHN_LORESERVE); +} + +/* Accessor for sym->st_shndx, hides ugliness of "64k sections" */ +static inline unsigned int get_secindex(const struct elf_info *info, + const Elf_Sym *sym) +{ + if (sym->st_shndx != SHN_XINDEX) + return sym->st_shndx; + return shndx2secindex(info->symtab_shndx_start[sym - + info->symtab_start]); +} + /* file2alias.c */ extern unsigned int cross_build; void handle_moddevtable(struct module *mod, struct elf_info *info, -- cgit v1.2.3 From 14828349719aa09845843477df8bad60792d18f3 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 6 Aug 2010 07:13:54 +0200 Subject: kconfig: fix make oldconfig Linus wrote: This seems to make "make oldconfig" a _lot_ more verbose than it used to be. In a very annoying way. I just did a quick git bisect. It's introduced by commit 4062f1a4c030 ("kconfig: use long options in conf") by Sam Ravnborg. Apparently that thing is totally buggy, and doesn't just change the option names, but actively breaks them. The old behaviour (from years ago) were reintroduced by accident. Fix this so we are back to the version that are silent if there is nothing to ask about. Reported-by: Linus Torvalds Signed-off-by: Sam Ravnborg Reviewed-by: Michal Marek Signed-off-by: Linus Torvalds --- scripts/kconfig/conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 010600ef58c0..274f2716b03e 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -599,12 +599,12 @@ int main(int ac, char **av) break; case savedefconfig: break; - case oldconfig: case oldaskconfig: rootEntry = &rootmenu; conf(&rootmenu); input_mode = silentoldconfig; /* fall through */ + case oldconfig: case listnewconfig: case oldnoconfig: case silentoldconfig: -- cgit v1.2.3 From 37ed19d5cce35a40d3913cf9aa208ce9f60db3d7 Mon Sep 17 00:00:00 2001 From: Alexey Fomenko Date: Mon, 9 Aug 2010 17:20:24 -0700 Subject: scripts/mod/modpost.c: fix memory leak sec2annotation returns malloc'ed buffer directly to printf as an argument. Free this buffer after printing. Signed-off-by: Alexey Fomenko Cc: Trevor Keith Cc: Rusty Russell Cc: Michal Marek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/mod/modpost.c | 54 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 14 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c827309c29cf..1ce655dde99e 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1245,6 +1245,8 @@ static void report_sec_mismatch(const char *modname, { const char *from, *from_p; const char *to, *to_p; + char *prl_from; + char *prl_to; switch (from_is_func) { case 0: from = "variable"; from_p = ""; break; @@ -1268,16 +1270,21 @@ static void report_sec_mismatch(const char *modname, switch (mismatch->mismatch) { case TEXT_TO_ANY_INIT: + prl_from = sec2annotation(fromsec); + prl_to = sec2annotation(tosec); fprintf(stderr, "The function %s%s() references\n" "the %s %s%s%s.\n" "This is often because %s lacks a %s\n" "annotation or the annotation of %s is wrong.\n", - sec2annotation(fromsec), fromsym, - to, sec2annotation(tosec), tosym, to_p, - fromsym, sec2annotation(tosec), tosym); + prl_from, fromsym, + to, prl_to, tosym, to_p, + fromsym, prl_to, tosym); + free(prl_from); + free(prl_to); break; case DATA_TO_ANY_INIT: { + prl_to = sec2annotation(tosec); const char *const *s = mismatch->symbol_white_list; fprintf(stderr, "The variable %s references\n" @@ -1285,20 +1292,24 @@ static void report_sec_mismatch(const char *modname, "If the reference is valid then annotate the\n" "variable with __init* or __refdata (see linux/init.h) " "or name the variable:\n", - fromsym, to, sec2annotation(tosec), tosym, to_p); + fromsym, to, prl_to, tosym, to_p); while (*s) fprintf(stderr, "%s, ", *s++); fprintf(stderr, "\n"); + free(prl_to); break; } case TEXT_TO_ANY_EXIT: + prl_to = sec2annotation(tosec); fprintf(stderr, "The function %s() references a %s in an exit section.\n" "Often the %s %s%s has valid usage outside the exit section\n" "and the fix is to remove the %sannotation of %s.\n", - fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym); + fromsym, to, to, tosym, to_p, prl_to, tosym); + free(prl_to); break; case DATA_TO_ANY_EXIT: { + prl_to = sec2annotation(tosec); const char *const *s = mismatch->symbol_white_list; fprintf(stderr, "The variable %s references\n" @@ -1306,24 +1317,31 @@ static void report_sec_mismatch(const char *modname, "If the reference is valid then annotate the\n" "variable with __exit* (see linux/init.h) or " "name the variable:\n", - fromsym, to, sec2annotation(tosec), tosym, to_p); + fromsym, to, prl_to, tosym, to_p); while (*s) fprintf(stderr, "%s, ", *s++); fprintf(stderr, "\n"); + free(prl_to); break; } case XXXINIT_TO_SOME_INIT: case XXXEXIT_TO_SOME_EXIT: + prl_from = sec2annotation(fromsec); + prl_to = sec2annotation(tosec); fprintf(stderr, "The %s %s%s%s references\n" "a %s %s%s%s.\n" "If %s is only used by %s then\n" "annotate %s with a matching annotation.\n", - from, sec2annotation(fromsec), fromsym, from_p, - to, sec2annotation(tosec), tosym, to_p, + from, prl_from, fromsym, from_p, + to, prl_to, tosym, to_p, tosym, fromsym, tosym); + free(prl_from); + free(prl_to); break; case ANY_INIT_TO_ANY_EXIT: + prl_from = sec2annotation(fromsec); + prl_to = sec2annotation(tosec); fprintf(stderr, "The %s %s%s%s references\n" "a %s %s%s%s.\n" @@ -1332,11 +1350,15 @@ static void report_sec_mismatch(const char *modname, "uses functionality in the exit path.\n" "The fix is often to remove the %sannotation of\n" "%s%s so it may be used outside an exit section.\n", - from, sec2annotation(fromsec), fromsym, from_p, - to, sec2annotation(tosec), tosym, to_p, + from, prl_from, fromsym, from_p, + to, prl_to, tosym, to_p, sec2annotation(tosec), tosym, to_p); + free(prl_from); + free(prl_to); break; case ANY_EXIT_TO_ANY_INIT: + prl_from = sec2annotation(fromsec); + prl_to = sec2annotation(tosec); fprintf(stderr, "The %s %s%s%s references\n" "a %s %s%s%s.\n" @@ -1345,16 +1367,20 @@ static void report_sec_mismatch(const char *modname, "uses functionality in the init path.\n" "The fix is often to remove the %sannotation of\n" "%s%s so it may be used outside an init section.\n", - from, sec2annotation(fromsec), fromsym, from_p, - to, sec2annotation(tosec), tosym, to_p, - sec2annotation(tosec), tosym, to_p); + from, prl_from, fromsym, from_p, + to, prl_to, tosym, to_p, + prl_to, tosym, to_p); + free(prl_from); + free(prl_to); break; case EXPORT_TO_INIT_EXIT: + prl_to = sec2annotation(tosec); fprintf(stderr, "The symbol %s is exported and annotated %s\n" "Fix this by removing the %sannotation of %s " "or drop the export.\n", - tosym, sec2annotation(tosec), sec2annotation(tosec), tosym); + tosym, prl_to, prl_to, tosym); + free(prl_to); break; } fprintf(stderr, "\n"); -- cgit v1.2.3 From 7840a94cd12559d8aee6382fafb85fbc9eb3a2c2 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 9 Aug 2010 17:20:57 -0700 Subject: checkpatch: refactor 'allowed asm includes' and add memory.h Change the check suggesting replacement of asm-includes with linux-includes. Exceptions to this rule are easier to extend now. Add memory.h because ARM has a custom one. Signed-off-by: Wolfram Sang Cc: Russell King Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index bd88f11b0953..315faf99effd 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -224,6 +224,12 @@ our @modifierList = ( qr{fastcall}, ); +our $allowed_asm_includes = qr{(?x: + irq| + memory +)}; +# memory.h: ARM has a custom one + sub build_types { my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)"; my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)"; @@ -2308,7 +2314,7 @@ sub process { my $checkfile = "include/linux/$file"; if (-f "$root/$checkfile" && $realfile ne $checkfile && - $1 ne 'irq') + $1 !~ /$allowed_asm_includes/) { if ($realfile =~ m{^arch/}) { CHK("Consider using #include instead of \n" . $herecurr); -- cgit v1.2.3 From 5f7ddae6104d85e27c0fbcb508cfe8286a01a5e1 Mon Sep 17 00:00:00 2001 From: Raffaele Recalcati Date: Mon, 9 Aug 2010 17:20:59 -0700 Subject: checkpatch: fix handling of leading spaces I've got a false positive when spaces are present at the beginning of a line. So I add this check, obviously excluding to check the lines in the middle of comments. For instance this code passes the checkpatch test: +struct davinci_mcbsp_data { + unsigned int fmt; + int clk_div; +}; + +static struct davinci_mcbsp_data mcbsp_data; Where, before the string "int clk_div", I have 4 spaces (\040 ascii character). With v2.6.34 scripts/checkpatch.pl script I get: scripts/checkpatch.pl 0001-ASoC-DaVinci-Added-support-for-stereo-I2S.patch total: 0 errors, 0 warnings, 201 lines checked 0001-ASoC-DaVinci-Added-support-for-stereo-I2S.patch has no obvious style problems and is ready for submission. That is not correct. Instead with the proposed patch I get: scripts/checkpatch.pl 0001-ASoC-DaVinci-Added-support-for-stereo-I2S.patch WARNING: please, no space for starting a line, excluding comments #63: FILE: sound/soc/davinci/davinci-i2s.c:165: + int clk_div;$ WARNING: please, no space for starting a line, excluding comments #95: FILE: sound/soc/davinci/davinci-i2s.c:406: + return 0;$ total: 0 errors, 2 warnings, 201 lines checked That is correct. Signed-off-by: Raffaele Recalcati Cc: Wolfram Sang Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 315faf99effd..d7a44fd3b224 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1454,6 +1454,13 @@ sub process { WARN("please, no space before tabs\n" . $herevet); } +# check for spaces at the beginning of a line. + if ($rawline =~ /^\+ / && $rawline !~ /\+ +\*/) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + WARN("please, no space for starting a line, \ + excluding comments\n" . $herevet); + } + # check we are in a valid C source file if not then ignore this hunk next if ($realfile !~ /\.(h|c)$/); -- cgit v1.2.3 From 5150bda43c58cdce7eb851c3fe2ca913524459a0 Mon Sep 17 00:00:00 2001 From: Joe Eloff Date: Mon, 9 Aug 2010 17:21:00 -0700 Subject: checkpatch: change externals to globals Make error message say 'ERROR: do not initialise globals to 0 or NULL' rather than 'ERROR: do not initialise externals to 0 or NULL'. Makes more sense in the context since there is an extern keyword in C and that is a global declaration within the scope of the current file. Signed-off-by: Joe Eloff Cc: Andy Whitcroft Cc: Wolfram Sang Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index d7a44fd3b224..25d716cc44dc 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1791,9 +1791,9 @@ sub process { WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); } -# check for external initialisers. +# check for global initialisers. if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) { - ERROR("do not initialise externals to 0 or NULL\n" . + ERROR("do not initialise globals to 0 or NULL\n" . $herecurr); } # check for static initialisers. -- cgit v1.2.3 From 8bbea968f9022c3f66a36902509574597611be99 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 9 Aug 2010 17:21:01 -0700 Subject: checkpatch: add more exceptions to 80 char lines Add new logging functions netdev_ and netif_. Don't complain if the only thing on a line is a quoted string. Signed-off-by: Joe Perches Cc: Andy Whitcroft Cc: Wolfram Sang Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 25d716cc44dc..2018f4349b47 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -195,7 +195,7 @@ our $typeTypedefs = qr{(?x: our $logFunctions = qr{(?x: printk| pr_(debug|dbg|vdbg|devel|info|warning|err|notice|alert|crit|emerg|cont)| - dev_(printk|dbg|vdbg|info|warn|err|notice|alert|crit|emerg|WARN)| + (dev|netdev|netif)_(printk|dbg|vdbg|info|warn|err|notice|alert|crit|emerg|WARN)| WARN| panic )}; @@ -1409,7 +1409,8 @@ sub process { #80 column limit if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && $rawline !~ /^.\s*\*\s*\@$Ident\s/ && - $line !~ /^\+\s*$logFunctions\s*\(\s*(?:KERN_\S+\s*)?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ && + !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ || + $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) && $length > 80) { WARN("line over 80 characters\n" . $herecurr); -- cgit v1.2.3 From 1a15a250862fda3fbdf8454cc7131e24de904e7c Mon Sep 17 00:00:00 2001 From: Patrick Pannuto Date: Mon, 9 Aug 2010 17:21:01 -0700 Subject: checkpatch: prefer usleep_range over udelay When possible, sleeping is (usually) better than delaying; however, don't bother callers of udelay < 10us, as those cases are generally not worth the switch to usleep [akpm@linux-foundation.org: fix mismatched parentheses] Signed-off-by: Patrick Pannuto Cc: Thomas Gleixner Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 2018f4349b47..8b69af8a76f9 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2584,6 +2584,14 @@ sub process { } } +# prefer usleep_range over udelay + if ($line =~ /\budelay\s*\(\s*(\w+)\s*\)/) { + # ignore udelay's < 10, however + if (! (($1 =~ /(\d+)/) && ($1 < 10)) ) { + CHK("usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line); + } + } + # warn about #ifdefs in C files # if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { # print "#ifdef in C files should be avoided\n"; -- cgit v1.2.3 From 09ef87255da0e005dd0ab39ca25714208cf29cb3 Mon Sep 17 00:00:00 2001 From: Patrick Pannuto Date: Mon, 9 Aug 2010 17:21:02 -0700 Subject: checkpatch: warn about unexpectedly long msleep's As explained in Documentation/timers/timers-howto.txt, msleep's of < 20ms may sleep for as long as 20ms. Caller's of msleep(1) or msleep(2), etc are likely not to expect this quirky behavior - warn them. Signed-off-by: Patrick Pannuto Cc: Thomas Gleixner Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 8b69af8a76f9..dd11bbe01338 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2592,6 +2592,13 @@ sub process { } } +# warn about unexpectedly long msleep's + if ($line =~ /\bmsleep\s*\((\d+)\);/) { + if ($1 < 20) { + WARN("msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $line); + } + } + # warn about #ifdefs in C files # if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { # print "#ifdef in C files should be avoided\n"; -- cgit v1.2.3 From b998e001e6ce6540ea04a264debc50ae44d2db7a Mon Sep 17 00:00:00 2001 From: Patrick Pannuto Date: Mon, 9 Aug 2010 17:21:03 -0700 Subject: checkpatch: fix extraneous EXPORT_SYMBOL* warnings These are caused by checkpatch incorrectly parsing its internal representation of a statement block for struct's (or anything else that is a statement block encapsulated in {}'s that also ends with a ';'). Fix this by properly parsing a statement block. An example: +struct dummy_type dummy = { + .foo = "baz", +}; +EXPORT_SYMBOL_GPL(dummy); + +static int dummy_func(void) +{ + return -EDUMMYCODE; +} +EXPORT_SYMBOL_GPL(dummy_func); WARNING: EXPORT_SYMBOL(foo); should immediately \ follow its function/variable #19: FILE: dummy.c:4: +EXPORT_SYMBOL_GPL(dummy); The above warning is issued when it should not be. Signed-off-by: Patrick Pannuto Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 3 +++ 1 file changed, 3 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index dd11bbe01338..2039acdf5122 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -558,6 +558,9 @@ sub ctx_statement_block { $type = ($level != 0)? '{' : ''; if ($level == 0) { + if (substr($blk, $off + 1, 1) eq ';') { + $off++; + } last; } } -- cgit v1.2.3 From 6a841528d288ac420052f5c98fd426b0fcdc5b52 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 11 Aug 2010 23:04:16 -0600 Subject: param: silence .init.text references from param ops Ideally, we'd check that it was only the "set" function which was __init, and that the permissions were r/o. But that's a little hard. Signed-off-by: Rusty Russell Acked-by: Sam Ravnborg Tested-by: Phil Carmody --- scripts/mod/modpost.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 1ce655dde99e..b16044002d91 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1033,6 +1033,13 @@ static const struct sectioncheck *section_mismatch( * fromsec = .data* * atsym =__param* * + * Pattern 1a: + * module_param_call() ops can refer to __init set function if permissions=0 + * The pattern is identified by: + * tosec = .init.text + * fromsec = .data* + * atsym = __param_ops_* + * * Pattern 2: * Many drivers utilise a *driver container with references to * add, remove, probe functions etc. @@ -1067,6 +1074,12 @@ static int secref_whitelist(const struct sectioncheck *mismatch, (strncmp(fromsym, "__param", strlen("__param")) == 0)) return 0; + /* Check for pattern 1a */ + if (strcmp(tosec, ".init.text") == 0 && + match(fromsec, data_sections) && + (strncmp(fromsym, "__param_ops_", strlen("__param_ops_")) == 0)) + return 0; + /* Check for pattern 2 */ if (match(tosec, init_exit_sections) && match(fromsec, data_sections) && -- cgit v1.2.3 From 5003bab82d56754b27be01eef24495a02e00039d Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 11 Aug 2010 00:42:26 -0700 Subject: fix "scripts/mod/modpost.c: fix memory leak" Fix error introduced by 37ed19d5cce35a40d3913cf9aa208ce9f60db3d7 ("scripts/mod/modpost.c: fix memory leak"). - don't kfree("") - fix one missed conversion Reported-by: Stephen Rothwell Tested-by: Stephen Rothwell Cc: Alexey Fomenko Cc: Trevor Keith Cc: Rusty Russell Cc: Michal Marek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/mod/modpost.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 1ce655dde99e..7acbdd8fcaed 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -14,6 +14,7 @@ #define _GNU_SOURCE #include #include +#include #include "modpost.h" #include "../../include/generated/autoconf.h" #include "../../include/linux/license.h" @@ -1217,7 +1218,7 @@ static char *sec2annotation(const char *s) strcat(p, " "); return r; /* we leak her but we do not care */ } else { - return ""; + return strdup(""); } } @@ -1352,7 +1353,7 @@ static void report_sec_mismatch(const char *modname, "%s%s so it may be used outside an exit section.\n", from, prl_from, fromsym, from_p, to, prl_to, tosym, to_p, - sec2annotation(tosec), tosym, to_p); + prl_to, tosym, to_p); free(prl_from); free(prl_to); break; -- cgit v1.2.3 From b6d676db35ca6c99180bb12dcbd4a8c3b2995e49 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 10 Aug 2010 18:02:50 -0700 Subject: mtd/nand_base: fix kernel-doc warnings & typos Fix mtd/nand_base.c kernel-doc warnings and typos. Warning(drivers/mtd/nand/nand_base.c:893): No description found for parameter 'mtd' Warning(drivers/mtd/nand/nand_base.c:893): No description found for parameter 'ofs' Warning(drivers/mtd/nand/nand_base.c:893): No description found for parameter 'len' Warning(drivers/mtd/nand/nand_base.c:893): No description found for parameter 'invert' Warning(drivers/mtd/nand/nand_base.c:930): No description found for parameter 'mtd' Warning(drivers/mtd/nand/nand_base.c:930): No description found for parameter 'ofs' Warning(drivers/mtd/nand/nand_base.c:930): No description found for parameter 'len' Warning(drivers/mtd/nand/nand_base.c:987): No description found for parameter 'mtd' Warning(drivers/mtd/nand/nand_base.c:987): No description found for parameter 'ofs' Warning(drivers/mtd/nand/nand_base.c:987): No description found for parameter 'len' Warning(drivers/mtd/nand/nand_base.c:2087): No description found for parameter 'len' Signed-off-by: Randy Dunlap Cc: David Woodhouse Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/kernel-doc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index fcdfb245a575..102e1235fd5c 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1454,6 +1454,8 @@ sub dump_enum($$) { my $file = shift; $x =~ s@/\*.*?\*/@@gos; # strip comments. + $x =~ s/^#\s*define\s+.*$//; # strip #define macros inside enums + if ($x =~ /enum\s+(\w+)\s*{(.*)}/) { $declaration_name = $1; my $members = $2; -- cgit v1.2.3 From 801690caf1894d4f8b1277ca9f5dcf0bcf9b3f58 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Thu, 12 Aug 2010 09:11:51 +0200 Subject: kconfig: fix savedefconfig for tristate choices savedefconfig failed to save choice symbols equal to 'y' for tristate choices. This resulted in this value being lost. In particular is fixes an issue where make ARCH=avr32 atngw100_defconfig make ARCH=avr32 savedefconfig cp defconfig arch/avr32/configs/atngw100_defconfig make ARCH=avr32 atngw100_defconfig diff -u .config .config.old failed to produce an identical .config. Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index f81f263b64f2..e5d66e4f1484 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -497,7 +497,7 @@ int conf_write_defconfig(const char *filename) /* * If symbol is a choice value and equals to the * default for a choice - skip. - * But only if value equal to "y". + * But only if value is bool and equal to "y" . */ if (sym_is_choice_value(sym)) { struct symbol *cs; @@ -506,9 +506,8 @@ int conf_write_defconfig(const char *filename) cs = prop_get_symbol(sym_get_choice_prop(sym)); ds = sym_choice_default(cs); if (sym == ds) { - if ((sym->type == S_BOOLEAN || - sym->type == S_TRISTATE) && - sym_get_tristate_value(sym) == yes) + if ((sym->type == S_BOOLEAN) && + sym_get_tristate_value(sym) == yes) goto next_menu; } } -- cgit v1.2.3 From a64b44ead002ba15fdf841106a6fd344b8dd46d8 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Thu, 12 Aug 2010 09:11:52 +0200 Subject: kconfig: fix tristate choice with minimal config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a minimal config did not specify the value of all choice values, the resulting configuration could have wrong values. Consider following example: config M def_bool y option modules choice prompt "choice list" config A tristate "a" config B tristate "b" endchoice With a defconfig like this: CONFIG_M=y CONFIG_A=y The resulting configuration would have CONFIG_A=m which was unexpected. The problem was not not all choice values were set and thus kconfig calculated a wrong value. The fix is to set all choice values when we read a defconfig files. conf_set_all_new_symbols() is refactored such that random choice values are now handled by a dedicated function. And new choice values are set by set_all_choice_values(). This was not the minimal fix, but the fix that resulted in the most readable code. Signed-off-by: Sam Ravnborg Reported-by: Arve Hjønnevåg Tested-by: Arve Hjønnevåg Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 102 +++++++++++++++++++++++++++++---------------- 1 file changed, 67 insertions(+), 35 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index e5d66e4f1484..ac13f0ff8e81 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -918,13 +918,73 @@ void conf_set_changed_callback(void (*fn)(void)) conf_changed_callback = fn; } +static void randomize_choice_values(struct symbol *csym) +{ + struct property *prop; + struct symbol *sym; + struct expr *e; + int cnt, def; -void conf_set_all_new_symbols(enum conf_def_mode mode) + /* + * If choice is mod then we may have more items slected + * and if no then no-one. + * In both cases stop. + */ + if (csym->curr.tri != yes) + return; + + prop = sym_get_choice_prop(csym); + + /* count entries in choice block */ + cnt = 0; + expr_list_for_each_sym(prop->expr, e, sym) + cnt++; + + /* + * find a random value and set it to yes, + * set the rest to no so we have only one set + */ + def = (rand() % cnt); + + cnt = 0; + expr_list_for_each_sym(prop->expr, e, sym) { + if (def == cnt++) { + sym->def[S_DEF_USER].tri = yes; + csym->def[S_DEF_USER].val = sym; + } + else { + sym->def[S_DEF_USER].tri = no; + } + } + csym->flags |= SYMBOL_DEF_USER; + /* clear VALID to get value calculated */ + csym->flags &= ~(SYMBOL_VALID); +} + +static void set_all_choice_values(struct symbol *csym) { - struct symbol *sym, *csym; struct property *prop; + struct symbol *sym; struct expr *e; - int i, cnt, def; + + prop = sym_get_choice_prop(csym); + + /* + * Set all non-assinged choice values to no + */ + expr_list_for_each_sym(prop->expr, e, sym) { + if (!sym_has_value(sym)) + sym->def[S_DEF_USER].tri = no; + } + csym->flags |= SYMBOL_DEF_USER; + /* clear VALID to get value calculated */ + csym->flags &= ~(SYMBOL_VALID); +} + +void conf_set_all_new_symbols(enum conf_def_mode mode) +{ + struct symbol *sym, *csym; + int i, cnt; for_all_symbols(i, sym) { if (sym_has_value(sym)) @@ -960,8 +1020,6 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) sym_clear_all_valid(); - if (mode != def_random) - return; /* * We have different type of choice blocks. * If curr.tri equal to mod then we can select several @@ -976,35 +1034,9 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) continue; sym_calc_value(csym); - - if (csym->curr.tri != yes) - continue; - - prop = sym_get_choice_prop(csym); - - /* count entries in choice block */ - cnt = 0; - expr_list_for_each_sym(prop->expr, e, sym) - cnt++; - - /* - * find a random value and set it to yes, - * set the rest to no so we have only one set - */ - def = (rand() % cnt); - - cnt = 0; - expr_list_for_each_sym(prop->expr, e, sym) { - if (def == cnt++) { - sym->def[S_DEF_USER].tri = yes; - csym->def[S_DEF_USER].val = sym; - } - else { - sym->def[S_DEF_USER].tri = no; - } - } - csym->flags |= SYMBOL_DEF_USER; - /* clear VALID to get value calculated */ - csym->flags &= ~(SYMBOL_VALID); + if (mode == def_random) + randomize_choice_values(csym); + else + set_all_choice_values(csym); } } -- cgit v1.2.3 From 465c6cca2668a2db2a4ffce3dca5714017873f2b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 6 Aug 2010 03:26:24 -0400 Subject: tracing: Extend recordmcount to better support Blackfin mcount The mcount call on Blackfin systems includes some stack manipulation around the actual call site, so extend the build time perl script to support this. This way we can avoid doing the calculation at runtime. Signed-off-by: Mike Frysinger LKML-Reference: <1281079584-21205-1-git-send-email-vapier@gentoo.org> Signed-off-by: Steven Rostedt --- scripts/recordmcount.pl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index f3c9c0a90b98..2c56539e5da2 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -159,6 +159,7 @@ my $section_regex; # Find the start of a section my $function_regex; # Find the name of a function # (return offset and func name) my $mcount_regex; # Find the call site to mcount (return offset) +my $mcount_adjust; # Address adjustment to mcount offset my $alignment; # The .align value to use for $mcount_section my $section_type; # Section header plus possible alignment command my $can_use_local = 0; # If we can use local function references @@ -213,6 +214,7 @@ $section_regex = "Disassembly of section\\s+(\\S+):"; $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:"; $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$"; $section_type = '@progbits'; +$mcount_adjust = 0; $type = ".long"; if ($arch eq "x86_64") { @@ -351,6 +353,9 @@ if ($arch eq "x86_64") { } elsif ($arch eq "microblaze") { # Microblaze calls '_mcount' instead of plain 'mcount'. $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; +} elsif ($arch eq "blackfin") { + $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s__mcount\$"; + $mcount_adjust = -4; } else { die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; } @@ -511,7 +516,7 @@ while () { } # is this a call site to mcount? If so, record it to print later if ($text_found && /$mcount_regex/) { - push(@offsets, hex $1); + push(@offsets, (hex $1) + $mcount_adjust); } } -- cgit v1.2.3 From 019fca84e7c4b94817abc77df9081ba208fcc46a Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 12 Aug 2010 16:54:47 +0100 Subject: MN10300: Permit .GCC-command-line sections Permit .GCC-command-line sections in modules. Otherwise modpost says things like: WARNING: drivers/mtd/chips/map_ram.o (.GCC-command-line): unexpected non-allocatable section. Did you forget to use "ax"/"aw" in a .S file? Note that for example contains section definitions for use in .S files. Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- scripts/mod/modpost.c | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 7acbdd8fcaed..253c107b9a99 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -790,6 +790,7 @@ static const char *section_white_list[] = { ".comment*", ".debug*", + ".GCC-command-line", /* mn10300 */ ".mdebug*", /* alpha, score, mips etc. */ ".pdr", /* alpha, score, mips etc. */ ".stab*", -- cgit v1.2.3 From 866af407dad3f2202e5d5d717ebd6156ccc33cdd Mon Sep 17 00:00:00 2001 From: Andrej Gelenberg Date: Mon, 2 Aug 2010 11:59:31 +0200 Subject: nconfig: Fix segfault when menu is empty nconf crush with segfault if press right arrow in empty menu. Signed-off-by: Andrej Gelenberg Signed-off-by: Michal Marek --- scripts/kconfig/nconf.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 762caf80ce37..2ba71bcd38e6 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -676,6 +676,8 @@ static void *item_data(void) struct mitem *mcur; cur = current_item(curses_menu); + if (!cur) + return NULL; mcur = (struct mitem *) item_userptr(cur); return mcur->usrptr; -- cgit v1.2.3 From bf5e327a300a9ac959a89440e7c67dc89f3bd804 Mon Sep 17 00:00:00 2001 From: Jean Sacren Date: Wed, 4 Aug 2010 16:01:02 -0600 Subject: kconfig: Fix warning: ignoring return value of 'fwrite' This fix facilitates fwrite() in both confdata.c and expr.c, either it succeeds in writing, or an error occurs, or the end of file is reached. Signed-off-by: Jean Sacren Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 2 +- scripts/kconfig/expr.c | 2 +- scripts/kconfig/lkc.h | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index ac13f0ff8e81..c39327e60ea4 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -412,7 +412,7 @@ static void conf_write_string(bool headerfile, const char *name, while (1) { l = strcspn(str, "\"\\"); if (l) { - fwrite(str, l, 1, out); + xfwrite(str, l, 1, out); str += l; } if (!*str) diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 8f18e37892cb..330e7c0048a8 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -1087,7 +1087,7 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char * static void expr_print_file_helper(void *data, struct symbol *sym, const char *str) { - fwrite(str, strlen(str), 1, data); + xfwrite(str, strlen(str), 1, data); } void expr_fprint(struct expr *e, FILE *out) diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 76db065ed72c..2ac33f5d273c 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -80,6 +80,13 @@ void sym_set_change_count(int count); void sym_add_change_count(int count); void conf_set_all_new_symbols(enum conf_def_mode mode); +/* 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"); +} + /* kconfig_load.c */ void kconfig_load(void); -- cgit v1.2.3 From 4418a2b904805814bbd14b555d6add6a175f49f3 Mon Sep 17 00:00:00 2001 From: Jean Sacren Date: Wed, 4 Aug 2010 16:03:16 -0600 Subject: kconfig: Fix warning: ignoring return value of 'fgets' This fix facilitates fgets() either it returns on success or on error or when end of file occurs. Signed-off-by: Jean Sacren Signed-off-by: Michal Marek --- scripts/kconfig/conf.c | 15 +++++++++++++-- scripts/kconfig/lkc.h | 3 +++ 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 010600ef58c0..4f0ed5b3a75e 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -108,7 +108,7 @@ static int conf_askvalue(struct symbol *sym, const char *def) check_stdin(); case oldaskconfig: fflush(stdout); - fgets(line, 128, stdin); + xfgets(line, 128, stdin); return 1; default: break; @@ -306,7 +306,7 @@ static int conf_choice(struct menu *menu) check_stdin(); case oldaskconfig: fflush(stdout); - fgets(line, 128, stdin); + xfgets(line, 128, stdin); strip(line); if (line[0] == '?') { print_help(menu); @@ -644,3 +644,14 @@ int main(int ac, char **av) } return 0; } +/* + * Helper function to facilitate fgets() by Jean Sacren. + */ +void xfgets(str, size, in) + char *str; + int size; + FILE *in; +{ + if (fgets(str, size, in) == NULL) + fprintf(stderr, "\nError in reading or end of file.\n"); +} diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 2ac33f5d273c..bdf71bd31412 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -72,6 +72,9 @@ void zconf_nextfile(const char *name); int zconf_lineno(void); char *zconf_curname(void); +/* conf.c */ +void xfgets(char *str, int size, FILE *in); + /* confdata.c */ const char *conf_get_configname(void); const char *conf_get_autoconfig_name(void); -- cgit v1.2.3 From 55c640c3abff301eed5ee11c34a40bfe043c8c2d Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Thu, 22 Jul 2010 10:19:38 -0500 Subject: setlocalversion: fix version for untaged nontip mercurial revs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The manpage for cut says it will return all lines without the delimiter unless -s is specified. When I backed up my mecurial tree to generate modules, I found that the scm part of localversion was turning up blank. Signed-off-by: Milton Miller Cc: Michal Marek Cc: "Michał Górny" Signed-off-by: Michal Marek --- scripts/setlocalversion | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 64a9cb5556cd..e90a91cc5185 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -86,7 +86,7 @@ scm_version() # Check for mercurial and a mercurial repo. if hgid=`hg id 2>/dev/null`; then - tag=`printf '%s' "$hgid" | cut -d' ' -f2` + tag=`printf '%s' "$hgid" | cut -s -d' ' -f2` # Do we have an untagged version? if [ -z "$tag" -o "$tag" = tip ]; then -- cgit v1.2.3 From 7cfddeef357aac78179ea804b11cffb5fbba8288 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 14 Aug 2010 10:22:58 +0200 Subject: kbuild: drop unifdef-y support unifdef-y is not used anymore - drop remaining references Signed-off-by: Sam Ravnborg --- scripts/Makefile.headersinst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst index 0fcd83838771..f89cb87f5c01 100644 --- a/scripts/Makefile.headersinst +++ b/scripts/Makefile.headersinst @@ -3,7 +3,6 @@ # # header-y - list files to be installed. They are preprocessed # to remove __KERNEL__ section of the file -# unifdef-y - Same as header-y. Obsolete # objhdr-y - Same as header-y but for generated files # # ========================================================================== @@ -20,7 +19,7 @@ include scripts/Kbuild.include install := $(INSTALL_HDR_PATH)/$(_dst) -header-y := $(sort $(header-y) $(unifdef-y)) +header-y := $(sort $(header-y)) subdirs := $(patsubst %/,%,$(filter %/, $(header-y))) header-y := $(filter-out %/, $(header-y)) -- cgit v1.2.3 From 84062dd3a6a045395a43de1d9adc9b8eb2d1426e Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 14 Aug 2010 23:22:16 +0200 Subject: kconfig: fix savedefconfig with choice marked optional savedefconfig failed to save the correct minimal config when it encountered a choice marked optional. Consider following minimal configuration: $cat Kconfig choice prompt "choice" optional config A bool "a" config B bool "b" endchoice $cat .config | grep -v ^# CONFIG_A=y $conf --savedefconfig=defconfig Kconfig would before this fix result in an empty file, because kconfig would assume that CONFIG_A=y is a default value. But because the choice is optional the default is that both A and B are =n. Fix so we handle optional choices correct. Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index c39327e60ea4..515253fe46cf 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -497,7 +497,9 @@ int conf_write_defconfig(const char *filename) /* * If symbol is a choice value and equals to the * default for a choice - skip. - * But only if value is bool and equal to "y" . + * But only if value is bool and equal to "y" and + * choice is not "optional". + * (If choice is "optional" then all values can be "n") */ if (sym_is_choice_value(sym)) { struct symbol *cs; @@ -505,7 +507,7 @@ int conf_write_defconfig(const char *filename) cs = prop_get_symbol(sym_get_choice_prop(sym)); ds = sym_choice_default(cs); - if (sym == ds) { + if (!sym_is_optional(cs) && sym == ds) { if ((sym->type == S_BOOLEAN) && sym_get_tristate_value(sym) == yes) goto next_menu; -- cgit v1.2.3 From 3643f849d7da5c12da589beb03c12303fe79b841 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 14 Aug 2010 14:40:00 +0200 Subject: kconfig: fix segfault when detecting recursive dependency Following sample Kconfig generated a segfault: config FOO bool select PERF_EVENTS if HAVE_HW_BREAKPOINT config PERF_EVENTS bool config HAVE_HW_BREAKPOINT bool depends on PERF_EVENTS Fix by reverting back to a valid property if there was no property on the stack of symbols. The above pattern were seen in sh Kconfig. A fix for the Kconfig file has been sent to the sh folks. Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/kconfig/symbol.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index e95718fea355..943712ca6c0a 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -937,6 +937,8 @@ static void sym_check_print_recursive(struct symbol *last_sym) sym = stack->sym; next_sym = stack->next ? stack->next->sym : last_sym; prop = stack->prop; + if (prop == NULL) + prop = stack->sym->prop; /* for choice values find the menu entry (used below) */ if (sym_is_choice(sym) || sym_is_choice_value(sym)) { -- cgit v1.2.3 From a72f3e2b82eb26f43bed1f83beeeb47830918811 Mon Sep 17 00:00:00 2001 From: Nir Tzachar Date: Sun, 8 Aug 2010 16:50:06 +0300 Subject: nconfig: add search support Remove the old hotkeys feature, and replace it by an interactive string search. From nconfig help: Searching: pressing '/' triggers interactive search mode. nconfig performs a case insensitive search for the string in the menu prompts (no regex support). Pressing the up/down keys highlights the previous/next matching item. Backspace removes one character from the match string. Pressing either '/' again or ESC exits search mode. All other keys behave normally. Miscellaneous other changes (including Rundy's and Justin's input). Signed-off-by: Nir Tzachar Acked-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/kconfig/nconf.c | 365 ++++++++++++++++++++++++-------------------- scripts/kconfig/nconf.gui.c | 20 +-- scripts/kconfig/nconf.h | 3 +- 3 files changed, 208 insertions(+), 180 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 2ba71bcd38e6..18a215de9f36 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -5,9 +5,12 @@ * Derived from menuconfig. * */ +#define _GNU_SOURCE +#include #define LKC_DIRECT_LINK #include "lkc.h" #include "nconf.h" +#include static const char nconf_readme[] = N_( "Overview\n" @@ -23,7 +26,7 @@ static const char nconf_readme[] = N_( " < > can be built in, modularized or removed\n" " { } can be built in or modularized (selected by other feature)\n" " - - are selected by other feature,\n" -" XXX cannot be selected. use Symbol Info to find out why,\n" +" XXX cannot be selected. Use Symbol Info to find out why,\n" "while *, M or whitespace inside braces means to build in, build as\n" "a module or to exclude the feature respectively.\n" "\n" @@ -41,9 +44,13 @@ static const char nconf_readme[] = N_( " pressing of . Use or to go back.\n" " Submenus are designated by \"--->\".\n" "\n" -" Shortcut: Press the option's highlighted letter (hotkey).\n" -" Pressing a hotkey more than once will sequence\n" -" through all visible items which use that hotkey.\n" +" Searching: pressing '/' triggers interactive search mode.\n" +" nconfig performs a case insensitive search for the string\n" +" in the menu prompts (no regex support).\n" +" Pressing the up/down keys highlights the previous/next\n" +" matching item. Backspace removes one character from the\n" +" match string. Pressing either '/' again or ESC exits\n" +" search mode. All other keys behave normally.\n" "\n" " You may also use the and keys to scroll\n" " unseen options into view.\n" @@ -141,21 +148,21 @@ menu_no_f_instructions[] = N_( " or selects submenus --->.\n" " Capital Letters are hotkeys.\n" " Pressing includes, excludes, modularizes features.\n" -" Pressing SpaceBar toggles between the above options\n" -" Press or to go back one menu, \n" +" Pressing SpaceBar toggles between the above options.\n" +" Press or to go back one menu,\n" " or for Help, for Search.\n" -" <1> is interchangable with , <2> with , etc.\n" +" <1> is interchangeable with , <2> with , etc.\n" " Legend: [*] built-in [ ] excluded module < > module capable.\n" -" always leaves the current window\n"), +" always leaves the current window.\n"), menu_instructions[] = N_( " Arrow keys navigate the menu.\n" " or selects submenus --->.\n" " Capital Letters are hotkeys.\n" " Pressing includes, excludes, modularizes features.\n" " Pressing SpaceBar toggles between the above options\n" -" Press , or to go back one menu, \n" +" Press , or to go back one menu,\n" " , or for Help, for Search.\n" -" <1> is interchangable with , <2> with , etc.\n" +" <1> is interchangeable with , <2> with , etc.\n" " Legend: [*] built-in [ ] excluded module < > module capable.\n" " always leaves the current window\n"), radiolist_instructions[] = N_( @@ -252,7 +259,6 @@ struct mitem { char str[256]; char tag; void *usrptr; - int is_hot; int is_visible; }; @@ -275,14 +281,6 @@ static int items_num; static int global_exit; /* the currently selected button */ const char *current_instructions = menu_instructions; -/* this array is used to implement hot keys. it is updated in item_make and - * resetted in clean_items. It would be better to use a hash, but lets keep it - * simple... */ -#define MAX_SAME_KEY MAX_MENU_ITEMS -struct { - int count; - int ptrs[MAX_MENU_ITEMS]; -} hotkeys[1<<(sizeof(char)*8)]; static void conf(struct menu *menu); static void conf_choice(struct menu *menu); @@ -292,6 +290,7 @@ static void conf_save(void); static void show_help(struct menu *menu); static int do_exit(void); static void setup_windows(void); +static void search_conf(void); typedef void (*function_key_handler_t)(int *key, struct menu *menu); static void handle_f1(int *key, struct menu *current_item); @@ -302,6 +301,7 @@ static void handle_f5(int *key, struct menu *current_item); static void handle_f6(int *key, struct menu *current_item); static void handle_f7(int *key, struct menu *current_item); static void handle_f8(int *key, struct menu *current_item); +static void handle_f9(int *key, struct menu *current_item); struct function_keys { const char *key_str; @@ -310,7 +310,7 @@ struct function_keys { function_key_handler_t handler; }; -static const int function_keys_num = 8; +static const int function_keys_num = 9; struct function_keys function_keys[] = { { .key_str = "F1", @@ -320,13 +320,13 @@ struct function_keys function_keys[] = { }, { .key_str = "F2", - .func = "Symbol Info", + .func = "Sym Info", .key = F_SYMBOL, .handler = handle_f2, }, { .key_str = "F3", - .func = "Instructions", + .func = "Insts", .key = F_INSTS, .handler = handle_f3, }, @@ -356,9 +356,15 @@ struct function_keys function_keys[] = { }, { .key_str = "F8", + .func = "Sym Search", + .key = F_SEARCH, + .handler = handle_f8, + }, + { + .key_str = "F9", .func = "Exit", .key = F_EXIT, - .handler = handle_f8, + .handler = handle_f9, }, }; @@ -444,8 +450,15 @@ static void handle_f7(int *key, struct menu *current_item) return; } -/* exit */ +/* search */ static void handle_f8(int *key, struct menu *current_item) +{ + search_conf(); + return; +} + +/* exit */ +static void handle_f9(int *key, struct menu *current_item) { do_exit(); return; @@ -479,110 +492,44 @@ static void clean_items(void) free_item(curses_menu_items[i]); bzero(curses_menu_items, sizeof(curses_menu_items)); bzero(k_menu_items, sizeof(k_menu_items)); - bzero(hotkeys, sizeof(hotkeys)); items_num = 0; } -/* return the index of the next hot item, or -1 if no such item exists */ -static int get_next_hot(int c) -{ - static int hot_index; - static int hot_char; - - if (c < 0 || c > 255 || hotkeys[c].count <= 0) - return -1; - - if (hot_char == c) { - hot_index = (hot_index+1)%hotkeys[c].count; - return hotkeys[c].ptrs[hot_index]; - } else { - hot_char = c; - hot_index = 0; - return hotkeys[c].ptrs[0]; - } -} - -/* can the char c be a hot key? no, if c is a common shortcut used elsewhere */ -static int canbhot(char c) -{ - c = tolower(c); - return isalnum(c) && c != 'y' && c != 'm' && c != 'h' && - c != 'n' && c != '?'; -} - -/* check if str already contains a hot key. */ -static int is_hot(int index) -{ - return k_menu_items[index].is_hot; -} +typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN, + FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f; -/* find the first possible hot key, and mark it. - * index is the index of the item in the menu - * return 0 on success*/ -static int make_hot(char *dest, int len, const char *org, int index) +/* return the index of the matched item, or -1 if no such item exists */ +static int get_mext_match(const char *match_str, match_f flag) { - int position = -1; - int i; - int tmp; - int c; - int org_len = strlen(org); - - if (org == NULL || is_hot(index)) - return 1; - - /* make sure not to make hot keys out of markers. - * find where to start looking for a hot key - */ - i = 0; - /* skip white space */ - while (i < org_len && org[i] == ' ') - i++; - if (i == org_len) - return -1; - /* if encountering '(' or '<' or '[', find the match and look from there - **/ - if (org[i] == '[' || org[i] == '<' || org[i] == '(') { - i++; - for (; i < org_len; i++) - if (org[i] == ']' || org[i] == '>' || org[i] == ')') - break; - } - if (i == org_len) - return -1; - for (; i < org_len; i++) { - if (canbhot(org[i]) && org[i-1] != '<' && org[i-1] != '(') { - position = i; - break; - } + int match_start = item_index(current_item(curses_menu)); + int index; + + if (flag == FIND_NEXT_MATCH_DOWN) + ++match_start; + else if (flag == FIND_NEXT_MATCH_UP) + --match_start; + + index = match_start; + index = (index + items_num) % items_num; + while (true) { + char *str = k_menu_items[index].str; + if (strcasestr(str, match_str) != 0) + return index; + if (flag == FIND_NEXT_MATCH_UP || + flag == MATCH_TINKER_PATTERN_UP) + --index; + else + ++index; + index = (index + items_num) % items_num; + if (index == match_start) + return -1; } - if (position == -1) - return 1; - - /* ok, char at org[position] should be a hot key to this item */ - c = tolower(org[position]); - tmp = hotkeys[c].count; - hotkeys[c].ptrs[tmp] = index; - hotkeys[c].count++; - /* - snprintf(dest, len, "%.*s(%c)%s", position, org, org[position], - &org[position+1]); - */ - /* make org[position] uppercase, and all leading letter small case */ - strncpy(dest, org, len); - for (i = 0; i < position; i++) - dest[i] = tolower(dest[i]); - dest[position] = toupper(dest[position]); - k_menu_items[index].is_hot = 1; - return 0; } -/* Make a new item. Add a hotkey mark in the first possible letter. - * As ncurses does not allow any attributes inside menue item, we mark the - * hot key as the first capitalized letter in the string */ +/* Make a new item. */ static void item_make(struct menu *menu, char tag, const char *fmt, ...) { va_list ap; - char tmp_str[256]; if (items_num > MAX_MENU_ITEMS-1) return; @@ -597,16 +544,13 @@ static void item_make(struct menu *menu, char tag, const char *fmt, ...) k_menu_items[items_num].is_visible = 1; va_start(ap, fmt); - vsnprintf(tmp_str, sizeof(tmp_str), fmt, ap); - if (!k_menu_items[items_num].is_visible) - memcpy(tmp_str, "XXX", 3); + vsnprintf(k_menu_items[items_num].str, + sizeof(k_menu_items[items_num].str), + fmt, ap); va_end(ap); - if (make_hot( - k_menu_items[items_num].str, - sizeof(k_menu_items[items_num].str), tmp_str, items_num) != 0) - strncpy(k_menu_items[items_num].str, - tmp_str, - sizeof(k_menu_items[items_num].str)); + + if (!k_menu_items[items_num].is_visible) + memcpy(k_menu_items[items_num].str, "XXX", 3); curses_menu_items[items_num] = new_item( k_menu_items[items_num].str, @@ -638,11 +582,9 @@ static void item_add_str(const char *fmt, ...) va_end(ap); snprintf(tmp_str, sizeof(tmp_str), "%s%s", k_menu_items[index].str, new_str); - if (make_hot(k_menu_items[index].str, - sizeof(k_menu_items[index].str), tmp_str, index) != 0) - strncpy(k_menu_items[index].str, - tmp_str, - sizeof(k_menu_items[index].str)); + strncpy(k_menu_items[index].str, + tmp_str, + sizeof(k_menu_items[index].str)); free_item(curses_menu_items[index]); curses_menu_items[index] = new_item( @@ -1027,23 +969,18 @@ static void reset_menu(void) static void center_item(int selected_index, int *last_top_row) { int toprow; - int maxy, maxx; - scale_menu(curses_menu, &maxy, &maxx); set_top_row(curses_menu, *last_top_row); toprow = top_row(curses_menu); - if (selected_index >= toprow && selected_index < toprow+maxy) { - /* we can only move the selected item. no need to scroll */ - set_current_item(curses_menu, - curses_menu_items[selected_index]); - } else { - toprow = max(selected_index-maxy/2, 0); - if (toprow >= item_count(curses_menu)-maxy) + if (selected_index < toprow || + selected_index >= toprow+mwin_max_lines) { + toprow = max(selected_index-mwin_max_lines/2, 0); + if (toprow >= item_count(curses_menu)-mwin_max_lines) toprow = item_count(curses_menu)-mwin_max_lines; set_top_row(curses_menu, toprow); - set_current_item(curses_menu, - curses_menu_items[selected_index]); } + set_current_item(curses_menu, + curses_menu_items[selected_index]); *last_top_row = toprow; post_menu(curses_menu); refresh_all_windows(main_window); @@ -1075,7 +1012,7 @@ static void show_menu(const char *prompt, const char *instructions, /* position the menu at the middle of the screen */ scale_menu(curses_menu, &maxy, &maxx); maxx = min(maxx, mwin_max_cols-2); - maxy = mwin_max_lines-2; + maxy = mwin_max_lines; menu_window = derwin(main_window, maxy, maxx, @@ -1099,10 +1036,77 @@ static void show_menu(const char *prompt, const char *instructions, refresh_all_windows(main_window); } +static void adj_match_dir(match_f *match_direction) +{ + if (*match_direction == FIND_NEXT_MATCH_DOWN) + *match_direction = + MATCH_TINKER_PATTERN_DOWN; + else if (*match_direction == FIND_NEXT_MATCH_UP) + *match_direction = + MATCH_TINKER_PATTERN_UP; + /* else, do no change.. */ +} -static void conf(struct menu *menu) +struct match_state { + int in_search; + match_f match_direction; char pattern[256]; +}; + +/* Return 0 means I have handled the key. In such a case, ans should hold the + * item to center, or -1 otherwise. + * Else return -1 . + */ +static int do_match(int key, struct match_state *state, int *ans) +{ + char c = (char) key; + int terminate_search = 0; + *ans = -1; + if (key == '/' || (state->in_search && key == 27)) { + move(0, 0); + refresh(); + clrtoeol(); + state->in_search = 1-state->in_search; + bzero(state->pattern, sizeof(state->pattern)); + state->match_direction = MATCH_TINKER_PATTERN_DOWN; + return 0; + } else if (!state->in_search) + return 1; + + if (isalnum(c) || isgraph(c) || c == ' ') { + state->pattern[strlen(state->pattern)] = c; + state->pattern[strlen(state->pattern)] = '\0'; + adj_match_dir(&state->match_direction); + *ans = get_mext_match(state->pattern, + state->match_direction); + } else if (key == KEY_DOWN) { + state->match_direction = FIND_NEXT_MATCH_DOWN; + *ans = get_mext_match(state->pattern, + state->match_direction); + } else if (key == KEY_UP) { + state->match_direction = FIND_NEXT_MATCH_UP; + *ans = get_mext_match(state->pattern, + state->match_direction); + } else if (key == KEY_BACKSPACE || key == 127) { + state->pattern[strlen(state->pattern)-1] = '\0'; + adj_match_dir(&state->match_direction); + } else + terminate_search = 1; + + if (terminate_search) { + state->in_search = 0; + bzero(state->pattern, sizeof(state->pattern)); + move(0, 0); + refresh(); + clrtoeol(); + return -1; + } + return 0; +} + +static void conf(struct menu *menu) +{ struct menu *submenu = 0; const char *prompt = menu_get_prompt(menu); struct symbol *sym; @@ -1110,8 +1114,11 @@ static void conf(struct menu *menu) int res; int current_index = 0; int last_top_row = 0; - - bzero(pattern, sizeof(pattern)); + struct match_state match_state = { + .in_search = 0, + .match_direction = MATCH_TINKER_PATTERN_DOWN, + .pattern = "", + }; while (!global_exit) { reset_menu(); @@ -1124,7 +1131,22 @@ static void conf(struct menu *menu) _(menu_instructions), current_index, &last_top_row); keypad((menu_win(curses_menu)), TRUE); - while (!global_exit && (res = wgetch(menu_win(curses_menu)))) { + while (!global_exit) { + if (match_state.in_search) { + mvprintw(0, 0, + "searching: %s", match_state.pattern); + clrtoeol(); + } + refresh_all_windows(main_window); + res = wgetch(menu_win(curses_menu)); + if (!res) + break; + if (do_match(res, &match_state, ¤t_index) == 0) { + if (current_index != -1) + center_item(current_index, + &last_top_row); + continue; + } if (process_special_keys(&res, (struct menu *) item_data())) break; @@ -1155,19 +1177,13 @@ static void conf(struct menu *menu) if (res == 10 || res == 27 || res == 32 || res == 'n' || res == 'y' || res == KEY_LEFT || res == KEY_RIGHT || - res == 'm' || res == '/') + res == 'm') break; - else if (canbhot(res)) { - /* check for hot keys: */ - int tmp = get_next_hot(res); - if (tmp != -1) - center_item(tmp, &last_top_row); - } refresh_all_windows(main_window); } refresh_all_windows(main_window); - /* if ESC or left*/ + /* if ESC or left*/ if (res == 27 || (menu != &rootmenu && res == KEY_LEFT)) break; @@ -1235,9 +1251,6 @@ static void conf(struct menu *menu) if (item_is_tag('t')) sym_set_tristate_value(sym, mod); break; - case '/': - search_conf(); - break; } } } @@ -1268,6 +1281,11 @@ static void conf_choice(struct menu *menu) int selected_index = 0; int last_top_row = 0; int res, i = 0; + struct match_state match_state = { + .in_search = 0, + .match_direction = MATCH_TINKER_PATTERN_DOWN, + .pattern = "", + }; active = sym_get_choice_value(menu->sym); /* this is mostly duplicated from the conf() function. */ @@ -1294,7 +1312,22 @@ static void conf_choice(struct menu *menu) _(radiolist_instructions), selected_index, &last_top_row); - while (!global_exit && (res = wgetch(menu_win(curses_menu)))) { + while (!global_exit) { + if (match_state.in_search) { + mvprintw(0, 0, "searching: %s", + match_state.pattern); + clrtoeol(); + } + refresh_all_windows(main_window); + res = wgetch(menu_win(curses_menu)); + if (!res) + break; + if (do_match(res, &match_state, &selected_index) == 0) { + if (selected_index != -1) + center_item(selected_index, + &last_top_row); + continue; + } if (process_special_keys( &res, (struct menu *) item_data())) @@ -1324,13 +1357,8 @@ static void conf_choice(struct menu *menu) break; } if (res == 10 || res == 27 || res == ' ' || - res == KEY_LEFT) + res == KEY_LEFT){ break; - else if (canbhot(res)) { - /* check for hot keys: */ - int tmp = get_next_hot(res); - if (tmp != -1) - center_item(tmp, &last_top_row); } refresh_all_windows(main_window); } @@ -1485,7 +1513,7 @@ void setup_windows(void) /* set up the menu and menu window */ main_window = newwin(LINES-2, COLS-2, 2, 1); keypad(main_window, TRUE); - mwin_max_lines = LINES-6; + mwin_max_lines = LINES-7; mwin_max_cols = COLS-6; /* panels order is from bottom to top */ @@ -1532,9 +1560,10 @@ int main(int ac, char **av) /* set btns menu */ curses_menu = new_menu(curses_menu_items); menu_opts_off(curses_menu, O_SHOWDESC); - menu_opts_off(curses_menu, O_SHOWMATCH); + menu_opts_on(curses_menu, O_SHOWMATCH); menu_opts_on(curses_menu, O_ONEVALUE); menu_opts_on(curses_menu, O_NONCYCLIC); + menu_opts_on(curses_menu, O_IGNORECASE); set_menu_mark(curses_menu, " "); set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]); set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]); @@ -1550,8 +1579,6 @@ int main(int ac, char **av) _(menu_no_f_instructions)); } - - /* do the work */ while (!global_exit) { conf(&rootmenu); diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index a9d9344e1365..d963071e48df 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -167,7 +167,7 @@ void print_in_middle(WINDOW *win, length = strlen(string); temp = (width - length) / 2; x = startx + (int)temp; - wattrset(win, color); + (void) wattrset(win, color); mvwprintw(win, y, x, "%s", string); refresh(); } @@ -297,11 +297,11 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...) set_menu_fore(menu, attributes[DIALOG_MENU_FORE]); set_menu_back(menu, attributes[DIALOG_MENU_BACK]); - wattrset(win, attributes[DIALOG_BOX]); + (void) wattrset(win, attributes[DIALOG_BOX]); box(win, 0, 0); /* print message */ - wattrset(msg_win, attributes[DIALOG_TEXT]); + (void) wattrset(msg_win, attributes[DIALOG_TEXT]); fill_window(msg_win, msg); set_menu_win(menu, win); @@ -392,16 +392,16 @@ int dialog_inputbox(WINDOW *main_window, form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); keypad(form_win, TRUE); - wattrset(form_win, attributes[INPUT_FIELD]); + (void) wattrset(form_win, attributes[INPUT_FIELD]); - wattrset(win, attributes[INPUT_BOX]); + (void) wattrset(win, attributes[INPUT_BOX]); box(win, 0, 0); - wattrset(win, attributes[INPUT_HEADING]); + (void) wattrset(win, attributes[INPUT_HEADING]); if (title) mvwprintw(win, 0, 3, "%s", title); /* print message */ - wattrset(prompt_win, attributes[INPUT_TEXT]); + (void) wattrset(prompt_win, attributes[INPUT_TEXT]); fill_window(prompt_win, prompt); mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); @@ -531,7 +531,7 @@ void show_scroll_win(WINDOW *main_window, /* create the pad */ pad = newpad(total_lines+10, total_cols+10); - wattrset(pad, attributes[SCROLLWIN_TEXT]); + (void) wattrset(pad, attributes[SCROLLWIN_TEXT]); fill_window(pad, text); win_lines = min(total_lines+4, LINES-2); @@ -546,9 +546,9 @@ void show_scroll_win(WINDOW *main_window, win = newwin(win_lines, win_cols, y, x); keypad(win, TRUE); /* show the help in the help window, and show the help panel */ - wattrset(win, attributes[SCROLLWIN_BOX]); + (void) wattrset(win, attributes[SCROLLWIN_BOX]); box(win, 0, 0); - wattrset(win, attributes[SCROLLWIN_HEADING]); + (void) wattrset(win, attributes[SCROLLWIN_HEADING]); mvwprintw(win, 0, 3, " %s ", title); panel = new_panel(win); diff --git a/scripts/kconfig/nconf.h b/scripts/kconfig/nconf.h index fb4296666004..58fbda8fc0dc 100644 --- a/scripts/kconfig/nconf.h +++ b/scripts/kconfig/nconf.h @@ -69,7 +69,8 @@ typedef enum { F_BACK = 5, F_SAVE = 6, F_LOAD = 7, - F_EXIT = 8 + F_SEARCH = 8, + F_EXIT = 9, } function_key; void set_colors(void); -- cgit v1.2.3 From 94bedeca77bf79a81952ed4c3abb8c1cce4c85dd Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Tue, 17 Aug 2010 01:40:20 -0400 Subject: kbuild: confdata.c explicitly reference errno, thus need This fixes: % gmake LKC_GENPARSER=1 menuconfig [...] scripts/kconfig/confdata.c:739: error: 'errno' undeclared (first use in this function) scripts/kconfig/confdata.c:739: error: (Each undeclared identifier is reported only once scripts/kconfig/confdata.c:739: error: for each function it appears in.) scripts/kconfig/confdata.c:739: error: 'ENOENT' undeclared (first use in this function) triggered on NetBSD. Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 515253fe46cf..dc11d51bd8b3 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include -- cgit v1.2.3 From 42368c37fbd51f7b478d041ae55c5df000897158 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Tue, 17 Aug 2010 10:21:19 +0200 Subject: kconfig: Allow frontends to display messages themselves Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 35 +++++++++++++++++++++++++------ scripts/kconfig/lkc_proto.h | 2 ++ scripts/kconfig/nconf.c | 51 ++++++++------------------------------------- 3 files changed, 40 insertions(+), 48 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index dc11d51bd8b3..c07060ab7820 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -19,6 +19,9 @@ static void conf_warning(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); +static void conf_message(const char *fmt, ...) + __attribute__ ((format (printf, 1, 2))); + static const char *conf_filename; static int conf_lineno, conf_warnings, conf_unsaved; @@ -35,6 +38,29 @@ static void conf_warning(const char *fmt, ...) conf_warnings++; } +static void conf_default_message_callback(const char *fmt, va_list ap) +{ + printf("#\n# "); + vprintf(fmt, ap); + printf("\n#\n"); +} + +static void (*conf_message_callback) (const char *fmt, va_list ap) = + conf_default_message_callback; +void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap)) +{ + conf_message_callback = fn; +} + +static void conf_message(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (conf_message_callback) + conf_message_callback(fmt, ap); +} + const char *conf_get_configname(void) { char *name = getenv("KCONFIG_CONFIG"); @@ -184,9 +210,8 @@ int conf_read_simple(const char *name, int def) name = conf_expand_value(prop->expr->left.sym->name); in = zconf_fopen(name); if (in) { - printf(_("#\n" - "# using defaults found in %s\n" - "#\n"), name); + conf_message(_("using defaults found in %s"), + name); goto load; } } @@ -651,9 +676,7 @@ next: return 1; } - printf(_("#\n" - "# configuration written to %s\n" - "#\n"), newname); + conf_message(_("configuration written to %s"), newname); sym_set_change_count(0); diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 9a948c9ce44e..481d4849d0f0 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -1,3 +1,4 @@ +#include /* confdata.c */ P(conf_parse,void,(const char *name)); @@ -8,6 +9,7 @@ P(conf_write,int,(const char *name)); P(conf_write_autoconf,int,(void)); P(conf_get_changed,bool,(void)); P(conf_set_changed_callback, void,(void (*fn)(void))); +P(conf_set_message_callback, void,(void (*fn)(const char *fmt, va_list ap))); /* menu.c */ P(rootmenu,struct menu,); diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 18a215de9f36..16233a9382c8 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -651,25 +651,6 @@ static const char *set_config_filename(const char *config_filename) return menu_backtitle; } -/* command = 0 is supress, 1 is restore */ -static void supress_stdout(int command) -{ - static FILE *org_stdout; - static FILE *org_stderr; - - if (command == 0) { - org_stdout = stdout; - org_stderr = stderr; - stdout = fopen("/dev/null", "a"); - stderr = fopen("/dev/null", "a"); - } else { - fclose(stdout); - fclose(stderr); - stdout = org_stdout; - stderr = org_stderr; - } -} - /* return = 0 means we are successful. * -1 means go on doing what you were doing */ @@ -695,9 +676,7 @@ static int do_exit(void) /* if we got here, the user really wants to exit */ switch (res) { case 0: - supress_stdout(0); res = conf_write(filename); - supress_stdout(1); if (res) btn_dialog( main_window, @@ -707,19 +686,6 @@ static int do_exit(void) "changes were NOT saved."), 1, ""); - else { - char buf[1024]; - snprintf(buf, 1024, - _("Configuration written to %s\n" - "End of Linux kernel configuration.\n" - "Execute 'make' to build the kernel or try" - " 'make help'."), filename); - btn_dialog( - main_window, - buf, - 1, - ""); - } break; default: btn_dialog( @@ -1255,6 +1221,14 @@ static void conf(struct menu *menu) } } +static void conf_message_callback(const char *fmt, va_list ap) +{ + char buf[1024]; + + vsnprintf(buf, sizeof(buf), fmt, ap); + btn_dialog(main_window, buf, 1, ""); +} + static void show_help(struct menu *menu) { struct gstr help = str_new(); @@ -1477,16 +1451,8 @@ static void conf_save(void) case 0: if (!dialog_input_result[0]) return; - supress_stdout(0); res = conf_write(dialog_input_result); - supress_stdout(1); if (!res) { - char buf[1024]; - sprintf(buf, "%s %s", - _("configuration file saved to: "), - dialog_input_result); - btn_dialog(main_window, - buf, 1, ""); set_config_filename(dialog_input_result); return; } @@ -1579,6 +1545,7 @@ int main(int ac, char **av) _(menu_no_f_instructions)); } + conf_set_message_callback(conf_message_callback); /* do the work */ while (!global_exit) { conf(&rootmenu); -- cgit v1.2.3 From 7080e47bb2783c04982526068204c1c8fc2c4c38 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Mon, 16 Aug 2010 00:19:04 -0400 Subject: kbuild: don't include `check-lxdialog' ldflags in global HOST_LOADLIBES On BSD systems, `check-lxdialog' would select -lcurses as the default curses library which would conflict with -lncurses at runtime: curses' compatible symbols are getting handled by the system's curses library while the ncurses-specific symbols are getting handled by the ports' ncurses. This fixes `nconf' segmentation fault on these systems. Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index de934def410f..7522a8bc0553 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -146,7 +146,6 @@ check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh # Use recursively expanded variables so we do not call gcc unless # we really need to do so. (Do not call gcc as part of make mrproper) HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) -HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) HOST_EXTRACFLAGS += -DLOCALE @@ -208,7 +207,7 @@ clean-files += config.pot linux.pot PHONY += $(obj)/dochecklxdialog $(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog $(obj)/dochecklxdialog: - $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOST_LOADLIBES) + $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTLOADLIBES_mconf) always := dochecklxdialog @@ -226,6 +225,8 @@ HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` -ldl HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ -D LKC_DIRECT_LINK +HOSTLOADLIBES_mconf = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) + HOSTLOADLIBES_nconf = -lmenu -lpanel -lncurses $(obj)/qconf.o: $(obj)/.tmp_qtcheck -- cgit v1.2.3 From c24035b9edad6164ddc12e88444acea741d5e309 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Mon, 16 Aug 2010 00:19:06 -0400 Subject: kbuild: fix typo Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/nconf.gui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index d963071e48df..f8137b3a5382 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -137,7 +137,7 @@ void set_colors() if (has_colors()) { normal_color_theme(); } else { - /* give deafults */ + /* give defaults */ no_colors_theme(); } } -- cgit v1.2.3 From 3c955b407a084810f57260d61548cc92c14bc627 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 16 Aug 2010 11:58:58 +0100 Subject: fixes for using make 3.82 It doesn't like pattern and explicit rules to be on the same line, and it seems to be more picky when matching file (or really directory) names with different numbers of trailing slashes. Signed-off-by: Jan Beulich Acked-by: Sam Ravnborg Andrew Benton Cc: Signed-off-by: Michal Marek --- scripts/mkmakefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mkmakefile b/scripts/mkmakefile index 67d59c7a18dc..5325423ceab4 100644 --- a/scripts/mkmakefile +++ b/scripts/mkmakefile @@ -44,7 +44,9 @@ all: Makefile:; -\$(all) %/: all +\$(all): all @: +%/: all + @: EOF -- cgit v1.2.3 From 8558f59edf935cf5ee5ffc29a9e9458fd9a71be1 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Mon, 16 Aug 2010 17:09:52 +0200 Subject: setlocalversion: Ignote SCMs above the linux source tree Dan McGee writes: > Note that when in git, you get the appended "+" sign. If > LOCALVERSION_AUTO is set, you will get something like > "eee-gb01b08c-dirty" (whereas the copy of the tree in /tmp still > returns "eee"). It doesn't matter whether the working tree is dirty or > clean. > > Is there a way to disable this? I'm building from a clean tarball that > just happens to be unpacked inside a git repository. One would think > setting LOCALVERSION_AUTO to false would do it, but no such luck... Fix this by checking if the kernel source tree is the root of the git or hg repository. No fix for svn: If the kernel source is not tracked in the svn repository, it works as expected, otherwise determining the 'repository root' is not really a defined task. Reported-and-tested-by: Dan McGee Signed-off-by: Michal Marek --- scripts/setlocalversion | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/setlocalversion b/scripts/setlocalversion index e90a91cc5185..057b6b3c5dfb 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -43,7 +43,7 @@ scm_version() fi # Check for git and a git repo. - if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then + if test -d .git && head=`git rev-parse --verify --short HEAD 2>/dev/null`; then # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore # it, because this version is defined in the top level Makefile. @@ -85,7 +85,7 @@ scm_version() fi # Check for mercurial and a mercurial repo. - if hgid=`hg id 2>/dev/null`; then + if test -d .hg && hgid=`hg id 2>/dev/null`; then tag=`printf '%s' "$hgid" | cut -s -d' ' -f2` # Do we have an untagged version? -- cgit v1.2.3 From cbcf14a942eb06d031628046739b983e84b383bf Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 17 Aug 2010 13:36:40 +0300 Subject: scripts/mod/modpost.c: fix commentary accordingly to last changes The last commits 37ed19d5cce35a40d3913cf9aa208ce9f60db3d7 5003bab82d56754b27be01eef24495a02e00039d have introduced new behaviour of sec2annotation() method. However, the commentary inside the method was left as before. Let's fix it accordingly. Signed-off-by: Andy Shevchenko Cc: Rusty Russell Cc: Andrew Morton Acked-by: WANG Cong Signed-off-by: Michal Marek --- scripts/mod/modpost.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c827309c29cf..859bee4972e9 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1193,6 +1193,9 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr, * .cpuinit.data => __cpudata * .memexitconst => __memconst * etc. + * + * The memory of returned value has been allocated on a heap. The user of this + * method should free it after usage. */ static char *sec2annotation(const char *s) { @@ -1215,7 +1218,7 @@ static char *sec2annotation(const char *s) strcat(p, "data "); else strcat(p, " "); - return r; /* we leak her but we do not care */ + return r; } else { return ""; } -- cgit v1.2.3 From 9ba9568259f71bc848ac460bc616ce9640634693 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 22 Aug 2010 20:03:06 -0400 Subject: kbuild: don't overwrite HOST_EXTRACFLAGS This might be used by the user to specify extra arguments for the host compiler. Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 7522a8bc0553..06c1c2f80bb7 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -145,10 +145,8 @@ check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh # Use recursively expanded variables so we do not call gcc unless # we really need to do so. (Do not call gcc as part of make mrproper) -HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) - -HOST_EXTRACFLAGS += -DLOCALE - +HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \ + -DLOCALE # =========================================================================== # Shared Makefile for the various kconfig executables: -- cgit v1.2.3 From c75b81bffa0a9493a24ae61d0c52f85e4043c183 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:38:55 +0200 Subject: Coccinelle: Add null/eno.cocci The various basic memory allocation functions don't return ERR_PTR Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/null/eno.cocci | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 scripts/coccinelle/null/eno.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/null/eno.cocci b/scripts/coccinelle/null/eno.cocci new file mode 100644 index 000000000000..4c9c52b9c413 --- /dev/null +++ b/scripts/coccinelle/null/eno.cocci @@ -0,0 +1,20 @@ +/// 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. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual patch + +@@ +expression x,E; +@@ + +x = \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...) +... when != x = E +- IS_ERR(x) ++ !x -- cgit v1.2.3 From 2e1e1605fc60b3fcf1e9382729a92fc305727952 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:38:56 +0200 Subject: Coccinelle: Add null/kmerr.cocci This semantic patch looks for kmalloc etc that are not followed by a NULL check. It only gives a report in the case where there is some error handling code later in the function, which may be helpful in determining what the error handling code for the call to kmalloc etc should be. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/null/kmerr.cocci | 72 +++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 scripts/coccinelle/null/kmerr.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/null/kmerr.cocci b/scripts/coccinelle/null/kmerr.cocci new file mode 100644 index 000000000000..949bf656c64c --- /dev/null +++ b/scripts/coccinelle/null/kmerr.cocci @@ -0,0 +1,72 @@ +/// This semantic patch looks for kmalloc etc that are not followed by a +/// NULL check. It only gives a report in the case where there is some +/// error handling code later in the function, which may be helpful +/// in determining what the error handling code for the call to kmalloc etc +/// should be. +/// +// Confidence: High +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual context +virtual org +virtual report + +@withtest@ +expression x; +position p; +identifier f,fld; +@@ + +x@p = f(...); +... when != x->fld +\(x == NULL \| x != NULL\) + +@fixed depends on context && !org && !report@ +expression x,x1; +position p1 != withtest.p; +statement S; +position any withtest.p; +identifier f; +@@ + +*x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...); +... +*x1@p = f(...); +if (!x1) S + +// ------------------------------------------------------------------------ + +@rfixed depends on (org || report) && !context exists@ +expression x,x1; +position p1 != withtest.p; +position p2; +statement S; +position any withtest.p; +identifier f; +@@ + +x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...); +... +x1@p = f@p2(...); +if (!x1) S + +@script:python depends on org@ +p1 << rfixed.p1; +p2 << rfixed.p2; +@@ + +cocci.print_main("alloc call",p1) +cocci.print_secs("possible model",p2) + +@script:python depends on report@ +p1 << rfixed.p1; +p2 << rfixed.p2; +@@ + +msg = "alloc with no test, possible model on line %s" % (p2[0].line) +coccilib.report.print_report(p1[0],msg) -- cgit v1.2.3 From 7703692ef8d6356c32fbe9665d8cbe5b040eec09 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:38:57 +0200 Subject: Coccinelle: Move deref_null.cocci to a more appropriate directory deref_null.cocci is moved to the 'null' directory which contains other null related rules. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/deref_null.cocci | 293 ------------------------------- scripts/coccinelle/null/deref_null.cocci | 293 +++++++++++++++++++++++++++++++ 2 files changed, 293 insertions(+), 293 deletions(-) delete mode 100644 scripts/coccinelle/deref_null.cocci create mode 100644 scripts/coccinelle/null/deref_null.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/deref_null.cocci b/scripts/coccinelle/deref_null.cocci deleted file mode 100644 index 9969d76d0f4b..000000000000 --- a/scripts/coccinelle/deref_null.cocci +++ /dev/null @@ -1,293 +0,0 @@ -/// -/// A variable is dereference under a NULL test. -/// Even though it is know to be NULL. -/// -// Confidence: Moderate -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. -// URL: http://coccinelle.lip6.fr/ -// Comments: -I ... -all_includes can give more complete results -// Options: - -virtual context -virtual patch -virtual org -virtual report - -@initialize:python depends on !context && patch && !org && !report@ - -import sys -print >> sys.stderr, "This semantic patch does not support the 'patch' mode." - -@depends on patch@ -@@ - -this_rule_should_never_matches(); - -@ifm depends on !patch@ -expression *E; -statement S1,S2; -position p1; -@@ - -if@p1 ((E == NULL && ...) || ...) S1 else S2 - -// The following two rules are separate, because both can match a single -// expression in different ways -@pr1 depends on !patch expression@ -expression *ifm.E; -identifier f; -position p1; -@@ - - (E != NULL && ...) ? <+...E->f@p1...+> : ... - -@pr2 depends on !patch expression@ -expression *ifm.E; -identifier f; -position p2; -@@ - -( - (E != NULL) && ... && <+...E->f@p2...+> -| - (E == NULL) || ... || <+...E->f@p2...+> -| - sizeof(<+...E->f@p2...+>) -) - -// For org and report modes - -@r depends on !context && !patch && (org || report) exists@ -expression subE <= ifm.E; -expression *ifm.E; -expression E1,E2; -identifier f; -statement S1,S2,S3,S4; -iterator iter; -position p!={pr1.p1,pr2.p2}; -position ifm.p1; -@@ - -if@p1 ((E == NULL && ...) || ...) -{ - ... when != if (...) S1 else S2 -( - iter(subE,...) S4 // no use -| - list_remove_head(E2,subE,...) -| - subE = E1 -| - for(subE = E1;...;...) S4 -| - subE++ -| - ++subE -| - --subE -| - subE-- -| - &subE -| - E->f@p // bad use -) - ... when any - return ...; -} -else S3 - -@script:python depends on !context && !patch && !org && report@ -p << r.p; -p1 << ifm.p1; -x << ifm.E; -@@ - -msg="ERROR: %s is NULL but dereferenced." % (x) -coccilib.report.print_report(p[0], msg) -cocci.include_match(False) - -@script:python depends on !context && !patch && org && !report@ -p << r.p; -p1 << ifm.p1; -x << ifm.E; -@@ - -msg="ERROR: %s is NULL but dereferenced." % (x) -msg_safe=msg.replace("[","@(").replace("]",")") -cocci.print_main(msg_safe,p) -cocci.include_match(False) - -@s depends on !context && !patch && (org || report) exists@ -expression subE <= ifm.E; -expression *ifm.E; -expression E1,E2; -identifier f; -statement S1,S2,S3,S4; -iterator iter; -position p!={pr1.p1,pr2.p2}; -position ifm.p1; -@@ - -if@p1 ((E == NULL && ...) || ...) -{ - ... when != if (...) S1 else S2 -( - iter(subE,...) S4 // no use -| - list_remove_head(E2,subE,...) -| - subE = E1 -| - for(subE = E1;...;...) S4 -| - subE++ -| - ++subE -| - --subE -| - subE-- -| - &subE -| - E->f@p // bad use -) - ... when any -} -else S3 - -@script:python depends on !context && !patch && !org && report@ -p << s.p; -p1 << ifm.p1; -x << ifm.E; -@@ - -msg="ERROR: %s is NULL but dereferenced." % (x) -coccilib.report.print_report(p[0], msg) - -@script:python depends on !context && !patch && org && !report@ -p << s.p; -p1 << ifm.p1; -x << ifm.E; -@@ - -msg="ERROR: %s is NULL but dereferenced." % (x) -msg_safe=msg.replace("[","@(").replace("]",")") -cocci.print_main(msg_safe,p) - -// For context mode - -@depends on context && !patch && !org && !report exists@ -expression subE <= ifm.E; -expression *ifm.E; -expression E1,E2; -identifier f; -statement S1,S2,S3,S4; -iterator iter; -position p!={pr1.p1,pr2.p2}; -position ifm.p1; -@@ - -if@p1 ((E == NULL && ...) || ...) -{ - ... when != if (...) S1 else S2 -( - iter(subE,...) S4 // no use -| - list_remove_head(E2,subE,...) -| - subE = E1 -| - for(subE = E1;...;...) S4 -| - subE++ -| - ++subE -| - --subE -| - subE-- -| - &subE -| -* E->f@p // bad use -) - ... when any - return ...; -} -else S3 - -// The following three rules are duplicates of ifm, pr1 and pr2 respectively. -// It is need because the previous rule as already made a "change". - -@ifm1 depends on !patch@ -expression *E; -statement S1,S2; -position p1; -@@ - -if@p1 ((E == NULL && ...) || ...) S1 else S2 - -@pr11 depends on !patch expression@ -expression *ifm1.E; -identifier f; -position p1; -@@ - - (E != NULL && ...) ? <+...E->f@p1...+> : ... - -@pr12 depends on !patch expression@ -expression *ifm1.E; -identifier f; -position p2; -@@ - -( - (E != NULL) && ... && <+...E->f@p2...+> -| - (E == NULL) || ... || <+...E->f@p2...+> -| - sizeof(<+...E->f@p2...+>) -) - -@depends on context && !patch && !org && !report exists@ -expression subE <= ifm1.E; -expression *ifm1.E; -expression E1,E2; -identifier f; -statement S1,S2,S3,S4; -iterator iter; -position p!={pr11.p1,pr12.p2}; -position ifm1.p1; -@@ - -if@p1 ((E == NULL && ...) || ...) -{ - ... when != if (...) S1 else S2 -( - iter(subE,...) S4 // no use -| - list_remove_head(E2,subE,...) -| - subE = E1 -| - for(subE = E1;...;...) S4 -| - subE++ -| - ++subE -| - --subE -| - subE-- -| - &subE -| -* E->f@p // bad use -) - ... when any -} -else S3 diff --git a/scripts/coccinelle/null/deref_null.cocci b/scripts/coccinelle/null/deref_null.cocci new file mode 100644 index 000000000000..9969d76d0f4b --- /dev/null +++ b/scripts/coccinelle/null/deref_null.cocci @@ -0,0 +1,293 @@ +/// +/// A variable is dereference under a NULL test. +/// Even though it is know to be NULL. +/// +// Confidence: Moderate +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: -I ... -all_includes can give more complete results +// Options: + +virtual context +virtual patch +virtual org +virtual report + +@initialize:python depends on !context && patch && !org && !report@ + +import sys +print >> sys.stderr, "This semantic patch does not support the 'patch' mode." + +@depends on patch@ +@@ + +this_rule_should_never_matches(); + +@ifm depends on !patch@ +expression *E; +statement S1,S2; +position p1; +@@ + +if@p1 ((E == NULL && ...) || ...) S1 else S2 + +// The following two rules are separate, because both can match a single +// expression in different ways +@pr1 depends on !patch expression@ +expression *ifm.E; +identifier f; +position p1; +@@ + + (E != NULL && ...) ? <+...E->f@p1...+> : ... + +@pr2 depends on !patch expression@ +expression *ifm.E; +identifier f; +position p2; +@@ + +( + (E != NULL) && ... && <+...E->f@p2...+> +| + (E == NULL) || ... || <+...E->f@p2...+> +| + sizeof(<+...E->f@p2...+>) +) + +// For org and report modes + +@r depends on !context && !patch && (org || report) exists@ +expression subE <= ifm.E; +expression *ifm.E; +expression E1,E2; +identifier f; +statement S1,S2,S3,S4; +iterator iter; +position p!={pr1.p1,pr2.p2}; +position ifm.p1; +@@ + +if@p1 ((E == NULL && ...) || ...) +{ + ... when != if (...) S1 else S2 +( + iter(subE,...) S4 // no use +| + list_remove_head(E2,subE,...) +| + subE = E1 +| + for(subE = E1;...;...) S4 +| + subE++ +| + ++subE +| + --subE +| + subE-- +| + &subE +| + E->f@p // bad use +) + ... when any + return ...; +} +else S3 + +@script:python depends on !context && !patch && !org && report@ +p << r.p; +p1 << ifm.p1; +x << ifm.E; +@@ + +msg="ERROR: %s is NULL but dereferenced." % (x) +coccilib.report.print_report(p[0], msg) +cocci.include_match(False) + +@script:python depends on !context && !patch && org && !report@ +p << r.p; +p1 << ifm.p1; +x << ifm.E; +@@ + +msg="ERROR: %s is NULL but dereferenced." % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +cocci.print_main(msg_safe,p) +cocci.include_match(False) + +@s depends on !context && !patch && (org || report) exists@ +expression subE <= ifm.E; +expression *ifm.E; +expression E1,E2; +identifier f; +statement S1,S2,S3,S4; +iterator iter; +position p!={pr1.p1,pr2.p2}; +position ifm.p1; +@@ + +if@p1 ((E == NULL && ...) || ...) +{ + ... when != if (...) S1 else S2 +( + iter(subE,...) S4 // no use +| + list_remove_head(E2,subE,...) +| + subE = E1 +| + for(subE = E1;...;...) S4 +| + subE++ +| + ++subE +| + --subE +| + subE-- +| + &subE +| + E->f@p // bad use +) + ... when any +} +else S3 + +@script:python depends on !context && !patch && !org && report@ +p << s.p; +p1 << ifm.p1; +x << ifm.E; +@@ + +msg="ERROR: %s is NULL but dereferenced." % (x) +coccilib.report.print_report(p[0], msg) + +@script:python depends on !context && !patch && org && !report@ +p << s.p; +p1 << ifm.p1; +x << ifm.E; +@@ + +msg="ERROR: %s is NULL but dereferenced." % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +cocci.print_main(msg_safe,p) + +// For context mode + +@depends on context && !patch && !org && !report exists@ +expression subE <= ifm.E; +expression *ifm.E; +expression E1,E2; +identifier f; +statement S1,S2,S3,S4; +iterator iter; +position p!={pr1.p1,pr2.p2}; +position ifm.p1; +@@ + +if@p1 ((E == NULL && ...) || ...) +{ + ... when != if (...) S1 else S2 +( + iter(subE,...) S4 // no use +| + list_remove_head(E2,subE,...) +| + subE = E1 +| + for(subE = E1;...;...) S4 +| + subE++ +| + ++subE +| + --subE +| + subE-- +| + &subE +| +* E->f@p // bad use +) + ... when any + return ...; +} +else S3 + +// The following three rules are duplicates of ifm, pr1 and pr2 respectively. +// It is need because the previous rule as already made a "change". + +@ifm1 depends on !patch@ +expression *E; +statement S1,S2; +position p1; +@@ + +if@p1 ((E == NULL && ...) || ...) S1 else S2 + +@pr11 depends on !patch expression@ +expression *ifm1.E; +identifier f; +position p1; +@@ + + (E != NULL && ...) ? <+...E->f@p1...+> : ... + +@pr12 depends on !patch expression@ +expression *ifm1.E; +identifier f; +position p2; +@@ + +( + (E != NULL) && ... && <+...E->f@p2...+> +| + (E == NULL) || ... || <+...E->f@p2...+> +| + sizeof(<+...E->f@p2...+>) +) + +@depends on context && !patch && !org && !report exists@ +expression subE <= ifm1.E; +expression *ifm1.E; +expression E1,E2; +identifier f; +statement S1,S2,S3,S4; +iterator iter; +position p!={pr11.p1,pr12.p2}; +position ifm1.p1; +@@ + +if@p1 ((E == NULL && ...) || ...) +{ + ... when != if (...) S1 else S2 +( + iter(subE,...) S4 // no use +| + list_remove_head(E2,subE,...) +| + subE = E1 +| + for(subE = E1;...;...) S4 +| + subE++ +| + ++subE +| + --subE +| + subE-- +| + &subE +| +* E->f@p // bad use +) + ... when any +} +else S3 -- cgit v1.2.3 From e105007c1271243568d58c8a4285b19c8eea48d1 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:38:58 +0200 Subject: Coccinelle: Add locks/call_kern.cocci 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. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/locks/call_kern.cocci | 74 ++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 scripts/coccinelle/locks/call_kern.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/locks/call_kern.cocci b/scripts/coccinelle/locks/call_kern.cocci new file mode 100644 index 000000000000..00af5344a68f --- /dev/null +++ b/scripts/coccinelle/locks/call_kern.cocci @@ -0,0 +1,74 @@ +/// 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. +/// +// Confidence: Moderate +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual patch + +@gfp exists@ +identifier fn; +position p; +@@ + +fn(...) { + ... when != read_unlock_irq(...) + when != write_unlock_irq(...) + when != read_unlock_irqrestore(...) + when != write_unlock_irqrestore(...) + when != spin_unlock(...) + when != spin_unlock_irq(...) + when != spin_unlock_irqrestore(...) + when != local_irq_enable(...) + when any + GFP_KERNEL@p + ... when any +} + +@locked@ +identifier gfp.fn; +@@ + +( +read_lock_irq +| +write_lock_irq +| +read_lock_irqsave +| +write_lock_irqsave +| +spin_lock +| +spin_trylock +| +spin_lock_irq +| +spin_lock_irqsave +| +local_irq_disable +) + (...) +... when != read_unlock_irq(...) + when != write_unlock_irq(...) + when != read_unlock_irqrestore(...) + when != write_unlock_irqrestore(...) + when != spin_unlock(...) + when != spin_unlock_irq(...) + when != spin_unlock_irqrestore(...) + when != local_irq_enable(...) +fn(...) + +@depends on locked@ +position gfp.p; +@@ + +- GFP_KERNEL@p ++ GFP_ATOMIC -- cgit v1.2.3 From 8aa6273106756c30e5349b58eed28d93d8d88164 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:38:59 +0200 Subject: Coccinelle: Add locks/double_lock.cocci Find double locks. False positives may occur when some paths cannot occur at execution, due to the values of variables, and when there is an intervening function call that releases the lock. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/locks/double_lock.cocci | 92 ++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 scripts/coccinelle/locks/double_lock.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/locks/double_lock.cocci b/scripts/coccinelle/locks/double_lock.cocci new file mode 100644 index 000000000000..63b24e682fad --- /dev/null +++ b/scripts/coccinelle/locks/double_lock.cocci @@ -0,0 +1,92 @@ +/// Find double locks. False positives may occur when some paths cannot +/// occur at execution, due to the values of variables, and when there is +/// an intervening 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. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual org +virtual report + +@locked@ +position p1; +expression E1; +position p; +@@ + +( +mutex_lock@p1 +| +mutex_trylock@p1 +| +spin_lock@p1 +| +spin_trylock@p1 +| +read_lock@p1 +| +read_trylock@p1 +| +write_lock@p1 +| +write_trylock@p1 +) (E1@p,...); + +@balanced@ +position p1 != locked.p1; +position locked.p; +identifier lock,unlock; +expression x <= locked.E1; +expression E,locked.E1; +expression E2; +@@ + +if (E) { + <+... when != E1 + lock(E1@p,...) + ...+> +} +... when != E1 + when != \(x = E2\|&x\) + when forall +if (E) { + <+... when != E1 + unlock@p1(E1,...) + ...+> +} + +@r depends on !balanced exists@ +expression x <= locked.E1; +expression locked.E1; +expression E2; +identifier lock; +position locked.p,p1,p2; +@@ + +lock@p1 (E1@p,...); +... when != E1 + when != \(x = E2\|&x\) +lock@p2 (E1,...); + +@script:python depends on org@ +p1 << r.p1; +p2 << r.p2; +lock << r.lock; +@@ + +cocci.print_main(lock,p1) +cocci.print_secs("second lock",p2) + +@script:python depends on report@ +p1 << r.p1; +p2 << r.p2; +lock << r.lock; +@@ + +msg = "second lock on line %s" % (p2[0].line) +coccilib.report.print_report(p1[0],msg) -- cgit v1.2.3 From 54c056280e0dfcd39b33c4ed75116ce98697511c Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:00 +0200 Subject: Coccinelle: Add locks/mini_lock.cocci Find missing unlocks. This semantic match considers the specific case where the unlock is missing from an if branch, and there is a lock before the if and an unlock after the if. False positives are due to cases where the if branch represents a case where the function is supposed to exit with the lock held, or where there is some preceding function call that releases the lock. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/locks/mini_lock.cocci | 95 ++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 scripts/coccinelle/locks/mini_lock.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/locks/mini_lock.cocci b/scripts/coccinelle/locks/mini_lock.cocci new file mode 100644 index 000000000000..7641a2925434 --- /dev/null +++ b/scripts/coccinelle/locks/mini_lock.cocci @@ -0,0 +1,95 @@ +/// Find missing unlocks. This semantic match considers the specific case +/// where the unlock is missing from an if branch, and there is a lock +/// before the if and an unlock after the if. False positives are due to +/// cases where the if branch represents a case where the function is +/// supposed to exit with the lock held, or where there is some preceding +/// 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. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual org +virtual report + +@prelocked@ +position p1,p; +expression E1; +@@ + +( +mutex_lock@p1 +| +mutex_trylock@p1 +| +spin_lock@p1 +| +spin_trylock@p1 +| +read_lock@p1 +| +read_trylock@p1 +| +write_lock@p1 +| +write_trylock@p1 +| +read_lock_irq@p1 +| +write_lock_irq@p1 +| +read_lock_irqsave@p1 +| +write_lock_irqsave@p1 +| +spin_lock_irq@p1 +| +spin_lock_irqsave@p1 +) (E1@p,...); + +@looped@ +position r; +@@ + +for(...;...;...) { <+... return@r ...; ...+> } + +@err@ +expression E1; +position prelocked.p; +position up != prelocked.p1; +position r!=looped.r; +identifier lock,unlock; +@@ + +lock(E1@p,...); +<+... when != E1 +if (...) { + ... when != E1 + return@r ...; +} +...+> +unlock@up(E1,...); + +@script:python depends on org@ +p << prelocked.p1; +lock << err.lock; +unlock << err.unlock; +p2 << err.r; +@@ + +cocci.print_main(lock,p) +cocci.print_secs(unlock,p2) + +@script:python depends on report@ +p << prelocked.p1; +lock << err.lock; +unlock << err.unlock; +p2 << err.r; +@@ + +msg = "preceding lock on line %s" % (p[0].line) +coccilib.report.print_report(p2[0],msg) -- cgit v1.2.3 From 4045159253a49a56d117148d67bc86a72762a0d3 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:01 +0200 Subject: Coccinelle: Add iterators/fen.cocci for_each_node iterators only exit normally when the loop cursor is NULL, so there is no point to call of_node_put on the final value. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/iterators/fen.cocci | 64 ++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 scripts/coccinelle/iterators/fen.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/iterators/fen.cocci b/scripts/coccinelle/iterators/fen.cocci new file mode 100644 index 000000000000..77bc108c3f59 --- /dev/null +++ b/scripts/coccinelle/iterators/fen.cocci @@ -0,0 +1,64 @@ +/// These iterators only exit normally when the loop cursor is NULL, so there +/// 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. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual patch + +@@ +iterator name for_each_node_by_name; +expression np,E; +identifier l; +@@ + +for_each_node_by_name(np,...) { + ... when != break; + when != goto l; +} +... when != np = E +- of_node_put(np); + +@@ +iterator name for_each_node_by_type; +expression np,E; +identifier l; +@@ + +for_each_node_by_type(np,...) { + ... when != break; + when != goto l; +} +... when != np = E +- of_node_put(np); + +@@ +iterator name for_each_compatible_node; +expression np,E; +identifier l; +@@ + +for_each_compatible_node(np,...) { + ... when != break; + when != goto l; +} +... when != np = E +- of_node_put(np); + +@@ +iterator name for_each_matching_node; +expression np,E; +identifier l; +@@ + +for_each_matching_node(np,...) { + ... when != break; + when != goto l; +} +... when != np = E +- of_node_put(np); -- cgit v1.2.3 From afc48a82fafe55dbeeaf7c0d83d29cf279cb1c70 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:02 +0200 Subject: Coccinelle: Add iterators/itnull.cocci 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). Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/iterators/itnull.cocci | 58 +++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 scripts/coccinelle/iterators/itnull.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/iterators/itnull.cocci b/scripts/coccinelle/iterators/itnull.cocci new file mode 100644 index 000000000000..baa4297a4ed1 --- /dev/null +++ b/scripts/coccinelle/iterators/itnull.cocci @@ -0,0 +1,58 @@ +/// 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). +/// +// Confidence: Moderate +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual patch + +@@ +iterator I; +expression x,E,E1,E2; +statement S,S1,S2; +@@ + +I(x,...) { <... +( +- if (x == NULL && ...) S +| +- if (x != NULL || ...) + S +| +- (x == NULL) || + E +| +- (x != NULL) && + E +| +- (x == NULL && ...) ? E1 : + E2 +| +- (x != NULL || ...) ? + E1 +- : E2 +| +- if (x == NULL && ...) S1 else + S2 +| +- if (x != NULL || ...) + S1 +- else S2 +| ++ BAD( + x == NULL ++ ) +| ++ BAD( + x != NULL ++ ) +) + ...> } \ No newline at end of file -- cgit v1.2.3 From 5c34050188f5e3db7f8137d819ecbb7d9327dd93 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:03 +0200 Subject: Coccinelle: Add iterators/list_entry_update.cocci list_for_each_entry uses its first argument to get from one element of the list to the next, so it is usually not a good idea to reassign it. The first rule finds such a reassignment and the second rule checks that there is a path from the reassignment back to the top of the loop. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- .../coccinelle/iterators/list_entry_update.cocci | 62 ++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 scripts/coccinelle/iterators/list_entry_update.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/iterators/list_entry_update.cocci b/scripts/coccinelle/iterators/list_entry_update.cocci new file mode 100644 index 000000000000..b2967475679b --- /dev/null +++ b/scripts/coccinelle/iterators/list_entry_update.cocci @@ -0,0 +1,62 @@ +/// list_for_each_entry uses its first argument to get from one element of +/// the list to the next, so it is usually not a good idea to reassign it. +/// The first rule finds such a reassignment and the second rule checks +/// that there is a path from the reassignment back to the top of the loop. +/// +// Confidence: High +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual context +virtual org +virtual report + +@r@ +iterator name list_for_each_entry; +expression x,E; +position p1,p2; +@@ + +list_for_each_entry@p1(x,...) { <... x =@p2 E ...> } + +@depends on context && !org && !report@ +expression x,E; +position r.p1,r.p2; +statement S; +@@ + +*x =@p2 E +... +list_for_each_entry@p1(x,...) S + +// ------------------------------------------------------------------------ + +@back depends on (org || report) && !context exists@ +expression x,E; +position r.p1,r.p2; +statement S; +@@ + +x =@p2 E +... +list_for_each_entry@p1(x,...) S + +@script:python depends on back && org@ +p1 << r.p1; +p2 << r.p2; +@@ + +cocci.print_main("iterator",p1) +cocci.print_secs("update",p2) + +@script:python depends on back && report@ +p1 << r.p1; +p2 << r.p2; +@@ + +msg = "iterator with update on line %s" % (p2[0].line) +coccilib.report.print_report(p1[0],msg) -- cgit v1.2.3 From 43ba21b57a3e757000bfa8ccf46c81f232b4d881 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:04 +0200 Subject: Coccinelle: Add free/kfree.cocci Find a use after free. Values of variables may imply that some execution paths are not possible, resulting in false positives. Another source of false positives are macros such as SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/free/kfree.cocci | 116 ++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 scripts/coccinelle/free/kfree.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/free/kfree.cocci b/scripts/coccinelle/free/kfree.cocci new file mode 100644 index 000000000000..c13a5395707b --- /dev/null +++ b/scripts/coccinelle/free/kfree.cocci @@ -0,0 +1,116 @@ +/// Find a use after free. Values of variables may imply that some +/// execution paths are not possible, resulting in false positives. +/// Another source of false positives are macros such as +/// 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. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual org +virtual report + +@free@ +expression E; +position p1; +@@ + +kfree@p1(E) + +@print expression@ +constant char *c; +expression free.E,E2; +type T; +position p; +identifier f; +@@ + +( + f(...,c,...,(T)E@p,...) +| + E@p == E2 +| + E@p != E2 +| + !E@p +| + E@p || ... +) + +@sz@ +expression free.E; +position p; +@@ + + sizeof(<+...E@p...+>) + +@loop exists@ +expression E; +identifier l; +position ok; +@@ + +while (1) { ... + kfree@ok(E) + ... when != break; + when != goto l; + when forall +} + +@r exists@ +expression free.E, subE<=free.E, E2; +expression E1; +iterator iter; +statement S; +position free.p1!=loop.ok,p2!={print.p,sz.p}; +@@ + +kfree@p1(E,...) +... +( + iter(...,subE,...) S // no use +| + list_remove_head(E1,subE,...) +| + subE = E2 +| + subE++ +| + ++subE +| + --subE +| + subE-- +| + &subE +| + BUG(...) +| + BUG_ON(...) +| + return_VALUE(...) +| + return_ACPI_STATUS(...) +| + E@p2 // bad use +) + +@script:python depends on org@ +p1 << free.p1; +p2 << r.p2; +@@ + +cocci.print_main("kfree",p1) +cocci.print_secs("ref",p2) + +@script:python depends on report@ +p1 << free.p1; +p2 << r.p2; +@@ + +msg = "reference preceded by free on line %s" % (p1[0].line) +coccilib.report.print_report(p2[0],msg) -- cgit v1.2.3 From 998f5523230a8a837809f942d556360f69121677 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:05 +0200 Subject: Coccinelle: Add api/kstrdup.cocci Use kstrdup rather than duplicating its implementation Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/api/kstrdup.cocci | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 scripts/coccinelle/api/kstrdup.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/api/kstrdup.cocci b/scripts/coccinelle/api/kstrdup.cocci new file mode 100644 index 000000000000..e0805ad08d39 --- /dev/null +++ b/scripts/coccinelle/api/kstrdup.cocci @@ -0,0 +1,39 @@ +/// 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. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual patch + +@@ +expression from,to; +expression flag,E1,E2; +statement S; +@@ + +- to = kmalloc(strlen(from) + 1,flag); ++ to = kstrdup(from, flag); + ... when != \(from = E1 \| to = E1 \) + if (to==NULL || ...) S + ... when != \(from = E2 \| to = E2 \) +- strcpy(to, from); + +@@ +expression x,from,to; +expression flag,E1,E2,E3; +statement S; +@@ + +- x = strlen(from) + 1; + ... when != \( x = E1 \| from = E1 \) +- to = \(kmalloc\|kzalloc\)(x,flag); ++ to = kstrdup(from, flag); + ... when != \(x = E2 \| from = E2 \| to = E2 \) + if (to==NULL || ...) S + ... when != \(x = E3 \| from = E3 \| to = E3 \) +- memcpy(to, from, x); -- cgit v1.2.3 From 0426a97c4b672166cbcfdc7b18466d4f207f7a36 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:06 +0200 Subject: Coccinelle: Add api/memdup.cocci Use kmemdup rather than duplicating its implementation Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/api/memdup.cocci | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 scripts/coccinelle/api/memdup.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/api/memdup.cocci b/scripts/coccinelle/api/memdup.cocci new file mode 100644 index 000000000000..b5d722077dc1 --- /dev/null +++ b/scripts/coccinelle/api/memdup.cocci @@ -0,0 +1,40 @@ +/// 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. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual patch + +@r1@ +expression from,to; +expression flag; +position p; +@@ + + to = \(kmalloc@p\|kzalloc@p\)(strlen(from) + 1,flag); + +@r2@ +expression x,from,to; +expression flag,E1; +position p; +@@ + + x = strlen(from) + 1; + ... when != \( x = E1 \| from = E1 \) + to = \(kmalloc@p\|kzalloc@p\)(x,flag); + +@@ +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); -- cgit v1.2.3 From 034174598bc8ffd9586432852502e368a43ef0f1 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:07 +0200 Subject: Coccinelle: Add api/memdup_user Use kmemdup_user rather than duplicating its implementation This is a little bit restricted to reduce false positives Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/api/memdup_user.cocci | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 scripts/coccinelle/api/memdup_user.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/api/memdup_user.cocci b/scripts/coccinelle/api/memdup_user.cocci new file mode 100644 index 000000000000..72ce012e878a --- /dev/null +++ b/scripts/coccinelle/api/memdup_user.cocci @@ -0,0 +1,35 @@ +/// Use kmemdup_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. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual patch + +@@ +expression from,to,size,flag; +position p; +identifier l1,l2; +@@ + +- to = \(kmalloc@p\|kzalloc@p\)(size,flag); ++ to = memdup_user(from,size); + if ( +- to==NULL ++ IS_ERR(to) + || ...) { + <+... when != goto l1; +- -ENOMEM ++ PTR_ERR(to) + ...+> + } +- if (copy_from_user(to, from, size) != 0) { +- <+... when != goto l2; +- -EFAULT +- ...+> +- } -- cgit v1.2.3 From 99d653d4bc269aebf255f3864334110dbcc70f37 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:08 +0200 Subject: Coccinelle: Move err_cast.cocci to the api directory Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/api/err_cast.cocci | 56 +++++++++++++++++++++++++++++++++++ scripts/coccinelle/err_cast.cocci | 56 ----------------------------------- 2 files changed, 56 insertions(+), 56 deletions(-) create mode 100644 scripts/coccinelle/api/err_cast.cocci delete mode 100644 scripts/coccinelle/err_cast.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/api/err_cast.cocci b/scripts/coccinelle/api/err_cast.cocci new file mode 100644 index 000000000000..2ce115000af6 --- /dev/null +++ b/scripts/coccinelle/api/err_cast.cocci @@ -0,0 +1,56 @@ +/// +/// Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(...)) +/// +// Confidence: High +// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Options: +// +// Keywords: ERR_PTR, PTR_ERR, ERR_CAST +// Version min: 2.6.25 +// + +virtual context +virtual patch +virtual org +virtual report + + +@ depends on context && !patch && !org && !report@ +expression x; +@@ + +* ERR_PTR(PTR_ERR(x)) + +@ depends on !context && patch && !org && !report @ +expression x; +@@ + +- ERR_PTR(PTR_ERR(x)) ++ ERR_CAST(x) + +@r depends on !context && !patch && (org || report)@ +expression x; +position p; +@@ + + ERR_PTR@p(PTR_ERR(x)) + +@script:python depends on org@ +p << r.p; +x << r.x; +@@ + +msg="WARNING ERR_CAST can be used with %s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << r.p; +x << r.x; +@@ + +msg="WARNING: ERR_CAST can be used with %s" % (x) +coccilib.report.print_report(p[0], msg) diff --git a/scripts/coccinelle/err_cast.cocci b/scripts/coccinelle/err_cast.cocci deleted file mode 100644 index 2ce115000af6..000000000000 --- a/scripts/coccinelle/err_cast.cocci +++ /dev/null @@ -1,56 +0,0 @@ -/// -/// Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(...)) -/// -// Confidence: High -// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2. -// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2. -// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2. -// URL: http://coccinelle.lip6.fr/ -// Options: -// -// Keywords: ERR_PTR, PTR_ERR, ERR_CAST -// Version min: 2.6.25 -// - -virtual context -virtual patch -virtual org -virtual report - - -@ depends on context && !patch && !org && !report@ -expression x; -@@ - -* ERR_PTR(PTR_ERR(x)) - -@ depends on !context && patch && !org && !report @ -expression x; -@@ - -- ERR_PTR(PTR_ERR(x)) -+ ERR_CAST(x) - -@r depends on !context && !patch && (org || report)@ -expression x; -position p; -@@ - - ERR_PTR@p(PTR_ERR(x)) - -@script:python depends on org@ -p << r.p; -x << r.x; -@@ - -msg="WARNING ERR_CAST can be used with %s" % (x) -msg_safe=msg.replace("[","@(").replace("]",")") -coccilib.org.print_todo(p[0], msg_safe) - -@script:python depends on report@ -p << r.p; -x << r.x; -@@ - -msg="WARNING: ERR_CAST can be used with %s" % (x) -coccilib.report.print_report(p[0], msg) -- cgit v1.2.3 From 77c272fb24507c43fa301e3da83eb7d67d36a544 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:09 +0200 Subject: Coccinelle: Move resource_size.cocci to the api directory Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/api/resource_size.cocci | 93 ++++++++++++++++++++++++++++++ scripts/coccinelle/resource_size.cocci | 93 ------------------------------ 2 files changed, 93 insertions(+), 93 deletions(-) create mode 100644 scripts/coccinelle/api/resource_size.cocci delete mode 100644 scripts/coccinelle/resource_size.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/api/resource_size.cocci b/scripts/coccinelle/api/resource_size.cocci new file mode 100644 index 000000000000..1935a58b39d9 --- /dev/null +++ b/scripts/coccinelle/api/resource_size.cocci @@ -0,0 +1,93 @@ +/// +/// Use resource_size function on resource object +/// instead of explicit computation. +/// +// Confidence: High +// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Options: +// +// Keywords: resource_size +// Version min: 2.6.27 resource_size +// + +virtual context +virtual patch +virtual org +virtual report + +//---------------------------------------------------------- +// For context mode +//---------------------------------------------------------- + +@r_context depends on context && !patch && !org@ +struct resource *res; +@@ + +* (res->end - res->start) + 1 + +//---------------------------------------------------------- +// For patch mode +//---------------------------------------------------------- + +@r_patch depends on !context && patch && !org@ +struct resource *res; +@@ + +- (res->end - res->start) + 1 ++ resource_size(res) + +//---------------------------------------------------------- +// For org mode +//---------------------------------------------------------- + + +@r_org depends on !context && !patch && (org || report)@ +struct resource *res; +position p; +@@ + + (res->end@p - res->start) + 1 + +@rbad_org depends on !context && !patch && (org || report)@ +struct resource *res; +position p != r_org.p; +@@ + + res->end@p - res->start + +@script:python depends on org@ +p << r_org.p; +x << r_org.res; +@@ + +msg="ERROR with %s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << r_org.p; +x << r_org.res; +@@ + +msg="ERROR: Missing resource_size with %s" % (x) +coccilib.report.print_report(p[0], msg) + +@script:python depends on org@ +p << rbad_org.p; +x << rbad_org.res; +@@ + +msg="WARNING with %s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << rbad_org.p; +x << rbad_org.res; +@@ + +msg="WARNING: Suspicious code. resource_size is maybe missing with %s" % (x) +coccilib.report.print_report(p[0], msg) diff --git a/scripts/coccinelle/resource_size.cocci b/scripts/coccinelle/resource_size.cocci deleted file mode 100644 index 1935a58b39d9..000000000000 --- a/scripts/coccinelle/resource_size.cocci +++ /dev/null @@ -1,93 +0,0 @@ -/// -/// Use resource_size function on resource object -/// instead of explicit computation. -/// -// Confidence: High -// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2. -// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2. -// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2. -// URL: http://coccinelle.lip6.fr/ -// Options: -// -// Keywords: resource_size -// Version min: 2.6.27 resource_size -// - -virtual context -virtual patch -virtual org -virtual report - -//---------------------------------------------------------- -// For context mode -//---------------------------------------------------------- - -@r_context depends on context && !patch && !org@ -struct resource *res; -@@ - -* (res->end - res->start) + 1 - -//---------------------------------------------------------- -// For patch mode -//---------------------------------------------------------- - -@r_patch depends on !context && patch && !org@ -struct resource *res; -@@ - -- (res->end - res->start) + 1 -+ resource_size(res) - -//---------------------------------------------------------- -// For org mode -//---------------------------------------------------------- - - -@r_org depends on !context && !patch && (org || report)@ -struct resource *res; -position p; -@@ - - (res->end@p - res->start) + 1 - -@rbad_org depends on !context && !patch && (org || report)@ -struct resource *res; -position p != r_org.p; -@@ - - res->end@p - res->start - -@script:python depends on org@ -p << r_org.p; -x << r_org.res; -@@ - -msg="ERROR with %s" % (x) -msg_safe=msg.replace("[","@(").replace("]",")") -coccilib.org.print_todo(p[0], msg_safe) - -@script:python depends on report@ -p << r_org.p; -x << r_org.res; -@@ - -msg="ERROR: Missing resource_size with %s" % (x) -coccilib.report.print_report(p[0], msg) - -@script:python depends on org@ -p << rbad_org.p; -x << rbad_org.res; -@@ - -msg="WARNING with %s" % (x) -msg_safe=msg.replace("[","@(").replace("]",")") -coccilib.org.print_todo(p[0], msg_safe) - -@script:python depends on report@ -p << rbad_org.p; -x << rbad_org.res; -@@ - -msg="WARNING: Suspicious code. resource_size is maybe missing with %s" % (x) -coccilib.report.print_report(p[0], msg) -- cgit v1.2.3 From be8fe9d451936a7a412b02cb88a13ffe46879bcf Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:10 +0200 Subject: Coccinelle: Move alloc directory into api directory alloc contains various semantic patches related to the allocation APIs Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/alloc/drop_kmalloc_cast.cocci | 67 ----------------- scripts/coccinelle/alloc/kzalloc-simple.cocci | 82 --------------------- .../coccinelle/api/alloc/drop_kmalloc_cast.cocci | 67 +++++++++++++++++ scripts/coccinelle/api/alloc/kzalloc-simple.cocci | 86 ++++++++++++++++++++++ 4 files changed, 153 insertions(+), 149 deletions(-) delete mode 100644 scripts/coccinelle/alloc/drop_kmalloc_cast.cocci delete mode 100644 scripts/coccinelle/alloc/kzalloc-simple.cocci create mode 100644 scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci create mode 100644 scripts/coccinelle/api/alloc/kzalloc-simple.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci b/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci deleted file mode 100644 index 7d4771d449c3..000000000000 --- a/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci +++ /dev/null @@ -1,67 +0,0 @@ -/// -/// Casting (void *) value returned by kmalloc is useless -/// as mentioned in Documentation/CodingStyle, Chap 14. -/// -// Confidence: High -// Copyright: 2009,2010 Nicolas Palix, DIKU. GPLv2. -// URL: http://coccinelle.lip6.fr/ -// Options: -no_includes -include_headers -// -// Keywords: kmalloc, kzalloc, kcalloc -// Version min: < 2.6.12 kmalloc -// Version min: < 2.6.12 kcalloc -// Version min: 2.6.14 kzalloc -// - -virtual context -virtual patch -virtual org -virtual report - -//---------------------------------------------------------- -// For context mode -//---------------------------------------------------------- - -@depends on context@ -type T; -@@ - -* (T *) - \(kmalloc\|kzalloc\|kcalloc\)(...) - -//---------------------------------------------------------- -// For patch mode -//---------------------------------------------------------- - -@depends on patch@ -type T; -@@ - -- (T *) - \(kmalloc\|kzalloc\|kcalloc\)(...) - -//---------------------------------------------------------- -// For org and report mode -//---------------------------------------------------------- - -@r depends on org || report@ -type T; -position p; -@@ - - (T@p *)\(kmalloc\|kzalloc\|kcalloc\)(...) - -@script:python depends on org@ -p << r.p; -t << r.T; -@@ - -coccilib.org.print_safe_todo(p[0], t) - -@script:python depends on report@ -p << r.p; -t << r.T; -@@ - -msg="WARNING: casting value returned by k[cmz]alloc to (%s *) is useless." % (t) -coccilib.report.print_report(p[0], msg) diff --git a/scripts/coccinelle/alloc/kzalloc-simple.cocci b/scripts/coccinelle/alloc/kzalloc-simple.cocci deleted file mode 100644 index 2eae828fc657..000000000000 --- a/scripts/coccinelle/alloc/kzalloc-simple.cocci +++ /dev/null @@ -1,82 +0,0 @@ -/// -/// kzalloc should be used rather than kmalloc followed by memset 0 -/// -// Confidence: High -// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2. -// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6. GPLv2. -// URL: http://coccinelle.lip6.fr/rules/kzalloc.html -// Options: -no_includes -include_headers -// -// Keywords: kmalloc, kzalloc -// Version min: < 2.6.12 kmalloc -// Version min: 2.6.14 kzalloc -// - -virtual context -virtual patch -virtual org -virtual report - -//---------------------------------------------------------- -// For context mode -//---------------------------------------------------------- - -@depends on context@ -type T, T2; -expression x; -expression E1,E2; -statement S; -@@ - -* x = (T)kmalloc(E1,E2); - if ((x==NULL) || ...) S -* memset((T2)x,0,E1); - -//---------------------------------------------------------- -// For patch mode -//---------------------------------------------------------- - -@depends on patch@ -type T, T2; -expression x; -expression E1,E2; -statement S; -@@ - -- x = (T)kmalloc(E1,E2); -+ x = kzalloc(E1,E2); - if ((x==NULL) || ...) S -- memset((T2)x,0,E1); - -//---------------------------------------------------------- -// For org mode -//---------------------------------------------------------- - -@r depends on org || report@ -type T, T2; -expression x; -expression E1,E2; -statement S; -position p; -@@ - - x = (T)kmalloc@p(E1,E2); - if ((x==NULL) || ...) S - memset((T2)x,0,E1); - -@script:python depends on org@ -p << r.p; -x << r.x; -@@ - -msg="%s" % (x) -msg_safe=msg.replace("[","@(").replace("]",")") -coccilib.org.print_todo(p[0], msg_safe) - -@script:python depends on report@ -p << r.p; -x << r.x; -@@ - -msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x) -coccilib.report.print_report(p[0], msg) diff --git a/scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci b/scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci new file mode 100644 index 000000000000..7d4771d449c3 --- /dev/null +++ b/scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci @@ -0,0 +1,67 @@ +/// +/// Casting (void *) value returned by kmalloc is useless +/// as mentioned in Documentation/CodingStyle, Chap 14. +/// +// Confidence: High +// Copyright: 2009,2010 Nicolas Palix, DIKU. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Options: -no_includes -include_headers +// +// Keywords: kmalloc, kzalloc, kcalloc +// Version min: < 2.6.12 kmalloc +// Version min: < 2.6.12 kcalloc +// Version min: 2.6.14 kzalloc +// + +virtual context +virtual patch +virtual org +virtual report + +//---------------------------------------------------------- +// For context mode +//---------------------------------------------------------- + +@depends on context@ +type T; +@@ + +* (T *) + \(kmalloc\|kzalloc\|kcalloc\)(...) + +//---------------------------------------------------------- +// For patch mode +//---------------------------------------------------------- + +@depends on patch@ +type T; +@@ + +- (T *) + \(kmalloc\|kzalloc\|kcalloc\)(...) + +//---------------------------------------------------------- +// For org and report mode +//---------------------------------------------------------- + +@r depends on org || report@ +type T; +position p; +@@ + + (T@p *)\(kmalloc\|kzalloc\|kcalloc\)(...) + +@script:python depends on org@ +p << r.p; +t << r.T; +@@ + +coccilib.org.print_safe_todo(p[0], t) + +@script:python depends on report@ +p << r.p; +t << r.T; +@@ + +msg="WARNING: casting value returned by k[cmz]alloc to (%s *) is useless." % (t) +coccilib.report.print_report(p[0], msg) diff --git a/scripts/coccinelle/api/alloc/kzalloc-simple.cocci b/scripts/coccinelle/api/alloc/kzalloc-simple.cocci new file mode 100644 index 000000000000..046b9b16f8f9 --- /dev/null +++ b/scripts/coccinelle/api/alloc/kzalloc-simple.cocci @@ -0,0 +1,86 @@ +/// +/// Use kzalloc rather than kmalloc followed by memset with 0 +/// +/// This considers some simple cases that are common and easy to validate +/// Note in particular that there are no ...s in the rule, so all of the +/// matched code has to be contiguous +/// +// Confidence: High +// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/rules/kzalloc.html +// Options: -no_includes -include_headers +// +// Keywords: kmalloc, kzalloc +// Version min: < 2.6.12 kmalloc +// Version min: 2.6.14 kzalloc +// + +virtual context +virtual patch +virtual org +virtual report + +//---------------------------------------------------------- +// For context mode +//---------------------------------------------------------- + +@depends on context@ +type T, T2; +expression x; +expression E1,E2; +statement S; +@@ + +* x = (T)kmalloc(E1,E2); + if ((x==NULL) || ...) S +* memset((T2)x,0,E1); + +//---------------------------------------------------------- +// For patch mode +//---------------------------------------------------------- + +@depends on patch@ +type T, T2; +expression x; +expression E1,E2; +statement S; +@@ + +- x = (T)kmalloc(E1,E2); ++ x = kzalloc(E1,E2); + if ((x==NULL) || ...) S +- memset((T2)x,0,E1); + +//---------------------------------------------------------- +// For org mode +//---------------------------------------------------------- + +@r depends on org || report@ +type T, T2; +expression x; +expression E1,E2; +statement S; +position p; +@@ + + x = (T)kmalloc@p(E1,E2); + if ((x==NULL) || ...) S + memset((T2)x,0,E1); + +@script:python depends on org@ +p << r.p; +x << r.x; +@@ + +msg="%s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << r.p; +x << r.x; +@@ + +msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x) +coccilib.report.print_report(p[0], msg) -- cgit v1.2.3 From 033456e2c507a9b804de56dd258af55f03764334 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:11 +0200 Subject: Coccinelle: Add misc/doubleinit.cocci Find duplicate field initializations. This has a high rate of false positives due to #ifdefs, which Coccinelle is not aware of in a structure initialization. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/misc/doubleinit.cocci | 53 ++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 scripts/coccinelle/misc/doubleinit.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/misc/doubleinit.cocci b/scripts/coccinelle/misc/doubleinit.cocci new file mode 100644 index 000000000000..55d7dc19dfe0 --- /dev/null +++ b/scripts/coccinelle/misc/doubleinit.cocci @@ -0,0 +1,53 @@ +/// Find duplicate field initializations. This has a high rate of false +/// positives due to #ifdefs, which Coccinelle is not aware of in a structure +/// 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. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual org +virtual report + +@r@ +identifier I, s, fld; +position p0,p; +expression E; +@@ + +struct I s =@p0 { ... .fld@p = E, ...}; + +@s@ +identifier I, s, r.fld; +position r.p0,p; +expression E; +@@ + +struct I s =@p0 { ... .fld@p = E, ...}; + +@script:python depends on org@ +p0 << r.p0; +fld << r.fld; +ps << s.p; +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)): + cocci.print_main(fld,p0) + cocci.print_secs("s",ps) + cocci.print_secs("r",pr) + +@script:python depends on report@ +p0 << r.p0; +fld << r.fld; +ps << s.p; +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) + coccilib.report.print_report(p0[0],msg) -- cgit v1.2.3 From 49ab7a39136566eb8312e770031af4182c9f2967 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:12 +0200 Subject: Coccinelle: Add misc/ifcol.cocci Find confusingly indented code in or after an if. An if branch should be indented. The code following an if should not be indented. Sometimes, code after an if that is indented is actually intended to be part of the if branch. This has a high rate of false positives, because Coccinelle's column calculation does not distinguish between spaces and tabs, so code that is not visually aligned may be considered to be in the same column. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/misc/ifcol.cocci | 48 +++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 scripts/coccinelle/misc/ifcol.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/misc/ifcol.cocci b/scripts/coccinelle/misc/ifcol.cocci new file mode 100644 index 000000000000..b7ed91dbeb95 --- /dev/null +++ b/scripts/coccinelle/misc/ifcol.cocci @@ -0,0 +1,48 @@ +/// Find confusingly indented code in or after an if. An if branch should +/// be indented. The code following an if should not be indented. +/// Sometimes, code after an if that is indented is actually intended to be +/// part of the if branch. +/// +/// This has a high rate of false positives, because Coccinelle's column +/// calculation does not distinguish between spaces and tabs, so code that +/// is not visually aligned may be considered to be in the same column. +/// +// Confidence: Low +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual org +virtual report + +@r disable braces4@ +position p1,p2; +statement S1,S2; +@@ + +( +if (...) { ... } +| +if (...) S1@p1 S2@p2 +) + +@script:python depends on org@ +p1 << r.p1; +p2 << r.p2; +@@ + +if (p1[0].column == p2[0].column): + cocci.print_main("branch",p1) + cocci.print_secs("after",p2) + +@script:python depends on report@ +p1 << r.p1; +p2 << r.p2; +@@ + +if (p1[0].column == p2[0].column): + msg = "code aligned with following code on line %s" % (p2[0].line) + coccilib.report.print_report(p1[0],msg) -- cgit v1.2.3 From c94d3fb01fb6db1899cdf53ea4eb9d38e08a08fe Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Mon, 23 Aug 2010 12:01:24 -0400 Subject: kbuild: use getopt_long(), not its _only() variant NetBSD lacks getopt_long_only() whereas getopt_long() works just fine. Signed-off-by: Arnaud Lacombe Acked-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/kconfig/conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 4f0ed5b3a75e..4b3ad9b862b1 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -466,7 +466,7 @@ int main(int ac, char **av) bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - while ((opt = getopt_long_only(ac, av, "", long_opts, NULL)) != -1) { + while ((opt = getopt_long(ac, av, "", long_opts, NULL)) != -1) { input_mode = (enum input_mode)opt; switch (opt) { case silentoldconfig: -- cgit v1.2.3 From 133c5f7c10e4552ba41bcf03b9bda6c4e3413804 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Tue, 31 Aug 2010 17:34:37 +0200 Subject: kconfig qconf: port to QT4 A straight forward port to QT4 using qt3to4 and compiling against qt3support * Use pkg-config to detect QT4 which is hopefully portable enough * If no QT4, QT3 will by tried instead * Classes renamed using qt3to4 * If build using QT3 renamed to QT3 class names using defines * ConfigInfoView::menu has to be renamed as QT4 moc strips struct from struct menu and creates a name conflict * QT2 support has been dropped * The hidden options inserted in 39a4897c1bb66e8a36043c105d7fd73d8b32b480 are use in native API Signed-off-by: Alexander Stein Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 76 ++++++++++++---------- scripts/kconfig/qconf.cc | 162 ++++++++++++++++++++++++++--------------------- scripts/kconfig/qconf.h | 76 +++++++++++----------- 3 files changed, 168 insertions(+), 146 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 06c1c2f80bb7..cef3f75e1c2b 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -235,40 +235,50 @@ $(obj)/.tmp_qtcheck: $(src)/Makefile # QT needs some extra effort... $(obj)/.tmp_qtcheck: @set -e; echo " CHECK qt"; dir=""; pkg=""; \ - pkg-config --exists qt 2> /dev/null && pkg=qt; \ - pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \ - if [ -n "$$pkg" ]; then \ - cflags="\$$(shell pkg-config $$pkg --cflags)"; \ - libs="\$$(shell pkg-config $$pkg --libs)"; \ - moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \ - dir="$$(pkg-config $$pkg --variable=prefix)"; \ + if ! pkg-config --exists QtCore 2> /dev/null; then \ + echo "* Unable to find the QT4 tool qmake. Trying to use QT3"; \ + pkg-config --exists qt 2> /dev/null && pkg=qt; \ + pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \ + if [ -n "$$pkg" ]; then \ + cflags="\$$(shell pkg-config $$pkg --cflags)"; \ + libs="\$$(shell pkg-config $$pkg --libs)"; \ + moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \ + dir="$$(pkg-config $$pkg --variable=prefix)"; \ + else \ + for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \ + if [ -f $$d/include/qconfig.h ]; then dir=$$d; break; fi; \ + done; \ + if [ -z "$$dir" ]; then \ + echo "*"; \ + echo "* Unable to find any QT installation. Please make sure that"; \ + echo "* the QT4 or QT3 development package is correctly installed and"; \ + echo "* either qmake can be found or install pkg-config or set"; \ + echo "* the QTDIR environment variable to the correct location."; \ + echo "*"; \ + false; \ + fi; \ + libpath=$$dir/lib; lib=qt; osdir=""; \ + $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \ + osdir=x$$($(HOSTCXX) -print-multi-os-directory); \ + test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \ + test -f $$libpath/libqt-mt.so && lib=qt-mt; \ + cflags="-I$$dir/include"; \ + libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \ + moc="$$dir/bin/moc"; \ + fi; \ + if [ ! -x $$dir/bin/moc -a -x /usr/bin/moc ]; then \ + echo "*"; \ + echo "* Unable to find $$dir/bin/moc, using /usr/bin/moc instead."; \ + echo "*"; \ + moc="/usr/bin/moc"; \ + fi; \ else \ - for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \ - if [ -f $$d/include/qconfig.h ]; then dir=$$d; break; fi; \ - done; \ - if [ -z "$$dir" ]; then \ - echo "*"; \ - echo "* Unable to find the QT3 installation. Please make sure that"; \ - echo "* the QT3 development package is correctly installed and"; \ - echo "* either install pkg-config or set the QTDIR environment"; \ - echo "* variable to the correct location."; \ - echo "*"; \ - false; \ - fi; \ - libpath=$$dir/lib; lib=qt; osdir=""; \ - $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \ - osdir=x$$($(HOSTCXX) -print-multi-os-directory); \ - test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \ - test -f $$libpath/libqt-mt.so && lib=qt-mt; \ - cflags="-I$$dir/include"; \ - libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \ - moc="$$dir/bin/moc"; \ - fi; \ - if [ ! -x $$dir/bin/moc -a -x /usr/bin/moc ]; then \ - echo "*"; \ - echo "* Unable to find $$dir/bin/moc, using /usr/bin/moc instead."; \ - echo "*"; \ - moc="/usr/bin/moc"; \ + headerpath="\$$(shell qmake -query QT_INSTALL_HEADERS)"; \ + libpath="\$$(shell qmake -query QT_INSTALL_LIBS)"; \ + binpath="\$$(shell qmake -query QT_INSTALL_BINS)"; \ + cflags="-I$$headerpath -I$$headerpath/QtCore -I$$headerpath/QtGui -I$$headerpath/Qt3Support -DQT3_SUPPORT"; \ + libs="-L$$libpath -Wl,-rpath,$$libpath -lQtCore -lQtGui -lQt3Support"; \ + moc="$$binpath/moc"; \ fi; \ echo "KC_QT_CFLAGS=$$cflags" > $@; \ echo "KC_QT_LIBS=$$libs" >> $@; \ diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 820df2d1217b..88d3874ca8f4 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -3,25 +3,42 @@ * Released under the terms of the GNU GPL v2.0. */ -#include +#include + +#if QT_VERSION < 0x040000 #include +#include +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#include #include #include #include -#include #include -#include -#include #include #include #include #include #include -#include -#include -#include -#include #include +#include #include @@ -39,7 +56,7 @@ static QApplication *configApp; static ConfigSettings *configSettings; -QAction *ConfigMainWindow::saveAction; +Q3Action *ConfigMainWindow::saveAction; static inline QString qgettext(const char* str) { @@ -54,9 +71,9 @@ static inline QString qgettext(const QString& str) /** * Reads a list of integer values from the application settings. */ -QValueList ConfigSettings::readSizes(const QString& key, bool *ok) +Q3ValueList ConfigSettings::readSizes(const QString& key, bool *ok) { - QValueList result; + Q3ValueList result; QStringList entryList = readListEntry(key, ok); QStringList::Iterator it; @@ -69,10 +86,10 @@ QValueList ConfigSettings::readSizes(const QString& key, bool *ok) /** * Writes a list of integer values to the application settings. */ -bool ConfigSettings::writeSizes(const QString& key, const QValueList& value) +bool ConfigSettings::writeSizes(const QString& key, const Q3ValueList& value) { QStringList stringList; - QValueList::ConstIterator it; + Q3ValueList::ConstIterator it; for (it = value.begin(); it != value.end(); ++it) stringList.push_back(QString::number(*it)); @@ -80,7 +97,6 @@ bool ConfigSettings::writeSizes(const QString& key, const QValueList& value } -#if QT_VERSION >= 300 /* * set the new data * TODO check the value @@ -91,7 +107,6 @@ void ConfigItem::okRename(int col) sym_set_string_value(menu->sym, text(dataColIdx).latin1()); listView()->updateList(this); } -#endif /* * update the displayed of a menu entry @@ -195,11 +210,9 @@ void ConfigItem::updateMenu(void) data = sym_get_string_value(sym); -#if QT_VERSION >= 300 int i = list->mapIdx(dataColIdx); if (i >= 0) setRenameEnabled(i, TRUE); -#endif setText(dataColIdx, data); if (type == S_STRING) prompt = QString("%1: %2").arg(prompt).arg(data); @@ -432,7 +445,7 @@ void ConfigList::updateList(ConfigItem* item) if (!rootEntry) { if (mode != listMode) goto update; - QListViewItemIterator it(this); + Q3ListViewItemIterator it(this); ConfigItem* item; for (; it.current(); ++it) { @@ -527,11 +540,9 @@ void ConfigList::changeValue(ConfigItem* item) case S_INT: case S_HEX: case S_STRING: -#if QT_VERSION >= 300 if (colMap[dataColIdx] >= 0) item->startRename(colMap[dataColIdx]); else -#endif parent()->lineEdit->show(item); break; } @@ -563,7 +574,7 @@ void ConfigList::setParentMenu(void) return; setRootMenu(menu_get_parent_menu(rootEntry->parent)); - QListViewItemIterator it(this); + Q3ListViewItemIterator it(this); for (; (item = (ConfigItem*)it.current()); it++) { if (item->menu == oldroot) { setCurrentItem(item); @@ -645,7 +656,7 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu) void ConfigList::keyPressEvent(QKeyEvent* ev) { - QListViewItem* i = currentItem(); + Q3ListViewItem* i = currentItem(); ConfigItem* item; struct menu *menu; enum prop_type type; @@ -811,10 +822,10 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) { if (e->y() <= header()->geometry().bottom()) { if (!headerPopup) { - QAction *action; + Q3Action *action; - headerPopup = new QPopupMenu(this); - action = new QAction(NULL, _("Show Name"), 0, this); + headerPopup = new Q3PopupMenu(this); + action = new Q3Action(NULL, _("Show Name"), 0, this); action->setToggleAction(TRUE); connect(action, SIGNAL(toggled(bool)), parent(), SLOT(setShowName(bool))); @@ -822,7 +833,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) action, SLOT(setOn(bool))); action->setOn(showName); action->addTo(headerPopup); - action = new QAction(NULL, _("Show Range"), 0, this); + action = new Q3Action(NULL, _("Show Range"), 0, this); action->setToggleAction(TRUE); connect(action, SIGNAL(toggled(bool)), parent(), SLOT(setShowRange(bool))); @@ -830,7 +841,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) action, SLOT(setOn(bool))); action->setOn(showRange); action->addTo(headerPopup); - action = new QAction(NULL, _("Show Data"), 0, this); + action = new Q3Action(NULL, _("Show Data"), 0, this); action->setToggleAction(TRUE); connect(action, SIGNAL(toggled(bool)), parent(), SLOT(setShowData(bool))); @@ -914,7 +925,7 @@ void ConfigView::setShowData(bool b) void ConfigList::setAllOpen(bool open) { - QListViewItemIterator it(this); + Q3ListViewItemIterator it(this); for (; it.current(); it++) it.current()->setOpen(open); @@ -937,7 +948,7 @@ void ConfigView::updateListAll(void) } ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name) - : Parent(parent, name), sym(0), menu(0) + : Parent(parent, name), sym(0), _menu(0) { if (name) { configSettings->beginGroup(name); @@ -960,7 +971,7 @@ void ConfigInfoView::setShowDebug(bool b) { if (_showDebug != b) { _showDebug = b; - if (menu) + if (_menu) menuInfo(); else if (sym) symbolInfo(); @@ -970,11 +981,11 @@ void ConfigInfoView::setShowDebug(bool b) void ConfigInfoView::setInfo(struct menu *m) { - if (menu == m) + if (_menu == m) return; - menu = m; + _menu = m; sym = NULL; - if (!menu) + if (!_menu) clear(); else menuInfo(); @@ -1001,11 +1012,11 @@ void ConfigInfoView::menuInfo(void) struct symbol* sym; QString head, debug, help; - sym = menu->sym; + sym = _menu->sym; if (sym) { - if (menu->prompt) { + if (_menu->prompt) { head += ""; - head += print_filter(_(menu->prompt->text)); + head += print_filter(_(_menu->prompt->text)); head += ""; if (sym->name) { head += " ("; @@ -1031,23 +1042,23 @@ void ConfigInfoView::menuInfo(void) debug = debug_info(sym); struct gstr help_gstr = str_new(); - menu_get_ext_help(menu, &help_gstr); + menu_get_ext_help(_menu, &help_gstr); help = print_filter(str_get(&help_gstr)); str_free(&help_gstr); - } else if (menu->prompt) { + } else if (_menu->prompt) { head += ""; - head += print_filter(_(menu->prompt->text)); + head += print_filter(_(_menu->prompt->text)); head += "

"; if (showDebug()) { - if (menu->prompt->visible.expr) { + if (_menu->prompt->visible.expr) { debug += "  dep: "; - expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE); + expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE); debug += "

"; } } } if (showDebug()) - debug += QString().sprintf("defined at %s:%d

", menu->file->name, menu->lineno); + debug += QString().sprintf("defined at %s:%d

", _menu->file->name, _menu->lineno); setText(head + debug + help); } @@ -1150,10 +1161,10 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *text += str2; } -QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos) +Q3PopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos) { - QPopupMenu* popup = Parent::createPopupMenu(pos); - QAction* action = new QAction(NULL, _("Show Debug Info"), 0, popup); + Q3PopupMenu* popup = Parent::createPopupMenu(pos); + Q3Action* action = new Q3Action(NULL, _("Show Debug Info"), 0, popup); action->setToggleAction(TRUE); connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool))); @@ -1210,7 +1221,7 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam y = configSettings->readNumEntry("/window y", 0, &ok); if (ok) move(x, y); - QValueList sizes = configSettings->readSizes("/split", &ok); + Q3ValueList sizes = configSettings->readSizes("/split", &ok); if (ok) split->setSizes(sizes); configSettings->endGroup(); @@ -1297,42 +1308,42 @@ ConfigMainWindow::ConfigMainWindow(void) configList->setFocus(); menu = menuBar(); - toolBar = new QToolBar("Tools", this); + toolBar = new Q3ToolBar("Tools", this); - backAction = new QAction("Back", QPixmap(xpm_back), _("Back"), 0, this); + backAction = new Q3Action("Back", QPixmap(xpm_back), _("Back"), 0, this); connect(backAction, SIGNAL(activated()), SLOT(goBack())); backAction->setEnabled(FALSE); - QAction *quitAction = new QAction("Quit", _("&Quit"), Qt::CTRL + Qt::Key_Q, this); + Q3Action *quitAction = new Q3Action("Quit", _("&Quit"), Qt::CTRL + Qt::Key_Q, this); connect(quitAction, SIGNAL(activated()), SLOT(close())); - QAction *loadAction = new QAction("Load", QPixmap(xpm_load), _("&Load"), Qt::CTRL + Qt::Key_L, this); + Q3Action *loadAction = new Q3Action("Load", QPixmap(xpm_load), _("&Load"), Qt::CTRL + Qt::Key_L, this); connect(loadAction, SIGNAL(activated()), SLOT(loadConfig())); - saveAction = new QAction("Save", QPixmap(xpm_save), _("&Save"), Qt::CTRL + Qt::Key_S, this); + saveAction = new Q3Action("Save", QPixmap(xpm_save), _("&Save"), Qt::CTRL + Qt::Key_S, this); connect(saveAction, SIGNAL(activated()), SLOT(saveConfig())); conf_set_changed_callback(conf_changed); // Set saveAction's initial state conf_changed(); - QAction *saveAsAction = new QAction("Save As...", _("Save &As..."), 0, this); + Q3Action *saveAsAction = new Q3Action("Save As...", _("Save &As..."), 0, this); connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs())); - QAction *searchAction = new QAction("Find", _("&Find"), Qt::CTRL + Qt::Key_F, this); + Q3Action *searchAction = new Q3Action("Find", _("&Find"), Qt::CTRL + Qt::Key_F, this); connect(searchAction, SIGNAL(activated()), SLOT(searchConfig())); - QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this); + Q3Action *singleViewAction = new Q3Action("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this); connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView())); - QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this); + Q3Action *splitViewAction = new Q3Action("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this); connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView())); - QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this); + Q3Action *fullViewAction = new Q3Action("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this); connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView())); - QAction *showNameAction = new QAction(NULL, _("Show Name"), 0, this); + Q3Action *showNameAction = new Q3Action(NULL, _("Show Name"), 0, this); showNameAction->setToggleAction(TRUE); connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool))); connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool))); showNameAction->setOn(configView->showName()); - QAction *showRangeAction = new QAction(NULL, _("Show Range"), 0, this); + Q3Action *showRangeAction = new Q3Action(NULL, _("Show Range"), 0, this); showRangeAction->setToggleAction(TRUE); connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool))); connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool))); showRangeAction->setOn(configList->showRange); - QAction *showDataAction = new QAction(NULL, _("Show Data"), 0, this); + Q3Action *showDataAction = new Q3Action(NULL, _("Show Data"), 0, this); showDataAction->setToggleAction(TRUE); connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool))); connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool))); @@ -1345,9 +1356,15 @@ ConfigMainWindow::ConfigMainWindow(void) connect(optGroup, SIGNAL(selected(QAction *)), menuView, SLOT(setOptionMode(QAction *))); - configView->showNormalAction = new QAction(NULL, _("Show Normal Options"), 0, optGroup); - configView->showAllAction = new QAction(NULL, _("Show All Options"), 0, optGroup); - configView->showPromptAction = new QAction(NULL, _("Show Prompt Options"), 0, optGroup); +#if QT_VERSION >= 0x040000 + configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup); + configView->showAllAction = new QAction(_("Show All Options"), optGroup); + configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup); +#else + configView->showNormalAction = new QAction(_("Show Normal Options"), 0, optGroup); + configView->showAllAction = new QAction(_("Show All Options"), 0, optGroup); + configView->showPromptAction = new QAction(_("Show Prompt Options"), 0, optGroup); +#endif configView->showNormalAction->setToggleAction(TRUE); configView->showNormalAction->setOn(configList->optMode == normalOpt); configView->showAllAction->setToggleAction(TRUE); @@ -1355,15 +1372,15 @@ ConfigMainWindow::ConfigMainWindow(void) configView->showPromptAction->setToggleAction(TRUE); configView->showPromptAction->setOn(configList->optMode == promptOpt); - QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this); + Q3Action *showDebugAction = new Q3Action(NULL, _("Show Debug Info"), 0, this); showDebugAction->setToggleAction(TRUE); connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool))); connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool))); showDebugAction->setOn(helpText->showDebug()); - QAction *showIntroAction = new QAction(NULL, _("Introduction"), 0, this); + Q3Action *showIntroAction = new Q3Action(NULL, _("Introduction"), 0, this); connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro())); - QAction *showAboutAction = new QAction(NULL, _("About"), 0, this); + Q3Action *showAboutAction = new Q3Action(NULL, _("About"), 0, this); connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout())); // init tool bar @@ -1377,7 +1394,7 @@ ConfigMainWindow::ConfigMainWindow(void) fullViewAction->addTo(toolBar); // create config menu - QPopupMenu* config = new QPopupMenu(this); + Q3PopupMenu* config = new Q3PopupMenu(this); menu->insertItem(_("&File"), config); loadAction->addTo(config); saveAction->addTo(config); @@ -1386,12 +1403,12 @@ ConfigMainWindow::ConfigMainWindow(void) quitAction->addTo(config); // create edit menu - QPopupMenu* editMenu = new QPopupMenu(this); + Q3PopupMenu* editMenu = new Q3PopupMenu(this); menu->insertItem(_("&Edit"), editMenu); searchAction->addTo(editMenu); // create options menu - QPopupMenu* optionMenu = new QPopupMenu(this); + Q3PopupMenu* optionMenu = new Q3PopupMenu(this); menu->insertItem(_("&Option"), optionMenu); showNameAction->addTo(optionMenu); showRangeAction->addTo(optionMenu); @@ -1399,10 +1416,9 @@ ConfigMainWindow::ConfigMainWindow(void) optionMenu->insertSeparator(); optGroup->addTo(optionMenu); optionMenu->insertSeparator(); - showDebugAction->addTo(optionMenu); // create help menu - QPopupMenu* helpMenu = new QPopupMenu(this); + Q3PopupMenu* helpMenu = new Q3PopupMenu(this); menu->insertSeparator(); menu->insertItem(_("&Help"), helpMenu); showIntroAction->addTo(helpMenu); @@ -1437,7 +1453,7 @@ ConfigMainWindow::ConfigMainWindow(void) showSplitView(); // UI setup done, restore splitter positions - QValueList sizes = configSettings->readSizes("/split1", &ok); + Q3ValueList sizes = configSettings->readSizes("/split1", &ok); if (ok) split1->setSizes(sizes); @@ -1448,7 +1464,7 @@ ConfigMainWindow::ConfigMainWindow(void) void ConfigMainWindow::loadConfig(void) { - QString s = QFileDialog::getOpenFileName(conf_get_configname(), NULL, this); + QString s = Q3FileDialog::getOpenFileName(conf_get_configname(), NULL, this); if (s.isNull()) return; if (conf_read(QFile::encodeName(s))) @@ -1464,7 +1480,7 @@ void ConfigMainWindow::saveConfig(void) void ConfigMainWindow::saveConfigAs(void) { - QString s = QFileDialog::getSaveFileName(conf_get_configname(), NULL, this); + QString s = Q3FileDialog::getSaveFileName(conf_get_configname(), NULL, this); if (s.isNull()) return; if (conf_write(QFile::encodeName(s))) diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index 636a74b23bf9..91677d900dbd 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -3,26 +3,25 @@ * Released under the terms of the GNU GPL v2.0. */ +#if QT_VERSION < 0x040000 #include -#if QT_VERSION >= 300 -#include #else -class QSettings { -public: - void beginGroup(const QString& group) { } - void endGroup(void) { } - bool readBoolEntry(const QString& key, bool def = FALSE, bool* ok = 0) const - { if (ok) *ok = FALSE; return def; } - int readNumEntry(const QString& key, int def = 0, bool* ok = 0) const - { if (ok) *ok = FALSE; return def; } - QString readEntry(const QString& key, const QString& def = QString::null, bool* ok = 0) const - { if (ok) *ok = FALSE; return def; } - QStringList readListEntry(const QString& key, bool* ok = 0) const - { if (ok) *ok = FALSE; return QStringList(); } - template - bool writeEntry(const QString& key, t value) - { return TRUE; } -}; +#include +#endif +#include + +#if QT_VERSION < 0x040000 +#define Q3ValueList QValueList +#define Q3PopupMenu QPopupMenu +#define Q3ListView QListView +#define Q3ListViewItem QListViewItem +#define Q3VBox QVBox +#define Q3TextBrowser QTextBrowser +#define Q3MainWindow QMainWindow +#define Q3Action QAction +#define Q3ToolBar QToolBar +#define Q3ListViewItemIterator QListViewItemIterator +#define Q3FileDialog QFileDialog #endif class ConfigView; @@ -31,11 +30,10 @@ class ConfigItem; class ConfigLineEdit; class ConfigMainWindow; - class ConfigSettings : public QSettings { public: - QValueList readSizes(const QString& key, bool *ok); - bool writeSizes(const QString& key, const QValueList& value); + Q3ValueList readSizes(const QString& key, bool *ok); + bool writeSizes(const QString& key, const Q3ValueList& value); }; enum colIdx { @@ -48,9 +46,9 @@ enum optionMode { normalOpt = 0, allOpt, promptOpt }; -class ConfigList : public QListView { +class ConfigList : public Q3ListView { Q_OBJECT - typedef class QListView Parent; + typedef class Q3ListView Parent; public: ConfigList(ConfigView* p, const char *name = 0); void reinit(void); @@ -135,17 +133,17 @@ public: struct menu *rootEntry; QColorGroup disabledColorGroup; QColorGroup inactivedColorGroup; - QPopupMenu* headerPopup; + Q3PopupMenu* headerPopup; private: int colMap[colNr]; int colRevMap[colNr]; }; -class ConfigItem : public QListViewItem { - typedef class QListViewItem Parent; +class ConfigItem : public Q3ListViewItem { + typedef class Q3ListViewItem Parent; public: - ConfigItem(QListView *parent, ConfigItem *after, struct menu *m, bool v) + ConfigItem(Q3ListView *parent, ConfigItem *after, struct menu *m, bool v) : Parent(parent, after), menu(m), visible(v), goParent(false) { init(); @@ -155,16 +153,14 @@ public: { init(); } - ConfigItem(QListView *parent, ConfigItem *after, bool v) + ConfigItem(Q3ListView *parent, ConfigItem *after, bool v) : Parent(parent, after), menu(0), visible(v), goParent(true) { init(); } ~ConfigItem(void); void init(void); -#if QT_VERSION >= 300 void okRename(int col); -#endif void updateMenu(void); void testUpdateMenu(bool v); ConfigList* listView() const @@ -219,9 +215,9 @@ public: ConfigItem *item; }; -class ConfigView : public QVBox { +class ConfigView : public Q3VBox { Q_OBJECT - typedef class QVBox Parent; + typedef class Q3VBox Parent; public: ConfigView(QWidget* parent, const char *name = 0); ~ConfigView(void); @@ -252,9 +248,9 @@ public: static QAction *showPromptAction; }; -class ConfigInfoView : public QTextBrowser { +class ConfigInfoView : public Q3TextBrowser { Q_OBJECT - typedef class QTextBrowser Parent; + typedef class Q3TextBrowser Parent; public: ConfigInfoView(QWidget* parent, const char *name = 0); bool showDebug(void) const { return _showDebug; } @@ -274,11 +270,11 @@ protected: QString debug_info(struct symbol *sym); static QString print_filter(const QString &str); static void expr_print_help(void *data, struct symbol *sym, const char *str); - QPopupMenu* createPopupMenu(const QPoint& pos); + Q3PopupMenu* createPopupMenu(const QPoint& pos); void contentsContextMenuEvent(QContextMenuEvent *e); struct symbol *sym; - struct menu *menu; + struct menu *_menu; bool _showDebug; }; @@ -302,10 +298,10 @@ protected: struct symbol **result; }; -class ConfigMainWindow : public QMainWindow { +class ConfigMainWindow : public Q3MainWindow { Q_OBJECT - static QAction *saveAction; + static Q3Action *saveAction; static void conf_changed(void); public: ConfigMainWindow(void); @@ -334,8 +330,8 @@ protected: ConfigView *configView; ConfigList *configList; ConfigInfoView *helpText; - QToolBar *toolBar; - QAction *backAction; + Q3ToolBar *toolBar; + Q3Action *backAction; QSplitter* split1; QSplitter* split2; }; -- cgit v1.2.3 From f9810a82536e0c730c57844753e6c08cc7f77881 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Tue, 10 Aug 2010 19:39:20 +0100 Subject: ARM: 6317/1: ftrace: pass KBUILD_CFLAGS to record_mcount.pl On ARM, we have two ABIs, and the ABI used is controlled via a config option. Object files built with one ABI can't be merged with object files built with the other ABI. So, record_mcount.pl needs to use the same compiler flags as the kernel when generating the object file with the mcount locations. Ensure this by passing CFLAGS to the script. Acked-by: Steven Rostedt Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- scripts/Makefile.build | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index a1a5cf95a68d..108eeb99351d 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -212,7 +212,8 @@ ifdef CONFIG_FTRACE_MCOUNT_RECORD cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \ "$(if $(CONFIG_64BIT),64,32)" \ - "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" \ + "$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CFLAGS)" \ + "$(LD)" "$(NM)" "$(RM)" "$(MV)" \ "$(if $(part-of-module),1,0)" "$(@)"; endif -- cgit v1.2.3 From 3b6c223b1b97ad60bbb0f4efda57d649414ac2a2 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Tue, 10 Aug 2010 19:43:28 +0100 Subject: ARM: 6318/1: ftrace: fix and update dynamic ftrace This adds mcount recording and updates dynamic ftrace for ARM to work with the new ftrace dyamic tracing implementation. It also adds support for the mcount format used by newer ARM compilers. With dynamic tracing, mcount() is implemented as a nop. Callsites are patched on startup with nops, and dynamically patched to call to the ftrace_caller() routine as needed. Acked-by: Steven Rostedt [recordmcount.pl change] Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- scripts/recordmcount.pl | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index e67f05486087..022d4679b1b3 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -270,6 +270,8 @@ if ($arch eq "x86_64") { } elsif ($arch eq "arm") { $alignment = 2; $section_type = '%progbits'; + $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_ARM_(CALL|PC24)" . + "\\s+(__gnu_mcount_nc|mcount)\$"; } elsif ($arch eq "ia64") { $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; -- cgit v1.2.3 From 72dc43a9eb123d2742bd413c80dbeab0c588f622 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Tue, 10 Aug 2010 19:52:35 +0100 Subject: ARM: 6319/1: ftrace: add Thumb-2 support to dynamic ftrace Handle the different nop and call instructions for Thumb-2. Also, we need to adjust the recorded mcount_loc addresses because they have the lsb set. Cc: Catalin Marinas Acked-by: Steven Rostedt [recordmcount.pl change] Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- scripts/recordmcount.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 022d4679b1b3..1d7963f4ee79 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -270,7 +270,7 @@ if ($arch eq "x86_64") { } elsif ($arch eq "arm") { $alignment = 2; $section_type = '%progbits'; - $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_ARM_(CALL|PC24)" . + $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_ARM_(CALL|PC24|THM_CALL)" . "\\s+(__gnu_mcount_nc|mcount)\$"; } elsif ($arch eq "ia64") { -- cgit v1.2.3 From c3e2f196f9862cd75cb7f495a3cd1f1bbb82bb40 Mon Sep 17 00:00:00 2001 From: Michael Prokop Date: Mon, 6 Sep 2010 11:57:19 +0200 Subject: scripts/setlocalversion: update comment A tagged repository state isn't enough, git describe only looks at signed or annotated tags (git tag -a/-s). This documentation update makes sure the comment matches the current behaviour. Signed-off-by: Michael Prokop Signed-off-by: Michal Marek --- scripts/setlocalversion | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/setlocalversion b/scripts/setlocalversion index e90a91cc5185..dc54b1982958 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -160,8 +160,10 @@ if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then # full scm version string res="$res$(scm_version)" else - # apped a plus sign if the repository is not in a clean tagged - # state and LOCALVERSION= is not specified + # append a plus sign if the repository is not in a clean + # annotated or signed tagged state (as git describe only + # looks at signed or annotated tags - git tag -a/-s) and + # LOCALVERSION= is not specified if test "${LOCALVERSION+set}" != "set"; then scm=$(scm_version --short) res="$res${scm:++}" -- cgit v1.2.3 From 76a136c4a6bde90af8c899701cc1f0997af2f60a Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Wed, 1 Sep 2010 17:39:27 +0200 Subject: xconfig: Change the titlebar if using Qt3 Qt4 is now used by default and will get more testing. In case someone still uses Qt3 and reports a bug, make it easy to recognize that this is Qt3. Acked-by: Alexander Stein Signed-off-by: Michal Marek --- scripts/kconfig/qconf.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 88d3874ca8f4..a04e4517ead1 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1274,8 +1274,14 @@ ConfigMainWindow::ConfigMainWindow(void) char title[256]; QDesktopWidget *d = configApp->desktop(); - snprintf(title, sizeof(title), _("Linux Kernel v%s Configuration"), - getenv("KERNELVERSION")); + snprintf(title, sizeof(title), _("Linux Kernel v%s Configuration%s"), + getenv("KERNELVERSION"), +#if QT_VERSION < 0x040000 + " (Qt3)" +#else + "" +#endif + ); setCaption(title); width = configSettings->readNumEntry("/window width", d->width() - 64); -- cgit v1.2.3 From 71d8066265896a6498a4de1bed80dea8dc5daead Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Wed, 1 Sep 2010 11:21:30 -0400 Subject: kbuild: fix oldnoconfig to do the right thing Commit 861b4ea4 broke oldnoconfig when removed the oldnoconfig checks on if (input_mode == nonint_oldconfig || input_mode == oldnoconfig) { if (input_mode == nonint_oldconfig && sym->name && !sym_is_choice_value(sym)) { to avoid oldnoconfig chugging through the else stanza. Fix that to restore expected behaviour (which I've confirmed in the Fedora kernel build that the configs end up looking the same.) Signed-off-by: Kyle McMartin Acked-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/kconfig/conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 4b3ad9b862b1..d56131c0b3c5 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -427,7 +427,7 @@ static void check_conf(struct menu *menu) if (sym->name && !sym_is_choice_value(sym)) { printf("CONFIG_%s\n", sym->name); } - } else { + } else if (input_mode != oldnoconfig) { if (!conf_cnt++) printf(_("*\n* Restart config...\n*\n")); rootEntry = menu_get_parent_menu(menu); -- cgit v1.2.3 From 1f3a66889c4c80c821f3eadf899c140e91452f8e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 11 Sep 2010 15:55:12 -0700 Subject: kernel-doc: ignore case when stripping attributes There are valid attributes that could have upper case letters, but we still want to remove, like for example __attribute__((aligned(NETDEV_ALIGN))) as encountered in the wireless code. Signed-off-by: Johannes Berg Signed-off-by: Randy Dunlap Signed-off-by: Linus Torvalds --- scripts/kernel-doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 102e1235fd5c..a68240c188f3 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1679,7 +1679,7 @@ sub check_sections($$$$$$) { foreach $px (0 .. $#prms) { $prm_clean = $prms[$px]; $prm_clean =~ s/\[.*\]//; - $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//; + $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//i; # ignore array size in a parameter string; # however, the original param string may contain # spaces, e.g.: addr[6 + 2] -- cgit v1.2.3 From eda603f6cdba4b14dbf80531fab2fe545232e7a0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 11 Sep 2010 15:55:22 -0700 Subject: docbook: warn on unused doc entries When you don't use !E or !I but only !F, then it's very easy to miss including some functions, structs etc. in documentation. To help finding which ones were missed, allow printing out the unused ones as warnings. For example, using this on mac80211 yields a lot of warnings like this: Warning: didn't use docs for DOC: mac80211 workqueue Warning: didn't use docs for ieee80211_max_queues Warning: didn't use docs for ieee80211_bss_change Warning: didn't use docs for ieee80211_bss_conf when generating the documentation for it. Signed-off-by: Johannes Berg Signed-off-by: Randy Dunlap Signed-off-by: Linus Torvalds --- scripts/basic/docproc.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++- scripts/kernel-doc | 52 ++++++++++++++++++- 2 files changed, 178 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c index 79ab973fb43a..fc3b18d844af 100644 --- a/scripts/basic/docproc.c +++ b/scripts/basic/docproc.c @@ -34,12 +34,14 @@ * */ +#define _GNU_SOURCE #include #include #include #include #include #include +#include #include #include @@ -54,6 +56,7 @@ typedef void FILEONLY(char * file); FILEONLY *internalfunctions; FILEONLY *externalfunctions; FILEONLY *symbolsonly; +FILEONLY *findall; typedef void FILELINE(char * file, char * line); FILELINE * singlefunctions; @@ -65,12 +68,30 @@ FILELINE * docsection; #define KERNELDOCPATH "scripts/" #define KERNELDOC "kernel-doc" #define DOCBOOK "-docbook" +#define LIST "-list" #define FUNCTION "-function" #define NOFUNCTION "-nofunction" #define NODOCSECTIONS "-no-doc-sections" static char *srctree, *kernsrctree; +static char **all_list = NULL; +static int all_list_len = 0; + +static void consume_symbol(const char *sym) +{ + int i; + + for (i = 0; i < all_list_len; i++) { + if (!all_list[i]) + continue; + if (strcmp(sym, all_list[i])) + continue; + all_list[i] = NULL; + break; + } +} + static void usage (void) { fprintf(stderr, "Usage: docproc {doc|depend} file\n"); @@ -248,6 +269,7 @@ static void docfunctions(char * filename, char * type) struct symfile * sym = &symfilelist[i]; for (j=0; j < sym->symbolcnt; j++) { vec[idx++] = type; + consume_symbol(sym->symbollist[j].name); vec[idx++] = sym->symbollist[j].name; } } @@ -287,6 +309,11 @@ static void singfunc(char * filename, char * line) vec[idx++] = &line[i]; } } + for (i = 0; i < idx; i++) { + if (strcmp(vec[i], FUNCTION)) + continue; + consume_symbol(vec[i + 1]); + } vec[idx++] = filename; vec[idx] = NULL; exec_kernel_doc(vec); @@ -306,6 +333,10 @@ static void docsect(char *filename, char *line) if (*s == '\n') *s = '\0'; + asprintf(&s, "DOC: %s", line); + consume_symbol(s); + free(s); + vec[0] = KERNELDOC; vec[1] = DOCBOOK; vec[2] = FUNCTION; @@ -315,6 +346,84 @@ static void docsect(char *filename, char *line) exec_kernel_doc(vec); } +static void find_all_symbols(char *filename) +{ + char *vec[4]; /* kerneldoc -list file NULL */ + pid_t pid; + int ret, i, count, start; + char real_filename[PATH_MAX + 1]; + int pipefd[2]; + char *data, *str; + size_t data_len = 0; + + vec[0] = KERNELDOC; + vec[1] = LIST; + vec[2] = filename; + vec[3] = NULL; + + if (pipe(pipefd)) { + perror("pipe"); + exit(1); + } + + switch (pid=fork()) { + case -1: + perror("fork"); + exit(1); + case 0: + close(pipefd[0]); + dup2(pipefd[1], 1); + memset(real_filename, 0, sizeof(real_filename)); + strncat(real_filename, kernsrctree, PATH_MAX); + strncat(real_filename, "/" KERNELDOCPATH KERNELDOC, + PATH_MAX - strlen(real_filename)); + execvp(real_filename, vec); + fprintf(stderr, "exec "); + perror(real_filename); + exit(1); + default: + close(pipefd[1]); + data = malloc(4096); + do { + while ((ret = read(pipefd[0], + data + data_len, + 4096)) > 0) { + data_len += ret; + data = realloc(data, data_len + 4096); + } + } while (ret == -EAGAIN); + if (ret != 0) { + perror("read"); + exit(1); + } + waitpid(pid, &ret ,0); + } + if (WIFEXITED(ret)) + exitstatus |= WEXITSTATUS(ret); + else + exitstatus = 0xff; + + count = 0; + /* poor man's strtok, but with counting */ + for (i = 0; i < data_len; i++) { + if (data[i] == '\n') { + count++; + data[i] = '\0'; + } + } + start = all_list_len; + all_list_len += count; + all_list = realloc(all_list, sizeof(char *) * all_list_len); + str = data; + for (i = 0; i < data_len && start != all_list_len; i++) { + if (data[i] == '\0') { + all_list[start] = str; + str = data + i + 1; + start++; + } + } +} + /* * Parse file, calling action specific functions for: * 1) Lines containing !E @@ -322,7 +431,8 @@ static void docsect(char *filename, char *line) * 3) Lines containing !D * 4) Lines containing !F * 5) Lines containing !P - * 6) Default lines - lines not matching the above + * 6) Lines containing !C + * 7) Default lines - lines not matching the above */ static void parse_file(FILE *infile) { @@ -365,6 +475,12 @@ static void parse_file(FILE *infile) s++; docsection(line + 2, s); break; + case 'C': + while (*s && !isspace(*s)) s++; + *s = '\0'; + if (findall) + findall(line+2); + break; default: defaultline(line); } @@ -380,6 +496,7 @@ static void parse_file(FILE *infile) int main(int argc, char *argv[]) { FILE * infile; + int i; srctree = getenv("SRCTREE"); if (!srctree) @@ -415,6 +532,7 @@ int main(int argc, char *argv[]) symbolsonly = find_export_symbols; singlefunctions = noaction2; docsection = noaction2; + findall = find_all_symbols; parse_file(infile); /* Rewind to start from beginning of file again */ @@ -425,8 +543,16 @@ int main(int argc, char *argv[]) symbolsonly = printline; singlefunctions = singfunc; docsection = docsect; + findall = NULL; parse_file(infile); + + for (i = 0; i < all_list_len; i++) { + if (!all_list[i]) + continue; + fprintf(stderr, "Warning: didn't use docs for %s\n", + all_list[i]); + } } else if (strcmp("depend", argv[1]) == 0) { @@ -439,6 +565,7 @@ int main(int argc, char *argv[]) symbolsonly = adddep; singlefunctions = adddep2; docsection = adddep2; + findall = adddep; parse_file(infile); printf("\n"); } diff --git a/scripts/kernel-doc b/scripts/kernel-doc index a68240c188f3..cdb6dc1f6458 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -44,12 +44,13 @@ use strict; # Note: This only supports 'c'. # usage: -# kernel-doc [ -docbook | -html | -text | -man ] [ -no-doc-sections ] +# kernel-doc [ -docbook | -html | -text | -man | -list ] [ -no-doc-sections ] # [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile # or # [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile # # Set output format using one of -docbook -html -text or -man. Default is man. +# The -list format is for internal use by docproc. # # -no-doc-sections # Do not output DOC: sections @@ -210,9 +211,16 @@ my %highlights_text = ( $type_constant, "\$1", $type_param, "\$1" ); my $blankline_text = ""; +# list mode +my %highlights_list = ( $type_constant, "\$1", + $type_func, "\$1", + $type_struct, "\$1", + $type_param, "\$1" ); +my $blankline_list = ""; sub usage { - print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ] [ -no-doc-sections ]\n"; + print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -list ]\n"; + print " [ -no-doc-sections ]\n"; print " [ -function funcname [ -function funcname ...] ]\n"; print " [ -nofunction funcname [ -nofunction funcname ...] ]\n"; print " c source file(s) > outputfile\n"; @@ -318,6 +326,10 @@ while ($ARGV[0] =~ m/^-(.*)/) { $output_mode = "xml"; %highlights = %highlights_xml; $blankline = $blankline_xml; + } elsif ($cmd eq "-list") { + $output_mode = "list"; + %highlights = %highlights_list; + $blankline = $blankline_list; } elsif ($cmd eq "-gnome") { $output_mode = "gnome"; %highlights = %highlights_gnome; @@ -1361,6 +1373,42 @@ sub output_blockhead_text(%) { } } +## list mode output functions + +sub output_function_list(%) { + my %args = %{$_[0]}; + + print $args{'function'} . "\n"; +} + +# output enum in list +sub output_enum_list(%) { + my %args = %{$_[0]}; + print $args{'enum'} . "\n"; +} + +# output typedef in list +sub output_typedef_list(%) { + my %args = %{$_[0]}; + print $args{'typedef'} . "\n"; +} + +# output struct as list +sub output_struct_list(%) { + my %args = %{$_[0]}; + + print $args{'struct'} . "\n"; +} + +sub output_blockhead_list(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + + foreach $section (@{$args{'sectionlist'}}) { + print "DOC: $section\n"; + } +} + ## # generic output function for all types (function, struct/union, typedef, enum); # calls the generated, variable output_ function name based on -- cgit v1.2.3 From aee08ed499d65f78373b716fcacefcde1ceb7ade Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 10 Sep 2010 01:32:50 -0700 Subject: nconfig: Fix help for choice menus When getting the help for a choice menu with a help section (for example the "Choose SLAB allocator" menu) nconfig pops up a window with nothing inside it. This is due to show_help() passing an empty string to show_scroll_win()'s 3rd argument. The option really does have help though, but it isn't a config symbol, so just add the help text for the option, and don't try to add anything else like the config option name. Signed-off-by: Stephen Boyd Acked-by: Nir Tzachar Signed-off-by: Michal Marek --- scripts/kconfig/nconf.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 18a215de9f36..d4d1fa696c93 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -1265,6 +1265,8 @@ static void show_help(struct menu *menu) str_append(&help, _(menu_get_help(menu))); str_append(&help, "\n"); get_symbol_str(&help, menu->sym); + } else { + str_append(&help, _(menu_get_help(menu))); } } else { str_append(&help, nohelp_text); -- cgit v1.2.3 From 20f4ad8a19ad01405f9d6b3110d6eb93666ae21e Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Fri, 10 Sep 2010 19:01:14 +0200 Subject: Fix QT4 moc, cflags libs detection on dual QT3/Qt4 systems On system with QT3 and QT4 qmake in PATH may be from QT3. So we use pkg-config for proper QT4 detection. By reqesting cflags and libs for either QtCore, QtGui and QtSupport include dirs and libs get listed several times, but so we won't mis anything Signed-off-by: Alexander Stein Acked-by: Randy Dunlap Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index cef3f75e1c2b..996059ef1c4d 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -273,12 +273,10 @@ $(obj)/.tmp_qtcheck: moc="/usr/bin/moc"; \ fi; \ else \ - headerpath="\$$(shell qmake -query QT_INSTALL_HEADERS)"; \ - libpath="\$$(shell qmake -query QT_INSTALL_LIBS)"; \ - binpath="\$$(shell qmake -query QT_INSTALL_BINS)"; \ - cflags="-I$$headerpath -I$$headerpath/QtCore -I$$headerpath/QtGui -I$$headerpath/Qt3Support -DQT3_SUPPORT"; \ - libs="-L$$libpath -Wl,-rpath,$$libpath -lQtCore -lQtGui -lQt3Support"; \ - moc="$$binpath/moc"; \ + cflags="\$$(shell pkg-config QtCore --cflags) \$$(shell pkg-config QtGui --cflags) \$$(shell pkg-config Qt3Support --cflags)"; \ + libs="\$$(shell pkg-config QtCore --libs) \$$(shell pkg-config QtGui --libs) \$$(shell pkg-config Qt3Support --libs)"; \ + binpath="\$$(shell pkg-config QtCore --variable=prefix)"; \ + moc="$$binpath/bin/moc"; \ fi; \ echo "KC_QT_CFLAGS=$$cflags" > $@; \ echo "KC_QT_LIBS=$$libs" >> $@; \ -- cgit v1.2.3 From 458452f4a9b61228cf48a4232a19c8d7d686c11b Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Mon, 13 Sep 2010 13:41:31 +0200 Subject: kconfig: Simplify Makefile for xconfig Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 996059ef1c4d..3fbfe98be2b5 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -273,8 +273,8 @@ $(obj)/.tmp_qtcheck: moc="/usr/bin/moc"; \ fi; \ else \ - cflags="\$$(shell pkg-config QtCore --cflags) \$$(shell pkg-config QtGui --cflags) \$$(shell pkg-config Qt3Support --cflags)"; \ - libs="\$$(shell pkg-config QtCore --libs) \$$(shell pkg-config QtGui --libs) \$$(shell pkg-config Qt3Support --libs)"; \ + cflags="\$$(shell pkg-config QtCore QtGui Qt3Support --cflags)"; \ + libs="\$$(shell pkg-config QtCore QtGui Qt3Support --libs)"; \ binpath="\$$(shell pkg-config QtCore --variable=prefix)"; \ moc="$$binpath/bin/moc"; \ fi; \ -- cgit v1.2.3 From cec1921ec9a91b9bc7c083b6ebe47c17552b9a81 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 13 Sep 2010 12:55:56 -0700 Subject: scripts/kconfig/gconf.glade Update broken web addresses. As discussed, remove the DOCTYPE declaration since libglade validates the file against itself.. Signed-off-by: Justin P. Mattock Signed-off-by: Michal Marek --- scripts/kconfig/gconf.glade | 1 - 1 file changed, 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.glade index d52b0a75d824..aa483cb32755 100644 --- a/scripts/kconfig/gconf.glade +++ b/scripts/kconfig/gconf.glade @@ -1,5 +1,4 @@ - -- cgit v1.2.3 From 8baefd30b5b0101aa07aa75da44a9eee881eed28 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Tue, 24 Aug 2010 00:14:47 -0400 Subject: kconfig: replace a `switch()' statement by a more flexible `if()' statement With the upcoming dynamical configuration prefix, we can no longer assume that the prefix will start by a 'C'. As such, we can no longer hardcode this value in the `case ...:', so replace the `switch() { ... }' statement by a more flexible 'if () { ... }' statement. Signed-off-by: Arnaud Lacombe Reviewed-by: Sam Ravnborg Reviewed-by: Michal Marek --- scripts/kconfig/confdata.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index dc11d51bd8b3..d9181de78927 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -221,8 +221,7 @@ load: while (fgets(line, sizeof(line), in)) { conf_lineno++; sym = NULL; - switch (line[0]) { - case '#': + if (line[0] == '#') { if (memcmp(line + 2, "CONFIG_", 7)) continue; p = strchr(line + 9, ' '); @@ -254,12 +253,7 @@ load: default: ; } - break; - case 'C': - if (memcmp(line, "CONFIG_", 7)) { - conf_warning("unexpected data"); - continue; - } + } else if (memcmp(line, "CONFIG_", 7) == 0) { p = strchr(line + 7, '='); if (!p) continue; @@ -286,12 +280,9 @@ load: } if (conf_set_sym_val(sym, def, def_flags, p)) continue; - break; - case '\r': - case '\n': - break; - default: - conf_warning("unexpected data"); + } else { + if (line[0] != '\r' && line[0] != '\n') + conf_warning("unexpected data"); continue; } if (sym && sym_is_choice_value(sym)) { -- cgit v1.2.3 From 59dfa24da7cb02b3ccc39f5e74b74fe26ea9626a Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sat, 21 Aug 2010 00:43:46 -0400 Subject: kconfig: rephrase help text not to mention the internal prefix Signed-off-by: Arnaud Lacombe Reviewed-by: Sam Ravnborg Reviewed-by: Michal Marek --- scripts/kconfig/mconf.c | 10 +++++----- scripts/kconfig/nconf.c | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index d2f6e056c058..5c3d0c4b810f 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -232,7 +232,7 @@ save_config_help[] = N_( "leave this blank.\n"), search_help[] = N_( "\n" - "Search for CONFIG_ symbols and display their relations.\n" + "Search for symbols and display their relations.\n" "Regular expressions are allowed.\n" "Example: search for \"^FOO\"\n" "Result:\n" @@ -249,7 +249,7 @@ search_help[] = N_( "Selected by: BAR\n" "-----------------------------------------------------------------\n" "o The line 'Prompt:' shows the text used in the menu structure for\n" - " this CONFIG_ symbol\n" + " this symbol\n" "o The 'Defined at' line tell at what file / line number the symbol\n" " is defined\n" "o The 'Depends on:' line tell what symbols needs to be defined for\n" @@ -265,9 +265,9 @@ search_help[] = N_( "Only relevant lines are shown.\n" "\n\n" "Search examples:\n" - "Examples: USB => find all CONFIG_ symbols containing USB\n" - " ^USB => find all CONFIG_ symbols starting with USB\n" - " USB$ => find all CONFIG_ symbols ending with USB\n" + "Examples: USB => find all symbols containing USB\n" + " ^USB => find all symbols starting with USB\n" + " USB$ => find all symbols ending with USB\n" "\n"); static int indent; diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 18a215de9f36..b8a9f37b036b 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -217,8 +217,8 @@ save_config_help[] = N_( "leave this blank.\n"), search_help[] = N_( "\n" -"Search for CONFIG_ symbols and display their relations.\n" -"Regular expressions are allowed.\n" +"Search for symbols and display their relations. Regular expressions\n" +"are allowed.\n" "Example: search for \"^FOO\"\n" "Result:\n" "-----------------------------------------------------------------\n" @@ -234,7 +234,7 @@ search_help[] = N_( "Selected by: BAR\n" "-----------------------------------------------------------------\n" "o The line 'Prompt:' shows the text used in the menu structure for\n" -" this CONFIG_ symbol\n" +" this symbol\n" "o The 'Defined at' line tell at what file / line number the symbol\n" " is defined\n" "o The 'Depends on:' line tell what symbols needs to be defined for\n" @@ -250,9 +250,9 @@ search_help[] = N_( "Only relevant lines are shown.\n" "\n\n" "Search examples:\n" -"Examples: USB = > find all CONFIG_ symbols containing USB\n" -" ^USB => find all CONFIG_ symbols starting with USB\n" -" USB$ => find all CONFIG_ symbols ending with USB\n" +"Examples: USB = > find all symbols containing USB\n" +" ^USB => find all symbols starting with USB\n" +" USB$ => find all symbols ending with USB\n" "\n"); struct mitem { -- cgit v1.2.3 From ffb5957bc48f64f0773fd3fbc43cb9bb9b38e270 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sat, 14 Aug 2010 23:57:43 -0400 Subject: kconfig: allow build-time definition of the internal config prefix Signed-off-by: Arnaud Lacombe Reviewed-by: Sam Ravnborg Reviewed-by: Michal Marek --- scripts/kconfig/conf.c | 2 +- scripts/kconfig/confdata.c | 48 ++++++++++++++++++++++++++-------------------- scripts/kconfig/lkc.h | 3 +++ scripts/kconfig/mconf.c | 10 +++++----- scripts/kconfig/menu.c | 2 +- scripts/kconfig/nconf.c | 12 ++++++------ 6 files changed, 43 insertions(+), 34 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index d56131c0b3c5..d6cfa0ffbaf0 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -425,7 +425,7 @@ static void check_conf(struct menu *menu) (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { if (input_mode == listnewconfig) { if (sym->name && !sym_is_choice_value(sym)) { - printf("CONFIG_%s\n", sym->name); + printf("%s%s\n", CONFIG_, sym->name); } } else if (input_mode != oldnoconfig) { if (!conf_cnt++) diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index d9181de78927..9f3c8899da5a 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -222,22 +222,22 @@ load: conf_lineno++; sym = NULL; if (line[0] == '#') { - if (memcmp(line + 2, "CONFIG_", 7)) + if (memcmp(line + 2, CONFIG_, strlen(CONFIG_))) continue; - p = strchr(line + 9, ' '); + p = strchr(line + 2 + strlen(CONFIG_), ' '); if (!p) continue; *p++ = 0; if (strncmp(p, "is not set", 10)) continue; if (def == S_DEF_USER) { - sym = sym_find(line + 9); + sym = sym_find(line + 2 + strlen(CONFIG_)); if (!sym) { sym_add_change_count(1); break; } } else { - sym = sym_lookup(line + 9, 0); + sym = sym_lookup(line + 2 + strlen(CONFIG_), 0); if (sym->type == S_UNKNOWN) sym->type = S_BOOLEAN; } @@ -253,8 +253,8 @@ load: default: ; } - } else if (memcmp(line, "CONFIG_", 7) == 0) { - p = strchr(line + 7, '='); + } else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) { + p = strchr(line + strlen(CONFIG_), '='); if (!p) continue; *p++ = 0; @@ -265,13 +265,13 @@ load: *p2 = 0; } if (def == S_DEF_USER) { - sym = sym_find(line + 7); + sym = sym_find(line + strlen(CONFIG_)); if (!sym) { sym_add_change_count(1); break; } } else { - sym = sym_lookup(line + 7, 0); + sym = sym_lookup(line + strlen(CONFIG_), 0); if (sym->type == S_UNKNOWN) sym->type = S_OTHER; } @@ -397,9 +397,9 @@ static void conf_write_string(bool headerfile, const char *name, { int l; if (headerfile) - fprintf(out, "#define CONFIG_%s \"", name); + fprintf(out, "#define %s%s \"", CONFIG_, name); else - fprintf(out, "CONFIG_%s=\"", name); + fprintf(out, "%s%s=\"", CONFIG_, name); while (1) { l = strcspn(str, "\"\\"); @@ -425,13 +425,14 @@ static void conf_write_symbol(struct symbol *sym, enum symbol_type type, switch (sym_get_tristate_value(sym)) { case no: if (write_no) - fprintf(out, "# CONFIG_%s is not set\n", sym->name); + fprintf(out, "# %s%s is not set\n", + CONFIG_, sym->name); break; case mod: - fprintf(out, "CONFIG_%s=m\n", sym->name); + fprintf(out, "%s%s=m\n", CONFIG_, sym->name); break; case yes: - fprintf(out, "CONFIG_%s=y\n", sym->name); + fprintf(out, "%s%s=y\n", CONFIG_, sym->name); break; } break; @@ -441,7 +442,7 @@ static void conf_write_symbol(struct symbol *sym, enum symbol_type type, case S_HEX: case S_INT: str = sym_get_string_value(sym); - fprintf(out, "CONFIG_%s=%s\n", sym->name, str); + fprintf(out, "%s%s=%s\n", CONFIG_, sym->name, str); break; case S_OTHER: case S_UNKNOWN: @@ -832,14 +833,17 @@ int conf_write_autoconf(void) case no: break; case mod: - fprintf(tristate, "CONFIG_%s=M\n", sym->name); - fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); + fprintf(tristate, "%s%s=M\n", + CONFIG_, sym->name); + fprintf(out_h, "#define %s%s_MODULE 1\n", + CONFIG_, sym->name); break; case yes: if (sym->type == S_TRISTATE) - fprintf(tristate, "CONFIG_%s=Y\n", - sym->name); - fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); + fprintf(tristate,"%s%s=Y\n", + CONFIG_, sym->name); + fprintf(out_h, "#define %s%s 1\n", + CONFIG_, sym->name); break; } break; @@ -849,12 +853,14 @@ int conf_write_autoconf(void) case S_HEX: str = sym_get_string_value(sym); if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { - fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); + fprintf(out_h, "#define %s%s 0x%s\n", + CONFIG_, sym->name, str); break; } case S_INT: str = sym_get_string_value(sym); - fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); + fprintf(out_h, "#define %s%s %s\n", + CONFIG_, sym->name, str); break; default: break; diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index bdf71bd31412..1b966bf02b12 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -37,6 +37,9 @@ extern "C" { #define _(text) gettext(text) #define N_(text) (text) +#ifndef CONFIG_ +#define CONFIG_ "CONFIG_" +#endif #define TF_COMMAND 0x0001 #define TF_PARAM 0x0002 diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 5c3d0c4b810f..17ba2227932d 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -316,8 +316,8 @@ static void search_conf(void) again: dialog_clear(); dres = dialog_inputbox(_("Search Configuration Parameter"), - _("Enter CONFIG_ (sub)string to search for " - "(with or without \"CONFIG\")"), + _("Enter " CONFIG_ " (sub)string to search for " + "(with or without \"" CONFIG_ "\")"), 10, 75, ""); switch (dres) { case 0: @@ -329,10 +329,10 @@ again: return; } - /* strip CONFIG_ if necessary */ + /* strip the prefix if necessary */ dialog_input = dialog_input_result; - if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0) - dialog_input += 7; + if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0) + dialog_input += strlen(CONFIG_); sym_arr = sym_re_search(dialog_input); res = get_relations_str(sym_arr); diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 4fb590247f33..64da30c76894 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -566,7 +566,7 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help) if (menu_has_help(menu)) { if (sym->name) { - str_printf(help, "CONFIG_%s:\n\n", sym->name); + str_printf(help, "%s%s:\n\n", CONFIG_, sym->name); str_append(help, _(menu_get_help(menu))); str_append(help, "\n"); } diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index b8a9f37b036b..da5e45d43f15 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -744,8 +744,8 @@ static void search_conf(void) again: dres = dialog_inputbox(main_window, _("Search Configuration Parameter"), - _("Enter CONFIG_ (sub)string to search for " - "(with or without \"CONFIG\")"), + _("Enter " CONFIG_ " (sub)string to search for " + "(with or without \"" CONFIG_ "\")"), "", dialog_input_result, 99); switch (dres) { case 0: @@ -758,10 +758,10 @@ again: return; } - /* strip CONFIG_ if necessary */ + /* strip the prefix if necessary */ dialog_input = dialog_input_result; - if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0) - dialog_input += 7; + if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0) + dialog_input += strlen(CONFIG_); sym_arr = sym_re_search(dialog_input); res = get_relations_str(sym_arr); @@ -1261,7 +1261,7 @@ static void show_help(struct menu *menu) if (menu && menu->sym && menu_has_help(menu)) { if (menu->sym->name) { - str_printf(&help, "CONFIG_%s:\n\n", menu->sym->name); + str_printf(&help, "%s%s:\n\n", CONFIG_, menu->sym->name); str_append(&help, _(menu_get_help(menu))); str_append(&help, "\n"); get_symbol_str(&help, menu->sym); -- cgit v1.2.3 From 652cf9821d2a5b22a1725ce8dc235ea5de0e1c6f Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sat, 14 Aug 2010 23:51:40 -0400 Subject: kconfig: rephrase help texts/comments not to include the package name Signed-off-by: Arnaud Lacombe Reviewed-by: Randy Dunlap Reviewed-by: Sam Ravnborg Reviewed-by: Michal Marek --- scripts/kconfig/conf.c | 11 +++++------ scripts/kconfig/gconf.c | 3 +-- scripts/kconfig/mconf.c | 38 ++++++++++++++++++-------------------- scripts/kconfig/menu.c | 2 +- scripts/kconfig/nconf.c | 43 +++++++++++++++++++------------------------ scripts/kconfig/qconf.cc | 2 +- 6 files changed, 45 insertions(+), 54 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index d6cfa0ffbaf0..eba5906dc4ab 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -508,8 +508,7 @@ int main(int ac, char **av) name = conf_get_configname(); if (stat(name, &tmpstat)) { fprintf(stderr, _("***\n" - "*** You have not yet configured your kernel!\n" - "*** (missing kernel config file \"%s\")\n" + "*** Configuration file \"%s\" not found!\n" "***\n" "*** Please run some configurator (e.g. \"make oldconfig\" or\n" "*** \"make menuconfig\" or \"make xconfig\").\n" @@ -571,7 +570,7 @@ int main(int ac, char **av) name = getenv("KCONFIG_NOSILENTUPDATE"); if (name && *name) { fprintf(stderr, - _("\n*** Kernel configuration requires explicit update.\n\n")); + _("\n*** The configuration requires explicit update.\n\n")); return 1; } } @@ -623,11 +622,11 @@ int main(int ac, char **av) * All other commands are only used to generate a config. */ if (conf_get_changed() && conf_write(NULL)) { - fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); + fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n")); exit(1); } if (conf_write_autoconf()) { - fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n")); + fprintf(stderr, _("\n*** Error during update of the configuration.\n\n")); return 1; } } else if (input_mode == savedefconfig) { @@ -638,7 +637,7 @@ int main(int ac, char **av) } } else if (input_mode != listnewconfig) { if (conf_write(NULL)) { - fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); + fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n")); exit(1); } } diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index d66988265f89..16362139d52a 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -671,8 +671,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkWidget *dialog; const gchar *intro_text = _( - "Welcome to gkc, the GTK+ graphical kernel configuration tool\n" - "for Linux.\n" + "Welcome to gkc, the GTK+ graphical configuration tool\n" "For each option, a blank box indicates the feature is disabled, a\n" "check indicates it is enabled, and a dot indicates that it is to\n" "be compiled as a module. Clicking on the box will cycle through the three states.\n" diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 17ba2227932d..cee4281ad209 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -25,11 +25,9 @@ static const char mconf_readme[] = N_( "Overview\n" "--------\n" -"Some kernel features may be built directly into the kernel.\n" -"Some may be made into loadable runtime modules. Some features\n" -"may be completely removed altogether. There are also certain\n" -"kernel parameters which are not really features, but must be\n" -"entered in as decimal or hexadecimal numbers or possibly text.\n" +"This interface let you select features and parameters for the build.\n" +"Features can either be built-in, modularized, or ignored. Parameters\n" +"must be entered in as decimal or hexadecimal numbers or text.\n" "\n" "Menu items beginning with following braces represent features that\n" " [ ] can be built in or removed\n" @@ -117,7 +115,7 @@ static const char mconf_readme[] = N_( "-----------------------------\n" "Menuconfig supports the use of alternate configuration files for\n" "those who, for various reasons, find it necessary to switch\n" -"between different kernel configurations.\n" +"between different configurations.\n" "\n" "At the end of the main menu you will find two options. One is\n" "for saving the current configuration to a file of your choosing.\n" @@ -150,9 +148,9 @@ static const char mconf_readme[] = N_( "\n" "Optional personality available\n" "------------------------------\n" -"If you prefer to have all of the kernel options listed in a single\n" -"menu, rather than the default multimenu hierarchy, run the menuconfig\n" -"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n" +"If you prefer to have all of the options listed in a single menu, rather\n" +"than the default multimenu hierarchy, run the menuconfig with\n" +"MENUCONFIG_MODE environment variable set to single_menu. Example:\n" "\n" "make MENUCONFIG_MODE=single_menu menuconfig\n" "\n" @@ -207,12 +205,12 @@ load_config_text[] = N_( "last retrieved. Leave blank to abort."), load_config_help[] = N_( "\n" - "For various reasons, one may wish to keep several different kernel\n" + "For various reasons, one may wish to keep several different\n" "configurations available on a single machine.\n" "\n" "If you have saved a previous configuration in a file other than the\n" - "kernel's default, entering the name of the file here will allow you\n" - "to modify that configuration.\n" + "default one, entering its name here will allow you to modify that\n" + "configuration.\n" "\n" "If you are uncertain, then you have probably never used alternate\n" "configuration files. You should therefore leave this blank to abort.\n"), @@ -221,8 +219,8 @@ save_config_text[] = N_( "as an alternate. Leave blank to abort."), save_config_help[] = N_( "\n" - "For various reasons, one may wish to keep different kernel\n" - "configurations available on a single machine.\n" + "For various reasons, one may wish to keep different configurations\n" + "available on a single machine.\n" "\n" "Entering a file name here will allow you to later retrieve, modify\n" "and use the current configuration as an alternate to whatever\n" @@ -834,7 +832,7 @@ int main(int ac, char **av) if (conf_get_changed()) res = dialog_yesno(NULL, _("Do you wish to save your " - "new kernel configuration?\n" + "new configuration?\n" " to continue."), 6, 60); else @@ -846,20 +844,20 @@ int main(int ac, char **av) case 0: if (conf_write(filename)) { fprintf(stderr, _("\n\n" - "Error during writing of the kernel configuration.\n" - "Your kernel configuration changes were NOT saved." + "Error while writing of the configuration.\n" + "Your configuration changes were NOT saved." "\n\n")); return 1; } case -1: printf(_("\n\n" - "*** End of Linux kernel configuration.\n" - "*** Execute 'make' to build the kernel or try 'make help'." + "*** End of the configuration.\n" + "*** Execute 'make' to start the build or try 'make help'." "\n\n")); break; default: fprintf(stderr, _("\n\n" - "Your kernel configuration changes were NOT saved." + "Your configuration changes were NOT saved." "\n\n")); } diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 64da30c76894..682045a7aae4 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -10,7 +10,7 @@ #include "lkc.h" static const char nohelp_text[] = N_( - "There is no help available for this kernel option.\n"); + "There is no help available for this option.\n"); struct menu rootmenu; static struct menu **last_entry_ptr; diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index da5e45d43f15..801cc048704a 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -15,11 +15,9 @@ static const char nconf_readme[] = N_( "Overview\n" "--------\n" -"Some kernel features may be built directly into the kernel.\n" -"Some may be made into loadable runtime modules. Some features\n" -"may be completely removed altogether. There are also certain\n" -"kernel parameters which are not really features, but must be\n" -"entered in as decimal or hexadecimal numbers or possibly text.\n" +"This interface let you select features and parameters for the build.\n" +"Features can either be built-in, modularized, or ignored. Parameters\n" +"must be entered in as decimal or hexadecimal numbers or text.\n" "\n" "Menu items beginning with following braces represent features that\n" " [ ] can be built in or removed\n" @@ -95,7 +93,7 @@ static const char nconf_readme[] = N_( "-----------------------------\n" "nconfig supports the use of alternate configuration files for\n" "those who, for various reasons, find it necessary to switch\n" -"between different kernel configurations.\n" +"between different configurations.\n" "\n" "At the end of the main menu you will find two options. One is\n" "for saving the current configuration to a file of your choosing.\n" @@ -128,9 +126,9 @@ static const char nconf_readme[] = N_( "\n" "Optional personality available\n" "------------------------------\n" -"If you prefer to have all of the kernel options listed in a single\n" -"menu, rather than the default multimenu hierarchy, run the nconfig\n" -"with NCONFIG_MODE environment variable set to single_menu. Example:\n" +"If you prefer to have all of the options listed in a single menu, rather\n" +"than the default multimenu hierarchy, run the nconfig with NCONFIG_MODE\n" +"environment variable set to single_menu. Example:\n" "\n" "make NCONFIG_MODE=single_menu nconfig\n" "\n" @@ -185,19 +183,19 @@ setmod_text[] = N_( "has been configured as a module.\n" "As a result, this feature will be built as a module."), nohelp_text[] = N_( -"There is no help available for this kernel option.\n"), +"There is no help available for this option.\n"), load_config_text[] = N_( "Enter the name of the configuration file you wish to load.\n" "Accept the name shown to restore the configuration you\n" "last retrieved. Leave blank to abort."), load_config_help[] = N_( "\n" -"For various reasons, one may wish to keep several different kernel\n" +"For various reasons, one may wish to keep several different\n" "configurations available on a single machine.\n" "\n" "If you have saved a previous configuration in a file other than the\n" -"kernel's default, entering the name of the file here will allow you\n" -"to modify that configuration.\n" +"default one, entering its name here will allow you to modify that\n" +"configuration.\n" "\n" "If you are uncertain, then you have probably never used alternate\n" "configuration files. You should therefor leave this blank to abort.\n"), @@ -206,8 +204,8 @@ save_config_text[] = N_( "as an alternate. Leave blank to abort."), save_config_help[] = N_( "\n" -"For various reasons, one may wish to keep different kernel\n" -"configurations available on a single machine.\n" +"For various reasons, one may wish to keep different configurations\n" +"available on a single machine.\n" "\n" "Entering a file name here will allow you to later retrieve, modify\n" "and use the current configuration as an alternate to whatever\n" @@ -681,8 +679,7 @@ static int do_exit(void) return 0; } res = btn_dialog(main_window, - _("Do you wish to save your " - "new kernel configuration?\n" + _("Do you wish to save your new configuration?\n" " to cancel and resume nconfig."), 2, " ", @@ -701,18 +698,16 @@ static int do_exit(void) if (res) btn_dialog( main_window, - _("Error during writing of the kernel " - "configuration.\n" - "Your kernel configuration " - "changes were NOT saved."), + _("Error during writing of configuration.\n" + "Your configuration changes were NOT saved."), 1, ""); else { char buf[1024]; snprintf(buf, 1024, _("Configuration written to %s\n" - "End of Linux kernel configuration.\n" - "Execute 'make' to build the kernel or try" + "End of the configuration.\n" + "Execute 'make' to start the build or try" " 'make help'."), filename); btn_dialog( main_window, @@ -724,7 +719,7 @@ static int do_exit(void) default: btn_dialog( main_window, - _("Your kernel configuration changes were NOT saved."), + _("Your configuration changes were NOT saved."), 1, ""); break; diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index a04e4517ead1..fe18f7efdca1 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1655,7 +1655,7 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e) void ConfigMainWindow::showIntro(void) { - static const QString str = _("Welcome to the qconf graphical kernel configuration tool for Linux.\n\n" + static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n" "For each option, a blank box indicates the feature is disabled, a check\n" "indicates it is enabled, and a dot indicates that it is to be compiled\n" "as a module. Clicking on the box will cycle through the three states.\n\n" -- cgit v1.2.3 From ef211607ed49c475735898514c60a9797208b699 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sat, 21 Aug 2010 01:20:52 -0400 Subject: kconfig: allow PACKAGE to be defined on the compiler's command-line Signed-off-by: Arnaud Lacombe Reviewed-by: Sam Ravnborg Reviewed-by: Michal Marek --- scripts/kconfig/lkc.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 1b966bf02b12..5d5f1872d651 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -31,7 +31,10 @@ extern "C" { #define SRCTREE "srctree" +#ifndef PACKAGE #define PACKAGE "linux" +#endif + #define LOCALEDIR "/usr/share/locale" #define _(text) gettext(text) -- cgit v1.2.3 From 8ea13e2c87c83b7cb0b360cb8779415967727647 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Mon, 16 Aug 2010 22:55:31 -0400 Subject: kconfig: implement the `mainmenu' directive If specified, the directive must be placed at the top of the Kconfig file. We need to change the grammar to make the mainmenu directive set the `rootmenu' prompt. This reflect how menu_add_prompt() works internally, ie. set the prompt of the `current_entry', pointing originally to `rootmenu'. Signed-off-by: Arnaud Lacombe Reviewed-by: Sam Ravnborg Reviewed-by: Michal Marek --- scripts/kconfig/zconf.y | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y index 23dfd3baa7a1..e9b14efd7414 100644 --- a/scripts/kconfig/zconf.y +++ b/scripts/kconfig/zconf.y @@ -36,7 +36,7 @@ static struct menu *current_menu, *current_entry; #define YYERROR_VERBOSE #endif %} -%expect 26 +%expect 28 %union { @@ -104,14 +104,15 @@ static struct menu *current_menu, *current_entry; %} %% -input: stmt_list; +input: nl start | start; + +start: mainmenu_stmt stmt_list | stmt_list; stmt_list: /* empty */ | stmt_list common_stmt | stmt_list choice_stmt | stmt_list menu_stmt - | stmt_list T_MAINMENU prompt nl | stmt_list end { zconf_error("unexpected end statement"); } | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); } | stmt_list option_name error T_EOL @@ -342,6 +343,13 @@ if_block: | if_block choice_stmt ; +/* mainmenu entry */ + +mainmenu_stmt: T_MAINMENU prompt nl +{ + menu_add_prompt(P_MENU, $2, NULL); +}; + /* menu entry */ menu: T_MENU prompt T_EOL -- cgit v1.2.3 From c0920a1cbd7aecefa5f9768e82136935132ef1cf Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Fri, 10 Sep 2010 21:23:28 -0400 Subject: kconfig: regen parser Signed-off-by: Arnaud Lacombe Reviewed-by: Sam Ravnborg Reviewed-by: Michal Marek --- scripts/kconfig/lex.zconf.c_shipped | 7 +- scripts/kconfig/zconf.tab.c_shipped | 547 +++++++++++++++++++----------------- 2 files changed, 287 insertions(+), 267 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped index fdc7113b08d1..6eb039718259 100644 --- a/scripts/kconfig/lex.zconf.c_shipped +++ b/scripts/kconfig/lex.zconf.c_shipped @@ -2373,9 +2373,10 @@ void zconf_nextfile(const char *name) memset(buf, 0, sizeof(*buf)); current_buf->state = YY_CURRENT_BUFFER; - zconfin = zconf_fopen(name); + zconfin = zconf_fopen(file->name); if (!zconfin) { - printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name); + printf("%s:%d: can't open file \"%s\"\n", + zconf_curname(), zconf_lineno(), file->name); exit(1); } zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE)); @@ -2422,7 +2423,7 @@ int zconf_lineno(void) return current_pos.lineno; } -char *zconf_curname(void) +const char *zconf_curname(void) { return current_pos.file ? current_pos.file->name : ""; } diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped index 32a9eefd842c..699d4b265186 100644 --- a/scripts/kconfig/zconf.tab.c_shipped +++ b/scripts/kconfig/zconf.tab.c_shipped @@ -417,18 +417,18 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 3 +#define YYFINAL 11 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 259 +#define YYLAST 277 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 35 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 46 +#define YYNNTS 48 /* YYNRULES -- Number of rules. */ -#define YYNRULES 110 +#define YYNRULES 113 /* YYNRULES -- Number of states. */ -#define YYNSTATES 180 +#define YYNSTATES 185 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 @@ -476,73 +476,74 @@ static const yytype_uint8 yytranslate[] = YYRHS. */ static const yytype_uint16 yyprhs[] = { - 0, 0, 3, 5, 6, 9, 12, 15, 20, 23, - 28, 33, 37, 39, 41, 43, 45, 47, 49, 51, - 53, 55, 57, 59, 61, 63, 67, 70, 74, 77, - 81, 84, 85, 88, 91, 94, 97, 100, 103, 107, - 112, 117, 122, 128, 132, 133, 137, 138, 141, 145, - 148, 150, 154, 155, 158, 161, 164, 167, 170, 175, - 179, 182, 187, 188, 191, 195, 197, 201, 202, 205, - 208, 211, 215, 218, 220, 224, 225, 228, 231, 234, - 238, 242, 245, 248, 251, 252, 255, 258, 261, 266, - 267, 270, 272, 274, 277, 280, 283, 285, 288, 289, - 292, 294, 298, 302, 306, 309, 313, 317, 319, 321, - 322 + 0, 0, 3, 6, 8, 11, 13, 14, 17, 20, + 23, 26, 31, 36, 40, 42, 44, 46, 48, 50, + 52, 54, 56, 58, 60, 62, 64, 66, 70, 73, + 77, 80, 84, 87, 88, 91, 94, 97, 100, 103, + 106, 110, 115, 120, 125, 131, 135, 136, 140, 141, + 144, 148, 151, 153, 157, 158, 161, 164, 167, 170, + 173, 178, 182, 185, 190, 191, 194, 198, 200, 204, + 205, 208, 211, 214, 218, 222, 225, 227, 231, 232, + 235, 238, 241, 245, 249, 252, 255, 258, 259, 262, + 265, 268, 273, 274, 277, 279, 281, 284, 287, 290, + 292, 295, 296, 299, 301, 305, 309, 313, 316, 320, + 324, 326, 328, 329 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 36, 0, -1, 37, -1, -1, 37, 39, -1, 37, - 53, -1, 37, 64, -1, 37, 3, 74, 76, -1, - 37, 75, -1, 37, 25, 1, 30, -1, 37, 38, - 1, 30, -1, 37, 1, 30, -1, 16, -1, 18, - -1, 19, -1, 21, -1, 17, -1, 22, -1, 20, - -1, 30, -1, 59, -1, 68, -1, 42, -1, 44, - -1, 66, -1, 25, 1, 30, -1, 1, 30, -1, - 10, 25, 30, -1, 41, 45, -1, 11, 25, 30, - -1, 43, 45, -1, -1, 45, 46, -1, 45, 47, - -1, 45, 72, -1, 45, 70, -1, 45, 40, -1, - 45, 30, -1, 19, 73, 30, -1, 18, 74, 77, - 30, -1, 20, 78, 77, 30, -1, 21, 25, 77, - 30, -1, 22, 79, 79, 77, 30, -1, 23, 48, - 30, -1, -1, 48, 25, 49, -1, -1, 33, 74, - -1, 7, 80, 30, -1, 50, 54, -1, 75, -1, - 51, 56, 52, -1, -1, 54, 55, -1, 54, 72, - -1, 54, 70, -1, 54, 30, -1, 54, 40, -1, - 18, 74, 77, 30, -1, 19, 73, 30, -1, 17, - 30, -1, 20, 25, 77, 30, -1, -1, 56, 39, - -1, 14, 78, 76, -1, 75, -1, 57, 60, 58, - -1, -1, 60, 39, -1, 60, 64, -1, 60, 53, - -1, 4, 74, 30, -1, 61, 71, -1, 75, -1, - 62, 65, 63, -1, -1, 65, 39, -1, 65, 64, - -1, 65, 53, -1, 6, 74, 30, -1, 9, 74, - 30, -1, 67, 71, -1, 12, 30, -1, 69, 13, - -1, -1, 71, 72, -1, 71, 30, -1, 71, 40, - -1, 16, 24, 78, 30, -1, -1, 74, 77, -1, - 25, -1, 26, -1, 5, 30, -1, 8, 30, -1, - 15, 30, -1, 30, -1, 76, 30, -1, -1, 14, - 78, -1, 79, -1, 79, 33, 79, -1, 79, 27, - 79, -1, 29, 78, 28, -1, 34, 78, -1, 78, - 31, 78, -1, 78, 32, 78, -1, 25, -1, 26, - -1, -1, 25, -1 + 36, 0, -1, 78, 37, -1, 37, -1, 62, 38, + -1, 38, -1, -1, 38, 40, -1, 38, 54, -1, + 38, 66, -1, 38, 77, -1, 38, 25, 1, 30, + -1, 38, 39, 1, 30, -1, 38, 1, 30, -1, + 16, -1, 18, -1, 19, -1, 21, -1, 17, -1, + 22, -1, 20, -1, 30, -1, 60, -1, 70, -1, + 43, -1, 45, -1, 68, -1, 25, 1, 30, -1, + 1, 30, -1, 10, 25, 30, -1, 42, 46, -1, + 11, 25, 30, -1, 44, 46, -1, -1, 46, 47, + -1, 46, 48, -1, 46, 74, -1, 46, 72, -1, + 46, 41, -1, 46, 30, -1, 19, 75, 30, -1, + 18, 76, 79, 30, -1, 20, 80, 79, 30, -1, + 21, 25, 79, 30, -1, 22, 81, 81, 79, 30, + -1, 23, 49, 30, -1, -1, 49, 25, 50, -1, + -1, 33, 76, -1, 7, 82, 30, -1, 51, 55, + -1, 77, -1, 52, 57, 53, -1, -1, 55, 56, + -1, 55, 74, -1, 55, 72, -1, 55, 30, -1, + 55, 41, -1, 18, 76, 79, 30, -1, 19, 75, + 30, -1, 17, 30, -1, 20, 25, 79, 30, -1, + -1, 57, 40, -1, 14, 80, 78, -1, 77, -1, + 58, 61, 59, -1, -1, 61, 40, -1, 61, 66, + -1, 61, 54, -1, 3, 76, 78, -1, 4, 76, + 30, -1, 63, 73, -1, 77, -1, 64, 67, 65, + -1, -1, 67, 40, -1, 67, 66, -1, 67, 54, + -1, 6, 76, 30, -1, 9, 76, 30, -1, 69, + 73, -1, 12, 30, -1, 71, 13, -1, -1, 73, + 74, -1, 73, 30, -1, 73, 41, -1, 16, 24, + 80, 30, -1, -1, 76, 79, -1, 25, -1, 26, + -1, 5, 30, -1, 8, 30, -1, 15, 30, -1, + 30, -1, 78, 30, -1, -1, 14, 80, -1, 81, + -1, 81, 33, 81, -1, 81, 27, 81, -1, 29, + 80, 28, -1, 34, 80, -1, 80, 31, 80, -1, + 80, 32, 80, -1, 25, -1, 26, -1, -1, 25, + -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 107, 107, 109, 111, 112, 113, 114, 115, 116, - 117, 121, 125, 125, 125, 125, 125, 125, 125, 129, - 130, 131, 132, 133, 134, 138, 139, 145, 153, 159, - 167, 177, 179, 180, 181, 182, 183, 184, 187, 195, - 201, 211, 217, 223, 226, 228, 239, 240, 245, 254, - 259, 267, 270, 272, 273, 274, 275, 276, 279, 285, - 296, 302, 312, 314, 319, 327, 335, 338, 340, 341, - 342, 347, 354, 359, 367, 370, 372, 373, 374, 377, - 385, 392, 399, 405, 412, 414, 415, 416, 419, 427, - 429, 434, 435, 438, 439, 440, 444, 445, 448, 449, - 452, 453, 454, 455, 456, 457, 458, 461, 462, 465, - 466 + 0, 107, 107, 107, 109, 109, 111, 113, 114, 115, + 116, 117, 118, 122, 126, 126, 126, 126, 126, 126, + 126, 130, 131, 132, 133, 134, 135, 139, 140, 146, + 154, 160, 168, 178, 180, 181, 182, 183, 184, 185, + 188, 196, 202, 212, 218, 224, 227, 229, 240, 241, + 246, 255, 260, 268, 271, 273, 274, 275, 276, 277, + 280, 286, 297, 303, 313, 315, 320, 328, 336, 339, + 341, 342, 343, 348, 355, 362, 367, 375, 378, 380, + 381, 382, 385, 393, 400, 407, 413, 420, 422, 423, + 424, 427, 435, 437, 442, 443, 446, 447, 448, 452, + 453, 456, 457, 460, 461, 462, 463, 464, 465, 466, + 469, 470, 473, 474 }; #endif @@ -557,17 +558,17 @@ static const char *const yytname[] = "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_RANGE", "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL", - "T_NOT", "$accept", "input", "stmt_list", "option_name", "common_stmt", - "option_error", "config_entry_start", "config_stmt", + "T_NOT", "$accept", "input", "start", "stmt_list", "option_name", + "common_stmt", "option_error", "config_entry_start", "config_stmt", "menuconfig_entry_start", "menuconfig_stmt", "config_option_list", "config_option", "symbol_option", "symbol_option_list", "symbol_option_arg", "choice", "choice_entry", "choice_end", "choice_stmt", "choice_option_list", "choice_option", "choice_block", - "if_entry", "if_end", "if_stmt", "if_block", "menu", "menu_entry", - "menu_end", "menu_stmt", "menu_block", "source_stmt", "comment", - "comment_stmt", "help_start", "help", "depends_list", "depends", - "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr", "symbol", - "word_opt", 0 + "if_entry", "if_end", "if_stmt", "if_block", "mainmenu_stmt", "menu", + "menu_entry", "menu_end", "menu_stmt", "menu_block", "source_stmt", + "comment", "comment_stmt", "help_start", "help", "depends_list", + "depends", "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr", + "symbol", "word_opt", 0 }; #endif @@ -586,35 +587,35 @@ static const yytype_uint16 yytoknum[] = /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 35, 36, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 38, 38, 38, 38, 38, 38, 38, 39, - 39, 39, 39, 39, 39, 40, 40, 41, 42, 43, - 44, 45, 45, 45, 45, 45, 45, 45, 46, 46, - 46, 46, 46, 47, 48, 48, 49, 49, 50, 51, - 52, 53, 54, 54, 54, 54, 54, 54, 55, 55, - 55, 55, 56, 56, 57, 58, 59, 60, 60, 60, - 60, 61, 62, 63, 64, 65, 65, 65, 65, 66, - 67, 68, 69, 70, 71, 71, 71, 71, 72, 73, - 73, 74, 74, 75, 75, 75, 76, 76, 77, 77, - 78, 78, 78, 78, 78, 78, 78, 79, 79, 80, - 80 + 0, 35, 36, 36, 37, 37, 38, 38, 38, 38, + 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, + 39, 40, 40, 40, 40, 40, 40, 41, 41, 42, + 43, 44, 45, 46, 46, 46, 46, 46, 46, 46, + 47, 47, 47, 47, 47, 48, 49, 49, 50, 50, + 51, 52, 53, 54, 55, 55, 55, 55, 55, 55, + 56, 56, 56, 56, 57, 57, 58, 59, 60, 61, + 61, 61, 61, 62, 63, 64, 65, 66, 67, 67, + 67, 67, 68, 69, 70, 71, 72, 73, 73, 73, + 73, 74, 75, 75, 76, 76, 77, 77, 77, 78, + 78, 79, 79, 80, 80, 80, 80, 80, 80, 80, + 81, 81, 82, 82 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 1, 0, 2, 2, 2, 4, 2, 4, - 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 2, 3, 2, 3, - 2, 0, 2, 2, 2, 2, 2, 2, 3, 4, - 4, 4, 5, 3, 0, 3, 0, 2, 3, 2, - 1, 3, 0, 2, 2, 2, 2, 2, 4, 3, - 2, 4, 0, 2, 3, 1, 3, 0, 2, 2, - 2, 3, 2, 1, 3, 0, 2, 2, 2, 3, - 3, 2, 2, 2, 0, 2, 2, 2, 4, 0, - 2, 1, 1, 2, 2, 2, 1, 2, 0, 2, - 1, 3, 3, 3, 2, 3, 3, 1, 1, 0, - 1 + 0, 2, 2, 1, 2, 1, 0, 2, 2, 2, + 2, 4, 4, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 2, 3, + 2, 3, 2, 0, 2, 2, 2, 2, 2, 2, + 3, 4, 4, 4, 5, 3, 0, 3, 0, 2, + 3, 2, 1, 3, 0, 2, 2, 2, 2, 2, + 4, 3, 2, 4, 0, 2, 3, 1, 3, 0, + 2, 2, 2, 3, 3, 2, 1, 3, 0, 2, + 2, 2, 3, 3, 2, 2, 2, 0, 2, 2, + 2, 4, 0, 2, 1, 1, 2, 2, 2, 1, + 2, 0, 2, 1, 3, 3, 3, 2, 3, 3, + 1, 1, 0, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -622,158 +623,165 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 3, 0, 0, 1, 0, 0, 0, 0, 0, 109, - 0, 0, 0, 0, 0, 0, 12, 16, 13, 14, - 18, 15, 17, 0, 19, 0, 4, 31, 22, 31, - 23, 52, 62, 5, 67, 20, 84, 75, 6, 24, - 84, 21, 8, 11, 91, 92, 0, 0, 93, 0, - 110, 0, 94, 0, 0, 0, 107, 108, 0, 0, - 0, 100, 95, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 96, 7, 71, 79, 48, 80, 27, - 29, 0, 104, 0, 0, 64, 0, 0, 9, 10, - 0, 0, 0, 0, 89, 0, 0, 0, 44, 0, - 37, 36, 32, 33, 0, 35, 34, 0, 0, 89, - 0, 56, 57, 53, 55, 54, 63, 51, 50, 68, - 70, 66, 69, 65, 86, 87, 85, 76, 78, 74, - 77, 73, 97, 103, 105, 106, 102, 101, 26, 82, - 0, 98, 0, 98, 98, 98, 0, 0, 0, 83, - 60, 98, 0, 98, 0, 0, 0, 38, 90, 0, - 0, 98, 46, 43, 25, 0, 59, 0, 88, 99, - 39, 40, 41, 0, 0, 45, 58, 61, 42, 47 + 6, 0, 99, 0, 3, 0, 6, 6, 94, 95, + 0, 1, 0, 0, 0, 0, 112, 0, 0, 0, + 0, 0, 0, 14, 18, 15, 16, 20, 17, 19, + 0, 21, 0, 7, 33, 24, 33, 25, 54, 64, + 8, 69, 22, 87, 78, 9, 26, 87, 23, 10, + 0, 100, 2, 73, 13, 0, 96, 0, 113, 0, + 97, 0, 0, 0, 110, 111, 0, 0, 0, 103, + 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 74, 82, 50, 83, 29, 31, 0, 107, 0, + 0, 66, 0, 0, 11, 12, 0, 0, 0, 0, + 92, 0, 0, 0, 46, 0, 39, 38, 34, 35, + 0, 37, 36, 0, 0, 92, 0, 58, 59, 55, + 57, 56, 65, 53, 52, 70, 72, 68, 71, 67, + 89, 90, 88, 79, 81, 77, 80, 76, 106, 108, + 109, 105, 104, 28, 85, 0, 101, 0, 101, 101, + 101, 0, 0, 0, 86, 62, 101, 0, 101, 0, + 0, 0, 40, 93, 0, 0, 101, 48, 45, 27, + 0, 61, 0, 91, 102, 41, 42, 43, 0, 0, + 47, 60, 63, 44, 49 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 1, 2, 25, 26, 101, 27, 28, 29, 30, - 65, 102, 103, 147, 175, 31, 32, 117, 33, 67, - 113, 68, 34, 121, 35, 69, 36, 37, 129, 38, - 71, 39, 40, 41, 104, 105, 70, 106, 142, 143, - 42, 74, 156, 60, 61, 51 + -1, 3, 4, 5, 32, 33, 107, 34, 35, 36, + 37, 73, 108, 109, 152, 180, 38, 39, 123, 40, + 75, 119, 76, 41, 127, 42, 77, 6, 43, 44, + 135, 45, 79, 46, 47, 48, 110, 111, 78, 112, + 147, 148, 49, 7, 161, 68, 69, 59 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -80 +#define YYPACT_NINF -89 static const yytype_int16 yypact[] = { - -80, 2, 132, -80, -13, -1, -1, -2, -1, 9, - 33, -1, 27, 40, -3, 38, -80, -80, -80, -80, - -80, -80, -80, 71, -80, 77, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, 57, 61, -80, 63, - -80, 76, -80, 87, 101, 133, -80, -80, -3, -3, - 195, -6, -80, 136, 149, 39, 104, 65, 150, 5, - 194, 5, 167, -80, 176, -80, -80, -80, -80, -80, - -80, 68, -80, -3, -3, 176, 72, 72, -80, -80, - 177, 187, 78, -1, -1, -3, 196, 72, -80, 222, - -80, -80, -80, -80, 221, -80, -80, 205, -1, -1, - 211, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, 206, -80, -80, -80, -80, -80, - -3, 223, 209, 223, 197, 223, 72, 7, 210, -80, - -80, 223, 212, 223, 201, -3, 213, -80, -80, 214, - 215, 223, 208, -80, -80, 216, -80, 217, -80, 113, - -80, -80, -80, 218, -1, -80, -80, -80, -80, -80 + 3, 4, -89, 20, -89, 100, -89, 7, -89, -89, + -8, -89, 17, 4, 28, 4, 37, 36, 4, 68, + 87, -18, 69, -89, -89, -89, -89, -89, -89, -89, + 128, -89, 138, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + 127, -89, -89, 110, -89, 126, -89, 136, -89, 137, + -89, 147, 150, 152, -89, -89, -18, -18, 171, -14, + -89, 153, 157, 34, 67, 180, 233, 220, 207, 220, + 154, -89, -89, -89, -89, -89, -89, 0, -89, -18, + -18, 110, 44, 44, -89, -89, 163, 174, 182, 4, + 4, -18, 194, 44, -89, 219, -89, -89, -89, -89, + 223, -89, -89, 203, 4, 4, 215, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, 213, + -89, -89, -89, -89, -89, -18, 232, 227, 232, -5, + 232, 44, 35, 234, -89, -89, 232, 235, 232, 224, + -18, 236, -89, -89, 237, 238, 232, 216, -89, -89, + 240, -89, 241, -89, 71, -89, -89, -89, 242, 4, + -89, -89, -89, -89, -89 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -80, -80, -80, -80, 122, -34, -80, -80, -80, -80, - 220, -80, -80, -80, -80, -80, -80, -80, 59, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, 125, - -80, -80, -80, -80, -80, 183, 219, 22, 142, -5, - 147, 192, 69, -54, -79, -80 + -89, -89, 255, 267, -89, 47, -57, -89, -89, -89, + -89, 239, -89, -89, -89, -89, -89, -89, -89, 130, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, 181, -89, -89, -89, -89, -89, 199, 229, 16, + 162, -1, 74, -7, 103, -65, -88, -89 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -82 +#define YYTABLE_NINF -85 static const yytype_int16 yytable[] = { - 46, 47, 3, 49, 81, 82, 53, 136, 137, 6, - 7, 8, 9, 10, 11, 12, 13, 43, 146, 14, - 15, 86, 56, 57, 44, 45, 58, 87, 48, 134, - 135, 59, 162, 112, 50, 24, 125, 163, 125, -28, - 90, 144, -28, -28, -28, -28, -28, -28, -28, -28, - -28, 91, 54, -28, -28, 92, -28, 93, 94, 95, - 96, 97, 98, 52, 99, 55, 90, 161, 62, 100, - -49, -49, 63, -49, -49, -49, -49, 91, 64, -49, - -49, 92, 107, 108, 109, 110, 154, 73, 141, 115, - 99, 75, 126, 76, 126, 111, 133, 56, 57, 83, - 84, 169, 140, 151, -30, 90, 77, -30, -30, -30, - -30, -30, -30, -30, -30, -30, 91, 78, -30, -30, - 92, -30, 93, 94, 95, 96, 97, 98, 120, 99, - 128, 79, -2, 4, 100, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 83, 84, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 7, 8, 23, 10, 11, - 12, 13, 24, 80, 14, 15, 88, -81, 90, 179, - -81, -81, -81, -81, -81, -81, -81, -81, -81, 89, - 24, -81, -81, 92, -81, -81, -81, -81, -81, -81, - 116, 119, 99, 127, 122, 90, 130, 124, -72, -72, - -72, -72, -72, -72, -72, -72, 132, 138, -72, -72, - 92, 155, 158, 159, 160, 118, 123, 139, 131, 99, - 165, 145, 167, 148, 124, 73, 83, 84, 83, 84, - 173, 168, 83, 84, 149, 150, 153, 155, 84, 157, - 164, 174, 166, 170, 171, 172, 176, 177, 178, 66, - 114, 152, 85, 0, 0, 0, 0, 0, 0, 72 + 10, 87, 88, 53, 141, 142, 1, 64, 65, 160, + 1, 66, 55, 92, 57, 151, 67, 61, 118, 93, + 11, 131, 2, 131, 139, 140, 89, 90, 138, 8, + 9, 89, 90, 2, -30, 96, 149, 51, -30, -30, + -30, -30, -30, -30, -30, -30, 97, 54, -30, -30, + 98, -30, 99, 100, 101, 102, 103, 104, 56, 105, + 167, 91, 58, 166, 106, 168, 60, -32, 96, 64, + 65, -32, -32, -32, -32, -32, -32, -32, -32, 97, + 159, -32, -32, 98, -32, 99, 100, 101, 102, 103, + 104, 121, 105, 62, 132, 174, 132, 106, 146, 70, + -5, 12, 89, 90, 13, 14, 15, 16, 17, 18, + 19, 20, 63, 156, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 122, 125, 30, 133, -4, 12, 71, + 31, 13, 14, 15, 16, 17, 18, 19, 20, 72, + 51, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 124, 129, 30, 137, -84, 96, 81, 31, -84, -84, + -84, -84, -84, -84, -84, -84, 82, 83, -84, -84, + 98, -84, -84, -84, -84, -84, -84, 84, 184, 105, + 85, 96, 86, 94, 130, -51, -51, 95, -51, -51, + -51, -51, 97, 143, -51, -51, 98, 113, 114, 115, + 116, 2, 89, 90, 144, 105, 145, 126, 96, 134, + 117, -75, -75, -75, -75, -75, -75, -75, -75, 150, + 153, -75, -75, 98, 13, 14, 15, 16, 17, 18, + 19, 20, 105, 155, 21, 22, 154, 130, 14, 15, + 158, 17, 18, 19, 20, 90, 160, 21, 22, 179, + 31, 163, 164, 165, 173, 89, 90, 162, 128, 170, + 136, 172, 52, 31, 169, 171, 175, 176, 177, 178, + 181, 182, 183, 50, 120, 74, 80, 157 }; -static const yytype_int16 yycheck[] = +static const yytype_uint8 yycheck[] = { - 5, 6, 0, 8, 58, 59, 11, 86, 87, 4, - 5, 6, 7, 8, 9, 10, 11, 30, 97, 14, - 15, 27, 25, 26, 25, 26, 29, 33, 30, 83, - 84, 34, 25, 67, 25, 30, 70, 30, 72, 0, - 1, 95, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 25, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 30, 25, 25, 1, 146, 30, 30, - 5, 6, 1, 8, 9, 10, 11, 12, 1, 14, - 15, 16, 17, 18, 19, 20, 140, 30, 93, 67, - 25, 30, 70, 30, 72, 30, 28, 25, 26, 31, - 32, 155, 24, 108, 0, 1, 30, 3, 4, 5, + 1, 66, 67, 10, 92, 93, 3, 25, 26, 14, + 3, 29, 13, 27, 15, 103, 34, 18, 75, 33, + 0, 78, 30, 80, 89, 90, 31, 32, 28, 25, + 26, 31, 32, 30, 0, 1, 101, 30, 4, 5, 6, 7, 8, 9, 10, 11, 12, 30, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 69, 25, - 71, 30, 0, 1, 30, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 31, 32, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 5, 6, 25, 8, 9, - 10, 11, 30, 30, 14, 15, 30, 0, 1, 174, - 3, 4, 5, 6, 7, 8, 9, 10, 11, 30, + 16, 17, 18, 19, 20, 21, 22, 23, 30, 25, + 25, 68, 25, 151, 30, 30, 30, 0, 1, 25, + 26, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 145, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 75, 25, 25, 78, 160, 80, 30, 99, 30, + 0, 1, 31, 32, 4, 5, 6, 7, 8, 9, + 10, 11, 25, 114, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 76, 77, 25, 79, 0, 1, 1, + 30, 4, 5, 6, 7, 8, 9, 10, 11, 1, 30, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 68, 69, 25, 71, 69, 1, 71, 30, 4, 5, + 76, 77, 25, 79, 0, 1, 30, 30, 4, 5, 6, 7, 8, 9, 10, 11, 30, 30, 14, 15, - 16, 14, 143, 144, 145, 68, 69, 30, 71, 25, - 151, 25, 153, 1, 30, 30, 31, 32, 31, 32, - 161, 30, 31, 32, 13, 30, 25, 14, 32, 30, - 30, 33, 30, 30, 30, 30, 30, 30, 30, 29, - 67, 109, 60, -1, -1, -1, -1, -1, -1, 40 + 16, 17, 18, 19, 20, 21, 22, 30, 179, 25, + 30, 1, 30, 30, 30, 5, 6, 30, 8, 9, + 10, 11, 12, 30, 14, 15, 16, 17, 18, 19, + 20, 30, 31, 32, 30, 25, 24, 77, 1, 79, + 30, 4, 5, 6, 7, 8, 9, 10, 11, 25, + 1, 14, 15, 16, 4, 5, 6, 7, 8, 9, + 10, 11, 25, 30, 14, 15, 13, 30, 5, 6, + 25, 8, 9, 10, 11, 32, 14, 14, 15, 33, + 30, 148, 149, 150, 30, 31, 32, 30, 77, 156, + 79, 158, 7, 30, 30, 30, 30, 30, 30, 166, + 30, 30, 30, 6, 75, 36, 47, 115 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 36, 37, 0, 1, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 25, 30, 38, 39, 41, 42, 43, - 44, 50, 51, 53, 57, 59, 61, 62, 64, 66, - 67, 68, 75, 30, 25, 26, 74, 74, 30, 74, - 25, 80, 30, 74, 25, 25, 25, 26, 29, 34, - 78, 79, 30, 1, 1, 45, 45, 54, 56, 60, - 71, 65, 71, 30, 76, 30, 30, 30, 30, 30, - 30, 78, 78, 31, 32, 76, 27, 33, 30, 30, - 1, 12, 16, 18, 19, 20, 21, 22, 23, 25, - 30, 40, 46, 47, 69, 70, 72, 17, 18, 19, - 20, 30, 40, 55, 70, 72, 39, 52, 75, 39, - 53, 58, 64, 75, 30, 40, 72, 39, 53, 63, - 64, 75, 30, 28, 78, 78, 79, 79, 30, 30, - 24, 74, 73, 74, 78, 25, 79, 48, 1, 13, - 30, 74, 73, 25, 78, 14, 77, 30, 77, 77, - 77, 79, 25, 30, 30, 77, 30, 77, 30, 78, - 30, 30, 30, 77, 33, 49, 30, 30, 30, 74 + 0, 3, 30, 36, 37, 38, 62, 78, 25, 26, + 76, 0, 1, 4, 5, 6, 7, 8, 9, 10, + 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 25, 30, 39, 40, 42, 43, 44, 45, 51, 52, + 54, 58, 60, 63, 64, 66, 68, 69, 70, 77, + 38, 30, 37, 78, 30, 76, 30, 76, 25, 82, + 30, 76, 25, 25, 25, 26, 29, 34, 80, 81, + 30, 1, 1, 46, 46, 55, 57, 61, 73, 67, + 73, 30, 30, 30, 30, 30, 30, 80, 80, 31, + 32, 78, 27, 33, 30, 30, 1, 12, 16, 18, + 19, 20, 21, 22, 23, 25, 30, 41, 47, 48, + 71, 72, 74, 17, 18, 19, 20, 30, 41, 56, + 72, 74, 40, 53, 77, 40, 54, 59, 66, 77, + 30, 41, 74, 40, 54, 65, 66, 77, 28, 80, + 80, 81, 81, 30, 30, 24, 76, 75, 76, 80, + 25, 81, 49, 1, 13, 30, 76, 75, 25, 80, + 14, 79, 30, 79, 79, 79, 81, 25, 30, 30, + 79, 30, 79, 30, 80, 30, 30, 30, 79, 33, + 50, 30, 30, 30, 76 }; #define yyerrok (yyerrstatus = 0) @@ -1284,7 +1292,7 @@ yydestruct (yymsg, yytype, yyvaluep) switch (yytype) { - case 51: /* "choice_entry" */ + case 52: /* "choice_entry" */ { fprintf(stderr, "%s:%d: missing end statement for this entry\n", @@ -1294,7 +1302,7 @@ yydestruct (yymsg, yytype, yyvaluep) }; break; - case 57: /* "if_entry" */ + case 58: /* "if_entry" */ { fprintf(stderr, "%s:%d: missing end statement for this entry\n", @@ -1304,7 +1312,7 @@ yydestruct (yymsg, yytype, yyvaluep) }; break; - case 62: /* "menu_entry" */ + case 64: /* "menu_entry" */ { fprintf(stderr, "%s:%d: missing end statement for this entry\n", @@ -1614,39 +1622,39 @@ yyreduce: YY_REDUCE_PRINT (yyn); switch (yyn) { - case 8: + case 10: { zconf_error("unexpected end statement"); ;} break; - case 9: + case 11: { zconf_error("unknown statement \"%s\"", (yyvsp[(2) - (4)].string)); ;} break; - case 10: + case 12: { zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[(2) - (4)].id)->name); ;} break; - case 11: + case 13: { zconf_error("invalid statement"); ;} break; - case 25: + case 27: { zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); ;} break; - case 26: + case 28: { zconf_error("invalid option"); ;} break; - case 27: + case 29: { struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0); @@ -1656,7 +1664,7 @@ yyreduce: ;} break; - case 28: + case 30: { menu_end_entry(); @@ -1664,7 +1672,7 @@ yyreduce: ;} break; - case 29: + case 31: { struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0); @@ -1674,7 +1682,7 @@ yyreduce: ;} break; - case 30: + case 32: { if (current_entry->prompt) @@ -1686,7 +1694,7 @@ yyreduce: ;} break; - case 38: + case 40: { menu_set_type((yyvsp[(1) - (3)].id)->stype); @@ -1696,7 +1704,7 @@ yyreduce: ;} break; - case 39: + case 41: { menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr)); @@ -1704,7 +1712,7 @@ yyreduce: ;} break; - case 40: + case 42: { menu_add_expr(P_DEFAULT, (yyvsp[(2) - (4)].expr), (yyvsp[(3) - (4)].expr)); @@ -1716,7 +1724,7 @@ yyreduce: ;} break; - case 41: + case 43: { menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr)); @@ -1724,7 +1732,7 @@ yyreduce: ;} break; - case 42: + case 44: { menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[(2) - (5)].symbol), (yyvsp[(3) - (5)].symbol)), (yyvsp[(4) - (5)].expr)); @@ -1732,7 +1740,7 @@ yyreduce: ;} break; - case 45: + case 47: { struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string))); @@ -1744,17 +1752,17 @@ yyreduce: ;} break; - case 46: + case 48: { (yyval.string) = NULL; ;} break; - case 47: + case 49: { (yyval.string) = (yyvsp[(2) - (2)].string); ;} break; - case 48: + case 50: { struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), SYMBOL_CHOICE); @@ -1765,14 +1773,14 @@ yyreduce: ;} break; - case 49: + case 51: { (yyval.menu) = menu_add_menu(); ;} break; - case 50: + case 52: { if (zconf_endtoken((yyvsp[(1) - (1)].id), T_CHOICE, T_ENDCHOICE)) { @@ -1782,7 +1790,7 @@ yyreduce: ;} break; - case 58: + case 60: { menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr)); @@ -1790,7 +1798,7 @@ yyreduce: ;} break; - case 59: + case 61: { if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) { @@ -1803,7 +1811,7 @@ yyreduce: ;} break; - case 60: + case 62: { current_entry->sym->flags |= SYMBOL_OPTIONAL; @@ -1811,7 +1819,7 @@ yyreduce: ;} break; - case 61: + case 63: { if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) { @@ -1823,7 +1831,7 @@ yyreduce: ;} break; - case 64: + case 66: { printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); @@ -1833,7 +1841,7 @@ yyreduce: ;} break; - case 65: + case 67: { if (zconf_endtoken((yyvsp[(1) - (1)].id), T_IF, T_ENDIF)) { @@ -1843,7 +1851,14 @@ yyreduce: ;} break; - case 71: + case 73: + + { + menu_add_prompt(P_MENU, (yyvsp[(2) - (3)].string), NULL); +;} + break; + + case 74: { menu_add_entry(NULL); @@ -1852,14 +1867,14 @@ yyreduce: ;} break; - case 72: + case 75: { (yyval.menu) = menu_add_menu(); ;} break; - case 73: + case 76: { if (zconf_endtoken((yyvsp[(1) - (1)].id), T_MENU, T_ENDMENU)) { @@ -1869,7 +1884,7 @@ yyreduce: ;} break; - case 79: + case 82: { printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); @@ -1877,7 +1892,7 @@ yyreduce: ;} break; - case 80: + case 83: { menu_add_entry(NULL); @@ -1886,14 +1901,14 @@ yyreduce: ;} break; - case 81: + case 84: { menu_end_entry(); ;} break; - case 82: + case 85: { printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); @@ -1901,14 +1916,14 @@ yyreduce: ;} break; - case 83: + case 86: { current_entry->help = (yyvsp[(2) - (2)].string); ;} break; - case 88: + case 91: { menu_add_dep((yyvsp[(3) - (4)].expr)); @@ -1916,84 +1931,84 @@ yyreduce: ;} break; - case 90: + case 93: { menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr)); ;} break; - case 93: + case 96: { (yyval.id) = (yyvsp[(1) - (2)].id); ;} break; - case 94: + case 97: { (yyval.id) = (yyvsp[(1) - (2)].id); ;} break; - case 95: + case 98: { (yyval.id) = (yyvsp[(1) - (2)].id); ;} break; - case 98: + case 101: { (yyval.expr) = NULL; ;} break; - case 99: + case 102: { (yyval.expr) = (yyvsp[(2) - (2)].expr); ;} break; - case 100: + case 103: { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); ;} break; - case 101: + case 104: { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;} break; - case 102: + case 105: { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;} break; - case 103: + case 106: { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;} break; - case 104: + case 107: { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); ;} break; - case 105: + case 108: { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; - case 106: + case 109: { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; - case 107: + case 110: { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); ;} break; - case 108: + case 111: { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); ;} break; - case 109: + case 112: { (yyval.string) = NULL; ;} break; @@ -2239,6 +2254,10 @@ void conf_parse(const char *name) prop = prop_alloc(P_DEFAULT, modules_sym); prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); } + + rootmenu.prompt->text = _(rootmenu.prompt->text); + rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text); + menu_finalize(&rootmenu); for_all_symbols(i, sym) { if (sym_check_deps(sym)) -- cgit v1.2.3 From 76a540958af5390a94b7f68c46cb7f2aed34ccf1 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Wed, 18 Aug 2010 01:23:50 -0400 Subject: kconfig: add a symbol string expansion helper Signed-off-by: Arnaud Lacombe Reviewed-by: Sam Ravnborg Reviewed-by: Michal Marek --- scripts/kconfig/lkc_proto.h | 1 + scripts/kconfig/symbol.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 9a948c9ce44e..4531badb3fe1 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -28,6 +28,7 @@ P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); P(sym_lookup,struct symbol *,(const char *name, int flags)); P(sym_find,struct symbol *,(const char *name)); +P(sym_expand_string_value,const char *,(const char *in)); P(sym_re_search,struct symbol **,(const char *pattern)); P(sym_type_name,const char *,(enum symbol_type type)); P(sym_calc_value,void,(struct symbol *sym)); diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 943712ca6c0a..dc5dcf2189a0 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -840,6 +840,55 @@ struct symbol *sym_find(const char *name) return symbol; } +/* + * Expand symbol's names embedded in the string given in argument. Symbols' + * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to + * the empty string. + */ +const char *sym_expand_string_value(const char *in) +{ + const char *src; + char *res; + size_t reslen; + + reslen = strlen(in) + 1; + res = malloc(reslen); + res[0] = '\0'; + + while ((src = strchr(in, '$'))) { + char *p, name[SYMBOL_MAXLENGTH]; + const char *symval = ""; + struct symbol *sym; + size_t newlen; + + strncat(res, in, src - in); + src++; + + p = name; + while (isalnum(*src) || *src == '_') + *p++ = *src++; + *p = '\0'; + + sym = sym_find(name); + if (sym != NULL) { + sym_calc_value(sym); + symval = sym_get_string_value(sym); + } + + newlen = strlen(res) + strlen(symval) + strlen(src); + if (newlen > reslen) { + reslen = newlen; + realloc(res, reslen); + } + + strcat(res, symval); + in = src; + } + strcat(res, in); + + return res; +} + struct symbol **sym_re_search(const char *pattern) { struct symbol *sym, **sym_arr = NULL; -- cgit v1.2.3 From f6ce00b8cca0517f7296cd76059e1fb37d01c871 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Thu, 9 Sep 2010 21:17:26 -0400 Subject: kconfig: expand by default the rootmenu's prompt Signed-off-by: Arnaud Lacombe Reviewed-by: Sam Ravnborg Reviewed-by: Michal Marek --- scripts/kconfig/zconf.y | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y index e9b14efd7414..2abd3c7ff15d 100644 --- a/scripts/kconfig/zconf.y +++ b/scripts/kconfig/zconf.y @@ -502,6 +502,10 @@ void conf_parse(const char *name) prop = prop_alloc(P_DEFAULT, modules_sym); prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); } + + rootmenu.prompt->text = _(rootmenu.prompt->text); + rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text); + menu_finalize(&rootmenu); for_all_symbols(i, sym) { if (sym_check_deps(sym)) -- cgit v1.2.3 From c55c9d571a3db7a096834b6c8a58d5a32dc807e6 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 19 Sep 2010 22:47:17 -0400 Subject: kconfig: delay gconf window initialization Delay the window initialization to let the rootmenu's prompt be initialized as it will be used to get the window's title. Signed-off-by: Arnaud Lacombe --- scripts/kconfig/gconf.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 16362139d52a..262fbd19c1ea 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -1530,12 +1530,6 @@ int main(int ac, char *av[]) else glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL); - /* Load the interface and connect signals */ - init_main_window(glade_file); - init_tree_model(); - init_left_tree(); - init_right_tree(); - /* Conf stuffs */ if (ac > 1 && av[1][0] == '-') { switch (av[1][1]) { @@ -1555,6 +1549,12 @@ int main(int ac, char *av[]) fixup_rootmenu(&rootmenu); conf_read(NULL); + /* Load the interface and connect signals */ + init_main_window(glade_file); + init_tree_model(); + init_left_tree(); + init_right_tree(); + switch (view_mode) { case SINGLE_VIEW: display_tree_part(); -- cgit v1.2.3 From 0954828fcbf3bd13d593499b16b901a4e801b0b9 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Wed, 18 Aug 2010 01:57:13 -0400 Subject: kconfig: replace KERNELVERSION usage by the mainmenu's prompt Signed-off-by: Arnaud Lacombe Reviewed-by: Sam Ravnborg Reviewed-by: Michal Marek --- scripts/kconfig/confdata.c | 16 ++++++---------- scripts/kconfig/gconf.c | 5 +---- scripts/kconfig/mconf.c | 6 +----- scripts/kconfig/nconf.c | 6 +----- scripts/kconfig/qconf.cc | 4 ++-- 5 files changed, 11 insertions(+), 26 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 9f3c8899da5a..f7d89d7065b7 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -574,8 +574,6 @@ int conf_write(const char *name) if (!out) return 1; - sym = sym_lookup("KERNELVERSION", 0); - sym_calc_value(sym); time(&now); env = getenv("KCONFIG_NOTIMESTAMP"); if (env && *env) @@ -583,10 +581,10 @@ int conf_write(const char *name) fprintf(out, _("#\n" "# Automatically generated make config: don't edit\n" - "# Linux kernel version: %s\n" + "# %s\n" "%s%s" "#\n"), - sym_get_string_value(sym), + rootmenu.prompt->text, use_timestamp ? "# " : "", use_timestamp ? ctime(&now) : ""); @@ -797,25 +795,23 @@ int conf_write_autoconf(void) return 1; } - sym = sym_lookup("KERNELVERSION", 0); - sym_calc_value(sym); time(&now); fprintf(out, "#\n" "# Automatically generated make config: don't edit\n" - "# Linux kernel version: %s\n" + "# %s\n" "# %s" "#\n", - sym_get_string_value(sym), ctime(&now)); + rootmenu.prompt->text, ctime(&now)); fprintf(tristate, "#\n" "# Automatically generated - do not edit\n" "\n"); fprintf(out_h, "/*\n" " * Automatically generated C config: don't edit\n" - " * Linux kernel version: %s\n" + " * %s\n" " * %s" " */\n" "#define AUTOCONF_INCLUDED\n", - sym_get_string_value(sym), ctime(&now)); + rootmenu.prompt->text, ctime(&now)); for_all_symbols(i, sym) { sym_calc_value(sym); diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 262fbd19c1ea..455896164d72 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -133,7 +133,6 @@ void init_main_window(const gchar * glade_file) GladeXML *xml; GtkWidget *widget; GtkTextBuffer *txtbuf; - char title[256]; GtkStyle *style; xml = glade_xml_new(glade_file, "window1", NULL); @@ -210,9 +209,7 @@ void init_main_window(const gchar * glade_file) /*"style", PANGO_STYLE_OBLIQUE, */ NULL); - sprintf(title, _("Linux Kernel v%s Configuration"), - getenv("KERNELVERSION")); - gtk_window_set_title(GTK_WINDOW(main_wnd), title); + gtk_window_set_title(GTK_WINDOW(main_wnd), rootmenu.prompt->text); gtk_widget_show(main_wnd); } diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index cee4281ad209..d433c7a24745 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -288,13 +288,9 @@ static void set_config_filename(const char *config_filename) { static char menu_backtitle[PATH_MAX+128]; int size; - struct symbol *sym; - sym = sym_lookup("KERNELVERSION", 0); - sym_calc_value(sym); size = snprintf(menu_backtitle, sizeof(menu_backtitle), - _("%s - Linux Kernel v%s Configuration"), - config_filename, sym_get_string_value(sym)); + "%s - %s", config_filename, rootmenu.prompt->text); if (size >= sizeof(menu_backtitle)) menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; set_dialog_backtitle(menu_backtitle); diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 801cc048704a..545e1af7cb68 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -633,13 +633,9 @@ static char menu_backtitle[PATH_MAX+128]; static const char *set_config_filename(const char *config_filename) { int size; - struct symbol *sym; - sym = sym_lookup("KERNELVERSION", 0); - sym_calc_value(sym); size = snprintf(menu_backtitle, sizeof(menu_backtitle), - _("%s - Linux Kernel v%s Configuration"), - config_filename, sym_get_string_value(sym)); + "%s - %s", config_filename, rootmenu.prompt->text); if (size >= sizeof(menu_backtitle)) menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index fe18f7efdca1..06dd2e33581d 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1274,8 +1274,8 @@ ConfigMainWindow::ConfigMainWindow(void) char title[256]; QDesktopWidget *d = configApp->desktop(); - snprintf(title, sizeof(title), _("Linux Kernel v%s Configuration%s"), - getenv("KERNELVERSION"), + snprintf(title, sizeof(title), "%s%s", + rootmenu.prompt->text, #if QT_VERSION < 0x040000 " (Qt3)" #else -- cgit v1.2.3 From ba6ff60d5eb47d52f1a5eb0bb6ffa751be838c46 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sat, 4 Sep 2010 16:05:15 -0400 Subject: kconfig: don't emit warning upon rootmenu's prompt redefinition This silences the warning printed upon prompt redefinition for the rootmenu. We will encounter this redefinition when a "mainmenu" statement is specified and override the default prompt. Signed-off-by: Arnaud Lacombe Reviewed-by: Sam Ravnborg Reviewed-by: Michal Marek --- scripts/kconfig/menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 682045a7aae4..23acbdb2fd50 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -139,7 +139,7 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e while (isspace(*prompt)) prompt++; } - if (current_entry->prompt) + if (current_entry->prompt && current_entry != &rootmenu) prop_warn(prop, "prompt redefined"); current_entry->prompt = prop; } -- cgit v1.2.3 From 2e7a091833f014cac8a6b92573ca6cd2edd2753c Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sat, 4 Sep 2010 16:03:30 -0400 Subject: kconfig: constify file name Signed-off-by: Arnaud Lacombe Reviewed-by: Sam Ravnborg Reviewed-by: Michal Marek --- scripts/kconfig/expr.h | 2 +- scripts/kconfig/lkc.h | 2 +- scripts/kconfig/zconf.l | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 6ee2e4fb1481..648c609caba0 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -18,7 +18,7 @@ extern "C" { struct file { struct file *next; struct file *parent; - char *name; + const char *name; int lineno; int flags; }; diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 5d5f1872d651..753cdbd7b805 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -76,7 +76,7 @@ FILE *zconf_fopen(const char *name); void zconf_initscan(const char *name); void zconf_nextfile(const char *name); int zconf_lineno(void); -char *zconf_curname(void); +const char *zconf_curname(void); /* conf.c */ void xfgets(char *str, int size, FILE *in); diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l index d8f7236cb0a3..2b0265082d0a 100644 --- a/scripts/kconfig/zconf.l +++ b/scripts/kconfig/zconf.l @@ -353,7 +353,7 @@ int zconf_lineno(void) return current_pos.lineno; } -char *zconf_curname(void) +const char *zconf_curname(void) { return current_pos.file ? current_pos.file->name : ""; } -- cgit v1.2.3 From e82dae9083c8ca97c0f6ba1f5d09591aff67bb4e Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sat, 4 Sep 2010 16:09:26 -0400 Subject: kconfig: use the file's name of sourced file Signed-off-by: Arnaud Lacombe Reviewed-by: Sam Ravnborg Reviewed-by: Michal Marek --- scripts/kconfig/zconf.l | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l index 2b0265082d0a..3dbaec185cc4 100644 --- a/scripts/kconfig/zconf.l +++ b/scripts/kconfig/zconf.l @@ -304,9 +304,10 @@ void zconf_nextfile(const char *name) memset(buf, 0, sizeof(*buf)); current_buf->state = YY_CURRENT_BUFFER; - yyin = zconf_fopen(name); + yyin = zconf_fopen(file->name); if (!yyin) { - printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name); + printf("%s:%d: can't open file \"%s\"\n", + zconf_curname(), zconf_lineno(), file->name); exit(1); } yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); -- cgit v1.2.3 From c7abe8630ae63e90c2267c2c385a682e729e08be Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sat, 4 Sep 2010 16:11:26 -0400 Subject: kconfig: expand file names This will allow to use the following construct in source files: config FOO string default "foo" source "$FOO/Kconfig" Signed-off-by: Arnaud Lacombe Reviewed-by: Sam Ravnborg Reviewed-by: Michal Marek --- scripts/kconfig/util.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c index 78b5c04e736b..6330cc871a47 100644 --- a/scripts/kconfig/util.c +++ b/scripts/kconfig/util.c @@ -12,15 +12,18 @@ struct file *file_lookup(const char *name) { struct file *file; + const char *file_name = sym_expand_string_value(name); for (file = file_list; file; file = file->next) { - if (!strcmp(name, file->name)) + if (!strcmp(name, file->name)) { + free((void *)file_name); return file; + } } file = malloc(sizeof(*file)); memset(file, 0, sizeof(*file)); - file->name = strdup(name); + file->name = file_name; file->next = file_list; file_list = file; return file; -- cgit v1.2.3 From 838a2e55e6a4e9e8a10451ed2ef0f7a08dabdb04 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sat, 4 Sep 2010 17:10:20 -0400 Subject: kbuild: migrate all arch to the kconfig mainmenu upgrade Signed-off-by: Arnaud Lacombe Reviewed-by: Sam Ravnborg Reviewed-by: Michal Marek --- scripts/kconfig/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index cef3f75e1c2b..52c34b914fc7 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -8,7 +8,7 @@ PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-c ifdef KBUILD_KCONFIG Kconfig := $(KBUILD_KCONFIG) else -Kconfig := arch/$(SRCARCH)/Kconfig +Kconfig := Kconfig endif xconfig: $(obj)/qconf -- cgit v1.2.3 From 8c41e5e363db55d91aa3b1cdce4ab02ad9821de7 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 18 Sep 2010 19:25:32 -0700 Subject: kconfig: fix menuconfig on debian lenny In 60f33b8 (kconfig: get rid of stray a.o, support ncursesw, 2006-01-15), support to link menuconfig with ncursesw library was added. To compute the linker command option -l, we check "libncursesw.{so,a,dylib}" to allow ncursesw to be used as a replacement ncurses. However, when checking what header file to include, we do not check /usr/include/ncursesw directory. Add /usr/include/ncursesw to the list of directories that are checked. With this patch, on my Debian Lenny box with libncursesw5-dev package but not libncurses5-dev package, I can say "make menuconfig". Signed-off-by: Junio C Hamano Acked-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/kconfig/lxdialog/check-lxdialog.sh | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index fcef0f59d553..82cc3a85e7f8 100644 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -23,6 +23,8 @@ ccflags() echo '-I/usr/include/ncurses -DCURSES_LOC=""' elif [ -f /usr/include/ncurses/curses.h ]; then echo '-I/usr/include/ncurses -DCURSES_LOC=""' + elif [ -f /usr/include/ncursesw/curses.h ]; then + echo '-I/usr/include/ncursesw -DCURSES_LOC=""' elif [ -f /usr/include/ncurses.h ]; then echo '-DCURSES_LOC=""' else -- cgit v1.2.3 From bf5438fca2950b03c21ad868090cc1a8fcd49536 Mon Sep 17 00:00:00 2001 From: Jason Baron Date: Fri, 17 Sep 2010 11:09:00 -0400 Subject: jump label: Base patch for jump label base patch to implement 'jump labeling'. Based on a new 'asm goto' inline assembly gcc mechanism, we can now branch to labels from an 'asm goto' statment. This allows us to create a 'no-op' fastpath, which can subsequently be patched with a jump to the slowpath code. This is useful for code which might be rarely used, but which we'd like to be able to call, if needed. Tracepoints are the current usecase that these are being implemented for. Acked-by: David S. Miller Signed-off-by: Jason Baron LKML-Reference: [ cleaned up some formating ] Signed-off-by: Steven Rostedt --- scripts/gcc-goto.sh | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 scripts/gcc-goto.sh (limited to 'scripts') diff --git a/scripts/gcc-goto.sh b/scripts/gcc-goto.sh new file mode 100644 index 000000000000..8e82424be7aa --- /dev/null +++ b/scripts/gcc-goto.sh @@ -0,0 +1,5 @@ +#!/bin/sh +# Test for gcc 'asm goto' suport +# Copyright (C) 2010, Jason Baron + +echo "int main(void) { entry: asm goto (\"\"::::entry); return 0; }" | $1 -x c - -c -o /dev/null >/dev/null 2>&1 && echo "y" -- cgit v1.2.3 From 52159d98be6f26c48f5e02c7ab3c9848a85979b5 Mon Sep 17 00:00:00 2001 From: Jason Baron Date: Fri, 17 Sep 2010 11:09:17 -0400 Subject: jump label: Convert dynamic debug to use jump labels Convert the 'dynamic debug' infrastructure to use jump labels. Signed-off-by: Jason Baron LKML-Reference: Signed-off-by: Steven Rostedt --- scripts/Makefile.lib | 11 +-------- scripts/basic/Makefile | 2 +- scripts/basic/hash.c | 64 -------------------------------------------------- 3 files changed, 2 insertions(+), 75 deletions(-) delete mode 100644 scripts/basic/hash.c (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 54fd1b700131..7bfcf1a09ac5 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -101,14 +101,6 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" modname_flags = $(if $(filter 1,$(words $(modname))),\ -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") -#hash values -ifdef CONFIG_DYNAMIC_DEBUG -debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\ - -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))" -else -debug_flags = -endif - orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \ $(ccflags-y) $(CFLAGS_$(basetarget).o) _c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) @@ -152,8 +144,7 @@ endif c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ $(__c_flags) $(modkern_cflags) \ - -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \ - $(debug_flags) + -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ $(__a_flags) $(modkern_aflags) diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile index 09559951df12..4c324a1f1e0e 100644 --- a/scripts/basic/Makefile +++ b/scripts/basic/Makefile @@ -9,7 +9,7 @@ # fixdep: Used to generate dependency information during build process # docproc: Used in Documentation/DocBook -hostprogs-y := fixdep docproc hash +hostprogs-y := fixdep docproc always := $(hostprogs-y) # fixdep is needed to compile other host programs diff --git a/scripts/basic/hash.c b/scripts/basic/hash.c deleted file mode 100644 index 2ef5d3f666b8..000000000000 --- a/scripts/basic/hash.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2008 Red Hat, Inc., Jason Baron - * - */ - -#include -#include -#include - -#define DYNAMIC_DEBUG_HASH_BITS 6 - -static const char *program; - -static void usage(void) -{ - printf("Usage: %s \n", program); - exit(1); -} - -/* djb2 hashing algorithm by Dan Bernstein. From: - * http://www.cse.yorku.ca/~oz/hash.html - */ - -static unsigned int djb2_hash(char *str) -{ - unsigned long hash = 5381; - int c; - - c = *str; - while (c) { - hash = ((hash << 5) + hash) + c; - c = *++str; - } - return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1)); -} - -static unsigned int r5_hash(char *str) -{ - unsigned long hash = 0; - int c; - - c = *str; - while (c) { - hash = (hash + (c << 4) + (c >> 4)) * 11; - c = *++str; - } - return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1)); -} - -int main(int argc, char *argv[]) -{ - program = argv[0]; - - if (argc != 3) - usage(); - if (!strcmp(argv[1], "djb2")) - printf("%d\n", djb2_hash(argv[2])); - else if (!strcmp(argv[1], "r5")) - printf("%d\n", r5_hash(argv[2])); - else - usage(); - exit(0); -} - -- cgit v1.2.3 From d6dad199a10423ce37b8bfec1f055c380dc4a3d5 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 24 Sep 2010 09:12:25 +0200 Subject: jump label: Fix GCC feature check when distcc is used The following build bug occurs on distcc builds: CC arch/x86/kernel/asm-offsets.s In file included from include/linux/module.h:24, from include/linux/crypto.h:22, from arch/x86/kernel/asm-offsets_64.c:9, from arch/x86/kernel/asm-offsets.c:5: include/trace/events/module.h: In function 'trace_module_load': include/trace/events/module.h:18: error: expected '(' before 'goto' include/trace/events/module.h:18: error: expected identifier or '*' before '(' token It triggers because distcc is invoked by turning $CC into "distcc gcc", but gcc-goto.sh check script was using $1 not $@ to expand parameters. Cc: Jason Baron Cc: Steven Rostedt LKML-Reference: <20100923034910.867858597@goodmis.org> Signed-off-by: Ingo Molnar --- scripts/gcc-goto.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/gcc-goto.sh b/scripts/gcc-goto.sh index 8e82424be7aa..520d16b1ffaf 100644 --- a/scripts/gcc-goto.sh +++ b/scripts/gcc-goto.sh @@ -2,4 +2,4 @@ # Test for gcc 'asm goto' suport # Copyright (C) 2010, Jason Baron -echo "int main(void) { entry: asm goto (\"\"::::entry); return 0; }" | $1 -x c - -c -o /dev/null >/dev/null 2>&1 && echo "y" +echo "int main(void) { entry: asm goto (\"\"::::entry); return 0; }" | $@ -x c - -c -o /dev/null >/dev/null 2>&1 && echo "y" -- cgit v1.2.3 From ef894870c6c38580e540c29cfb22a827d54a950a Mon Sep 17 00:00:00 2001 From: Jean Sacren Date: Fri, 10 Sep 2010 23:13:33 -0600 Subject: scripts/kallsyms: Enable error messages while hush up unnecessary warnings As no error was handled, we wouldn't be able to know when an error does occur. The fix preserves error messages while it doesn't let unnecessary compiling warnings show up. Signed-off-by: Jean Sacren Signed-off-by: Michal Marek --- scripts/kallsyms.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index e3902fb39afd..60dd3eb9366e 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -107,12 +107,8 @@ static int read_symbol(FILE *in, struct sym_entry *s) rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str); if (rc != 3) { - if (rc != EOF) { - /* skip line. sym is used as dummy to - * shut of "warn_unused_result" warning. - */ - sym = fgets(str, 500, in); - } + if (rc != EOF && fgets(str, 500, in) == NULL) + fprintf(stderr, "Read error or end of file.\n"); return -1; } -- cgit v1.2.3 From 8bea7548ee0223175bea5fddcc54af93bd252d9b Mon Sep 17 00:00:00 2001 From: Naohiro Aota Date: Fri, 1 Oct 2010 04:23:17 +0900 Subject: kconfig: Don't go out from read config loop when you read new symbol commit 8baefd30b5b0101aa07aa75da44a9eee881eed28 of linux-next replaced a `switch()' statement with some `if()' statements, but left `break's in the `switch()' statement untouched. This cause read config loop to exit and so "make oldconfig" is not much usable (see below). > $ make oldconfig > > scripts/kconfig/conf --oldconfig Kconfig > # > # using defaults found in /boot/config-2.6.34-ccs-r1 > # > * > * Restart config... > * > * > * General setup > * > Prompt for development and/or incomplete code/drivers (EXPERIMENTAL) [N/y/?] (NEW) (I've already have "CONFIG_EXPERIMENTAL=y" in the old config file. But that's not read here.) This patch should fix this problem. Signed-off-by: Naohiro Aota Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index f7d89d7065b7..35c08ecaad17 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -234,7 +234,7 @@ load: sym = sym_find(line + 2 + strlen(CONFIG_)); if (!sym) { sym_add_change_count(1); - break; + goto setsym; } } else { sym = sym_lookup(line + 2 + strlen(CONFIG_), 0); @@ -268,7 +268,7 @@ load: sym = sym_find(line + strlen(CONFIG_)); if (!sym) { sym_add_change_count(1); - break; + goto setsym; } } else { sym = sym_lookup(line + strlen(CONFIG_), 0); @@ -285,6 +285,7 @@ load: conf_warning("unexpected data"); continue; } +setsym: if (sym && sym_is_choice_value(sym)) { struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); switch (sym->def[def].tri) { -- cgit v1.2.3 From a01ebe154c03f6ad58a1ec1bda616032bfe232e0 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Thu, 30 Sep 2010 22:17:48 +0200 Subject: kconfig: Propagate const Commit 2e7a091 made struct file->name a const char*, but forgot to constify all users of it. Reported-by: Stephen Rothwell Signed-off-by: Michal Marek --- scripts/kconfig/kxgettext.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c index dcc3fcc0cc9a..e9d8e791bf0d 100644 --- a/scripts/kconfig/kxgettext.c +++ b/scripts/kconfig/kxgettext.c @@ -63,11 +63,11 @@ next: struct file_line { struct file_line *next; - char* file; - int lineno; + const char *file; + int lineno; }; -static struct file_line *file_line__new(char *file, int lineno) +static struct file_line *file_line__new(const char *file, int lineno) { struct file_line *self = malloc(sizeof(*self)); @@ -90,7 +90,8 @@ struct message { static struct message *message__list; -static struct message *message__new(const char *msg, char *option, char *file, int lineno) +static struct message *message__new(const char *msg, char *option, + const char *file, int lineno) { struct message *self = malloc(sizeof(*self)); @@ -130,7 +131,8 @@ static struct message *mesage__find(const char *msg) return m; } -static int message__add_file_line(struct message *self, char *file, int lineno) +static int message__add_file_line(struct message *self, const char *file, + int lineno) { int rc = -1; struct file_line *fl = file_line__new(file, lineno); @@ -145,7 +147,8 @@ out: return rc; } -static int message__add(const char *msg, char *option, char *file, int lineno) +static int message__add(const char *msg, char *option, const char *file, + int lineno) { int rc = 0; char bf[16384]; -- cgit v1.2.3 From 19c29f326075e2c66e34d98f2a0cf22901b2d8e9 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Thu, 30 Sep 2010 22:21:12 +0200 Subject: kconfig: Fix realloc usage() Reported-by: Stephen Rothwell Signed-off-by: Michal Marek --- scripts/kconfig/symbol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index dc5dcf2189a0..c0efe102d655 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -878,7 +878,7 @@ const char *sym_expand_string_value(const char *in) newlen = strlen(res) + strlen(symval) + strlen(src); if (newlen > reslen) { reslen = newlen; - realloc(res, reslen); + res = realloc(res, reslen); } strcat(res, symval); -- cgit v1.2.3 From ff5ff6060bf880aac233e68dd666cbe9e39ec620 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 26 Sep 2010 16:22:03 -0400 Subject: kconfig: delay symbol direct dependency initialization This fixes the use-after-free and associated crash in kconfig introduced in commit 246cf9c26bf11f2bffbecea6e5bd222eee7b1df8. Signed-off-by: Arnaud Lacombe Acked-by: Catalin Marinas Signed-off-by: Michal Marek --- scripts/kconfig/expr.h | 1 - scripts/kconfig/menu.c | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 6ee2e4fb1481..170459c224a1 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -165,7 +165,6 @@ struct menu { struct symbol *sym; struct property *prompt; struct expr *dep; - struct expr *dir_dep; unsigned int flags; char *help; struct file *file; diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 4fb590247f33..edda8b49619d 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -107,7 +107,6 @@ static struct expr *menu_check_dep(struct expr *e) void menu_add_dep(struct expr *dep) { current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); - current_entry->dir_dep = current_entry->dep; } void menu_set_type(int type) @@ -291,10 +290,6 @@ void menu_finalize(struct menu *parent) for (menu = parent->list; menu; menu = menu->next) menu_finalize(menu); } else if (sym) { - /* ignore inherited dependencies for dir_dep */ - sym->dir_dep.expr = expr_transform(expr_copy(parent->dir_dep)); - sym->dir_dep.expr = expr_eliminate_dups(sym->dir_dep.expr); - basedep = parent->prompt ? parent->prompt->visible.expr : NULL; basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); basedep = expr_eliminate_dups(expr_transform(basedep)); @@ -325,6 +320,8 @@ void menu_finalize(struct menu *parent) parent->next = last_menu->next; last_menu->next = NULL; } + + sym->dir_dep.expr = parent->dep; } for (menu = parent->list; menu; menu = menu->next) { if (sym && sym_is_choice(sym) && -- cgit v1.2.3 From 1408b15b98635a13bad2e2a50b3c2ae2ccdf625b Mon Sep 17 00:00:00 2001 From: Will Newton Date: Wed, 22 Sep 2010 15:59:13 +0100 Subject: kconfig: Use PATH_MAX instead of 128 for path buffer sizes. This prevents the buffers being overflowed when using a config file with a long name. PATH_MAX is used elsewhere in the same file, so use it here as well. Signed-off-by: Will Newton Acked-by: WANG Cong Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 35c08ecaad17..96110ea41cf3 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -535,7 +535,7 @@ int conf_write(const char *name) struct menu *menu; const char *basename; const char *str; - char dirname[128], tmpname[128], newname[128]; + char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1]; enum symbol_type type; time_t now; int use_timestamp = 1; @@ -654,7 +654,7 @@ next: static int conf_split_config(void) { const char *name; - char path[128]; + char path[PATH_MAX+1]; char *s, *d, c; struct symbol *sym; struct stat sb; -- cgit v1.2.3 From 71ebc01d3ad4fa3f20e86603bc31ff2cbc535d95 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Fri, 8 Oct 2010 16:40:27 +0200 Subject: kconfig: Temporarily disable dependency warnings After fixing a use-after-free bug in kconfig, a 'make defconfig' or 'make allmodconfig' fills the screen with warnings that were not detected before. Given that we are close to the release now, disable the warnings temporarily and deal with them after 2.6.36. Signed-off-by: Michal Marek --- scripts/kconfig/symbol.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 943712ca6c0a..1f8b305449db 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -350,6 +350,7 @@ void sym_calc_value(struct symbol *sym) } } calc_newval: +#if 0 if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { fprintf(stderr, "warning: ("); expr_fprint(sym->rev_dep.expr, stderr); @@ -358,6 +359,7 @@ void sym_calc_value(struct symbol *sym) expr_fprint(sym->dir_dep.expr, stderr); fprintf(stderr, ")\n"); } +#endif newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); } if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) -- cgit v1.2.3 From e9203c988234aa512bd45ca32b52e21c7bbfc414 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Wed, 1 Sep 2010 11:21:30 -0400 Subject: kbuild: fix oldnoconfig to do the right thing Commit 861b4ea4 broke oldnoconfig when removed the oldnoconfig checks on if (input_mode == nonint_oldconfig || input_mode == oldnoconfig) { if (input_mode == nonint_oldconfig && sym->name && !sym_is_choice_value(sym)) { to avoid oldnoconfig chugging through the else stanza. Fix that to restore expected behaviour (which I've confirmed in the Fedora kernel build that the configs end up looking the same.) Signed-off-by: Kyle McMartin Acked-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/kconfig/conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 5b7c86ea43a1..7ef429cd5cb3 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -427,7 +427,7 @@ static void check_conf(struct menu *menu) if (sym->name && !sym_is_choice_value(sym)) { printf("CONFIG_%s\n", sym->name); } - } else { + } else if (input_mode != oldnoconfig) { if (!conf_cnt++) printf(_("*\n* Restart config...\n*\n")); rootEntry = menu_get_parent_menu(menu); -- cgit v1.2.3 From b1f7d6e1909c72338aa93a113d5844767434dacb Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Tue, 12 Oct 2010 15:12:23 +0200 Subject: Revert "kconfig: Temporarily disable dependency warnings" This reverts commit 71ebc01, which was a 2.6.36-only stopgap solution. Signed-off-by: Michal Marek --- scripts/kconfig/symbol.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index cb0056841974..c0efe102d655 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -350,7 +350,6 @@ void sym_calc_value(struct symbol *sym) } } calc_newval: -#if 0 if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { fprintf(stderr, "warning: ("); expr_fprint(sym->rev_dep.expr, stderr); @@ -359,7 +358,6 @@ void sym_calc_value(struct symbol *sym) expr_fprint(sym->dir_dep.expr, stderr); fprintf(stderr, ")\n"); } -#endif newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); } if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) -- cgit v1.2.3 From 3c908417677f890265ff9d5efd372207cf75fd45 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Fri, 8 Oct 2010 21:27:38 +0200 Subject: Coccinelle: Improve user information with a new kind of comment Improve user information with a new kind of comment about semantic patch output. Fix spelling. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccicheck | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/coccicheck b/scripts/coccicheck index b8bcf1f7bed7..ef78c875a0e3 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -25,7 +25,7 @@ fi if [ "$MODE" = "" ] ; then if [ "$ONLINE" = "0" ] ; then - echo 'You have not explicitly specify the mode to use. Fallback to "report".' + echo 'You have not explicitly specified the mode to use. Fallback to "report".' echo 'You can specify the mode with "make coccicheck MODE="' echo 'Available modes are: report, patch, context, org' fi @@ -52,10 +52,12 @@ coccinelle () { FILE=`echo $COCCI | sed "s|$srctree/||"` - echo "Processing `basename $COCCI` with option(s) \"$OPT\"" + echo "Processing `basename $COCCI`" + echo "with option(s) \"$OPT\"" + echo '' echo 'Message example to submit a patch:' - sed -e '/\/\/\//!d' -e 's|^///||' $COCCI + sed -ne 's|^///||p' $COCCI echo ' The semantic patch that makes this change is available' echo " in $FILE." @@ -64,6 +66,12 @@ coccinelle () { echo ' http://coccinelle.lip6.fr/' echo '' + if [ "`sed -ne 's|^//#||p' $COCCI`" ] ; then + echo 'Semantic patch information:' + sed -ne 's|^//#||p' $COCCI + echo '' + fi + $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT -dir $srctree || exit 1 else $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1 -- cgit v1.2.3 From e90f6590219a0082618b9b6828458b1c74f37cc0 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Fri, 8 Oct 2010 21:27:39 +0200 Subject: Coccinelle: Use new comment format to explain kfree.cocci Use new comment format to separate proposed commit message and information about generated false positives Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/free/kfree.cocci | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/coccinelle/free/kfree.cocci b/scripts/coccinelle/free/kfree.cocci index c13a5395707b..f9f79d9245ee 100644 --- a/scripts/coccinelle/free/kfree.cocci +++ b/scripts/coccinelle/free/kfree.cocci @@ -1,7 +1,8 @@ -/// Find a use after free. Values of variables may imply that some -/// execution paths are not possible, resulting in false positives. -/// Another source of false positives are macros such as -/// SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument +/// Find a use after free. +//# Values of variables may imply that some +//# execution paths are not possible, resulting in false positives. +//# Another source of false positives are macros such as +//# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument /// // Confidence: Moderate // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. -- cgit v1.2.3 From 2c1160c87465ee2d61eee14596e5376d2ff74f31 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Fri, 8 Oct 2010 21:27:40 +0200 Subject: Coccinelle: Add a new mode named 'chain' spatch now returns -1 when a virtual rule (given with -D on the command line) is not defined in the semantic patch. Using this spatch feature, coccicheck is now tries several modes by default, in the order: patch, report, context, org Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccicheck | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/coccicheck b/scripts/coccicheck index ef78c875a0e3..c7beb63de2e8 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -16,6 +16,7 @@ if [ "$C" = "1" -o "$C" = "2" ]; then else ONLINE=0 FLAGS="-very_quiet" + OPTIONS="-dir $srctree" fi if [ ! -x "$SPATCH" ]; then @@ -25,11 +26,11 @@ fi if [ "$MODE" = "" ] ; then if [ "$ONLINE" = "0" ] ; then - echo 'You have not explicitly specified the mode to use. Fallback to "report".' + echo 'You have not explicitly specified the mode to use. Using default "chain" mode.' + echo 'All available modes will be tried (in that order): patch, report, context, org' echo 'You can specify the mode with "make coccicheck MODE="' - echo 'Available modes are: report, patch, context, org' fi - MODE="report" + MODE="chain" fi if [ "$ONLINE" = "0" ] ; then @@ -71,10 +72,15 @@ coccinelle () { sed -ne 's|^//#||p' $COCCI echo '' fi + fi - $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT -dir $srctree || exit 1 + if [ "$MODE" = "chain" ] ; then + $SPATCH -D patch $FLAGS -sp_file $COCCI $OPT $OPTIONS || \ + $SPATCH -D report $FLAGS -sp_file $COCCI $OPT $OPTIONS || \ + $SPATCH -D context $FLAGS -sp_file $COCCI $OPT $OPTIONS || \ + $SPATCH -D org $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1 else - $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1 + $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1 fi } -- cgit v1.2.3 From 03ee0c42a77fbf60bfa6b0eacaff30ae4e19fce8 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Fri, 8 Oct 2010 21:27:41 +0200 Subject: Coccinelle: Use the -no_show_diff option for org and report mode This allows to write the semantic patches with code sharing for the matching parts. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccicheck | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/coccicheck b/scripts/coccicheck index c7beb63de2e8..7529af15672d 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -31,6 +31,8 @@ if [ "$MODE" = "" ] ; then echo 'You can specify the mode with "make coccicheck MODE="' fi MODE="chain" +elif [ "$MODE" = "report" -o "$MODE" = "org" ] ; then + FLAGS="$FLAGS -no_show_diff" fi if [ "$ONLINE" = "0" ] ; then @@ -75,10 +77,10 @@ coccinelle () { fi if [ "$MODE" = "chain" ] ; then - $SPATCH -D patch $FLAGS -sp_file $COCCI $OPT $OPTIONS || \ - $SPATCH -D report $FLAGS -sp_file $COCCI $OPT $OPTIONS || \ - $SPATCH -D context $FLAGS -sp_file $COCCI $OPT $OPTIONS || \ - $SPATCH -D org $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1 + $SPATCH -D patch $FLAGS -sp_file $COCCI $OPT $OPTIONS || \ + $SPATCH -D report $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || \ + $SPATCH -D context $FLAGS -sp_file $COCCI $OPT $OPTIONS || \ + $SPATCH -D org $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || exit 1 else $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1 fi -- cgit v1.2.3 From 81d3858d3131a589cade0d8b57f95cc1fc699b89 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Wed, 13 Oct 2010 15:12:54 -0400 Subject: ftrace: Add C version of recordmcount compile time code Currently, the mcount callers are found with a perl script that does an objdump on every file in the kernel. This is a C version of that same code which should increase the performance time of compiling the kernel with dynamic ftrace enabled. Signed-off-by: John Reiser [ Updated the code to include .text.unlikely section as well as changing the format to follow Linux coding style. ] Signed-off-by: Steven Rostedt --- scripts/recordmcount.c | 885 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 885 insertions(+) create mode 100644 scripts/recordmcount.c (limited to 'scripts') diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c new file mode 100644 index 000000000000..34f32be17090 --- /dev/null +++ b/scripts/recordmcount.c @@ -0,0 +1,885 @@ +/* + * recordmcount.c: construct a table of the locations of calls to 'mcount' + * so that ftrace can find them quickly. + * Copyright 2009 John F. Reiser . All rights reserved. + * Licensed under the GNU General Public License, version 2 (GPLv2). + * + * Restructured to fit Linux format, as well as other updates: + * Copyright 2010 Steven Rostedt , Red Hat Inc. + */ + +/* + * Strategy: alter the .o file in-place. + * + * Append a new STRTAB that has the new section names, followed by a new array + * ElfXX_Shdr[] that has the new section headers, followed by the section + * contents for __mcount_loc and its relocations. The old shstrtab strings, + * and the old ElfXX_Shdr[] array, remain as "garbage" (commonly, a couple + * kilobytes.) Subsequent processing by /bin/ld (or the kernel module loader) + * will ignore the garbage regions, because they are not designated by the + * new .e_shoff nor the new ElfXX_Shdr[]. [In order to remove the garbage, + * then use "ld -r" to create a new file that omits the garbage.] + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int fd_map; /* File descriptor for file being modified. */ +static int mmap_failed; /* Boolean flag. */ +static void *ehdr_curr; /* current ElfXX_Ehdr * for resource cleanup */ +static char gpfx; /* prefix for global symbol name (sometimes '_') */ +static struct stat sb; /* Remember .st_size, etc. */ +static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */ + +/* setjmp() return values */ +enum { + SJ_SETJMP = 0, /* hardwired first return */ + SJ_FAIL, + SJ_SUCCEED +}; + +/* Per-file resource cleanup when multiple files. */ +static void +cleanup(void) +{ + if (!mmap_failed) + munmap(ehdr_curr, sb.st_size); + else + free(ehdr_curr); + close(fd_map); +} + +static void __attribute__((noreturn)) +fail_file(void) +{ + cleanup(); + longjmp(jmpenv, SJ_FAIL); +} + +static void __attribute__((noreturn)) +succeed_file(void) +{ + cleanup(); + longjmp(jmpenv, SJ_SUCCEED); +} + +/* ulseek, uread, ...: Check return value for errors. */ + +static off_t +ulseek(int const fd, off_t const offset, int const whence) +{ + off_t const w = lseek(fd, offset, whence); + if ((off_t)-1 == w) { + perror("lseek"); + fail_file(); + } + return w; +} + +static size_t +uread(int const fd, void *const buf, size_t const count) +{ + size_t const n = read(fd, buf, count); + if (n != count) { + perror("read"); + fail_file(); + } + return n; +} + +static size_t +uwrite(int const fd, void const *const buf, size_t const count) +{ + size_t const n = write(fd, buf, count); + if (n != count) { + perror("write"); + fail_file(); + } + return n; +} + +static void * +umalloc(size_t size) +{ + void *const addr = malloc(size); + if (0 == addr) { + fprintf(stderr, "malloc failed: %zu bytes\n", size); + fail_file(); + } + return addr; +} + +/* + * Get the whole file as a programming convenience in order to avoid + * malloc+lseek+read+free of many pieces. If successful, then mmap + * avoids copying unused pieces; else just read the whole file. + * Open for both read and write; new info will be appended to the file. + * Use MAP_PRIVATE so that a few changes to the in-memory ElfXX_Ehdr + * do not propagate to the file until an explicit overwrite at the last. + * This preserves most aspects of consistency (all except .st_size) + * for simultaneous readers of the file while we are appending to it. + * However, multiple writers still are bad. We choose not to use + * locking because it is expensive and the use case of kernel build + * makes multiple writers unlikely. + */ +static void *mmap_file(char const *fname) +{ + void *addr; + + fd_map = open(fname, O_RDWR); + if (0 > fd_map || 0 > fstat(fd_map, &sb)) { + perror(fname); + fail_file(); + } + if (!S_ISREG(sb.st_mode)) { + fprintf(stderr, "not a regular file: %s\n", fname); + fail_file(); + } + addr = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, + fd_map, 0); + mmap_failed = 0; + if (MAP_FAILED == addr) { + mmap_failed = 1; + addr = umalloc(sb.st_size); + uread(fd_map, addr, sb.st_size); + } + return addr; +} + +/* w8rev, w8nat, ...: Handle endianness. */ + +static uint64_t w8rev(uint64_t const x) +{ + return ((0xff & (x >> (0 * 8))) << (7 * 8)) + | ((0xff & (x >> (1 * 8))) << (6 * 8)) + | ((0xff & (x >> (2 * 8))) << (5 * 8)) + | ((0xff & (x >> (3 * 8))) << (4 * 8)) + | ((0xff & (x >> (4 * 8))) << (3 * 8)) + | ((0xff & (x >> (5 * 8))) << (2 * 8)) + | ((0xff & (x >> (6 * 8))) << (1 * 8)) + | ((0xff & (x >> (7 * 8))) << (0 * 8)); +} + +static uint32_t w4rev(uint32_t const x) +{ + return ((0xff & (x >> (0 * 8))) << (3 * 8)) + | ((0xff & (x >> (1 * 8))) << (2 * 8)) + | ((0xff & (x >> (2 * 8))) << (1 * 8)) + | ((0xff & (x >> (3 * 8))) << (0 * 8)); +} + +static uint32_t w2rev(uint16_t const x) +{ + return ((0xff & (x >> (0 * 8))) << (1 * 8)) + | ((0xff & (x >> (1 * 8))) << (0 * 8)); +} + +static uint64_t w8nat(uint64_t const x) +{ + return x; +} + +static uint32_t w4nat(uint32_t const x) +{ + return x; +} + +static uint32_t w2nat(uint16_t const x) +{ + return x; +} + +static uint64_t (*w8)(uint64_t); +static uint32_t (*w)(uint32_t); +static uint32_t (*w2)(uint16_t); + +/* Names of the sections that could contain calls to mcount. */ +static int +is_mcounted_section_name(char const *const txtname) +{ + return 0 == strcmp(".text", txtname) || + 0 == strcmp(".sched.text", txtname) || + 0 == strcmp(".spinlock.text", txtname) || + 0 == strcmp(".irqentry.text", txtname) || + 0 == strcmp(".text.unlikely", txtname); +} + +/* Append the new shstrtab, Elf32_Shdr[], __mcount_loc and its relocations. */ +static void append32(Elf32_Ehdr *const ehdr, + Elf32_Shdr *const shstr, + uint32_t const *const mloc0, + uint32_t const *const mlocp, + Elf32_Rel const *const mrel0, + Elf32_Rel const *const mrelp, + unsigned int const rel_entsize, + unsigned int const symsec_sh_link) +{ + /* Begin constructing output file */ + Elf32_Shdr mcsec; + char const *mc_name = (sizeof(Elf32_Rela) == rel_entsize) + ? ".rela__mcount_loc" + : ".rel__mcount_loc"; + unsigned const old_shnum = w2(ehdr->e_shnum); + uint32_t const old_shoff = w(ehdr->e_shoff); + uint32_t const old_shstr_sh_size = w(shstr->sh_size); + uint32_t const old_shstr_sh_offset = w(shstr->sh_offset); + uint32_t t = 1 + strlen(mc_name) + w(shstr->sh_size); + uint32_t new_e_shoff; + + shstr->sh_size = w(t); + shstr->sh_offset = w(sb.st_size); + t += sb.st_size; + t += (3u & -t); /* 4-byte align */ + new_e_shoff = t; + + /* body for new shstrtab */ + ulseek(fd_map, sb.st_size, SEEK_SET); + uwrite(fd_map, old_shstr_sh_offset + (void *)ehdr, old_shstr_sh_size); + uwrite(fd_map, mc_name, 1 + strlen(mc_name)); + + /* old(modified) Elf32_Shdr table, 4-byte aligned */ + ulseek(fd_map, t, SEEK_SET); + t += sizeof(Elf32_Shdr) * old_shnum; + uwrite(fd_map, old_shoff + (void *)ehdr, + sizeof(Elf32_Shdr) * old_shnum); + + /* new sections __mcount_loc and .rel__mcount_loc */ + t += 2*sizeof(mcsec); + mcsec.sh_name = w((sizeof(Elf32_Rela) == rel_entsize) + strlen(".rel") + + old_shstr_sh_size); + mcsec.sh_type = w(SHT_PROGBITS); + mcsec.sh_flags = w(SHF_ALLOC); + mcsec.sh_addr = 0; + mcsec.sh_offset = w(t); + mcsec.sh_size = w((void *)mlocp - (void *)mloc0); + mcsec.sh_link = 0; + mcsec.sh_info = 0; + mcsec.sh_addralign = w(4); + mcsec.sh_entsize = w(4); + uwrite(fd_map, &mcsec, sizeof(mcsec)); + + mcsec.sh_name = w(old_shstr_sh_size); + mcsec.sh_type = (sizeof(Elf32_Rela) == rel_entsize) + ? w(SHT_RELA) + : w(SHT_REL); + mcsec.sh_flags = 0; + mcsec.sh_addr = 0; + mcsec.sh_offset = w((void *)mlocp - (void *)mloc0 + t); + mcsec.sh_size = w((void *)mrelp - (void *)mrel0); + mcsec.sh_link = w(symsec_sh_link); + mcsec.sh_info = w(old_shnum); + mcsec.sh_addralign = w(4); + mcsec.sh_entsize = w(rel_entsize); + uwrite(fd_map, &mcsec, sizeof(mcsec)); + + uwrite(fd_map, mloc0, (void *)mlocp - (void *)mloc0); + uwrite(fd_map, mrel0, (void *)mrelp - (void *)mrel0); + + ehdr->e_shoff = w(new_e_shoff); + ehdr->e_shnum = w2(2 + w2(ehdr->e_shnum)); /* {.rel,}__mcount_loc */ + ulseek(fd_map, 0, SEEK_SET); + uwrite(fd_map, ehdr, sizeof(*ehdr)); +} + +/* + * append64 and append32 (and other analogous pairs) could be templated + * using C++, but the complexity is high. (For an example, look at p_elf.h + * in the source for UPX, http://upx.sourceforge.net) So: remember to make + * the corresponding change in the routine for the other size. + */ +static void append64(Elf64_Ehdr *const ehdr, + Elf64_Shdr *const shstr, + uint64_t const *const mloc0, + uint64_t const *const mlocp, + Elf64_Rel const *const mrel0, + Elf64_Rel const *const mrelp, + unsigned int const rel_entsize, + unsigned int const symsec_sh_link) +{ + /* Begin constructing output file */ + Elf64_Shdr mcsec; + char const *mc_name = (sizeof(Elf64_Rela) == rel_entsize) + ? ".rela__mcount_loc" + : ".rel__mcount_loc"; + unsigned const old_shnum = w2(ehdr->e_shnum); + uint64_t const old_shoff = w8(ehdr->e_shoff); + uint64_t const old_shstr_sh_size = w8(shstr->sh_size); + uint64_t const old_shstr_sh_offset = w8(shstr->sh_offset); + uint64_t t = 1 + strlen(mc_name) + w8(shstr->sh_size); + uint64_t new_e_shoff; + + shstr->sh_size = w8(t); + shstr->sh_offset = w8(sb.st_size); + t += sb.st_size; + t += (7u & -t); /* 8-byte align */ + new_e_shoff = t; + + /* body for new shstrtab */ + ulseek(fd_map, sb.st_size, SEEK_SET); + uwrite(fd_map, old_shstr_sh_offset + (void *)ehdr, old_shstr_sh_size); + uwrite(fd_map, mc_name, 1 + strlen(mc_name)); + + /* old(modified) Elf64_Shdr table, 8-byte aligned */ + ulseek(fd_map, t, SEEK_SET); + t += sizeof(Elf64_Shdr) * old_shnum; + uwrite(fd_map, old_shoff + (void *)ehdr, + sizeof(Elf64_Shdr) * old_shnum); + + /* new sections __mcount_loc and .rel__mcount_loc */ + t += 2*sizeof(mcsec); + mcsec.sh_name = w((sizeof(Elf64_Rela) == rel_entsize) + strlen(".rel") + + old_shstr_sh_size); + mcsec.sh_type = w(SHT_PROGBITS); + mcsec.sh_flags = w8(SHF_ALLOC); + mcsec.sh_addr = 0; + mcsec.sh_offset = w8(t); + mcsec.sh_size = w8((void *)mlocp - (void *)mloc0); + mcsec.sh_link = 0; + mcsec.sh_info = 0; + mcsec.sh_addralign = w8(8); + mcsec.sh_entsize = w8(8); + uwrite(fd_map, &mcsec, sizeof(mcsec)); + + mcsec.sh_name = w(old_shstr_sh_size); + mcsec.sh_type = (sizeof(Elf64_Rela) == rel_entsize) + ? w(SHT_RELA) + : w(SHT_REL); + mcsec.sh_flags = 0; + mcsec.sh_addr = 0; + mcsec.sh_offset = w8((void *)mlocp - (void *)mloc0 + t); + mcsec.sh_size = w8((void *)mrelp - (void *)mrel0); + mcsec.sh_link = w(symsec_sh_link); + mcsec.sh_info = w(old_shnum); + mcsec.sh_addralign = w8(8); + mcsec.sh_entsize = w8(rel_entsize); + uwrite(fd_map, &mcsec, sizeof(mcsec)); + + uwrite(fd_map, mloc0, (void *)mlocp - (void *)mloc0); + uwrite(fd_map, mrel0, (void *)mrelp - (void *)mrel0); + + ehdr->e_shoff = w8(new_e_shoff); + ehdr->e_shnum = w2(2 + w2(ehdr->e_shnum)); /* {.rel,}__mcount_loc */ + ulseek(fd_map, 0, SEEK_SET); + uwrite(fd_map, ehdr, sizeof(*ehdr)); +} + +/* + * Look at the relocations in order to find the calls to mcount. + * Accumulate the section offsets that are found, and their relocation info, + * onto the end of the existing arrays. + */ +static uint32_t *sift32_rel_mcount(uint32_t *mlocp, + unsigned const offbase, + Elf32_Rel **const mrelpp, + Elf32_Shdr const *const relhdr, + Elf32_Ehdr const *const ehdr, + unsigned const recsym, + uint32_t const recval, + unsigned const reltype) +{ + uint32_t *const mloc0 = mlocp; + Elf32_Rel *mrelp = *mrelpp; + Elf32_Shdr *const shdr0 = (Elf32_Shdr *)(w(ehdr->e_shoff) + + (void *)ehdr); + unsigned const symsec_sh_link = w(relhdr->sh_link); + Elf32_Shdr const *const symsec = &shdr0[symsec_sh_link]; + Elf32_Sym const *const sym0 = (Elf32_Sym const *)(w(symsec->sh_offset) + + (void *)ehdr); + + Elf32_Shdr const *const strsec = &shdr0[w(symsec->sh_link)]; + char const *const str0 = (char const *)(w(strsec->sh_offset) + + (void *)ehdr); + + Elf32_Rel const *const rel0 = (Elf32_Rel const *)(w(relhdr->sh_offset) + + (void *)ehdr); + unsigned rel_entsize = w(relhdr->sh_entsize); + unsigned const nrel = w(relhdr->sh_size) / rel_entsize; + Elf32_Rel const *relp = rel0; + + unsigned mcountsym = 0; + unsigned t; + + for (t = nrel; t; --t) { + if (!mcountsym) { + Elf32_Sym const *const symp = + &sym0[ELF32_R_SYM(w(relp->r_info))]; + + if (0 == strcmp((('_' == gpfx) ? "_mcount" : "mcount"), + &str0[w(symp->st_name)])) + mcountsym = ELF32_R_SYM(w(relp->r_info)); + } + if (mcountsym == ELF32_R_SYM(w(relp->r_info))) { + uint32_t const addend = w(w(relp->r_offset) - recval); + mrelp->r_offset = w(offbase + + ((void *)mlocp - (void *)mloc0)); + mrelp->r_info = w(ELF32_R_INFO(recsym, reltype)); + if (sizeof(Elf32_Rela) == rel_entsize) { + ((Elf32_Rela *)mrelp)->r_addend = addend; + *mlocp++ = 0; + } else + *mlocp++ = addend; + + mrelp = (Elf32_Rel *)(rel_entsize + (void *)mrelp); + } + relp = (Elf32_Rel const *)(rel_entsize + (void *)relp); + } + *mrelpp = mrelp; + return mlocp; +} + +static uint64_t *sift64_rel_mcount(uint64_t *mlocp, + unsigned const offbase, + Elf64_Rel **const mrelpp, + Elf64_Shdr const *const relhdr, + Elf64_Ehdr const *const ehdr, + unsigned const recsym, + uint64_t const recval, + unsigned const reltype) +{ + uint64_t *const mloc0 = mlocp; + Elf64_Rel *mrelp = *mrelpp; + Elf64_Shdr *const shdr0 = (Elf64_Shdr *)(w8(ehdr->e_shoff) + + (void *)ehdr); + unsigned const symsec_sh_link = w(relhdr->sh_link); + Elf64_Shdr const *const symsec = &shdr0[symsec_sh_link]; + Elf64_Sym const *const sym0 = (Elf64_Sym const *)(w8(symsec->sh_offset) + + (void *)ehdr); + + Elf64_Shdr const *const strsec = &shdr0[w(symsec->sh_link)]; + char const *const str0 = (char const *)(w8(strsec->sh_offset) + + (void *)ehdr); + + Elf64_Rel const *const rel0 = (Elf64_Rel const *)(w8(relhdr->sh_offset) + + (void *)ehdr); + unsigned rel_entsize = w8(relhdr->sh_entsize); + unsigned const nrel = w8(relhdr->sh_size) / rel_entsize; + Elf64_Rel const *relp = rel0; + + unsigned mcountsym = 0; + unsigned t; + + for (t = nrel; 0 != t; --t) { + if (!mcountsym) { + Elf64_Sym const *const symp = + &sym0[ELF64_R_SYM(w8(relp->r_info))]; + char const *symname = &str0[w(symp->st_name)]; + + if ('.' == symname[0]) + ++symname; /* ppc64 hack */ + if (0 == strcmp((('_' == gpfx) ? "_mcount" : "mcount"), + symname)) + mcountsym = ELF64_R_SYM(w8(relp->r_info)); + } + + if (mcountsym == ELF64_R_SYM(w8(relp->r_info))) { + uint64_t const addend = w8(w8(relp->r_offset) - recval); + + mrelp->r_offset = w8(offbase + + ((void *)mlocp - (void *)mloc0)); + mrelp->r_info = w8(ELF64_R_INFO(recsym, reltype)); + if (sizeof(Elf64_Rela) == rel_entsize) { + ((Elf64_Rela *)mrelp)->r_addend = addend; + *mlocp++ = 0; + } else + *mlocp++ = addend; + + mrelp = (Elf64_Rel *)(rel_entsize + (void *)mrelp); + } + relp = (Elf64_Rel const *)(rel_entsize + (void *)relp); + } + *mrelpp = mrelp; + + return mlocp; +} + +/* + * Find a symbol in the given section, to be used as the base for relocating + * the table of offsets of calls to mcount. A local or global symbol suffices, + * but avoid a Weak symbol because it may be overridden; the change in value + * would invalidate the relocations of the offsets of the calls to mcount. + * Often the found symbol will be the unnamed local symbol generated by + * GNU 'as' for the start of each section. For example: + * Num: Value Size Type Bind Vis Ndx Name + * 2: 00000000 0 SECTION LOCAL DEFAULT 1 + */ +static unsigned find32_secsym_ndx(unsigned const txtndx, + char const *const txtname, + uint32_t *const recvalp, + Elf32_Shdr const *const symhdr, + Elf32_Ehdr const *const ehdr) +{ + Elf32_Sym const *const sym0 = (Elf32_Sym const *)(w(symhdr->sh_offset) + + (void *)ehdr); + unsigned const nsym = w(symhdr->sh_size) / w(symhdr->sh_entsize); + Elf32_Sym const *symp; + unsigned t; + + for (symp = sym0, t = nsym; t; --t, ++symp) { + unsigned int const st_bind = ELF32_ST_BIND(symp->st_info); + + if (txtndx == w2(symp->st_shndx) + /* avoid STB_WEAK */ + && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) { + *recvalp = w(symp->st_value); + return symp - sym0; + } + } + fprintf(stderr, "Cannot find symbol for section %d: %s.\n", + txtndx, txtname); + fail_file(); +} + +static unsigned find64_secsym_ndx(unsigned const txtndx, + char const *const txtname, + uint64_t *const recvalp, + Elf64_Shdr const *const symhdr, + Elf64_Ehdr const *const ehdr) +{ + Elf64_Sym const *const sym0 = (Elf64_Sym const *)(w8(symhdr->sh_offset) + + (void *)ehdr); + unsigned const nsym = w8(symhdr->sh_size) / w8(symhdr->sh_entsize); + Elf64_Sym const *symp; + unsigned t; + + for (symp = sym0, t = nsym; t; --t, ++symp) { + unsigned int const st_bind = ELF64_ST_BIND(symp->st_info); + + if (txtndx == w2(symp->st_shndx) + /* avoid STB_WEAK */ + && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) { + *recvalp = w8(symp->st_value); + return symp - sym0; + } + } + fprintf(stderr, "Cannot find symbol for section %d: %s.\n", + txtndx, txtname); + fail_file(); +} + +/* + * Evade ISO C restriction: no declaration after statement in + * has32_rel_mcount. + */ +static char const * +__has32_rel_mcount(Elf32_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */ + Elf32_Shdr const *const shdr0, + char const *const shstrtab, + char const *const fname) +{ + /* .sh_info depends on .sh_type == SHT_REL[,A] */ + Elf32_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)]; + char const *const txtname = &shstrtab[w(txthdr->sh_name)]; + + if (0 == strcmp("__mcount_loc", txtname)) { + fprintf(stderr, "warning: __mcount_loc already exists: %s\n", + fname); + succeed_file(); + } + if (SHT_PROGBITS != w(txthdr->sh_type) || + !is_mcounted_section_name(txtname)) + return NULL; + return txtname; +} + +static char const *has32_rel_mcount(Elf32_Shdr const *const relhdr, + Elf32_Shdr const *const shdr0, + char const *const shstrtab, + char const *const fname) +{ + if (SHT_REL != w(relhdr->sh_type) && SHT_RELA != w(relhdr->sh_type)) + return NULL; + return __has32_rel_mcount(relhdr, shdr0, shstrtab, fname); +} + +static char const *__has64_rel_mcount(Elf64_Shdr const *const relhdr, + Elf64_Shdr const *const shdr0, + char const *const shstrtab, + char const *const fname) +{ + /* .sh_info depends on .sh_type == SHT_REL[,A] */ + Elf64_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)]; + char const *const txtname = &shstrtab[w(txthdr->sh_name)]; + + if (0 == strcmp("__mcount_loc", txtname)) { + fprintf(stderr, "warning: __mcount_loc already exists: %s\n", + fname); + succeed_file(); + } + if (SHT_PROGBITS != w(txthdr->sh_type) || + !is_mcounted_section_name(txtname)) + return NULL; + return txtname; +} + +static char const *has64_rel_mcount(Elf64_Shdr const *const relhdr, + Elf64_Shdr const *const shdr0, + char const *const shstrtab, + char const *const fname) +{ + if (SHT_REL != w(relhdr->sh_type) && SHT_RELA != w(relhdr->sh_type)) + return NULL; + return __has64_rel_mcount(relhdr, shdr0, shstrtab, fname); +} + +static unsigned tot32_relsize(Elf32_Shdr const *const shdr0, + unsigned nhdr, + const char *const shstrtab, + const char *const fname) +{ + unsigned totrelsz = 0; + Elf32_Shdr const *shdrp = shdr0; + for (; 0 != nhdr; --nhdr, ++shdrp) { + if (has32_rel_mcount(shdrp, shdr0, shstrtab, fname)) + totrelsz += w(shdrp->sh_size); + } + return totrelsz; +} + +static unsigned tot64_relsize(Elf64_Shdr const *const shdr0, + unsigned nhdr, + const char *const shstrtab, + const char *const fname) +{ + unsigned totrelsz = 0; + Elf64_Shdr const *shdrp = shdr0; + + for (; nhdr; --nhdr, ++shdrp) { + if (has64_rel_mcount(shdrp, shdr0, shstrtab, fname)) + totrelsz += w8(shdrp->sh_size); + } + return totrelsz; +} + +/* Overall supervision for Elf32 ET_REL file. */ +static void +do32(Elf32_Ehdr *const ehdr, char const *const fname, unsigned const reltype) +{ + Elf32_Shdr *const shdr0 = (Elf32_Shdr *)(w(ehdr->e_shoff) + + (void *)ehdr); + unsigned const nhdr = w2(ehdr->e_shnum); + Elf32_Shdr *const shstr = &shdr0[w2(ehdr->e_shstrndx)]; + char const *const shstrtab = (char const *)(w(shstr->sh_offset) + + (void *)ehdr); + + Elf32_Shdr const *relhdr; + unsigned k; + + /* Upper bound on space: assume all relevant relocs are for mcount. */ + unsigned const totrelsz = tot32_relsize(shdr0, nhdr, shstrtab, fname); + Elf32_Rel *const mrel0 = umalloc(totrelsz); + Elf32_Rel * mrelp = mrel0; + + /* 2*sizeof(address) <= sizeof(Elf32_Rel) */ + uint32_t *const mloc0 = umalloc(totrelsz>>1); + uint32_t * mlocp = mloc0; + + unsigned rel_entsize = 0; + unsigned symsec_sh_link = 0; + + for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) { + char const *const txtname = has32_rel_mcount(relhdr, shdr0, + shstrtab, fname); + if (txtname) { + uint32_t recval = 0; + unsigned const recsym = find32_secsym_ndx( + w(relhdr->sh_info), txtname, &recval, + &shdr0[symsec_sh_link = w(relhdr->sh_link)], + ehdr); + + rel_entsize = w(relhdr->sh_entsize); + mlocp = sift32_rel_mcount(mlocp, + (void *)mlocp - (void *)mloc0, &mrelp, + relhdr, ehdr, recsym, recval, reltype); + } + } + if (mloc0 != mlocp) { + append32(ehdr, shstr, mloc0, mlocp, mrel0, mrelp, + rel_entsize, symsec_sh_link); + } + free(mrel0); + free(mloc0); +} + +static void +do64(Elf64_Ehdr *const ehdr, char const *const fname, unsigned const reltype) +{ + Elf64_Shdr *const shdr0 = (Elf64_Shdr *)(w8(ehdr->e_shoff) + + (void *)ehdr); + unsigned const nhdr = w2(ehdr->e_shnum); + Elf64_Shdr *const shstr = &shdr0[w2(ehdr->e_shstrndx)]; + char const *const shstrtab = (char const *)(w8(shstr->sh_offset) + + (void *)ehdr); + + Elf64_Shdr const *relhdr; + unsigned k; + + /* Upper bound on space: assume all relevant relocs are for mcount. */ + unsigned const totrelsz = tot64_relsize(shdr0, nhdr, shstrtab, fname); + Elf64_Rel *const mrel0 = umalloc(totrelsz); + Elf64_Rel * mrelp = mrel0; + + /* 2*sizeof(address) <= sizeof(Elf64_Rel) */ + uint64_t *const mloc0 = umalloc(totrelsz>>1); + uint64_t * mlocp = mloc0; + + unsigned rel_entsize = 0; + unsigned symsec_sh_link = 0; + + for ((relhdr = shdr0), k = nhdr; k; --k, ++relhdr) { + char const *const txtname = has64_rel_mcount(relhdr, shdr0, + shstrtab, fname); + if (txtname) { + uint64_t recval = 0; + unsigned const recsym = find64_secsym_ndx( + w(relhdr->sh_info), txtname, &recval, + &shdr0[symsec_sh_link = w(relhdr->sh_link)], + ehdr); + + rel_entsize = w8(relhdr->sh_entsize); + mlocp = sift64_rel_mcount(mlocp, + (void *)mlocp - (void *)mloc0, &mrelp, + relhdr, ehdr, recsym, recval, reltype); + } + } + if (mloc0 != mlocp) { + append64(ehdr, shstr, mloc0, mlocp, mrel0, mrelp, + rel_entsize, symsec_sh_link); + } + free(mrel0); + free(mloc0); +} + +static void +do_file(char const *const fname) +{ + Elf32_Ehdr *const ehdr = mmap_file(fname); + unsigned int reltype = 0; + + ehdr_curr = ehdr; + w = w4nat; + w2 = w2nat; + w8 = w8nat; + switch (ehdr->e_ident[EI_DATA]) { + static unsigned int const endian = 1; + default: { + fprintf(stderr, "unrecognized ELF data encoding %d: %s\n", + ehdr->e_ident[EI_DATA], fname); + fail_file(); + } break; + case ELFDATA2LSB: { + if (1 != *(unsigned char const *)&endian) { + /* main() is big endian, file.o is little endian. */ + w = w4rev; + w2 = w2rev; + w8 = w8rev; + } + } break; + case ELFDATA2MSB: { + if (0 != *(unsigned char const *)&endian) { + /* main() is little endian, file.o is big endian. */ + w = w4rev; + w2 = w2rev; + w8 = w8rev; + } + } break; + } /* end switch */ + if (0 != memcmp(ELFMAG, ehdr->e_ident, SELFMAG) + || ET_REL != w2(ehdr->e_type) + || EV_CURRENT != ehdr->e_ident[EI_VERSION]) { + fprintf(stderr, "unrecognized ET_REL file %s\n", fname); + fail_file(); + } + + gpfx = 0; + switch (w2(ehdr->e_machine)) { + default: { + fprintf(stderr, "unrecognized e_machine %d %s\n", + w2(ehdr->e_machine), fname); + fail_file(); + } break; + case EM_386: reltype = R_386_32; break; + case EM_ARM: reltype = R_ARM_ABS32; break; + case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break; + case EM_PPC: reltype = R_PPC_ADDR32; gpfx = '_'; break; + case EM_PPC64: reltype = R_PPC64_ADDR64; gpfx = '_'; break; + case EM_S390: /* reltype: e_class */ gpfx = '_'; break; + case EM_SH: reltype = R_SH_DIR32; break; + case EM_SPARCV9: reltype = R_SPARC_64; gpfx = '_'; break; + case EM_X86_64: reltype = R_X86_64_64; break; + } /* end switch */ + + switch (ehdr->e_ident[EI_CLASS]) { + default: { + fprintf(stderr, "unrecognized ELF class %d %s\n", + ehdr->e_ident[EI_CLASS], fname); + fail_file(); + } break; + case ELFCLASS32: { + if (sizeof(Elf32_Ehdr) != w2(ehdr->e_ehsize) + || sizeof(Elf32_Shdr) != w2(ehdr->e_shentsize)) { + fprintf(stderr, + "unrecognized ET_REL file: %s\n", fname); + fail_file(); + } + if (EM_S390 == w2(ehdr->e_machine)) + reltype = R_390_32; + do32(ehdr, fname, reltype); + } break; + case ELFCLASS64: { + Elf64_Ehdr *const ghdr = (Elf64_Ehdr *)ehdr; + if (sizeof(Elf64_Ehdr) != w2(ghdr->e_ehsize) + || sizeof(Elf64_Shdr) != w2(ghdr->e_shentsize)) { + fprintf(stderr, + "unrecognized ET_REL file: %s\n", fname); + fail_file(); + } + if (EM_S390 == w2(ghdr->e_machine)) + reltype = R_390_64; + do64(ghdr, fname, reltype); + } break; + } /* end switch */ + + cleanup(); +} + +int +main(int argc, char const *argv[]) +{ + int n_error = 0; /* gcc-4.3.0 false positive complaint */ + if (argc <= 1) + fprintf(stderr, "usage: recordmcount file.o...\n"); + else /* Process each file in turn, allowing deep failure. */ + for (--argc, ++argv; 0 < argc; --argc, ++argv) { + int const sjval = setjmp(jmpenv); + switch (sjval) { + default: { + fprintf(stderr, "internal error: %s\n", argv[0]); + exit(1); + } break; + case SJ_SETJMP: { /* normal sequence */ + /* Avoid problems if early cleanup() */ + fd_map = -1; + ehdr_curr = NULL; + mmap_failed = 1; + do_file(argv[0]); + } break; + case SJ_FAIL: { /* error in do_file or below */ + ++n_error; + } break; + case SJ_SUCCEED: { /* premature success */ + /* do nothing */ + } break; + } /* end switch */ + } + return !!n_error; +} + + -- cgit v1.2.3 From 72441cb1fd77d092f09ddfac748955703884c9a7 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 13 Oct 2010 17:12:30 -0400 Subject: ftrace/x86: Add support for C version of recordmcount This patch adds the support for the C version of recordmcount and compile times show ~ 12% improvement. After verifying this works, other archs can add: HAVE_C_MCOUNT_RECORD in its Kconfig and it will use the C version of recordmcount instead of the perl version. Cc: Cc: Michal Marek Cc: linux-kbuild@vger.kernel.org Cc: John Reiser Signed-off-by: Steven Rostedt --- scripts/Makefile | 1 + scripts/Makefile.build | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'scripts') diff --git a/scripts/Makefile b/scripts/Makefile index 842dbc2d5aed..2e088109fbd5 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -11,6 +11,7 @@ hostprogs-$(CONFIG_KALLSYMS) += kallsyms hostprogs-$(CONFIG_LOGO) += pnmtologo hostprogs-$(CONFIG_VT) += conmakehash hostprogs-$(CONFIG_IKCONFIG) += bin2c +hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount always := $(hostprogs-y) $(hostprogs-m) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index a1a5cf95a68d..4d03a7efc689 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -209,12 +209,16 @@ cmd_modversions = \ endif ifdef CONFIG_FTRACE_MCOUNT_RECORD +ifdef BUILD_C_RECORDMCOUNT +cmd_record_mcount = $(srctree)/scripts/recordmcount "$(@)"; +else cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \ "$(if $(CONFIG_64BIT),64,32)" \ "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" \ "$(if $(part-of-module),1,0)" "$(@)"; endif +endif define rule_cc_o_c $(call echo-cmd,checksrc) $(cmd_checksrc) \ -- cgit v1.2.3 From c28d5077f8d79bfce1e3f88db2e261cf2b6473dc Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 13 Oct 2010 19:06:14 -0400 Subject: ftrace: Remove duplicate code for 64 and 32 bit in recordmcount.c The elf reader for recordmcount.c had duplicate functions for both 32 bit and 64 bit elf handling. This was due to the need of using the 32 and 64 bit elf structures. This patch consolidates the two by using macros to define the 32 and 64 bit names in a recordmcount.h file, and then by just defining a RECORD_MCOUNT_64 macro and including recordmcount.h twice we create the funtions for both the 32 bit version as well as the 64 bit version using one code source. Cc: John Reiser Signed-off-by: Steven Rostedt --- scripts/recordmcount.c | 548 +------------------------------------------------ scripts/recordmcount.h | 366 +++++++++++++++++++++++++++++++++ 2 files changed, 370 insertions(+), 544 deletions(-) create mode 100644 scripts/recordmcount.h (limited to 'scripts') diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index 34f32be17090..7f7f7180fe24 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -212,550 +212,10 @@ is_mcounted_section_name(char const *const txtname) 0 == strcmp(".text.unlikely", txtname); } -/* Append the new shstrtab, Elf32_Shdr[], __mcount_loc and its relocations. */ -static void append32(Elf32_Ehdr *const ehdr, - Elf32_Shdr *const shstr, - uint32_t const *const mloc0, - uint32_t const *const mlocp, - Elf32_Rel const *const mrel0, - Elf32_Rel const *const mrelp, - unsigned int const rel_entsize, - unsigned int const symsec_sh_link) -{ - /* Begin constructing output file */ - Elf32_Shdr mcsec; - char const *mc_name = (sizeof(Elf32_Rela) == rel_entsize) - ? ".rela__mcount_loc" - : ".rel__mcount_loc"; - unsigned const old_shnum = w2(ehdr->e_shnum); - uint32_t const old_shoff = w(ehdr->e_shoff); - uint32_t const old_shstr_sh_size = w(shstr->sh_size); - uint32_t const old_shstr_sh_offset = w(shstr->sh_offset); - uint32_t t = 1 + strlen(mc_name) + w(shstr->sh_size); - uint32_t new_e_shoff; - - shstr->sh_size = w(t); - shstr->sh_offset = w(sb.st_size); - t += sb.st_size; - t += (3u & -t); /* 4-byte align */ - new_e_shoff = t; - - /* body for new shstrtab */ - ulseek(fd_map, sb.st_size, SEEK_SET); - uwrite(fd_map, old_shstr_sh_offset + (void *)ehdr, old_shstr_sh_size); - uwrite(fd_map, mc_name, 1 + strlen(mc_name)); - - /* old(modified) Elf32_Shdr table, 4-byte aligned */ - ulseek(fd_map, t, SEEK_SET); - t += sizeof(Elf32_Shdr) * old_shnum; - uwrite(fd_map, old_shoff + (void *)ehdr, - sizeof(Elf32_Shdr) * old_shnum); - - /* new sections __mcount_loc and .rel__mcount_loc */ - t += 2*sizeof(mcsec); - mcsec.sh_name = w((sizeof(Elf32_Rela) == rel_entsize) + strlen(".rel") - + old_shstr_sh_size); - mcsec.sh_type = w(SHT_PROGBITS); - mcsec.sh_flags = w(SHF_ALLOC); - mcsec.sh_addr = 0; - mcsec.sh_offset = w(t); - mcsec.sh_size = w((void *)mlocp - (void *)mloc0); - mcsec.sh_link = 0; - mcsec.sh_info = 0; - mcsec.sh_addralign = w(4); - mcsec.sh_entsize = w(4); - uwrite(fd_map, &mcsec, sizeof(mcsec)); - - mcsec.sh_name = w(old_shstr_sh_size); - mcsec.sh_type = (sizeof(Elf32_Rela) == rel_entsize) - ? w(SHT_RELA) - : w(SHT_REL); - mcsec.sh_flags = 0; - mcsec.sh_addr = 0; - mcsec.sh_offset = w((void *)mlocp - (void *)mloc0 + t); - mcsec.sh_size = w((void *)mrelp - (void *)mrel0); - mcsec.sh_link = w(symsec_sh_link); - mcsec.sh_info = w(old_shnum); - mcsec.sh_addralign = w(4); - mcsec.sh_entsize = w(rel_entsize); - uwrite(fd_map, &mcsec, sizeof(mcsec)); - - uwrite(fd_map, mloc0, (void *)mlocp - (void *)mloc0); - uwrite(fd_map, mrel0, (void *)mrelp - (void *)mrel0); - - ehdr->e_shoff = w(new_e_shoff); - ehdr->e_shnum = w2(2 + w2(ehdr->e_shnum)); /* {.rel,}__mcount_loc */ - ulseek(fd_map, 0, SEEK_SET); - uwrite(fd_map, ehdr, sizeof(*ehdr)); -} - -/* - * append64 and append32 (and other analogous pairs) could be templated - * using C++, but the complexity is high. (For an example, look at p_elf.h - * in the source for UPX, http://upx.sourceforge.net) So: remember to make - * the corresponding change in the routine for the other size. - */ -static void append64(Elf64_Ehdr *const ehdr, - Elf64_Shdr *const shstr, - uint64_t const *const mloc0, - uint64_t const *const mlocp, - Elf64_Rel const *const mrel0, - Elf64_Rel const *const mrelp, - unsigned int const rel_entsize, - unsigned int const symsec_sh_link) -{ - /* Begin constructing output file */ - Elf64_Shdr mcsec; - char const *mc_name = (sizeof(Elf64_Rela) == rel_entsize) - ? ".rela__mcount_loc" - : ".rel__mcount_loc"; - unsigned const old_shnum = w2(ehdr->e_shnum); - uint64_t const old_shoff = w8(ehdr->e_shoff); - uint64_t const old_shstr_sh_size = w8(shstr->sh_size); - uint64_t const old_shstr_sh_offset = w8(shstr->sh_offset); - uint64_t t = 1 + strlen(mc_name) + w8(shstr->sh_size); - uint64_t new_e_shoff; - - shstr->sh_size = w8(t); - shstr->sh_offset = w8(sb.st_size); - t += sb.st_size; - t += (7u & -t); /* 8-byte align */ - new_e_shoff = t; - - /* body for new shstrtab */ - ulseek(fd_map, sb.st_size, SEEK_SET); - uwrite(fd_map, old_shstr_sh_offset + (void *)ehdr, old_shstr_sh_size); - uwrite(fd_map, mc_name, 1 + strlen(mc_name)); - - /* old(modified) Elf64_Shdr table, 8-byte aligned */ - ulseek(fd_map, t, SEEK_SET); - t += sizeof(Elf64_Shdr) * old_shnum; - uwrite(fd_map, old_shoff + (void *)ehdr, - sizeof(Elf64_Shdr) * old_shnum); - - /* new sections __mcount_loc and .rel__mcount_loc */ - t += 2*sizeof(mcsec); - mcsec.sh_name = w((sizeof(Elf64_Rela) == rel_entsize) + strlen(".rel") - + old_shstr_sh_size); - mcsec.sh_type = w(SHT_PROGBITS); - mcsec.sh_flags = w8(SHF_ALLOC); - mcsec.sh_addr = 0; - mcsec.sh_offset = w8(t); - mcsec.sh_size = w8((void *)mlocp - (void *)mloc0); - mcsec.sh_link = 0; - mcsec.sh_info = 0; - mcsec.sh_addralign = w8(8); - mcsec.sh_entsize = w8(8); - uwrite(fd_map, &mcsec, sizeof(mcsec)); - - mcsec.sh_name = w(old_shstr_sh_size); - mcsec.sh_type = (sizeof(Elf64_Rela) == rel_entsize) - ? w(SHT_RELA) - : w(SHT_REL); - mcsec.sh_flags = 0; - mcsec.sh_addr = 0; - mcsec.sh_offset = w8((void *)mlocp - (void *)mloc0 + t); - mcsec.sh_size = w8((void *)mrelp - (void *)mrel0); - mcsec.sh_link = w(symsec_sh_link); - mcsec.sh_info = w(old_shnum); - mcsec.sh_addralign = w8(8); - mcsec.sh_entsize = w8(rel_entsize); - uwrite(fd_map, &mcsec, sizeof(mcsec)); - - uwrite(fd_map, mloc0, (void *)mlocp - (void *)mloc0); - uwrite(fd_map, mrel0, (void *)mrelp - (void *)mrel0); - - ehdr->e_shoff = w8(new_e_shoff); - ehdr->e_shnum = w2(2 + w2(ehdr->e_shnum)); /* {.rel,}__mcount_loc */ - ulseek(fd_map, 0, SEEK_SET); - uwrite(fd_map, ehdr, sizeof(*ehdr)); -} - -/* - * Look at the relocations in order to find the calls to mcount. - * Accumulate the section offsets that are found, and their relocation info, - * onto the end of the existing arrays. - */ -static uint32_t *sift32_rel_mcount(uint32_t *mlocp, - unsigned const offbase, - Elf32_Rel **const mrelpp, - Elf32_Shdr const *const relhdr, - Elf32_Ehdr const *const ehdr, - unsigned const recsym, - uint32_t const recval, - unsigned const reltype) -{ - uint32_t *const mloc0 = mlocp; - Elf32_Rel *mrelp = *mrelpp; - Elf32_Shdr *const shdr0 = (Elf32_Shdr *)(w(ehdr->e_shoff) - + (void *)ehdr); - unsigned const symsec_sh_link = w(relhdr->sh_link); - Elf32_Shdr const *const symsec = &shdr0[symsec_sh_link]; - Elf32_Sym const *const sym0 = (Elf32_Sym const *)(w(symsec->sh_offset) - + (void *)ehdr); - - Elf32_Shdr const *const strsec = &shdr0[w(symsec->sh_link)]; - char const *const str0 = (char const *)(w(strsec->sh_offset) - + (void *)ehdr); - - Elf32_Rel const *const rel0 = (Elf32_Rel const *)(w(relhdr->sh_offset) - + (void *)ehdr); - unsigned rel_entsize = w(relhdr->sh_entsize); - unsigned const nrel = w(relhdr->sh_size) / rel_entsize; - Elf32_Rel const *relp = rel0; - - unsigned mcountsym = 0; - unsigned t; - - for (t = nrel; t; --t) { - if (!mcountsym) { - Elf32_Sym const *const symp = - &sym0[ELF32_R_SYM(w(relp->r_info))]; - - if (0 == strcmp((('_' == gpfx) ? "_mcount" : "mcount"), - &str0[w(symp->st_name)])) - mcountsym = ELF32_R_SYM(w(relp->r_info)); - } - if (mcountsym == ELF32_R_SYM(w(relp->r_info))) { - uint32_t const addend = w(w(relp->r_offset) - recval); - mrelp->r_offset = w(offbase - + ((void *)mlocp - (void *)mloc0)); - mrelp->r_info = w(ELF32_R_INFO(recsym, reltype)); - if (sizeof(Elf32_Rela) == rel_entsize) { - ((Elf32_Rela *)mrelp)->r_addend = addend; - *mlocp++ = 0; - } else - *mlocp++ = addend; - - mrelp = (Elf32_Rel *)(rel_entsize + (void *)mrelp); - } - relp = (Elf32_Rel const *)(rel_entsize + (void *)relp); - } - *mrelpp = mrelp; - return mlocp; -} - -static uint64_t *sift64_rel_mcount(uint64_t *mlocp, - unsigned const offbase, - Elf64_Rel **const mrelpp, - Elf64_Shdr const *const relhdr, - Elf64_Ehdr const *const ehdr, - unsigned const recsym, - uint64_t const recval, - unsigned const reltype) -{ - uint64_t *const mloc0 = mlocp; - Elf64_Rel *mrelp = *mrelpp; - Elf64_Shdr *const shdr0 = (Elf64_Shdr *)(w8(ehdr->e_shoff) - + (void *)ehdr); - unsigned const symsec_sh_link = w(relhdr->sh_link); - Elf64_Shdr const *const symsec = &shdr0[symsec_sh_link]; - Elf64_Sym const *const sym0 = (Elf64_Sym const *)(w8(symsec->sh_offset) - + (void *)ehdr); - - Elf64_Shdr const *const strsec = &shdr0[w(symsec->sh_link)]; - char const *const str0 = (char const *)(w8(strsec->sh_offset) - + (void *)ehdr); - - Elf64_Rel const *const rel0 = (Elf64_Rel const *)(w8(relhdr->sh_offset) - + (void *)ehdr); - unsigned rel_entsize = w8(relhdr->sh_entsize); - unsigned const nrel = w8(relhdr->sh_size) / rel_entsize; - Elf64_Rel const *relp = rel0; - - unsigned mcountsym = 0; - unsigned t; - - for (t = nrel; 0 != t; --t) { - if (!mcountsym) { - Elf64_Sym const *const symp = - &sym0[ELF64_R_SYM(w8(relp->r_info))]; - char const *symname = &str0[w(symp->st_name)]; - - if ('.' == symname[0]) - ++symname; /* ppc64 hack */ - if (0 == strcmp((('_' == gpfx) ? "_mcount" : "mcount"), - symname)) - mcountsym = ELF64_R_SYM(w8(relp->r_info)); - } - - if (mcountsym == ELF64_R_SYM(w8(relp->r_info))) { - uint64_t const addend = w8(w8(relp->r_offset) - recval); - - mrelp->r_offset = w8(offbase - + ((void *)mlocp - (void *)mloc0)); - mrelp->r_info = w8(ELF64_R_INFO(recsym, reltype)); - if (sizeof(Elf64_Rela) == rel_entsize) { - ((Elf64_Rela *)mrelp)->r_addend = addend; - *mlocp++ = 0; - } else - *mlocp++ = addend; - - mrelp = (Elf64_Rel *)(rel_entsize + (void *)mrelp); - } - relp = (Elf64_Rel const *)(rel_entsize + (void *)relp); - } - *mrelpp = mrelp; - - return mlocp; -} - -/* - * Find a symbol in the given section, to be used as the base for relocating - * the table of offsets of calls to mcount. A local or global symbol suffices, - * but avoid a Weak symbol because it may be overridden; the change in value - * would invalidate the relocations of the offsets of the calls to mcount. - * Often the found symbol will be the unnamed local symbol generated by - * GNU 'as' for the start of each section. For example: - * Num: Value Size Type Bind Vis Ndx Name - * 2: 00000000 0 SECTION LOCAL DEFAULT 1 - */ -static unsigned find32_secsym_ndx(unsigned const txtndx, - char const *const txtname, - uint32_t *const recvalp, - Elf32_Shdr const *const symhdr, - Elf32_Ehdr const *const ehdr) -{ - Elf32_Sym const *const sym0 = (Elf32_Sym const *)(w(symhdr->sh_offset) - + (void *)ehdr); - unsigned const nsym = w(symhdr->sh_size) / w(symhdr->sh_entsize); - Elf32_Sym const *symp; - unsigned t; - - for (symp = sym0, t = nsym; t; --t, ++symp) { - unsigned int const st_bind = ELF32_ST_BIND(symp->st_info); - - if (txtndx == w2(symp->st_shndx) - /* avoid STB_WEAK */ - && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) { - *recvalp = w(symp->st_value); - return symp - sym0; - } - } - fprintf(stderr, "Cannot find symbol for section %d: %s.\n", - txtndx, txtname); - fail_file(); -} - -static unsigned find64_secsym_ndx(unsigned const txtndx, - char const *const txtname, - uint64_t *const recvalp, - Elf64_Shdr const *const symhdr, - Elf64_Ehdr const *const ehdr) -{ - Elf64_Sym const *const sym0 = (Elf64_Sym const *)(w8(symhdr->sh_offset) - + (void *)ehdr); - unsigned const nsym = w8(symhdr->sh_size) / w8(symhdr->sh_entsize); - Elf64_Sym const *symp; - unsigned t; - - for (symp = sym0, t = nsym; t; --t, ++symp) { - unsigned int const st_bind = ELF64_ST_BIND(symp->st_info); - - if (txtndx == w2(symp->st_shndx) - /* avoid STB_WEAK */ - && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) { - *recvalp = w8(symp->st_value); - return symp - sym0; - } - } - fprintf(stderr, "Cannot find symbol for section %d: %s.\n", - txtndx, txtname); - fail_file(); -} - -/* - * Evade ISO C restriction: no declaration after statement in - * has32_rel_mcount. - */ -static char const * -__has32_rel_mcount(Elf32_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */ - Elf32_Shdr const *const shdr0, - char const *const shstrtab, - char const *const fname) -{ - /* .sh_info depends on .sh_type == SHT_REL[,A] */ - Elf32_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)]; - char const *const txtname = &shstrtab[w(txthdr->sh_name)]; - - if (0 == strcmp("__mcount_loc", txtname)) { - fprintf(stderr, "warning: __mcount_loc already exists: %s\n", - fname); - succeed_file(); - } - if (SHT_PROGBITS != w(txthdr->sh_type) || - !is_mcounted_section_name(txtname)) - return NULL; - return txtname; -} - -static char const *has32_rel_mcount(Elf32_Shdr const *const relhdr, - Elf32_Shdr const *const shdr0, - char const *const shstrtab, - char const *const fname) -{ - if (SHT_REL != w(relhdr->sh_type) && SHT_RELA != w(relhdr->sh_type)) - return NULL; - return __has32_rel_mcount(relhdr, shdr0, shstrtab, fname); -} - -static char const *__has64_rel_mcount(Elf64_Shdr const *const relhdr, - Elf64_Shdr const *const shdr0, - char const *const shstrtab, - char const *const fname) -{ - /* .sh_info depends on .sh_type == SHT_REL[,A] */ - Elf64_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)]; - char const *const txtname = &shstrtab[w(txthdr->sh_name)]; - - if (0 == strcmp("__mcount_loc", txtname)) { - fprintf(stderr, "warning: __mcount_loc already exists: %s\n", - fname); - succeed_file(); - } - if (SHT_PROGBITS != w(txthdr->sh_type) || - !is_mcounted_section_name(txtname)) - return NULL; - return txtname; -} - -static char const *has64_rel_mcount(Elf64_Shdr const *const relhdr, - Elf64_Shdr const *const shdr0, - char const *const shstrtab, - char const *const fname) -{ - if (SHT_REL != w(relhdr->sh_type) && SHT_RELA != w(relhdr->sh_type)) - return NULL; - return __has64_rel_mcount(relhdr, shdr0, shstrtab, fname); -} - -static unsigned tot32_relsize(Elf32_Shdr const *const shdr0, - unsigned nhdr, - const char *const shstrtab, - const char *const fname) -{ - unsigned totrelsz = 0; - Elf32_Shdr const *shdrp = shdr0; - for (; 0 != nhdr; --nhdr, ++shdrp) { - if (has32_rel_mcount(shdrp, shdr0, shstrtab, fname)) - totrelsz += w(shdrp->sh_size); - } - return totrelsz; -} - -static unsigned tot64_relsize(Elf64_Shdr const *const shdr0, - unsigned nhdr, - const char *const shstrtab, - const char *const fname) -{ - unsigned totrelsz = 0; - Elf64_Shdr const *shdrp = shdr0; - - for (; nhdr; --nhdr, ++shdrp) { - if (has64_rel_mcount(shdrp, shdr0, shstrtab, fname)) - totrelsz += w8(shdrp->sh_size); - } - return totrelsz; -} - -/* Overall supervision for Elf32 ET_REL file. */ -static void -do32(Elf32_Ehdr *const ehdr, char const *const fname, unsigned const reltype) -{ - Elf32_Shdr *const shdr0 = (Elf32_Shdr *)(w(ehdr->e_shoff) - + (void *)ehdr); - unsigned const nhdr = w2(ehdr->e_shnum); - Elf32_Shdr *const shstr = &shdr0[w2(ehdr->e_shstrndx)]; - char const *const shstrtab = (char const *)(w(shstr->sh_offset) - + (void *)ehdr); - - Elf32_Shdr const *relhdr; - unsigned k; - - /* Upper bound on space: assume all relevant relocs are for mcount. */ - unsigned const totrelsz = tot32_relsize(shdr0, nhdr, shstrtab, fname); - Elf32_Rel *const mrel0 = umalloc(totrelsz); - Elf32_Rel * mrelp = mrel0; - - /* 2*sizeof(address) <= sizeof(Elf32_Rel) */ - uint32_t *const mloc0 = umalloc(totrelsz>>1); - uint32_t * mlocp = mloc0; - - unsigned rel_entsize = 0; - unsigned symsec_sh_link = 0; - - for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) { - char const *const txtname = has32_rel_mcount(relhdr, shdr0, - shstrtab, fname); - if (txtname) { - uint32_t recval = 0; - unsigned const recsym = find32_secsym_ndx( - w(relhdr->sh_info), txtname, &recval, - &shdr0[symsec_sh_link = w(relhdr->sh_link)], - ehdr); - - rel_entsize = w(relhdr->sh_entsize); - mlocp = sift32_rel_mcount(mlocp, - (void *)mlocp - (void *)mloc0, &mrelp, - relhdr, ehdr, recsym, recval, reltype); - } - } - if (mloc0 != mlocp) { - append32(ehdr, shstr, mloc0, mlocp, mrel0, mrelp, - rel_entsize, symsec_sh_link); - } - free(mrel0); - free(mloc0); -} - -static void -do64(Elf64_Ehdr *const ehdr, char const *const fname, unsigned const reltype) -{ - Elf64_Shdr *const shdr0 = (Elf64_Shdr *)(w8(ehdr->e_shoff) - + (void *)ehdr); - unsigned const nhdr = w2(ehdr->e_shnum); - Elf64_Shdr *const shstr = &shdr0[w2(ehdr->e_shstrndx)]; - char const *const shstrtab = (char const *)(w8(shstr->sh_offset) - + (void *)ehdr); - - Elf64_Shdr const *relhdr; - unsigned k; - - /* Upper bound on space: assume all relevant relocs are for mcount. */ - unsigned const totrelsz = tot64_relsize(shdr0, nhdr, shstrtab, fname); - Elf64_Rel *const mrel0 = umalloc(totrelsz); - Elf64_Rel * mrelp = mrel0; - - /* 2*sizeof(address) <= sizeof(Elf64_Rel) */ - uint64_t *const mloc0 = umalloc(totrelsz>>1); - uint64_t * mlocp = mloc0; - - unsigned rel_entsize = 0; - unsigned symsec_sh_link = 0; - - for ((relhdr = shdr0), k = nhdr; k; --k, ++relhdr) { - char const *const txtname = has64_rel_mcount(relhdr, shdr0, - shstrtab, fname); - if (txtname) { - uint64_t recval = 0; - unsigned const recsym = find64_secsym_ndx( - w(relhdr->sh_info), txtname, &recval, - &shdr0[symsec_sh_link = w(relhdr->sh_link)], - ehdr); - - rel_entsize = w8(relhdr->sh_entsize); - mlocp = sift64_rel_mcount(mlocp, - (void *)mlocp - (void *)mloc0, &mrelp, - relhdr, ehdr, recsym, recval, reltype); - } - } - if (mloc0 != mlocp) { - append64(ehdr, shstr, mloc0, mlocp, mrel0, mrelp, - rel_entsize, symsec_sh_link); - } - free(mrel0); - free(mloc0); -} +/* 32 bit and 64 bit are very similar */ +#include "recordmcount.h" +#define RECORD_MCOUNT_64 +#include "recordmcount.h" static void do_file(char const *const fname) diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h new file mode 100644 index 000000000000..7f39d0943d2d --- /dev/null +++ b/scripts/recordmcount.h @@ -0,0 +1,366 @@ +/* + * recordmcount.h + * + * This code was taken out of recordmcount.c written by + * Copyright 2009 John F. Reiser . All rights reserved. + * + * The original code had the same algorithms for both 32bit + * and 64bit ELF files, but the code was duplicated to support + * the difference in structures that were used. This + * file creates a macro of everything that is different between + * the 64 and 32 bit code, such that by including this header + * twice we can create both sets of functions by including this + * header once with RECORD_MCOUNT_64 undefined, and again with + * it defined. + * + * This conversion to macros was done by: + * Copyright 2010 Steven Rostedt , Red Hat Inc. + * + * Licensed under the GNU General Public License, version 2 (GPLv2). + */ +#undef append_func +#undef sift_rel_mcount +#undef find_secsym_ndx +#undef __has_rel_mcount +#undef has_rel_mcount +#undef tot_relsize +#undef do_func +#undef Elf_Ehdr +#undef Elf_Shdr +#undef Elf_Rel +#undef Elf_Rela +#undef Elf_Sym +#undef ELF_R_SYM +#undef ELF_R_INFO +#undef ELF_ST_BIND +#undef uint_t +#undef _w +#undef _align +#undef _size + +#ifdef RECORD_MCOUNT_64 +# define append_func append64 +# define sift_rel_mcount sift64_rel_mcount +# define find_secsym_ndx find64_secsym_ndx +# define __has_rel_mcount __has64_rel_mcount +# define has_rel_mcount has64_rel_mcount +# define tot_relsize tot64_relsize +# define do_func do64 +# define Elf_Ehdr Elf64_Ehdr +# define Elf_Shdr Elf64_Shdr +# define Elf_Rel Elf64_Rel +# define Elf_Rela Elf64_Rela +# define Elf_Sym Elf64_Sym +# define ELF_R_SYM ELF64_R_SYM +# define ELF_R_INFO ELF64_R_INFO +# define ELF_ST_BIND ELF64_ST_BIND +# define uint_t uint64_t +# define _w w8 +# define _align 7u +# define _size 8 +#else +# define append_func append32 +# define sift_rel_mcount sift32_rel_mcount +# define find_secsym_ndx find32_secsym_ndx +# define __has_rel_mcount __has32_rel_mcount +# define has_rel_mcount has32_rel_mcount +# define tot_relsize tot32_relsize +# define do_func do32 +# define Elf_Ehdr Elf32_Ehdr +# define Elf_Shdr Elf32_Shdr +# define Elf_Rel Elf32_Rel +# define Elf_Rela Elf32_Rela +# define Elf_Sym Elf32_Sym +# define ELF_R_SYM ELF32_R_SYM +# define ELF_R_INFO ELF32_R_INFO +# define ELF_ST_BIND ELF32_ST_BIND +# define uint_t uint32_t +# define _w w +# define _align 3u +# define _size 4 +#endif + +/* Append the new shstrtab, Elf_Shdr[], __mcount_loc and its relocations. */ +static void append_func(Elf_Ehdr *const ehdr, + Elf_Shdr *const shstr, + uint_t const *const mloc0, + uint_t const *const mlocp, + Elf_Rel const *const mrel0, + Elf_Rel const *const mrelp, + unsigned int const rel_entsize, + unsigned int const symsec_sh_link) +{ + /* Begin constructing output file */ + Elf_Shdr mcsec; + char const *mc_name = (sizeof(Elf_Rela) == rel_entsize) + ? ".rela__mcount_loc" + : ".rel__mcount_loc"; + unsigned const old_shnum = w2(ehdr->e_shnum); + uint_t const old_shoff = _w(ehdr->e_shoff); + uint_t const old_shstr_sh_size = _w(shstr->sh_size); + uint_t const old_shstr_sh_offset = _w(shstr->sh_offset); + uint_t t = 1 + strlen(mc_name) + _w(shstr->sh_size); + uint_t new_e_shoff; + + shstr->sh_size = _w(t); + shstr->sh_offset = _w(sb.st_size); + t += sb.st_size; + t += (_align & -t); /* word-byte align */ + new_e_shoff = t; + + /* body for new shstrtab */ + ulseek(fd_map, sb.st_size, SEEK_SET); + uwrite(fd_map, old_shstr_sh_offset + (void *)ehdr, old_shstr_sh_size); + uwrite(fd_map, mc_name, 1 + strlen(mc_name)); + + /* old(modified) Elf_Shdr table, word-byte aligned */ + ulseek(fd_map, t, SEEK_SET); + t += sizeof(Elf_Shdr) * old_shnum; + uwrite(fd_map, old_shoff + (void *)ehdr, + sizeof(Elf_Shdr) * old_shnum); + + /* new sections __mcount_loc and .rel__mcount_loc */ + t += 2*sizeof(mcsec); + mcsec.sh_name = w((sizeof(Elf_Rela) == rel_entsize) + strlen(".rel") + + old_shstr_sh_size); + mcsec.sh_type = w(SHT_PROGBITS); + mcsec.sh_flags = _w(SHF_ALLOC); + mcsec.sh_addr = 0; + mcsec.sh_offset = _w(t); + mcsec.sh_size = _w((void *)mlocp - (void *)mloc0); + mcsec.sh_link = 0; + mcsec.sh_info = 0; + mcsec.sh_addralign = _w(_size); + mcsec.sh_entsize = _w(_size); + uwrite(fd_map, &mcsec, sizeof(mcsec)); + + mcsec.sh_name = w(old_shstr_sh_size); + mcsec.sh_type = (sizeof(Elf_Rela) == rel_entsize) + ? w(SHT_RELA) + : w(SHT_REL); + mcsec.sh_flags = 0; + mcsec.sh_addr = 0; + mcsec.sh_offset = _w((void *)mlocp - (void *)mloc0 + t); + mcsec.sh_size = _w((void *)mrelp - (void *)mrel0); + mcsec.sh_link = w(symsec_sh_link); + mcsec.sh_info = w(old_shnum); + mcsec.sh_addralign = _w(_size); + mcsec.sh_entsize = _w(rel_entsize); + uwrite(fd_map, &mcsec, sizeof(mcsec)); + + uwrite(fd_map, mloc0, (void *)mlocp - (void *)mloc0); + uwrite(fd_map, mrel0, (void *)mrelp - (void *)mrel0); + + ehdr->e_shoff = _w(new_e_shoff); + ehdr->e_shnum = w2(2 + w2(ehdr->e_shnum)); /* {.rel,}__mcount_loc */ + ulseek(fd_map, 0, SEEK_SET); + uwrite(fd_map, ehdr, sizeof(*ehdr)); +} + + +/* + * Look at the relocations in order to find the calls to mcount. + * Accumulate the section offsets that are found, and their relocation info, + * onto the end of the existing arrays. + */ +static uint_t *sift_rel_mcount(uint_t *mlocp, + unsigned const offbase, + Elf_Rel **const mrelpp, + Elf_Shdr const *const relhdr, + Elf_Ehdr const *const ehdr, + unsigned const recsym, + uint_t const recval, + unsigned const reltype) +{ + uint_t *const mloc0 = mlocp; + Elf_Rel *mrelp = *mrelpp; + Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff) + + (void *)ehdr); + unsigned const symsec_sh_link = w(relhdr->sh_link); + Elf_Shdr const *const symsec = &shdr0[symsec_sh_link]; + Elf_Sym const *const sym0 = (Elf_Sym const *)(_w(symsec->sh_offset) + + (void *)ehdr); + + Elf_Shdr const *const strsec = &shdr0[w(symsec->sh_link)]; + char const *const str0 = (char const *)(_w(strsec->sh_offset) + + (void *)ehdr); + + Elf_Rel const *const rel0 = (Elf_Rel const *)(_w(relhdr->sh_offset) + + (void *)ehdr); + unsigned rel_entsize = _w(relhdr->sh_entsize); + unsigned const nrel = _w(relhdr->sh_size) / rel_entsize; + Elf_Rel const *relp = rel0; + + unsigned mcountsym = 0; + unsigned t; + + for (t = nrel; t; --t) { + if (!mcountsym) { + Elf_Sym const *const symp = + &sym0[ELF_R_SYM(_w(relp->r_info))]; + char const *symname = &str0[w(symp->st_name)]; + + if ('.' == symname[0]) + ++symname; /* ppc64 hack */ + if (0 == strcmp((('_' == gpfx) ? "_mcount" : "mcount"), + symname)) + mcountsym = ELF_R_SYM(_w(relp->r_info)); + } + + if (mcountsym == ELF_R_SYM(_w(relp->r_info))) { + uint_t const addend = _w(_w(relp->r_offset) - recval); + + mrelp->r_offset = _w(offbase + + ((void *)mlocp - (void *)mloc0)); + mrelp->r_info = _w(ELF_R_INFO(recsym, reltype)); + if (sizeof(Elf_Rela) == rel_entsize) { + ((Elf_Rela *)mrelp)->r_addend = addend; + *mlocp++ = 0; + } else + *mlocp++ = addend; + + mrelp = (Elf_Rel *)(rel_entsize + (void *)mrelp); + } + relp = (Elf_Rel const *)(rel_entsize + (void *)relp); + } + *mrelpp = mrelp; + return mlocp; +} + + +/* + * Find a symbol in the given section, to be used as the base for relocating + * the table of offsets of calls to mcount. A local or global symbol suffices, + * but avoid a Weak symbol because it may be overridden; the change in value + * would invalidate the relocations of the offsets of the calls to mcount. + * Often the found symbol will be the unnamed local symbol generated by + * GNU 'as' for the start of each section. For example: + * Num: Value Size Type Bind Vis Ndx Name + * 2: 00000000 0 SECTION LOCAL DEFAULT 1 + */ +static unsigned find_secsym_ndx(unsigned const txtndx, + char const *const txtname, + uint_t *const recvalp, + Elf_Shdr const *const symhdr, + Elf_Ehdr const *const ehdr) +{ + Elf_Sym const *const sym0 = (Elf_Sym const *)(_w(symhdr->sh_offset) + + (void *)ehdr); + unsigned const nsym = _w(symhdr->sh_size) / _w(symhdr->sh_entsize); + Elf_Sym const *symp; + unsigned t; + + for (symp = sym0, t = nsym; t; --t, ++symp) { + unsigned int const st_bind = ELF_ST_BIND(symp->st_info); + + if (txtndx == w2(symp->st_shndx) + /* avoid STB_WEAK */ + && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) { + *recvalp = _w(symp->st_value); + return symp - sym0; + } + } + fprintf(stderr, "Cannot find symbol for section %d: %s.\n", + txtndx, txtname); + fail_file(); +} + + +/* Evade ISO C restriction: no declaration after statement in has_rel_mcount. */ +static char const * +__has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */ + Elf_Shdr const *const shdr0, + char const *const shstrtab, + char const *const fname) +{ + /* .sh_info depends on .sh_type == SHT_REL[,A] */ + Elf_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)]; + char const *const txtname = &shstrtab[w(txthdr->sh_name)]; + + if (0 == strcmp("__mcount_loc", txtname)) { + fprintf(stderr, "warning: __mcount_loc already exists: %s\n", + fname); + succeed_file(); + } + if (SHT_PROGBITS != w(txthdr->sh_type) || + !is_mcounted_section_name(txtname)) + return NULL; + return txtname; +} + +static char const *has_rel_mcount(Elf_Shdr const *const relhdr, + Elf_Shdr const *const shdr0, + char const *const shstrtab, + char const *const fname) +{ + if (SHT_REL != w(relhdr->sh_type) && SHT_RELA != w(relhdr->sh_type)) + return NULL; + return __has_rel_mcount(relhdr, shdr0, shstrtab, fname); +} + + +static unsigned tot_relsize(Elf_Shdr const *const shdr0, + unsigned nhdr, + const char *const shstrtab, + const char *const fname) +{ + unsigned totrelsz = 0; + Elf_Shdr const *shdrp = shdr0; + + for (; nhdr; --nhdr, ++shdrp) { + if (has_rel_mcount(shdrp, shdr0, shstrtab, fname)) + totrelsz += _w(shdrp->sh_size); + } + return totrelsz; +} + + +/* Overall supervision for Elf32 ET_REL file. */ +static void +do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype) +{ + Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff) + + (void *)ehdr); + unsigned const nhdr = w2(ehdr->e_shnum); + Elf_Shdr *const shstr = &shdr0[w2(ehdr->e_shstrndx)]; + char const *const shstrtab = (char const *)(_w(shstr->sh_offset) + + (void *)ehdr); + + Elf_Shdr const *relhdr; + unsigned k; + + /* Upper bound on space: assume all relevant relocs are for mcount. */ + unsigned const totrelsz = tot_relsize(shdr0, nhdr, shstrtab, fname); + Elf_Rel *const mrel0 = umalloc(totrelsz); + Elf_Rel * mrelp = mrel0; + + /* 2*sizeof(address) <= sizeof(Elf_Rel) */ + uint_t *const mloc0 = umalloc(totrelsz>>1); + uint_t * mlocp = mloc0; + + unsigned rel_entsize = 0; + unsigned symsec_sh_link = 0; + + for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) { + char const *const txtname = has_rel_mcount(relhdr, shdr0, + shstrtab, fname); + if (txtname) { + uint_t recval = 0; + unsigned const recsym = find_secsym_ndx( + w(relhdr->sh_info), txtname, &recval, + &shdr0[symsec_sh_link = w(relhdr->sh_link)], + ehdr); + + rel_entsize = _w(relhdr->sh_entsize); + mlocp = sift_rel_mcount(mlocp, + (void *)mlocp - (void *)mloc0, &mrelp, + relhdr, ehdr, recsym, recval, reltype); + } + } + if (mloc0 != mlocp) { + append_func(ehdr, shstr, mloc0, mlocp, mrel0, mrelp, + rel_entsize, symsec_sh_link); + } + free(mrel0); + free(mloc0); +} -- cgit v1.2.3 From 444758636439810f110f86a3042c2dfd3626a9e2 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 15 Oct 2010 11:49:47 -0400 Subject: ftrace: Do not process kernel/trace/ftrace.o with C recordmcount program The file kernel/trace/ftrace.c references the mcount() call to convert the mcount() callers to nops. But because it references mcount(), the mcount() address is placed in the relocation table. The C version of recordmcount reads the relocation table of all object files, and it will add all references to mcount to the __mcount_loc table that is used to find the places that call mcount() and change the call to a nop. When recordmcount finds the mcount reference in kernel/trace/ftrace.o, it saves that location even though the code is not a call, but references mcount as data. On boot up, when all calls are converted to nops, the code has a safety check to determine what op code it is actually replacing before it replaces it. If that op code at the address does not match, then a warning is printed and the function tracer is disabled. The reference to mcount in ftrace.c, causes this warning to trigger, since the reference is not a call to mcount(). The ftrace.c file is not compiled with the -pg flag, so no calls to mcount() should be expected. This patch simply makes recordmcount.c skip the kernel/trace/ftrace.c file. This was the same solution used by the perl version of recordmcount. Reported-by: Ingo Molnar Cc: John Reiser Signed-off-by: Steven Rostedt --- scripts/recordmcount.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index 7f7f7180fe24..26e1271259ba 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -313,12 +313,30 @@ do_file(char const *const fname) int main(int argc, char const *argv[]) { + const char ftrace[] = "kernel/trace/ftrace.o"; + int ftrace_size = sizeof(ftrace) - 1; int n_error = 0; /* gcc-4.3.0 false positive complaint */ - if (argc <= 1) + + if (argc <= 1) { fprintf(stderr, "usage: recordmcount file.o...\n"); - else /* Process each file in turn, allowing deep failure. */ + return 0; + } + + /* Process each file in turn, allowing deep failure. */ for (--argc, ++argv; 0 < argc; --argc, ++argv) { int const sjval = setjmp(jmpenv); + int len; + + /* + * The file kernel/trace/ftrace.o references the mcount + * function but does not call it. Since ftrace.o should + * not be traced anyway, we just skip it. + */ + len = strlen(argv[0]); + if (len >= ftrace_size && + strcmp(argv[0] + (len - ftrace_size), ftrace) == 0) + continue; + switch (sjval) { default: { fprintf(stderr, "internal error: %s\n", argv[0]); -- cgit v1.2.3 From 85caa993d7f218b7c2abcfcb28e212396b6a3313 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 15 Oct 2010 12:09:25 -0400 Subject: ftrace: Use objtree for C version of recordmcount The C version of recordmcount is compiled to a binary, which will end up located in the objtree. If the kernel is built with O=path, the srctree will not include the binary recordmcount caller. Cc: Michal Marek Cc: linux-kbuild@vger.kernel.org Signed-off-by: Steven Rostedt --- scripts/Makefile.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 4d03a7efc689..4db60b2e2a76 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -210,7 +210,7 @@ endif ifdef CONFIG_FTRACE_MCOUNT_RECORD ifdef BUILD_C_RECORDMCOUNT -cmd_record_mcount = $(srctree)/scripts/recordmcount "$(@)"; +cmd_record_mcount = $(objtree)/scripts/recordmcount "$(@)"; else cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \ -- cgit v1.2.3 From d7b4d6de57d414a6384376880f2caf7125a45494 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 18 Oct 2010 14:42:00 -0400 Subject: ftrace: Remove recursion between recordmcount and scripts/mod/empty When DYNAMIC_FTRACE is enabled and we use the C version of recordmcount, all objects are run through the recordmcount program to create a separate section that stores all the callers of mcount. The build process has a special file: scripts/mod/empty.o. This is built from empty.c which is literally an empty file (except for a single comment). This file is used to find information about the target elf format, like endianness and word size. The problem comes up when we need to build recordmcount. The build process requires that empty.o is built first. The build rules for empty.o will try to execute recordmcount on the empty.o file. We get an error that recordmcount does not exist. To avoid this recursion, the build file will skip running recordmcount if the file that it is building is script/mod/empty.o. [ extra comment Suggested-by: Sam Ravnborg ] Reported-by: Ingo Molnar Tested-by: Ingo Molnar Cc: Michal Marek Cc: linux-kbuild@vger.kernel.org Signed-off-by: Steven Rostedt --- scripts/Makefile.build | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 4db60b2e2a76..843bd4f4ffc9 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -210,7 +210,13 @@ endif ifdef CONFIG_FTRACE_MCOUNT_RECORD ifdef BUILD_C_RECORDMCOUNT -cmd_record_mcount = $(objtree)/scripts/recordmcount "$(@)"; +# Due to recursion, we must skip empty.o. +# The empty.o file is created in the make process in order to determine +# the target endianness and word size. It is made before all other C +# files, including recordmcount. +cmd_record_mcount = if [ $(@) != "scripts/mod/empty.o" ]; then \ + $(objtree)/scripts/recordmcount "$(@)"; \ + fi; else cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \ -- cgit v1.2.3 From 63ab52db5ba7f362266cfed03109387ca73e5eb5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 26 Oct 2010 14:22:51 -0700 Subject: scripts/get_maintainer.pl: Add --git-blame --rolestats "Authored lines" information When options --git-blame and --rolestats are specified, add the maintainers with the qualifying --git-min-percent amount of lines authored of the complete file. Does not add more authors than specified by --git-max-maintainers. For anyone using hg, this option works but is _very_ slow. It's orders of magnitude slower than git slow. The get_maintainer.pl version was incremented to 0.25. This can be used with or without --git. For instance: $ ./scripts/get_maintainer.pl --git-blame --nogit --rolestats -f lib/bitmap.c Paul Jackson (authored lines:406/613=66%,commits:7/20=35%) Akinobu Mita (authored lines:87/613=14%,commits:3/20=15%) Reinette Chatre (authored lines:42/613=7%) Andrew Morton (commits:16/20=80%) Paul Mundt (commits:3/20=15%) Randy Dunlap (commits:2/20=10%) $ ./scripts/get_maintainer.pl --git-blame --git --rolestats -f lib/bitmap.c Andrew Morton (commit_signer:4/5=80%,commits:16/20=80%) Akinobu Mita (commit_signer:2/5=40%,authored lines:87/613=14%,commits:3/20=15%) Jack Steiner (commit_signer:1/5=20%) Ben Hutchings (commit_signer:1/5=20%) Lee Schermerhorn (commit_signer:1/5=20%) Paul Jackson (authored lines:406/613=66%,commits:7/20=35%) Reinette Chatre (authored lines:42/613=7%) Paul Mundt (commits:3/20=15%) Randy Dunlap (commits:2/20=10%) linux-kernel@vger.kernel.org (open list) Signed-off-by: Joe Perches Cc: Mark Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 60 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index b2281982f52f..a91ae6318403 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -13,7 +13,7 @@ use strict; my $P = $0; -my $V = '0.24'; +my $V = '0.25'; use Getopt::Long qw(:config no_auto_abbrev); @@ -88,6 +88,7 @@ my %VCS_cmds_git = ( "available" => '(which("git") ne "") && (-d ".git")', "find_signers_cmd" => "git log --no-color --since=\$email_git_since -- \$file", "find_commit_signers_cmd" => "git log --no-color -1 \$commit", + "find_commit_author_cmd" => "git log -1 --format=\"%an <%ae>\" \$commit", "blame_range_cmd" => "git blame -l -L \$diff_start,+\$diff_length \$file", "blame_file_cmd" => "git blame -l \$file", "commit_pattern" => "^commit [0-9a-f]{40,40}", @@ -101,6 +102,7 @@ my %VCS_cmds_hg = ( "hg log --date=\$email_hg_since" . " --template='commit {node}\\n{desc}\\n' -- \$file", "find_commit_signers_cmd" => "hg log --template='{desc}\\n' -r \$commit", + "find_commit_author_cmd" => "hg log -l 1 --template='{author}\\n' -r \$commit", "blame_range_cmd" => "", # not supported "blame_file_cmd" => "hg blame -c \$file", "commit_pattern" => "^commit [0-9a-f]{40,40}", @@ -1014,6 +1016,9 @@ sub vcs_find_signers { if (!$email_git_penguin_chiefs) { @lines = grep(!/${penguin_chiefs}/i, @lines); } + + return (0, @lines) if !@lines; + # cut -f2- -d":" s/.*:\s*(.+)\s*/$1/ for (@lines); @@ -1027,6 +1032,28 @@ sub vcs_find_signers { return ($commits, @lines); } +sub vcs_find_author { + my ($cmd) = @_; + my @lines = (); + + @lines = &{$VCS_cmds{"execute_cmd"}}($cmd); + + if (!$email_git_penguin_chiefs) { + @lines = grep(!/${penguin_chiefs}/i, @lines); + } + + return @lines if !@lines; + +## Reformat email addresses (with names) to avoid badly written signatures + + foreach my $line (@lines) { + my ($name, $address) = parse_email($line); + $line = format_email($name, $address, 1); + } + + return @lines; +} + sub vcs_save_commits { my ($cmd) = @_; my @lines = (); @@ -1084,6 +1111,10 @@ sub vcs_blame { @commits = vcs_save_commits($cmd); } + foreach my $commit (@commits) { + $commit =~ s/^\^//g; + } + return @commits; } @@ -1121,6 +1152,8 @@ sub vcs_assign { @lines = mailmap(@lines); } + return if (@lines <= 0); + @lines = sort(@lines); # uniq -c @@ -1165,14 +1198,17 @@ sub vcs_file_blame { my ($file) = @_; my @signers = (); + my @all_commits = (); my @commits = (); my $total_commits; + my $total_lines; return if (!vcs_exists()); - @commits = vcs_blame($file); - @commits = uniq(@commits); + @all_commits = vcs_blame($file); + @commits = uniq(@all_commits); $total_commits = @commits; + $total_lines = @all_commits; foreach my $commit (@commits) { my $commit_count; @@ -1182,10 +1218,28 @@ sub vcs_file_blame { $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd ($commit_count, @commit_signers) = vcs_find_signers($cmd); + push(@signers, @commit_signers); } if ($from_filename) { + if ($output_rolestats) { + my @blame_signers; + foreach my $commit (@commits) { + my $i; + my $cmd = $VCS_cmds{"find_commit_author_cmd"}; + $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd + my @author = vcs_find_author($cmd); + next if !@author; + my $count = grep(/$commit/, @all_commits); + for ($i = 0; $i < $count ; $i++) { + push(@blame_signers, $author[0]); + } + } + if (@blame_signers) { + vcs_assign("authored lines", $total_lines, @blame_signers); + } + } vcs_assign("commits", $total_commits, @signers); } else { vcs_assign("modified commits", $total_commits, @signers); -- cgit v1.2.3 From 6ffd9485f5c9c0b2d2aea9f904dff08e7088010a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 26 Oct 2010 14:22:51 -0700 Subject: scripts/get_maintainer.pl: use correct indentation Fix an overly indented block. Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index a91ae6318403..65c6acf1bb3b 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -420,23 +420,23 @@ foreach my $file (@files) { foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) { add_categories($line); - if ($sections) { - my $i; - my $start = find_starting_index($line); - my $end = find_ending_index($line); - for ($i = $start; $i < $end; $i++) { - my $line = $typevalue[$i]; - if ($line =~ /^[FX]:/) { ##Restore file patterns - $line =~ s/([^\\])\.([^\*])/$1\?$2/g; - $line =~ s/([^\\])\.$/$1\?/g; ##Convert . back to ? - $line =~ s/\\\./\./g; ##Convert \. to . - $line =~ s/\.\*/\*/g; ##Convert .* to * - } - $line =~ s/^([A-Z]):/$1:\t/g; - print("$line\n"); + if ($sections) { + my $i; + my $start = find_starting_index($line); + my $end = find_ending_index($line); + for ($i = $start; $i < $end; $i++) { + my $line = $typevalue[$i]; + if ($line =~ /^[FX]:/) { ##Restore file patterns + $line =~ s/([^\\])\.([^\*])/$1\?$2/g; + $line =~ s/([^\\])\.$/$1\?/g; ##Convert . back to ? + $line =~ s/\\\./\./g; ##Convert \. to . + $line =~ s/\.\*/\*/g; ##Convert .* to * } - print("\n"); + $line =~ s/^([A-Z]):/$1:\t/g; + print("$line\n"); } + print("\n"); + } } if ($email && $email_git) { -- cgit v1.2.3 From fab9ed12fcd0c182a72509382c3da55c527963e3 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 26 Oct 2010 14:22:52 -0700 Subject: scripts/get_maintainer.pl: don't search MAINTAINERS for keywords or emails Keyword matching uses K: patterns from MAINTAINERS, so if looking for the MAINTAINERS maintainer, don't search MAINTAINERS for pattern matches. MAINTAINERS also has rather a lot of email addresses and is easily searched using grep "^M:", so skip it. Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 65c6acf1bb3b..77f4f2e4cd81 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -304,7 +304,7 @@ foreach my $file (@ARGV) { } if ($from_filename) { push(@files, $file); - if (-f $file && ($keywords || $file_emails)) { + if ($file ne "MAINTAINERS" && -f $file && ($keywords || $file_emails)) { open(my $f, '<', $file) or die "$P: Can't open $file: $!\n"; my $text = do { local($/) ; <$f> }; -- cgit v1.2.3 From e3e9d11479737692f797bad1762f71468d577a93 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 26 Oct 2010 14:22:53 -0700 Subject: scripts/get_maintainer.pl: add default --git-fallback, remove default --git Adding commit signers when there is a listed MAINTAINER for a file can make the output list longer than necessary. Change the --git default from on to off. Add a new --git-fallback option (default on) used to add commit signers only when there is no MAINTAINER for a file. git history is used when --git-fallback is enabled and the pattern directory depth is not the same as the file directory depth. For instance: X86 ARCHITECTURE (32-BIT AND 64-BIT) M: Thomas Gleixner M: Ingo Molnar M: "H. Peter Anvin" M: x86@kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git S: Maintained F: Documentation/x86/ F: arch/x86/ If using "./scripts/get_maintainer -f arch/x86/lib/atomic64_32.c", the pattern for "arch/x86/" does not match the directory depth of "arch/x86/lib" so the MAINTAINERS entries and git history is used to produce: $ ./scripts/get_maintainer.pl -f --rolestats arch/x86/lib/atomic64_32.c Thomas Gleixner (maintainer:X86 ARCHITECTURE...) Ingo Molnar (maintainer:X86 ARCHITECTURE...) "H. Peter Anvin" (maintainer:X86 ARCHITECTURE...,commit_signer:1/1=100%) x86@kernel.org (maintainer:X86 ARCHITECTURE...) Luca Barbieri (commit_signer:1/1=100%) linux-kernel@vger.kernel.org (open list) Luca Barbieri is added because he signed the only commit to arch/x86/lib/atomic64_32.c during the last year and he meets the other default qualifications. --git-min-percent (default:10) --git-min-signatures (default:1) If current users of ./scripts/get_maintainers.pl have scripts that use --nogit that expect git history to be excluded, those scripts should be updated to include --nogit-fallback or a .get_maintainer.conf file should be created with --nogit-fallback. Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 77f4f2e4cd81..f46576949ccb 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -24,9 +24,10 @@ my $email_maintainer = 1; my $email_list = 1; my $email_subscriber_list = 0; my $email_git_penguin_chiefs = 0; -my $email_git = 1; +my $email_git = 0; my $email_git_all_signature_types = 0; my $email_git_blame = 0; +my $email_git_fallback = 1; my $email_git_min_signatures = 1; my $email_git_max_maintainers = 5; my $email_git_min_percent = 5; @@ -138,6 +139,7 @@ if (!GetOptions( 'git!' => \$email_git, 'git-all-signature-types!' => \$email_git_all_signature_types, 'git-blame!' => \$email_git_blame, + 'git-fallback!' => \$email_git_fallback, 'git-chief-penguins!' => \$email_git_penguin_chiefs, 'git-min-signatures=i' => \$email_git_min_signatures, 'git-max-maintainers=i' => \$email_git_max_maintainers, @@ -371,6 +373,7 @@ my @status = (); foreach my $file (@files) { my %hash; + my $exact_pattern_match = 0; my $tvi = find_first_section(); while ($tvi < @typevalue) { my $start = find_starting_index($tvi); @@ -405,6 +408,8 @@ foreach my $file (@files) { my $value_pd = ($value =~ tr@/@@); my $file_pd = ($file =~ tr@/@@); $value_pd++ if (substr($value,-1,1) ne "/"); + $value_pd = -1 if ($value =~ /^\.\*/); + $exact_pattern_match = 1 if ($value_pd >= $file_pd); if ($pattern_depth == 0 || (($file_pd - $value_pd) < $pattern_depth)) { $hash{$tvi} = $value_pd; @@ -439,7 +444,8 @@ foreach my $file (@files) { } } - if ($email && $email_git) { + if ($email && + ($email_git || ($email_git_fallback && !$exact_pattern_match))) { vcs_file_signoffs($file); } @@ -540,6 +546,7 @@ MAINTAINER field selection options: --git => include recent git \*-by: signers --git-all-signature-types => include signers regardless of signature type or use only ${signaturePattern} signers (default: $email_git_all_signature_types) + --git-fallback => use git when no exact MAINTAINERS pattern (default: $email_git_fallback) --git-chief-penguins => include ${penguin_chiefs} --git-min-signatures => number of signatures required (default: $email_git_min_signatures) --git-max-maintainers => maximum maintainers to add (default: $email_git_max_maintainers) -- cgit v1.2.3 From bcde44ed7d2a58733efdf04b5392c027d1348bac Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 26 Oct 2010 14:22:53 -0700 Subject: scripts/get_maintainer.pl: use .get_maintainer.conf from . then $HOME then scripts On Mon, 2010-09-13 at 00:01 -0400, Valdis.Kletnieks@vt.edu wrote: > Any chance of getting that to be ~/.get_maintainer.conf rather than > ./.get_maintainer.conf? I've just gotten bit like the 3rd or 4th time by > "oh but you didn't create that file in *this* tree" > (I usually have a linus git tree, a linux-next tree, and 3-4 -mm trees) Sure. Add a search path for the .conf file. 3 paths are added: . customized per-tree configurations $HOME user global configuration when per-tree configs don't exist ./scripts lk defaults to override script Signed-off-by: Joe Perches Cc: Valdis Kletnieks Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index f46576949ccb..e5a400c53bf0 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -110,10 +110,12 @@ my %VCS_cmds_hg = ( "blame_commit_pattern" => "^([0-9a-f]+):" ); -if (-f "${lk_path}.get_maintainer.conf") { +my $conf = which_conf(".get_maintainer.conf"); +if (-f $conf) { my @conf_args; - open(my $conffile, '<', "${lk_path}.get_maintainer.conf") - or warn "$P: Can't open .get_maintainer.conf: $!\n"; + open(my $conffile, '<', "$conf") + or warn "$P: Can't find a readable .get_maintainer.conf file $!\n"; + while (<$conffile>) { my $line = $_; @@ -961,6 +963,18 @@ sub which { return ""; } +sub which_conf { + my ($conf) = @_; + + foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { + if (-e "$path/$conf") { + return "$path/$conf"; + } + } + + return ""; +} + sub mailmap { my (@lines) = @_; my %hash; -- cgit v1.2.3 From dace8e300d6820c2842de750d12b498a743bcfe5 Mon Sep 17 00:00:00 2001 From: Florian Mickler Date: Tue, 26 Oct 2010 14:22:54 -0700 Subject: scripts/get_maintainer.pl: add interactive mode This is a first version of an interactive mode for scripts/get_maintainer.pl. It allows the user to interact with the script. Each cc candidate can be selected and deselected and a shortlog of authored commits can be displayed for each candidate. The menu is displayed via STDERR, the end result is outputted to STDOUT. This unusual mechanism allows using get_maintainer.pl in interactive mode via git send-email --cc-cmd. Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 146 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 141 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index e5a400c53bf0..1ae8c50f1908 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -33,6 +33,7 @@ my $email_git_max_maintainers = 5; my $email_git_min_percent = 5; my $email_git_since = "1-year-ago"; my $email_hg_since = "-365"; +my $interactive = 0; my $email_remove_duplicates = 1; my $output_multiline = 1; my $output_separator = ", "; @@ -52,6 +53,8 @@ my $help = 0; my $exit = 0; +my %shortlog_buffer; + my @penguin_chief = (); push(@penguin_chief, "Linus Torvalds:torvalds\@linux-foundation.org"); #Andrew wants in on most everything - 2009/01/14 @@ -93,7 +96,8 @@ my %VCS_cmds_git = ( "blame_range_cmd" => "git blame -l -L \$diff_start,+\$diff_length \$file", "blame_file_cmd" => "git blame -l \$file", "commit_pattern" => "^commit [0-9a-f]{40,40}", - "blame_commit_pattern" => "^([0-9a-f]+) " + "blame_commit_pattern" => "^([0-9a-f]+) ", + "shortlog_cmd" => "git log --no-color --oneline --since=\$email_git_since --author=\"\$email\" -- \$file" ); my %VCS_cmds_hg = ( @@ -107,7 +111,8 @@ my %VCS_cmds_hg = ( "blame_range_cmd" => "", # not supported "blame_file_cmd" => "hg blame -c \$file", "commit_pattern" => "^commit [0-9a-f]{40,40}", - "blame_commit_pattern" => "^([0-9a-f]+):" + "blame_commit_pattern" => "^([0-9a-f]+):", + "shortlog_cmd" => "ht log --date=\$email_hg_since" ); my $conf = which_conf(".get_maintainer.conf"); @@ -148,6 +153,7 @@ if (!GetOptions( 'git-min-percent=i' => \$email_git_min_percent, 'git-since=s' => \$email_git_since, 'hg-since=s' => \$email_hg_since, + 'i|interactive!' => \$interactive, 'remove-duplicates!' => \$email_remove_duplicates, 'm!' => \$email_maintainer, 'n!' => \$email_usename, @@ -225,6 +231,8 @@ if ($email_git_all_signature_types) { $signaturePattern = "(.+?)[Bb][Yy]:"; } + + ## Read MAINTAINERS for type/value pairs my @typevalue = (); @@ -450,10 +458,13 @@ foreach my $file (@files) { ($email_git || ($email_git_fallback && !$exact_pattern_match))) { vcs_file_signoffs($file); } - if ($email && $email_git_blame) { vcs_file_blame($file); } + if ($email && $interactive){ + vcs_file_shortlogs($file); + + } } if ($keywords) { @@ -486,9 +497,13 @@ if ($email) { } } + if ($email || $email_list) { my @to = (); if ($email) { + if ($interactive) { + @email_to = @{vcs_interactive_menu(\@email_to)}; + } @to = (@to, @email_to); } if ($email_list) { @@ -501,7 +516,6 @@ if ($scm) { @scm = uniq(@scm); output(@scm); } - if ($status) { @status = uniq(@status); output(@status); @@ -556,6 +570,7 @@ MAINTAINER field selection options: --git-blame => use git blame to find modified commits for patch or file --git-since => git history to use (default: $email_git_since) --hg-since => hg history to use (default: $email_hg_since) + --interactive => display a menu (mostly useful if used with the --git option) --m => include maintainer(s) if any --n => include name 'Full Name ' --l => include list(s) if any @@ -1156,6 +1171,127 @@ sub vcs_exists { return 0; } +sub vcs_interactive_menu { + my $list_ref = shift; + my @list = @$list_ref; + + return if (!vcs_exists()); + + my %selected; + my %shortlog; + my $input; + my $count = 0; + + #select maintainers by default + foreach my $entry (@list){ + my $role = $entry->[1]; + $selected{$count} = ($role =~ /maintainer:|supporter:/); + $count++; + } + + #menu loop + do { + my $count = 0; + foreach my $entry (@list){ + my $email = $entry->[0]; + my $role = $entry->[1]; + if ($selected{$count}){ + print STDERR "* "; + } else { + print STDERR " "; + } + print STDERR "$count: $email,\t\t $role"; + print STDERR "\n"; + if ($shortlog{$count}){ + my $entries_ref = vcs_get_shortlog($email); + foreach my $entry_ref (@{$entries_ref}){ + my $filename = @{$entry_ref}[0]; + my @shortlog = @{@{$entry_ref}[1]}; + print STDERR "\tshortlog for $filename (authored commits: " . @shortlog . ").\n"; + foreach my $commit (@shortlog){ + print STDERR "\t $commit\n"; + } + print STDERR "\n"; + } + } + $count++; + } + print STDERR "\n"; + print STDERR "Choose whom to cc by entering a commaseperated list of numbers and hitting enter.\n"; + print STDERR "To show a short list of commits, precede the number by a '?',\n"; + print STDERR "A blank line indicates that you are satisfied with your choice.\n"; + $input = ; + chomp($input); + + my @wish = split(/[, ]+/,$input); + foreach my $nr (@wish){ + my $logtoggle = 0; + if ($nr =~ /\?/){ + $nr =~ s/\?//; + $logtoggle = 1; + } + + #skip out of bounds numbers + next unless ($nr <= $count && $nr >= 0); + + if ($logtoggle){ + $shortlog{$nr} = !$shortlog{$nr}; + } else { + $selected{$nr} = !$selected{$nr}; + + #switch shortlog on if an entry get's selected + if ($selected{$nr}){ + $shortlog{$nr}=1; + } + } + }; + } while(length($input) > 0); + + #drop not selected entries + $count = 0; + my @new_emailto; + foreach my $entry (@list){ + if ($selected{$count}){ + push(@new_emailto,$list[$count]); + print STDERR "$count: "; + print STDERR $email_to[$count]->[0]; + print STDERR ",\t\t "; + print STDERR $email_to[$count]->[1]; + print STDERR "\n"; + } + $count++; + } + return \@new_emailto; +} + +sub vcs_get_shortlog { + my $arg = shift; + my ($name, $address) = parse_email($arg); + return $shortlog_buffer{$address}; +} + +sub vcs_file_shortlogs { + my ($file) = @_; + print STDERR "shortlog processing $file:"; + foreach my $entry (@email_to){ + my ($name, $address) = parse_email($entry->[0]); + print STDERR "."; + my $commits_ref = vcs_email_shortlog($address, $file); + push(@{$shortlog_buffer{$address}}, [ $file, $commits_ref ]); + } + print STDERR "\n"; +} + +sub vcs_email_shortlog { + my $email = shift; + my ($file) = @_; + + my $cmd = $VCS_cmds{"shortlog_cmd"}; + $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables + my @lines = &{$VCS_cmds{"execute_cmd"}}($cmd); + return \@lines; +} + sub vcs_assign { my ($role, $divisor, @lines) = @_; @@ -1236,7 +1372,7 @@ sub vcs_file_blame { my @commit_signers = (); my $cmd = $VCS_cmds{"find_commit_signers_cmd"}; - $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd + $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd ($commit_count, @commit_signers) = vcs_find_signers($cmd); -- cgit v1.2.3 From 683c6f8fcbcb6de8d07545ba70aff49e50d8bcf2 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 26 Oct 2010 14:22:55 -0700 Subject: scripts/get_maintainer.pl: improve --interactive UI o Added searching by git-blame as well as git-history o Added different selection toggles o Added ability to list commits by author or by sign-off-type o Use custom git and hg formats to make searching for subject/author a bit easier. o Move inlined section matching and searching git/hg history to new get_maintainer subroutine o Added subroutines save_commits_by_author and save_commits_by_signer o Removed subroutines vcs_get_shortlog and vcs_email_shortlog o Rename camelcase signaturePattern to signature_pattern Update to 0.26 beta3 Signed-off-by: Joe Perches Cc: Florian Mickler Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 871 +++++++++++++++++++++++++++++++--------------- 1 file changed, 596 insertions(+), 275 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 1ae8c50f1908..f51176039ff5 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -13,7 +13,7 @@ use strict; my $P = $0; -my $V = '0.25'; +my $V = '0.26-beta3'; use Getopt::Long qw(:config no_auto_abbrev); @@ -27,6 +27,7 @@ my $email_git_penguin_chiefs = 0; my $email_git = 0; my $email_git_all_signature_types = 0; my $email_git_blame = 0; +my $email_git_blame_signatures = 1; my $email_git_fallback = 1; my $email_git_min_signatures = 1; my $email_git_max_maintainers = 5; @@ -51,9 +52,12 @@ my $pattern_depth = 0; my $version = 0; my $help = 0; +my $vcs_used = 0; + my $exit = 0; -my %shortlog_buffer; +my %commit_author_hash; +my %commit_signer_hash; my @penguin_chief = (); push(@penguin_chief, "Linus Torvalds:torvalds\@linux-foundation.org"); @@ -77,7 +81,6 @@ my @signature_tags = (); push(@signature_tags, "Signed-off-by:"); push(@signature_tags, "Reviewed-by:"); push(@signature_tags, "Acked-by:"); -my $signaturePattern = "\(" . join("|", @signature_tags) . "\)"; # rfc822 email address - preloaded methods go here. my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])"; @@ -90,29 +93,62 @@ my %VCS_cmds; my %VCS_cmds_git = ( "execute_cmd" => \&git_execute_cmd, "available" => '(which("git") ne "") && (-d ".git")', - "find_signers_cmd" => "git log --no-color --since=\$email_git_since -- \$file", - "find_commit_signers_cmd" => "git log --no-color -1 \$commit", - "find_commit_author_cmd" => "git log -1 --format=\"%an <%ae>\" \$commit", + "find_signers_cmd" => + "git log --no-color --since=\$email_git_since " . + '--format="GitCommit: %H%n' . + 'GitAuthor: %an <%ae>%n' . + 'GitDate: %aD%n' . + 'GitSubject: %s%n' . + '%b%n"' . + " -- \$file", + "find_commit_signers_cmd" => + "git log --no-color " . + '--format="GitCommit: %H%n' . + 'GitAuthor: %an <%ae>%n' . + 'GitDate: %aD%n' . + 'GitSubject: %s%n' . + '%b%n"' . + " -1 \$commit", + "find_commit_author_cmd" => + "git log --no-color " . + '--format="GitCommit: %H%n' . + 'GitAuthor: %an <%ae>%n' . + 'GitDate: %aD%n' . + 'GitSubject: %s%n"' . + " -1 \$commit", "blame_range_cmd" => "git blame -l -L \$diff_start,+\$diff_length \$file", "blame_file_cmd" => "git blame -l \$file", - "commit_pattern" => "^commit [0-9a-f]{40,40}", + "commit_pattern" => "^GitCommit: ([0-9a-f]{40,40})", "blame_commit_pattern" => "^([0-9a-f]+) ", - "shortlog_cmd" => "git log --no-color --oneline --since=\$email_git_since --author=\"\$email\" -- \$file" + "author_pattern" => "^GitAuthor: (.*)", + "subject_pattern" => "^GitSubject: (.*)", ); my %VCS_cmds_hg = ( "execute_cmd" => \&hg_execute_cmd, "available" => '(which("hg") ne "") && (-d ".hg")', "find_signers_cmd" => - "hg log --date=\$email_hg_since" . - " --template='commit {node}\\n{desc}\\n' -- \$file", - "find_commit_signers_cmd" => "hg log --template='{desc}\\n' -r \$commit", - "find_commit_author_cmd" => "hg log -l 1 --template='{author}\\n' -r \$commit", + "hg log --date=\$email_hg_since " . + "--template='HgCommit: {node}\\n" . + "HgAuthor: {author}\\n" . + "HgSubject: {desc}\\n'" . + " -- \$file", + "find_commit_signers_cmd" => + "hg log " . + "--template='HgSubject: {desc}\\n'" . + " -r \$commit", + "find_commit_author_cmd" => + "hg log " . + "--template='HgCommit: {node}\\n" . + "HgAuthor: {author}\\n" . + "HgSubject: {desc|firstline}\\n'" . + " -r \$commit", "blame_range_cmd" => "", # not supported - "blame_file_cmd" => "hg blame -c \$file", - "commit_pattern" => "^commit [0-9a-f]{40,40}", - "blame_commit_pattern" => "^([0-9a-f]+):", - "shortlog_cmd" => "ht log --date=\$email_hg_since" + "blame_file_cmd" => "hg blame -n \$file", + "commit_pattern" => "^HgCommit: ([0-9a-f]{40,40})", + "blame_commit_pattern" => "^([ 0-9a-f]+):", + "author_pattern" => "^HgAuthor: (.*)", + "subject_pattern" => "^HgSubject: (.*)", ); my $conf = which_conf(".get_maintainer.conf"); @@ -146,6 +182,7 @@ if (!GetOptions( 'git!' => \$email_git, 'git-all-signature-types!' => \$email_git_all_signature_types, 'git-blame!' => \$email_git_blame, + 'git-blame-signatures!' => \$email_git_blame_signatures, 'git-fallback!' => \$email_git_fallback, 'git-chief-penguins!' => \$email_git_penguin_chiefs, 'git-min-signatures=i' => \$email_git_min_signatures, @@ -193,13 +230,9 @@ if (-t STDIN && !@ARGV) { die "$P: missing patchfile or -f file - use --help if necessary\n"; } -if ($output_separator ne ", ") { - $output_multiline = 0; -} - -if ($output_rolestats) { - $output_roles = 1; -} +$output_multiline = 0 if ($output_separator ne ", "); +$output_rolestats = 1 if ($interactive); +$output_roles = 1 if ($output_rolestats); if ($sections) { $email = 0; @@ -227,12 +260,6 @@ if (!top_of_kernel_tree($lk_path)) { . "a linux kernel source tree.\n"; } -if ($email_git_all_signature_types) { - $signaturePattern = "(.+?)[Bb][Yy]:"; -} - - - ## Read MAINTAINERS for type/value pairs my @typevalue = (); @@ -371,168 +398,193 @@ foreach my $file (@ARGV) { @file_emails = uniq(@file_emails); +my %email_hash_name; +my %email_hash_address; my @email_to = (); +my %hash_list_to; my @list_to = (); my @scm = (); my @web = (); my @subsystem = (); my @status = (); +my $signature_pattern; -# Find responsible parties +my @to = get_maintainer(); -foreach my $file (@files) { +@to = merge_email(@to); - my %hash; - my $exact_pattern_match = 0; - my $tvi = find_first_section(); - while ($tvi < @typevalue) { - my $start = find_starting_index($tvi); - my $end = find_ending_index($tvi); - my $exclude = 0; - my $i; - - #Do not match excluded file patterns - - for ($i = $start; $i < $end; $i++) { - my $line = $typevalue[$i]; - if ($line =~ m/^(\C):\s*(.*)/) { - my $type = $1; - my $value = $2; - if ($type eq 'X') { - if (file_match_pattern($file, $value)) { - $exclude = 1; - last; - } - } - } - } +output(@to) if (@to); + +if ($scm) { + @scm = uniq(@scm); + output(@scm); +} + +if ($status) { + @status = uniq(@status); + output(@status); +} + +if ($subsystem) { + @subsystem = uniq(@subsystem); + output(@subsystem); +} + +if ($web) { + @web = uniq(@web); + output(@web); +} + +exit($exit); + +sub get_maintainer { + %email_hash_name = (); + %email_hash_address = (); + %commit_author_hash = (); + %commit_signer_hash = (); + @email_to = (); + %hash_list_to = (); + @list_to = (); + @scm = (); + @web = (); + @subsystem = (); + @status = (); + + if ($email_git_all_signature_types) { + $signature_pattern = "(.+?)[Bb][Yy]:"; + } else { + $signature_pattern = "\(" . join("|", @signature_tags) . "\)"; + } + + # Find responsible parties + + foreach my $file (@files) { + + my %hash; + my $exact_pattern_match = 0; + my $tvi = find_first_section(); + while ($tvi < @typevalue) { + my $start = find_starting_index($tvi); + my $end = find_ending_index($tvi); + my $exclude = 0; + my $i; + + #Do not match excluded file patterns - if (!$exclude) { for ($i = $start; $i < $end; $i++) { my $line = $typevalue[$i]; if ($line =~ m/^(\C):\s*(.*)/) { my $type = $1; my $value = $2; - if ($type eq 'F') { + if ($type eq 'X') { if (file_match_pattern($file, $value)) { - my $value_pd = ($value =~ tr@/@@); - my $file_pd = ($file =~ tr@/@@); - $value_pd++ if (substr($value,-1,1) ne "/"); - $value_pd = -1 if ($value =~ /^\.\*/); - $exact_pattern_match = 1 if ($value_pd >= $file_pd); - if ($pattern_depth == 0 || - (($file_pd - $value_pd) < $pattern_depth)) { - $hash{$tvi} = $value_pd; + $exclude = 1; + last; + } + } + } + } + + if (!$exclude) { + for ($i = $start; $i < $end; $i++) { + my $line = $typevalue[$i]; + if ($line =~ m/^(\C):\s*(.*)/) { + my $type = $1; + my $value = $2; + if ($type eq 'F') { + if (file_match_pattern($file, $value)) { + my $value_pd = ($value =~ tr@/@@); + my $file_pd = ($file =~ tr@/@@); + $value_pd++ if (substr($value,-1,1) ne "/"); + $value_pd = -1 if ($value =~ /^\.\*/); + $exact_pattern_match = 1 if ($value_pd >= $file_pd); + if ($pattern_depth == 0 || + (($file_pd - $value_pd) < $pattern_depth)) { + $hash{$tvi} = $value_pd; + } } } } } } + $tvi = $end + 1; } - $tvi = $end + 1; - } - - foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) { - add_categories($line); - if ($sections) { - my $i; - my $start = find_starting_index($line); - my $end = find_ending_index($line); - for ($i = $start; $i < $end; $i++) { - my $line = $typevalue[$i]; - if ($line =~ /^[FX]:/) { ##Restore file patterns - $line =~ s/([^\\])\.([^\*])/$1\?$2/g; - $line =~ s/([^\\])\.$/$1\?/g; ##Convert . back to ? - $line =~ s/\\\./\./g; ##Convert \. to . - $line =~ s/\.\*/\*/g; ##Convert .* to * + foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) { + add_categories($line); + if ($sections) { + my $i; + my $start = find_starting_index($line); + my $end = find_ending_index($line); + for ($i = $start; $i < $end; $i++) { + my $line = $typevalue[$i]; + if ($line =~ /^[FX]:/) { ##Restore file patterns + $line =~ s/([^\\])\.([^\*])/$1\?$2/g; + $line =~ s/([^\\])\.$/$1\?/g; ##Convert . back to ? + $line =~ s/\\\./\./g; ##Convert \. to . + $line =~ s/\.\*/\*/g; ##Convert .* to * + } + $line =~ s/^([A-Z]):/$1:\t/g; + print("$line\n"); } - $line =~ s/^([A-Z]):/$1:\t/g; - print("$line\n"); + print("\n"); } - print("\n"); } - } - - if ($email && - ($email_git || ($email_git_fallback && !$exact_pattern_match))) { - vcs_file_signoffs($file); - } - if ($email && $email_git_blame) { - vcs_file_blame($file); - } - if ($email && $interactive){ - vcs_file_shortlogs($file); + if ($email && ($email_git || + ($email_git_fallback && !$exact_pattern_match))) { + vcs_file_signoffs($file); + } + if ($email && $email_git_blame) { + vcs_file_blame($file); + } } -} -if ($keywords) { - @keyword_tvi = sort_and_uniq(@keyword_tvi); - foreach my $line (@keyword_tvi) { - add_categories($line); + if ($keywords) { + @keyword_tvi = sort_and_uniq(@keyword_tvi); + foreach my $line (@keyword_tvi) { + add_categories($line); + } } -} -if ($email) { - foreach my $chief (@penguin_chief) { - if ($chief =~ m/^(.*):(.*)/) { - my $email_address; + if ($email) { + foreach my $chief (@penguin_chief) { + if ($chief =~ m/^(.*):(.*)/) { + my $email_address; - $email_address = format_email($1, $2, $email_usename); - if ($email_git_penguin_chiefs) { - push(@email_to, [$email_address, 'chief penguin']); - } else { - @email_to = grep($_->[0] !~ /${email_address}/, @email_to); + $email_address = format_email($1, $2, $email_usename); + if ($email_git_penguin_chiefs) { + push(@email_to, [$email_address, 'chief penguin']); + } else { + @email_to = grep($_->[0] !~ /${email_address}/, @email_to); + } } } - } - foreach my $email (@file_emails) { - my ($name, $address) = parse_email($email); + foreach my $email (@file_emails) { + my ($name, $address) = parse_email($email); - my $tmp_email = format_email($name, $address, $email_usename); - push_email_address($tmp_email, ''); - add_role($tmp_email, 'in file'); + my $tmp_email = format_email($name, $address, $email_usename); + push_email_address($tmp_email, ''); + add_role($tmp_email, 'in file'); + } } -} - -if ($email || $email_list) { my @to = (); - if ($email) { - if ($interactive) { - @email_to = @{vcs_interactive_menu(\@email_to)}; + if ($email || $email_list) { + if ($email) { + @to = (@to, @email_to); + } + if ($email_list) { + @to = (@to, @list_to); } - @to = (@to, @email_to); - } - if ($email_list) { - @to = (@to, @list_to); } - output(merge_email(@to)); -} -if ($scm) { - @scm = uniq(@scm); - output(@scm); -} -if ($status) { - @status = uniq(@status); - output(@status); -} + @to = interactive_get_maintainer(\@to) if ($interactive); -if ($subsystem) { - @subsystem = uniq(@subsystem); - output(@subsystem); + return @to; } -if ($web) { - @web = uniq(@web); - output(@web); -} - -exit($exit); - sub file_match_pattern { my ($file, $pattern) = @_; if (substr($pattern, -1) eq "/") { @@ -561,7 +613,7 @@ MAINTAINER field selection options: --email => print email address(es) if any --git => include recent git \*-by: signers --git-all-signature-types => include signers regardless of signature type - or use only ${signaturePattern} signers (default: $email_git_all_signature_types) + or use only ${signature_pattern} signers (default: $email_git_all_signature_types) --git-fallback => use git when no exact MAINTAINERS pattern (default: $email_git_fallback) --git-chief-penguins => include ${penguin_chiefs} --git-min-signatures => number of signatures required (default: $email_git_min_signatures) @@ -847,11 +899,19 @@ sub add_categories { } if ($list_additional =~ m/subscribers-only/) { if ($email_subscriber_list) { - push(@list_to, [$list_address, "subscriber list${list_role}"]); + if (!$hash_list_to{$list_address}) { + $hash_list_to{$list_address} = 1; + push(@list_to, [$list_address, + "subscriber list${list_role}"]); + } } } else { if ($email_list) { - push(@list_to, [$list_address, "open list${list_role}"]); + if (!$hash_list_to{$list_address}) { + $hash_list_to{$list_address} = 1; + push(@list_to, [$list_address, + "open list${list_role}"]); + } } } } elsif ($ptype eq "M") { @@ -882,9 +942,6 @@ sub add_categories { } } -my %email_hash_name; -my %email_hash_address; - sub email_inuse { my ($name, $address) = @_; @@ -1037,10 +1094,31 @@ sub hg_execute_cmd { return @lines; } +sub extract_formatted_signatures { + my (@signature_lines) = @_; + + my @type = @signature_lines; + + s/\s*(.*):.*/$1/ for (@type); + + # cut -f2- -d":" + s/\s*.*:\s*(.+)\s*/$1/ for (@signature_lines); + +## Reformat email addresses (with names) to avoid badly written signatures + + foreach my $signer (@signature_lines) { + my ($name, $address) = parse_email($signer); + $signer = format_email($name, $address, 1); + } + + return (\@type, \@signature_lines); +} + sub vcs_find_signers { my ($cmd) = @_; - my @lines = (); my $commits; + my @lines = (); + my @signatures = (); @lines = &{$VCS_cmds{"execute_cmd"}}($cmd); @@ -1048,24 +1126,20 @@ sub vcs_find_signers { $commits = grep(/$pattern/, @lines); # of commits - @lines = grep(/^[ \t]*${signaturePattern}.*\@.*$/, @lines); - if (!$email_git_penguin_chiefs) { - @lines = grep(!/${penguin_chiefs}/i, @lines); - } + @signatures = grep(/^[ \t]*${signature_pattern}.*\@.*$/, @lines); - return (0, @lines) if !@lines; + return (0, @signatures) if !@signatures; - # cut -f2- -d":" - s/.*:\s*(.+)\s*/$1/ for (@lines); + save_commits_by_author(@lines) if ($interactive); + save_commits_by_signer(@lines) if ($interactive); -## Reformat email addresses (with names) to avoid badly written signatures - - foreach my $line (@lines) { - my ($name, $address) = parse_email($line); - $line = format_email($name, $address, 1); + if (!$email_git_penguin_chiefs) { + @signatures = grep(!/${penguin_chiefs}/i, @signatures); } - return ($commits, @lines); + my ($types_ref, $signers_ref) = extract_formatted_signatures(@signatures); + + return ($commits, @$signers_ref); } sub vcs_find_author { @@ -1080,14 +1154,20 @@ sub vcs_find_author { return @lines if !@lines; -## Reformat email addresses (with names) to avoid badly written signatures - + my @authors = (); foreach my $line (@lines) { - my ($name, $address) = parse_email($line); - $line = format_email($name, $address, 1); + if ($line =~ m/$VCS_cmds{"author_pattern"}/) { + my $author = $1; + my ($name, $address) = parse_email($author); + $author = format_email($name, $address, 1); + push(@authors, $author); + } } - return @lines; + save_commits_by_author(@lines) if ($interactive); + save_commits_by_signer(@lines) if ($interactive); + + return @authors; } sub vcs_save_commits { @@ -1159,7 +1239,7 @@ sub vcs_exists { %VCS_cmds = %VCS_cmds_git; return 1 if eval $VCS_cmds{"available"}; %VCS_cmds = %VCS_cmds_hg; - return 1 if eval $VCS_cmds{"available"}; + return 2 if eval $VCS_cmds{"available"}; %VCS_cmds = (); if (!$printed_novcs) { warn("$P: No supported VCS found. Add --nogit to options?\n"); @@ -1171,125 +1251,309 @@ sub vcs_exists { return 0; } -sub vcs_interactive_menu { - my $list_ref = shift; +sub vcs_is_git { + return $vcs_used == 1; +} + +sub vcs_is_hg { + return $vcs_used == 2; +} + +sub interactive_get_maintainer { + my ($list_ref) = @_; my @list = @$list_ref; - return if (!vcs_exists()); + vcs_exists(); my %selected; - my %shortlog; - my $input; + my %authored; + my %signed; my $count = 0; #select maintainers by default foreach my $entry (@list){ - my $role = $entry->[1]; - $selected{$count} = ($role =~ /maintainer:|supporter:/); - $count++; + my $role = $entry->[1]; + $selected{$count} = ($role =~ /^(maintainer|supporter|open list)/); + $authored{$count} = 0; + $signed{$count} = 0; + $count++; } #menu loop - do { - my $count = 0; - foreach my $entry (@list){ - my $email = $entry->[0]; - my $role = $entry->[1]; - if ($selected{$count}){ - print STDERR "* "; - } else { - print STDERR " "; - } - print STDERR "$count: $email,\t\t $role"; - print STDERR "\n"; - if ($shortlog{$count}){ - my $entries_ref = vcs_get_shortlog($email); - foreach my $entry_ref (@{$entries_ref}){ - my $filename = @{$entry_ref}[0]; - my @shortlog = @{@{$entry_ref}[1]}; - print STDERR "\tshortlog for $filename (authored commits: " . @shortlog . ").\n"; - foreach my $commit (@shortlog){ - print STDERR "\t $commit\n"; + my $done = 0; + my $print_options = 0; + my $redraw = 1; + while (!$done) { + $count = 0; + if ($redraw) { + printf STDERR "\n%1s %2s %-65sauth sign\n", + "*", "#", "email/list and role:stats"; + foreach my $entry (@list) { + my $email = $entry->[0]; + my $role = $entry->[1]; + my $sel = ""; + $sel = "*" if ($selected{$count}); + my $commit_author = $commit_author_hash{$email}; + my $commit_signer = $commit_signer_hash{$email}; + my $authored = 0; + my $signed = 0; + $authored++ for (@{$commit_author}); + $signed++ for (@{$commit_signer}); + printf STDERR "%1s %2d %-65s", $sel, $count + 1, $email; + printf STDERR "%4d %4d", $authored, $signed + if ($authored > 0 || $signed > 0); + printf STDERR "\n %s\n", $role; + if ($authored{$count}) { + my $commit_author = $commit_author_hash{$email}; + foreach my $ref (@{$commit_author}) { + print STDERR " Author: @{$ref}[1]\n"; } - print STDERR "\n"; } + if ($signed{$count}) { + my $commit_signer = $commit_signer_hash{$email}; + foreach my $ref (@{$commit_signer}) { + print STDERR " @{$ref}[2]: @{$ref}[1]\n"; + } + } + + $count++; } - $count++; } - print STDERR "\n"; - print STDERR "Choose whom to cc by entering a commaseperated list of numbers and hitting enter.\n"; - print STDERR "To show a short list of commits, precede the number by a '?',\n"; - print STDERR "A blank line indicates that you are satisfied with your choice.\n"; - $input = ; + my $date_ref = \$email_git_since; + $date_ref = \$email_hg_since if (vcs_is_hg()); + if ($print_options) { + $print_options = 0; + if (vcs_exists()) { + print STDERR +"\nVersion Control options:\n" . +"g use git history [$email_git]\n" . +"gf use git-fallback [$email_git_fallback]\n" . +"b use git blame [$email_git_blame]\n" . +"bs use blame signatures [$email_git_blame_signatures]\n" . +"c# minimum commits [$email_git_min_signatures]\n" . +"%# min percent [$email_git_min_percent]\n" . +"d# history to use [$$date_ref]\n" . +"x# max maintainers [$email_git_max_maintainers]\n" . +"t all signature types [$email_git_all_signature_types]\n"; + } + print STDERR "\nAdditional options:\n" . +"0 toggle all\n" . +"f emails in file [$file_emails]\n" . +"k keywords in file [$keywords]\n" . +"r remove duplicates [$email_remove_duplicates]\n" . +"p# pattern match depth [$pattern_depth]\n"; + } + print STDERR +"\n#(toggle), A#(author), S#(signed) *(all), ^(none), O(options), Y(approve): "; + + my $input = ; chomp($input); - my @wish = split(/[, ]+/,$input); - foreach my $nr (@wish){ - my $logtoggle = 0; - if ($nr =~ /\?/){ - $nr =~ s/\?//; - $logtoggle = 1; + $redraw = 1; + my $rerun = 0; + my @wish = split(/[, ]+/, $input); + foreach my $nr (@wish) { + $nr = lc($nr); + my $sel = substr($nr, 0, 1); + my $str = substr($nr, 1); + my $val = 0; + $val = $1 if $str =~ /^(\d+)$/; + + if ($sel eq "y") { + $interactive = 0; + $done = 1; + $output_rolestats = 0; + $output_roles = 0; + last; + } elsif ($nr =~ /^\d+$/ && $nr > 0 && $nr <= $count) { + $selected{$nr - 1} = !$selected{$nr - 1}; + } elsif ($sel eq "*" || $sel eq '^') { + my $toggle = 0; + $toggle = 1 if ($sel eq '*'); + for (my $i = 0; $i < $count; $i++) { + $selected{$i} = $toggle; } - - #skip out of bounds numbers - next unless ($nr <= $count && $nr >= 0); - - if ($logtoggle){ - $shortlog{$nr} = !$shortlog{$nr}; + } elsif ($sel eq "0") { + for (my $i = 0; $i < $count; $i++) { + $selected{$i} = !$selected{$i}; + } + } elsif ($sel eq "a") { + if ($val > 0 && $val <= $count) { + $authored{$val - 1} = !$authored{$val - 1}; + } elsif ($str eq '*' || $str eq '^') { + my $toggle = 0; + $toggle = 1 if ($str eq '*'); + for (my $i = 0; $i < $count; $i++) { + $authored{$i} = $toggle; + } + } + } elsif ($sel eq "s") { + if ($val > 0 && $val <= $count) { + $signed{$val - 1} = !$signed{$val - 1}; + } elsif ($str eq '*' || $str eq '^') { + my $toggle = 0; + $toggle = 1 if ($str eq '*'); + for (my $i = 0; $i < $count; $i++) { + $signed{$i} = $toggle; + } + } + } elsif ($sel eq "o") { + $print_options = 1; + $redraw = 1; + } elsif ($sel eq "g") { + if ($str eq "f") { + bool_invert(\$email_git_fallback); } else { - $selected{$nr} = !$selected{$nr}; - - #switch shortlog on if an entry get's selected - if ($selected{$nr}){ - $shortlog{$nr}=1; - } + bool_invert(\$email_git); + } + $rerun = 1; + } elsif ($sel eq "b") { + if ($str eq "s") { + bool_invert(\$email_git_blame_signatures); + } else { + bool_invert(\$email_git_blame); + } + $rerun = 1; + } elsif ($sel eq "c") { + if ($val > 0) { + $email_git_min_signatures = $val; + $rerun = 1; + } + } elsif ($sel eq "x") { + if ($val > 0) { + $email_git_max_maintainers = $val; + $rerun = 1; + } + } elsif ($sel eq "%") { + if ($str ne "" && $val >= 0) { + $email_git_min_percent = $val; + $rerun = 1; } - }; - } while(length($input) > 0); + } elsif ($sel eq "d") { + if (vcs_is_git()) { + $email_git_since = $str; + } elsif (vcs_is_hg()) { + $email_hg_since = $str; + } + $rerun = 1; + } elsif ($sel eq "t") { + bool_invert(\$email_git_all_signature_types); + $rerun = 1; + } elsif ($sel eq "f") { + bool_invert(\$file_emails); + $rerun = 1; + } elsif ($sel eq "r") { + bool_invert(\$email_remove_duplicates); + $rerun = 1; + } elsif ($sel eq "k") { + bool_invert(\$keywords); + $rerun = 1; + } elsif ($sel eq "p") { + if ($str ne "" && $val >= 0) { + $pattern_depth = $val; + $rerun = 1; + } + } else { + print STDERR "invalid option: '$nr'\n"; + $redraw = 0; + } + } + if ($rerun) { + print STDERR "git-blame can be very slow, please have patience..." + if ($email_git_blame); + goto &get_maintainer; + } + } #drop not selected entries $count = 0; - my @new_emailto; - foreach my $entry (@list){ - if ($selected{$count}){ - push(@new_emailto,$list[$count]); - print STDERR "$count: "; - print STDERR $email_to[$count]->[0]; - print STDERR ",\t\t "; - print STDERR $email_to[$count]->[1]; - print STDERR "\n"; + my @new_emailto = (); + foreach my $entry (@list) { + if ($selected{$count}) { + push(@new_emailto, $list[$count]); } $count++; } - return \@new_emailto; + return @new_emailto; } -sub vcs_get_shortlog { - my $arg = shift; - my ($name, $address) = parse_email($arg); - return $shortlog_buffer{$address}; +sub bool_invert { + my ($bool_ref) = @_; + + if ($$bool_ref) { + $$bool_ref = 0; + } else { + $$bool_ref = 1; + } } -sub vcs_file_shortlogs { - my ($file) = @_; - print STDERR "shortlog processing $file:"; - foreach my $entry (@email_to){ - my ($name, $address) = parse_email($entry->[0]); - print STDERR "."; - my $commits_ref = vcs_email_shortlog($address, $file); - push(@{$shortlog_buffer{$address}}, [ $file, $commits_ref ]); +sub save_commits_by_author { + my (@lines) = @_; + + my @authors = (); + my @commits = (); + my @subjects = (); + + foreach my $line (@lines) { + if ($line =~ m/$VCS_cmds{"author_pattern"}/) { + my $author = $1; + my ($name, $address) = parse_email($author); + $author = format_email($name, $address, 1); + push(@authors, $author); + } + push(@commits, $1) if ($line =~ m/$VCS_cmds{"commit_pattern"}/); + push(@subjects, $1) if ($line =~ m/$VCS_cmds{"subject_pattern"}/); + } + + for (my $i = 0; $i < @authors; $i++) { + my $exists = 0; + foreach my $ref(@{$commit_author_hash{$authors[$i]}}) { + if (@{$ref}[0] eq $commits[$i] && + @{$ref}[1] eq $subjects[$i]) { + $exists = 1; + last; + } + } + if (!$exists) { + push(@{$commit_author_hash{$authors[$i]}}, + [ ($commits[$i], $subjects[$i]) ]); + } } - print STDERR "\n"; } -sub vcs_email_shortlog { - my $email = shift; - my ($file) = @_; +sub save_commits_by_signer { + my (@lines) = @_; + + my $commit = ""; + my $subject = ""; - my $cmd = $VCS_cmds{"shortlog_cmd"}; - $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables - my @lines = &{$VCS_cmds{"execute_cmd"}}($cmd); - return \@lines; + foreach my $line (@lines) { + $commit = $1 if ($line =~ m/$VCS_cmds{"commit_pattern"}/); + $subject = $1 if ($line =~ m/$VCS_cmds{"subject_pattern"}/); + if ($line =~ /^[ \t]*${signature_pattern}.*\@.*$/) { + my @signatures = ($line); + my ($types_ref, $signers_ref) = extract_formatted_signatures(@signatures); + my @types = @$types_ref; + my @signers = @$signers_ref; + + my $type = $types[0]; + my $signer = $signers[0]; + + my $exists = 0; + foreach my $ref(@{$commit_signer_hash{$signer}}) { + if (@{$ref}[0] eq $commit && + @{$ref}[1] eq $subject && + @{$ref}[2] eq $type) { + $exists = 1; + last; + } + } + if (!$exists) { + push(@{$commit_signer_hash{$signer}}, + [ ($commit, $subject, $type) ]); + } + } + } } sub vcs_assign { @@ -1342,7 +1606,8 @@ sub vcs_file_signoffs { my @signers = (); my $commits; - return if (!vcs_exists()); + $vcs_used = vcs_exists(); + return if (!$vcs_used); my $cmd = $VCS_cmds{"find_signers_cmd"}; $cmd =~ s/(\$\w+)/$1/eeg; # interpolate $cmd @@ -1360,37 +1625,93 @@ sub vcs_file_blame { my $total_commits; my $total_lines; - return if (!vcs_exists()); + $vcs_used = vcs_exists(); + return if (!$vcs_used); @all_commits = vcs_blame($file); @commits = uniq(@all_commits); $total_commits = @commits; $total_lines = @all_commits; - foreach my $commit (@commits) { - my $commit_count; - my @commit_signers = (); + if ($email_git_blame_signatures) { + if (vcs_is_hg()) { + my $commit_count; + my @commit_signers = (); + my $commit = join(" -r ", @commits); + my $cmd; - my $cmd = $VCS_cmds{"find_commit_signers_cmd"}; - $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd + $cmd = $VCS_cmds{"find_commit_signers_cmd"}; + $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd - ($commit_count, @commit_signers) = vcs_find_signers($cmd); + ($commit_count, @commit_signers) = vcs_find_signers($cmd); - push(@signers, @commit_signers); + push(@signers, @commit_signers); + } else { + foreach my $commit (@commits) { + my $commit_count; + my @commit_signers = (); + my $cmd; + + $cmd = $VCS_cmds{"find_commit_signers_cmd"}; + $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd + + ($commit_count, @commit_signers) = vcs_find_signers($cmd); + + push(@signers, @commit_signers); + } + } } if ($from_filename) { if ($output_rolestats) { my @blame_signers; - foreach my $commit (@commits) { - my $i; - my $cmd = $VCS_cmds{"find_commit_author_cmd"}; - $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd - my @author = vcs_find_author($cmd); - next if !@author; - my $count = grep(/$commit/, @all_commits); - for ($i = 0; $i < $count ; $i++) { - push(@blame_signers, $author[0]); + if (vcs_is_hg()) {{ # Double brace for last exit + my $commit_count; + my @commit_signers = (); + @commits = uniq(@commits); + @commits = sort(@commits); + my $commit = join(" -r ", @commits); + my $cmd; + + $cmd = $VCS_cmds{"find_commit_author_cmd"}; + $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd + + my @lines = (); + + @lines = &{$VCS_cmds{"execute_cmd"}}($cmd); + + if (!$email_git_penguin_chiefs) { + @lines = grep(!/${penguin_chiefs}/i, @lines); + } + + last if !@lines; + + my @authors = (); + foreach my $line (@lines) { + if ($line =~ m/$VCS_cmds{"author_pattern"}/) { + my $author = $1; + my ($name, $address) = parse_email($author); + $author = format_email($name, $address, 1); + push(@authors, $1); + } + } + + save_commits_by_author(@lines) if ($interactive); + save_commits_by_signer(@lines) if ($interactive); + + push(@signers, @authors); + }} + else { + foreach my $commit (@commits) { + my $i; + my $cmd = $VCS_cmds{"find_commit_author_cmd"}; + $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd + my @author = vcs_find_author($cmd); + next if !@author; + my $count = grep(/$commit/, @all_commits); + for ($i = 0; $i < $count ; $i++) { + push(@blame_signers, $author[0]); + } } } if (@blame_signers) { -- cgit v1.2.3 From 6ef1c52e122b675acc88a8b016d6477f67988b91 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 26 Oct 2010 14:22:56 -0700 Subject: scripts/get_maintainer.pl: use case insensitive name de-duplication Case insensitive name and email address matching can help reduce duplication when authors don't always use the exact same signature. o Add a --interactive per-file exact_match hash so git history can be checked on per-file only when there is no direct maintainer o Make @interactive_to list global so save_commits_by_ can check email names & addresses against this list for duplication o Don't allow --interactive and --sections o rename subroutine get_maintainer to get_maintainers o Added help text option to --interactive menu prompt Update version to 0.26-beta4 Signed-off-by: Joe Perches Cc: Florian Mickler Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 135 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 101 insertions(+), 34 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index f51176039ff5..61d3bb51bddf 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -13,7 +13,7 @@ use strict; my $P = $0; -my $V = '0.26-beta3'; +my $V = '0.26-beta4'; use Getopt::Long qw(:config no_auto_abbrev); @@ -242,6 +242,7 @@ if ($sections) { $subsystem = 0; $web = 0; $keywords = 0; + $interactive = 0; } else { my $selections = $email + $scm + $status + $subsystem + $web; if ($selections == 0) { @@ -407,13 +408,15 @@ my @scm = (); my @web = (); my @subsystem = (); my @status = (); +my @interactive_to = (); my $signature_pattern; -my @to = get_maintainer(); +my @maintainers = get_maintainers(); -@to = merge_email(@to); - -output(@to) if (@to); +if (@maintainers) { + @maintainers = merge_email(@maintainers); + output(@maintainers); +} if ($scm) { @scm = uniq(@scm); @@ -437,7 +440,7 @@ if ($web) { exit($exit); -sub get_maintainer { +sub get_maintainers { %email_hash_name = (); %email_hash_address = (); %commit_author_hash = (); @@ -449,7 +452,7 @@ sub get_maintainer { @web = (); @subsystem = (); @status = (); - + @interactive_to = (); if ($email_git_all_signature_types) { $signature_pattern = "(.+?)[Bb][Yy]:"; } else { @@ -458,10 +461,11 @@ sub get_maintainer { # Find responsible parties + my %exact_pattern_match_hash; + foreach my $file (@files) { my %hash; - my $exact_pattern_match = 0; my $tvi = find_first_section(); while ($tvi < @typevalue) { my $start = find_starting_index($tvi); @@ -497,7 +501,9 @@ sub get_maintainer { my $file_pd = ($file =~ tr@/@@); $value_pd++ if (substr($value,-1,1) ne "/"); $value_pd = -1 if ($value =~ /^\.\*/); - $exact_pattern_match = 1 if ($value_pd >= $file_pd); + if ($value_pd >= $file_pd) { + $exact_pattern_match_hash{$file} = 1; + } if ($pattern_depth == 0 || (($file_pd - $value_pd) < $pattern_depth)) { $hash{$tvi} = $value_pd; @@ -530,14 +536,6 @@ sub get_maintainer { print("\n"); } } - - if ($email && ($email_git || - ($email_git_fallback && !$exact_pattern_match))) { - vcs_file_signoffs($file); - } - if ($email && $email_git_blame) { - vcs_file_blame($file); - } } if ($keywords) { @@ -547,6 +545,19 @@ sub get_maintainer { } } + @interactive_to = (@email_to, @list_to); + + foreach my $file (@files) { + if ($email && + ($email_git || ($email_git_fallback && + !$exact_pattern_match_hash{$file}))) { + vcs_file_signoffs($file); + } + if ($email && $email_git_blame) { + vcs_file_blame($file); + } + } + if ($email) { foreach my $chief (@penguin_chief) { if ($chief =~ m/^(.*):(.*)/) { @@ -580,7 +591,10 @@ sub get_maintainer { } } - @to = interactive_get_maintainer(\@to) if ($interactive); + if ($interactive) { + @interactive_to = @to; + @to = interactive_get_maintainers(\@interactive_to); + } return @to; } @@ -899,16 +913,16 @@ sub add_categories { } if ($list_additional =~ m/subscribers-only/) { if ($email_subscriber_list) { - if (!$hash_list_to{$list_address}) { - $hash_list_to{$list_address} = 1; + if (!$hash_list_to{lc($list_address)}) { + $hash_list_to{lc($list_address)} = 1; push(@list_to, [$list_address, "subscriber list${list_role}"]); } } } else { if ($email_list) { - if (!$hash_list_to{$list_address}) { - $hash_list_to{$list_address} = 1; + if (!$hash_list_to{lc($list_address)}) { + $hash_list_to{lc($list_address)} = 1; push(@list_to, [$list_address, "open list${list_role}"]); } @@ -946,8 +960,8 @@ sub email_inuse { my ($name, $address) = @_; return 1 if (($name eq "") && ($address eq "")); - return 1 if (($name ne "") && exists($email_hash_name{$name})); - return 1 if (($address ne "") && exists($email_hash_address{$address})); + return 1 if (($name ne "") && exists($email_hash_name{lc($name)})); + return 1 if (($address ne "") && exists($email_hash_address{lc($address)})); return 0; } @@ -965,8 +979,8 @@ sub push_email_address { push(@email_to, [format_email($name, $address, $email_usename), $role]); } elsif (!email_inuse($name, $address)) { push(@email_to, [format_email($name, $address, $email_usename), $role]); - $email_hash_name{$name}++; - $email_hash_address{$address}++; + $email_hash_name{lc($name)}++; + $email_hash_address{lc($address)}++; } return 1; @@ -1259,7 +1273,7 @@ sub vcs_is_hg { return $vcs_used == 2; } -sub interactive_get_maintainer { +sub interactive_get_maintainers { my ($list_ref) = @_; my @list = @$list_ref; @@ -1269,11 +1283,12 @@ sub interactive_get_maintainer { my %authored; my %signed; my $count = 0; - + my $maintained = 0; #select maintainers by default - foreach my $entry (@list){ + foreach my $entry (@list) { my $role = $entry->[1]; - $selected{$count} = ($role =~ /^(maintainer|supporter|open list)/); + $selected{$count} = ($role =~ /^(maintainer|supporter|open list)/i); + $maintained = 1 if ($role =~ /^(maintainer|supporter)/i); $authored{$count} = 0; $signed{$count} = 0; $count++; @@ -1286,8 +1301,14 @@ sub interactive_get_maintainer { while (!$done) { $count = 0; if ($redraw) { - printf STDERR "\n%1s %2s %-65sauth sign\n", - "*", "#", "email/list and role:stats"; + printf STDERR "\n%1s %2s %-65s", + "*", "#", "email/list and role:stats"; + if ($email_git || + ($email_git_fallback && !$maintained) || + $email_git_blame) { + print STDERR "auth sign"; + } + print STDERR "\n"; foreach my $entry (@list) { my $email = $entry->[0]; my $role = $entry->[1]; @@ -1453,6 +1474,27 @@ sub interactive_get_maintainer { $pattern_depth = $val; $rerun = 1; } + } elsif ($sel eq "h" || $sel eq "?") { + print STDERR <[0]); + if ($email_remove_duplicates && + ((lc($name) eq lc($to_name)) || + (lc($address) eq lc($to_address)))) { + $author = $to->[0]; + $matched = 1; + last; + } + } + $author = format_email($name, $address, 1) if (!$matched); push(@authors, $author); } push(@commits, $1) if ($line =~ m/$VCS_cmds{"commit_pattern"}/); @@ -1539,6 +1592,20 @@ sub save_commits_by_signer { my $type = $types[0]; my $signer = $signers[0]; + my $matched = 0; + my ($name, $address) = parse_email($signer); + foreach my $to (@interactive_to) { + my ($to_name, $to_address) = parse_email($to->[0]); + if ($email_remove_duplicates && + ((lc($name) eq lc($to_name)) || + (lc($address) eq lc($to_address)))) { + $signer = $to->[0]; + $matched = 1; + last; + } + $signer = format_email($name, $address, 1) if (!$matched); + } + my $exists = 0; foreach my $ref(@{$commit_signer_hash{$signer}}) { if (@{$ref}[0] eq $commit && -- cgit v1.2.3 From 7fa8ff2e0c0f326cdaaa4ae7d00f5d021e43ffa2 Mon Sep 17 00:00:00 2001 From: Florian Mickler Date: Tue, 26 Oct 2010 14:22:56 -0700 Subject: scripts/get_maintainer.pl: fix mailmap handling Implement it, like it is described in git-shortlog. Signed-off-by: Florian Mickler Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 147 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 109 insertions(+), 38 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 61d3bb51bddf..faeace4e1fd0 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -295,31 +295,76 @@ while (<$maint>) { } close($maint); -my %mailmap; -if ($email_remove_duplicates) { - open(my $mailmap, '<', "${lk_path}.mailmap") +# +# Read mail address map +# + +my $mailmap = read_mailmap(); + +sub read_mailmap { + my $mailmap = { + names => {}, + addresses => {} + }; + + if (!$email_remove_duplicates) { + return $mailmap; + } + + open(my $mailmap_file, '<', "${lk_path}.mailmap") or warn "$P: Can't open .mailmap: $!\n"; - while (<$mailmap>) { - my $line = $_; - next if ($line =~ m/^\s*#/); - next if ($line =~ m/^\s*$/); + while (<$mailmap_file>) { + s/#.*$//; #strip comments + s/^\s+|\s+$//g; #trim - my ($name, $address) = parse_email($line); - $line = format_email($name, $address, $email_usename); + next if (/^\s*$/); #skip empty lines + #entries have one of the following formats: + # name1 + # + # name1 + # name1 name2 + # (see man git-shortlog) + if (/^(.+)<(.+)>$/) { + my $real_name = $1; + my $address = $2; - next if ($line =~ m/^\s*$/); + $real_name =~ s/\s+$//; + $mailmap->{names}->{$address} = $real_name; - if (exists($mailmap{$name})) { - my $obj = $mailmap{$name}; - push(@$obj, $address); - } else { - my @arr = ($address); - $mailmap{$name} = \@arr; + } elsif (/^<([^\s]+)>\s*<([^\s]+)>$/) { + my $real_address = $1; + my $wrong_address = $2; + + $mailmap->{addresses}->{$wrong_address} = $real_address; + + } elsif (/^(.+)<([^\s]+)>\s*<([^\s]+)>$/) { + my $real_name= $1; + my $real_address = $2; + my $wrong_address = $3; + + $real_name =~ s/\s+$//; + + $mailmap->{names}->{$wrong_address} = $real_name; + $mailmap->{addresses}->{$wrong_address} = $real_address; + + } elsif (/^(.+)<([^\s]+)>\s*([^\s].*)<([^\s]+)>$/) { + my $real_name = $1; + my $real_address = $2; + my $wrong_name = $3; + my $wrong_address = $4; + + $real_name =~ s/\s+$//; + $wrong_name =~ s/\s+$//; + + $mailmap->{names}->{format_email($wrong_name,$wrong_address,1)} = $real_name; + $mailmap->{addresses}->{format_email($wrong_name,$wrong_address,1)} = $real_address; } } - close($mailmap); + close($mailmap_file); + + return $mailmap; } ## use the filenames on the command line or find the filenames in the patchfiles @@ -1061,30 +1106,58 @@ sub which_conf { return ""; } -sub mailmap { - my (@lines) = @_; - my %hash; +sub mailmap_email { + my $line = shift; - foreach my $line (@lines) { my ($name, $address) = parse_email($line); - if (!exists($hash{$name})) { - $hash{$name} = $address; - } elsif ($address ne $hash{$name}) { - $address = $hash{$name}; - $line = format_email($name, $address, $email_usename); - } - if (exists($mailmap{$name})) { - my $obj = $mailmap{$name}; - foreach my $map_address (@$obj) { - if (($map_address eq $address) && - ($map_address ne $hash{$name})) { - $line = format_email($name, $hash{$name}, $email_usename); + my $email = format_email($name, $address, 1); + my $real_name = $name; + my $real_address = $address; + + if (exists $mailmap->{names}->{$email} || exists $mailmap->{addresses}->{$email}) { + if (exists $mailmap->{names}->{$email}) { + $real_name = $mailmap->{names}->{$email}; + } + if (exists $mailmap->{addresses}->{$email}) { + $real_address = $mailmap->{addresses}->{$email}; + } + } else { + if (exists $mailmap->{names}->{$address}) { + $real_name = $mailmap->{names}->{$address}; + } + if (exists $mailmap->{addresses}->{$address}) { + $real_address = $mailmap->{addresses}->{$address}; } - } } + return format_email($real_name, $real_address, 1); +} + +sub mailmap { + my (@addresses) = @_; + + my @ret = (); + foreach my $line (@addresses) { + push(@ret, mailmap_email($line), 1); } - return @lines; + merge_by_realname(@ret) if $email_remove_duplicates; + + return @ret; +} + +sub merge_by_realname { + my %address_map; + my (@emails) = @_; + foreach my $email (@emails) { + my ($name, $address) = parse_email($email); + if (!exists $address_map{$name}) { + $address_map{$name} = $address; + } else { + $address = $address_map{$name}; + $email = format_email($name,$address,1); + } + } + } sub git_execute_cmd { @@ -1636,9 +1709,7 @@ sub vcs_assign { $divisor = 1; } - if ($email_remove_duplicates) { - @lines = mailmap(@lines); - } + @lines = mailmap(@lines); return if (@lines <= 0); -- cgit v1.2.3 From 47abc7225761faf28be52b3ac4dc26ffeac7b750 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 26 Oct 2010 14:22:57 -0700 Subject: scripts/get_maintainer.pl: correct indentation in a few places And a miscellaneous conversion of You to you in a help message Signed-off-by: Joe Perches Cc: Florian Mickler Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 156 +++++++++++++++++++++++----------------------- 1 file changed, 78 insertions(+), 78 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index faeace4e1fd0..0abfdbc5cdff 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -306,7 +306,7 @@ sub read_mailmap { my $mailmap = { names => {}, addresses => {} - }; + }; if (!$email_remove_duplicates) { return $mailmap; @@ -327,39 +327,39 @@ sub read_mailmap { # name1 name2 # (see man git-shortlog) if (/^(.+)<(.+)>$/) { - my $real_name = $1; - my $address = $2; + my $real_name = $1; + my $address = $2; - $real_name =~ s/\s+$//; - $mailmap->{names}->{$address} = $real_name; + $real_name =~ s/\s+$//; + $mailmap->{names}->{$address} = $real_name; } elsif (/^<([^\s]+)>\s*<([^\s]+)>$/) { - my $real_address = $1; - my $wrong_address = $2; + my $real_address = $1; + my $wrong_address = $2; - $mailmap->{addresses}->{$wrong_address} = $real_address; + $mailmap->{addresses}->{$wrong_address} = $real_address; } elsif (/^(.+)<([^\s]+)>\s*<([^\s]+)>$/) { - my $real_name= $1; - my $real_address = $2; - my $wrong_address = $3; + my $real_name= $1; + my $real_address = $2; + my $wrong_address = $3; - $real_name =~ s/\s+$//; + $real_name =~ s/\s+$//; - $mailmap->{names}->{$wrong_address} = $real_name; - $mailmap->{addresses}->{$wrong_address} = $real_address; + $mailmap->{names}->{$wrong_address} = $real_name; + $mailmap->{addresses}->{$wrong_address} = $real_address; } elsif (/^(.+)<([^\s]+)>\s*([^\s].*)<([^\s]+)>$/) { - my $real_name = $1; - my $real_address = $2; - my $wrong_name = $3; - my $wrong_address = $4; + my $real_name = $1; + my $real_address = $2; + my $wrong_name = $3; + my $wrong_address = $4; - $real_name =~ s/\s+$//; - $wrong_name =~ s/\s+$//; + $real_name =~ s/\s+$//; + $wrong_name =~ s/\s+$//; - $mailmap->{names}->{format_email($wrong_name,$wrong_address,1)} = $real_name; - $mailmap->{addresses}->{format_email($wrong_name,$wrong_address,1)} = $real_address; + $mailmap->{names}->{format_email($wrong_name,$wrong_address,1)} = $real_name; + $mailmap->{addresses}->{format_email($wrong_name,$wrong_address,1)} = $real_address; } } close($mailmap_file); @@ -743,30 +743,30 @@ EOT } sub top_of_kernel_tree { - my ($lk_path) = @_; + my ($lk_path) = @_; - if ($lk_path ne "" && substr($lk_path,length($lk_path)-1,1) ne "/") { - $lk_path .= "/"; - } - if ( (-f "${lk_path}COPYING") - && (-f "${lk_path}CREDITS") - && (-f "${lk_path}Kbuild") - && (-f "${lk_path}MAINTAINERS") - && (-f "${lk_path}Makefile") - && (-f "${lk_path}README") - && (-d "${lk_path}Documentation") - && (-d "${lk_path}arch") - && (-d "${lk_path}include") - && (-d "${lk_path}drivers") - && (-d "${lk_path}fs") - && (-d "${lk_path}init") - && (-d "${lk_path}ipc") - && (-d "${lk_path}kernel") - && (-d "${lk_path}lib") - && (-d "${lk_path}scripts")) { - return 1; - } - return 0; + if ($lk_path ne "" && substr($lk_path,length($lk_path)-1,1) ne "/") { + $lk_path .= "/"; + } + if ( (-f "${lk_path}COPYING") + && (-f "${lk_path}CREDITS") + && (-f "${lk_path}Kbuild") + && (-f "${lk_path}MAINTAINERS") + && (-f "${lk_path}Makefile") + && (-f "${lk_path}README") + && (-d "${lk_path}Documentation") + && (-d "${lk_path}arch") + && (-d "${lk_path}include") + && (-d "${lk_path}drivers") + && (-d "${lk_path}fs") + && (-d "${lk_path}init") + && (-d "${lk_path}ipc") + && (-d "${lk_path}kernel") + && (-d "${lk_path}lib") + && (-d "${lk_path}scripts")) { + return 1; + } + return 0; } sub parse_email { @@ -1107,29 +1107,30 @@ sub which_conf { } sub mailmap_email { - my $line = shift; + my $line = shift; - my ($name, $address) = parse_email($line); - my $email = format_email($name, $address, 1); - my $real_name = $name; - my $real_address = $address; - - if (exists $mailmap->{names}->{$email} || exists $mailmap->{addresses}->{$email}) { - if (exists $mailmap->{names}->{$email}) { - $real_name = $mailmap->{names}->{$email}; - } - if (exists $mailmap->{addresses}->{$email}) { - $real_address = $mailmap->{addresses}->{$email}; - } - } else { - if (exists $mailmap->{names}->{$address}) { - $real_name = $mailmap->{names}->{$address}; - } - if (exists $mailmap->{addresses}->{$address}) { - $real_address = $mailmap->{addresses}->{$address}; - } + my ($name, $address) = parse_email($line); + my $email = format_email($name, $address, 1); + my $real_name = $name; + my $real_address = $address; + + if (exists $mailmap->{names}->{$email} || + exists $mailmap->{addresses}->{$email}) { + if (exists $mailmap->{names}->{$email}) { + $real_name = $mailmap->{names}->{$email}; + } + if (exists $mailmap->{addresses}->{$email}) { + $real_address = $mailmap->{addresses}->{$email}; + } + } else { + if (exists $mailmap->{names}->{$address}) { + $real_name = $mailmap->{names}->{$address}; + } + if (exists $mailmap->{addresses}->{$address}) { + $real_address = $mailmap->{addresses}->{$address}; } - return format_email($real_name, $real_address, 1); + } + return format_email($real_name, $real_address, 1); } sub mailmap { @@ -1146,18 +1147,17 @@ sub mailmap { } sub merge_by_realname { - my %address_map; - my (@emails) = @_; - foreach my $email (@emails) { - my ($name, $address) = parse_email($email); - if (!exists $address_map{$name}) { - $address_map{$name} = $address; - } else { - $address = $address_map{$name}; - $email = format_email($name,$address,1); - } + my %address_map; + my (@emails) = @_; + foreach my $email (@emails) { + my ($name, $address) = parse_email($email); + if (!exists $address_map{$name}) { + $address_map{$name} = $address; + } else { + $address = $address_map{$name}; + $email = format_email($name,$address,1); } - + } } sub git_execute_cmd { @@ -1555,7 +1555,7 @@ commit signers and mailing lists that could be CC'd on a patch. Any *'d entry is selected. -If you have git or hg installed, You can choose to summarize the commit +If you have git or hg installed, you can choose to summarize the commit history of files in the patch. Also, each line of the current file can be matched to its commit author and that commits signers with blame. -- cgit v1.2.3 From b9e2331dd1e0e04f7f2a6f8aa0c05bac2a7f0d7b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 26 Oct 2010 14:22:58 -0700 Subject: scripts/get_maintainer.pl: use mailmap in name deduplication and other updates Use Florian Mickler's mailmap routine to reduce name duplication. o Add subroutine deduplicate_email to centralize code o Add hashes for deduplicate_(name|address)_hash o Remove now unused @interactive_to o Whitespace neatening o Add command line --help text o Add --mailmap command line option control o Interactive changes: - Add toggles for maintainer, git and list selections - Default selection is all - Add mailmap control Update to 0.26-beta5 Signed-off-by: Joe Perches Cc: Florian Mickler Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 232 +++++++++++++++++++++++++++++----------------- 1 file changed, 148 insertions(+), 84 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 0abfdbc5cdff..e822518bc610 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -13,7 +13,7 @@ use strict; my $P = $0; -my $V = '0.26-beta4'; +my $V = '0.26-beta5'; use Getopt::Long qw(:config no_auto_abbrev); @@ -36,6 +36,7 @@ my $email_git_since = "1-year-ago"; my $email_hg_since = "-365"; my $interactive = 0; my $email_remove_duplicates = 1; +my $email_use_mailmap = 1; my $output_multiline = 1; my $output_separator = ", "; my $output_roles = 0; @@ -192,6 +193,7 @@ if (!GetOptions( 'hg-since=s' => \$email_hg_since, 'i|interactive!' => \$interactive, 'remove-duplicates!' => \$email_remove_duplicates, + 'mailmap!' => \$email_use_mailmap, 'm!' => \$email_maintainer, 'n!' => \$email_usename, 'l!' => \$email_list, @@ -300,17 +302,17 @@ close($maint); # Read mail address map # -my $mailmap = read_mailmap(); +my $mailmap; + +read_mailmap(); sub read_mailmap { - my $mailmap = { + $mailmap = { names => {}, addresses => {} }; - if (!$email_remove_duplicates) { - return $mailmap; - } + return if (!$email_use_mailmap || !(-f "${lk_path}.mailmap")); open(my $mailmap_file, '<', "${lk_path}.mailmap") or warn "$P: Can't open .mailmap: $!\n"; @@ -331,6 +333,7 @@ sub read_mailmap { my $address = $2; $real_name =~ s/\s+$//; + ($real_name, $address) = parse_email("$real_name <$address>"); $mailmap->{names}->{$address} = $real_name; } elsif (/^<([^\s]+)>\s*<([^\s]+)>$/) { @@ -340,12 +343,13 @@ sub read_mailmap { $mailmap->{addresses}->{$wrong_address} = $real_address; } elsif (/^(.+)<([^\s]+)>\s*<([^\s]+)>$/) { - my $real_name= $1; + my $real_name = $1; my $real_address = $2; my $wrong_address = $3; $real_name =~ s/\s+$//; - + ($real_name, $real_address) = + parse_email("$real_name <$real_address>"); $mailmap->{names}->{$wrong_address} = $real_name; $mailmap->{addresses}->{$wrong_address} = $real_address; @@ -356,15 +360,19 @@ sub read_mailmap { my $wrong_address = $4; $real_name =~ s/\s+$//; + ($real_name, $real_address) = + parse_email("$real_name <$real_address>"); + $wrong_name =~ s/\s+$//; + ($wrong_name, $wrong_address) = + parse_email("$wrong_name <$wrong_address>"); - $mailmap->{names}->{format_email($wrong_name,$wrong_address,1)} = $real_name; - $mailmap->{addresses}->{format_email($wrong_name,$wrong_address,1)} = $real_address; + my $wrong_email = format_email($wrong_name, $wrong_address, 1); + $mailmap->{names}->{$wrong_email} = $real_name; + $mailmap->{addresses}->{$wrong_email} = $real_address; } } close($mailmap_file); - - return $mailmap; } ## use the filenames on the command line or find the filenames in the patchfiles @@ -453,7 +461,8 @@ my @scm = (); my @web = (); my @subsystem = (); my @status = (); -my @interactive_to = (); +my %deduplicate_name_hash = (); +my %deduplicate_address_hash = (); my $signature_pattern; my @maintainers = get_maintainers(); @@ -497,7 +506,8 @@ sub get_maintainers { @web = (); @subsystem = (); @status = (); - @interactive_to = (); + %deduplicate_name_hash = (); + %deduplicate_address_hash = (); if ($email_git_all_signature_types) { $signature_pattern = "(.+?)[Bb][Yy]:"; } else { @@ -506,7 +516,7 @@ sub get_maintainers { # Find responsible parties - my %exact_pattern_match_hash; + my %exact_pattern_match_hash = (); foreach my $file (@files) { @@ -590,7 +600,9 @@ sub get_maintainers { } } - @interactive_to = (@email_to, @list_to); + foreach my $email (@email_to, @list_to) { + $email->[0] = deduplicate_email($email->[0]); + } foreach my $file (@files) { if ($email && @@ -637,8 +649,7 @@ sub get_maintainers { } if ($interactive) { - @interactive_to = @to; - @to = interactive_get_maintainers(\@interactive_to); + @to = interactive_get_maintainers(\@to); } return @to; @@ -702,8 +713,9 @@ Output type options: Other options: --pattern-depth => Number of pattern directory traversals (default: 0 (all)) - --keywords => scan patch for keywords (default: 1 (on)) - --sections => print the entire subsystem sections with pattern matches + --keywords => scan patch for keywords (default: $keywords) + --sections => print all of the subsystem sections with pattern matches + --mailmap => use .mailmap file (default: $email_use_mailmap) --version => show version --help => show this help information @@ -1107,7 +1119,7 @@ sub which_conf { } sub mailmap_email { - my $line = shift; + my ($line) = @_; my ($name, $address) = parse_email($line); my $email = format_email($name, $address, 1); @@ -1136,26 +1148,25 @@ sub mailmap_email { sub mailmap { my (@addresses) = @_; - my @ret = (); + my @mapped_emails = (); foreach my $line (@addresses) { - push(@ret, mailmap_email($line), 1); + push(@mapped_emails, mailmap_email($line)); } - - merge_by_realname(@ret) if $email_remove_duplicates; - - return @ret; + merge_by_realname(@mapped_emails) if ($email_use_mailmap); + return @mapped_emails; } sub merge_by_realname { my %address_map; my (@emails) = @_; + foreach my $email (@emails) { my ($name, $address) = parse_email($email); - if (!exists $address_map{$name}) { - $address_map{$name} = $address; - } else { + if (exists $address_map{$name}) { $address = $address_map{$name}; - $email = format_email($name,$address,1); + $email = format_email($name, $address, 1); + } else { + $address_map{$name} = $address; } } } @@ -1194,8 +1205,7 @@ sub extract_formatted_signatures { ## Reformat email addresses (with names) to avoid badly written signatures foreach my $signer (@signature_lines) { - my ($name, $address) = parse_email($signer); - $signer = format_email($name, $address, 1); + $signer = deduplicate_email($signer); } return (\@type, \@signature_lines); @@ -1339,6 +1349,7 @@ sub vcs_exists { } sub vcs_is_git { + vcs_exists(); return $vcs_used == 1; } @@ -1357,11 +1368,9 @@ sub interactive_get_maintainers { my %signed; my $count = 0; my $maintained = 0; - #select maintainers by default foreach my $entry (@list) { - my $role = $entry->[1]; - $selected{$count} = ($role =~ /^(maintainer|supporter|open list)/i); - $maintained = 1 if ($role =~ /^(maintainer|supporter)/i); + $maintained = 1 if ($entry->[1] =~ /^(maintainer|supporter)/i); + $selected{$count} = 1; $authored{$count} = 0; $signed{$count} = 0; $count++; @@ -1418,24 +1427,34 @@ sub interactive_get_maintainers { if ($print_options) { $print_options = 0; if (vcs_exists()) { - print STDERR -"\nVersion Control options:\n" . -"g use git history [$email_git]\n" . -"gf use git-fallback [$email_git_fallback]\n" . -"b use git blame [$email_git_blame]\n" . -"bs use blame signatures [$email_git_blame_signatures]\n" . -"c# minimum commits [$email_git_min_signatures]\n" . -"%# min percent [$email_git_min_percent]\n" . -"d# history to use [$$date_ref]\n" . -"x# max maintainers [$email_git_max_maintainers]\n" . -"t all signature types [$email_git_all_signature_types]\n"; + print STDERR <[1] =~ /^(maintainer|supporter)/i); + } + } elsif (lc($str) eq "g") { + for (my $i = 0; $i < $count; $i++) { + $selected{$i} = !$selected{$i} + if ($list[$i]->[1] =~ /^(author|commit|signer)/i); + } + } elsif (lc($str) eq "l") { + for (my $i = 0; $i < $count; $i++) { + $selected{$i} = !$selected{$i} + if ($list[$i]->[1] =~ /^(open list)/i); + } + } elsif (lc($str) eq "s") { + for (my $i = 0; $i < $count; $i++) { + $selected{$i} = !$selected{$i} + if ($list[$i]->[1] =~ /^(subscriber list)/i); + } + } } elsif ($sel eq "a") { if ($val > 0 && $val <= $count) { $authored{$val - 1} = !$authored{$val - 1}; @@ -1539,6 +1580,10 @@ sub interactive_get_maintainers { } elsif ($sel eq "r") { bool_invert(\$email_remove_duplicates); $rerun = 1; + } elsif ($sel eq "m") { + bool_invert(\$email_use_mailmap); + read_mailmap(); + $rerun = 1; } elsif ($sel eq "k") { bool_invert(\$keywords); $rerun = 1; @@ -1602,6 +1647,36 @@ sub bool_invert { } } +sub deduplicate_email { + my ($email) = @_; + + my $matched = 0; + my ($name, $address) = parse_email($email); + $email = format_email($name, $address, 1); + $email = mailmap_email($email); + + return $email if (!$email_remove_duplicates); + + ($name, $address) = parse_email($email); + + if ($deduplicate_name_hash{lc($name)}) { + $name = $deduplicate_name_hash{lc($name)}->[0]; + $address = $deduplicate_name_hash{lc($name)}->[1]; + $matched = 1; + } elsif ($deduplicate_address_hash{lc($address)}) { + $name = $deduplicate_address_hash{lc($address)}->[0]; + $address = $deduplicate_address_hash{lc($address)}->[1]; + $matched = 1; + } + if (!$matched) { + $deduplicate_name_hash{lc($name)} = [ $name, $address ]; + $deduplicate_address_hash{lc($address)} = [ $name, $address ]; + } + $email = format_email($name, $address, 1); + $email = mailmap_email($email); + return $email; +} + sub save_commits_by_author { my (@lines) = @_; @@ -1611,20 +1686,8 @@ sub save_commits_by_author { foreach my $line (@lines) { if ($line =~ m/$VCS_cmds{"author_pattern"}/) { - my $matched = 0; my $author = $1; - my ($name, $address) = parse_email($author); - foreach my $to (@interactive_to) { - my ($to_name, $to_address) = parse_email($to->[0]); - if ($email_remove_duplicates && - ((lc($name) eq lc($to_name)) || - (lc($address) eq lc($to_address)))) { - $author = $to->[0]; - $matched = 1; - last; - } - } - $author = format_email($name, $address, 1) if (!$matched); + $author = deduplicate_email($author); push(@authors, $author); } push(@commits, $1) if ($line =~ m/$VCS_cmds{"commit_pattern"}/); @@ -1665,19 +1728,7 @@ sub save_commits_by_signer { my $type = $types[0]; my $signer = $signers[0]; - my $matched = 0; - my ($name, $address) = parse_email($signer); - foreach my $to (@interactive_to) { - my ($to_name, $to_address) = parse_email($to->[0]); - if ($email_remove_duplicates && - ((lc($name) eq lc($to_name)) || - (lc($address) eq lc($to_address)))) { - $signer = $to->[0]; - $matched = 1; - last; - } - $signer = format_email($name, $address, 1) if (!$matched); - } + $signer = deduplicate_email($signer); my $exists = 0; foreach my $ref(@{$commit_signer_hash{$signer}}) { @@ -1751,6 +1802,11 @@ sub vcs_file_signoffs { $cmd =~ s/(\$\w+)/$1/eeg; # interpolate $cmd ($commits, @signers) = vcs_find_signers($cmd); + + foreach my $signer (@signers) { + $signer = deduplicate_email($signer); + } + vcs_assign("commit_signer", $commits, @signers); } @@ -1828,9 +1884,8 @@ sub vcs_file_blame { foreach my $line (@lines) { if ($line =~ m/$VCS_cmds{"author_pattern"}/) { my $author = $1; - my ($name, $address) = parse_email($author); - $author = format_email($name, $address, 1); - push(@authors, $1); + $author = deduplicate_email($author); + push(@authors, $author); } } @@ -1846,9 +1901,12 @@ sub vcs_file_blame { $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd my @author = vcs_find_author($cmd); next if !@author; + + my $formatted_author = deduplicate_email($author[0]); + my $count = grep(/$commit/, @all_commits); for ($i = 0; $i < $count ; $i++) { - push(@blame_signers, $author[0]); + push(@blame_signers, $formatted_author); } } } @@ -1856,8 +1914,14 @@ sub vcs_file_blame { vcs_assign("authored lines", $total_lines, @blame_signers); } } + foreach my $signer (@signers) { + $signer = deduplicate_email($signer); + } vcs_assign("commits", $total_commits, @signers); } else { + foreach my $signer (@signers) { + $signer = deduplicate_email($signer); + } vcs_assign("modified commits", $total_commits, @signers); } } -- cgit v1.2.3 From fae99206769b6bbf8a20ab883726b164945771d7 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 26 Oct 2010 14:22:58 -0700 Subject: scripts/get_maintainer.pl: don't deduplicate unnamed addresses ie: mailing lists Fix a defect with the first mailing list address being used for each subsequent mailing list. Updated to 0.26-beta6. Signed-off-by: Joe Perches Cc: Florian Mickler Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index e822518bc610..d21ec3a89603 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -13,7 +13,7 @@ use strict; my $P = $0; -my $V = '0.26-beta5'; +my $V = '0.26-beta6'; use Getopt::Long qw(:config no_auto_abbrev); @@ -1036,7 +1036,7 @@ sub push_email_address { push(@email_to, [format_email($name, $address, $email_usename), $role]); } elsif (!email_inuse($name, $address)) { push(@email_to, [format_email($name, $address, $email_usename), $role]); - $email_hash_name{lc($name)}++; + $email_hash_name{lc($name)}++ if ($name ne ""); $email_hash_address{lc($address)}++; } @@ -1659,7 +1659,7 @@ sub deduplicate_email { ($name, $address) = parse_email($email); - if ($deduplicate_name_hash{lc($name)}) { + if ($name ne "" && $deduplicate_name_hash{lc($name)}) { $name = $deduplicate_name_hash{lc($name)}->[0]; $address = $deduplicate_name_hash{lc($name)}->[1]; $matched = 1; -- cgit v1.2.3 From 6b4c5bebcebb0a48d29947e9aa749650751a7696 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Tue, 26 Oct 2010 14:23:11 -0700 Subject: checkpatch: fix regressions in "fix handling of leading spaces" The patch "checkpatch: fix handling of leading spaces" added checks for leading spaces on lines, but this introduces regressions. Firstly it does not correctly detect when we are in a comment. Secondly it does not allow for preprocessor command spacing. Finally it does not allow for label indentation which is required to be less than one tab. Fix these up: Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 2039acdf5122..0a87c7417ada 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1459,10 +1459,13 @@ sub process { } # check for spaces at the beginning of a line. - if ($rawline =~ /^\+ / && $rawline !~ /\+ +\*/) { +# Exceptions: +# 1) within comments +# 2) indented preprocessor commands +# 3) hanging labels + if ($rawline =~ /^\+ / && $line !~ /\+ *(?:$;|#|$Ident:)/) { my $herevet = "$here\n" . cat_vet($rawline) . "\n"; - WARN("please, no space for starting a line, \ - excluding comments\n" . $herevet); + WARN("please, no spaces at the start of a line\n" . $herevet); } # check we are in a valid C source file if not then ignore this hunk -- cgit v1.2.3 From e91b6e263ed6735c766cb14bbe63b9c7bd774526 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Tue, 26 Oct 2010 14:23:11 -0700 Subject: checkpatch: types may sit on a line on their own When the following form is used we have a type which fully fills a line. This means that a type may end at the end of line as well as at the following identifier. int ** foo; Reported-by: Daniel Walker Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 0a87c7417ada..41f59b1e209b 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -843,7 +843,7 @@ sub annotate_values { $av_preprocessor = 0; } - } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\()/) { + } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { print "DECLARE($1)\n" if ($dbg_values > 1); $type = 'T'; -- cgit v1.2.3 From d2c0a23514d8ac4ed10a8e742467cfb72ca3bed8 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Tue, 26 Oct 2010 14:23:12 -0700 Subject: checkpatch: suggest cleanpatch and cleanfile when appropriate When we hit types of whitespace which may be fixed by scripts/cleanpatch and scripts/cleanfile suggest their use in our report. Suggested-by: Bartlomiej Zolnierkiewicz Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 41f59b1e209b..32d6a236570d 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -103,6 +103,8 @@ for my $key (keys %debug) { die "$@" if ($@); } +my $rpt_cleaners = 0; + if ($terse) { $emacs = 1; $quiet++; @@ -1389,6 +1391,7 @@ sub process { } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { my $herevet = "$here\n" . cat_vet($rawline) . "\n"; ERROR("trailing whitespace\n" . $herevet); + $rpt_cleaners = 1; } # check for Kconfig help text having a real description @@ -1450,6 +1453,7 @@ sub process { $rawline =~ /^\+\s* \s*/) { my $herevet = "$here\n" . cat_vet($rawline) . "\n"; ERROR("code indent should use tabs where possible\n" . $herevet); + $rpt_cleaners = 1; } # check for space before tabs. @@ -2842,6 +2846,15 @@ sub process { print "\n" if ($quiet == 0); } + if ($quiet == 0) { + # If there were whitespace errors which cleanpatch can fix + # then suggest that. + if ($rpt_cleaners) { + print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n"; + print " scripts/cleanfile\n\n"; + } + } + if ($clean == 1 && $quiet == 0) { print "$vname has no obvious style problems and is ready for submission.\n" } -- cgit v1.2.3 From fb2d2c1b5825503d30fb6f2dc328dbe4a47d9794 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Tue, 26 Oct 2010 14:23:12 -0700 Subject: checkpatch: ensure we do not collapse bracketed sections into constants When determining if a return () sequence is a function style bracketing we simplify the expression one bracket at a time replacing each with a constant. However this can trigger a false merge with expressions as below: return (foo)0; Prevent this false merging. Reported-by: Hitoshi Mitake Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 32d6a236570d..8d010ac0efe1 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2183,15 +2183,16 @@ sub process { my $value = $2; # Flatten any parentheses - $value =~ s/\)\(/\) \(/g; + $value =~ s/\(/ \(/g; + $value =~ s/\)/\) /g; while ($value =~ s/\[[^\{\}]*\]/1/ || $value !~ /(?:$Ident|-?$Constant)\s* $Compare\s* (?:$Ident|-?$Constant)/x && $value =~ s/\([^\(\)]*\)/1/) { } - - if ($value =~ /^(?:$Ident|-?$Constant)$/) { +#print "value<$value>\n"; + if ($value =~ /^\s*(?:$Ident|-?$Constant)\s*$/) { ERROR("return is not a function, parentheses are not required\n" . $herecurr); } elsif ($spacing !~ /\s+/) { -- cgit v1.2.3 From 9446ef569c288e683225fec8337a0b2b81e75cc5 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Tue, 26 Oct 2010 14:23:13 -0700 Subject: checkpatch: handle casts better fixing false categorisation of : as binary The following incantation is triggering categorisation of its colon (:) as a binary form, which it is not: return foo ? (s8)bar : baz; Handle casts differently from types in the categoriser, allowing us to better track (s8)bar as a value and not a declaration. Reported-by: Jean Delvare Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 8d010ac0efe1..3cec2990d51e 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -845,6 +845,11 @@ sub annotate_values { $av_preprocessor = 0; } + } elsif ($cur =~ /^(\(\s*$Type\s*)\)/) { + print "CAST($1)\n" if ($dbg_values > 1); + push(@av_paren_type, $type); + $type = 'C'; + } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { print "DECLARE($1)\n" if ($dbg_values > 1); $type = 'T'; -- cgit v1.2.3 From 53a3c4487a05b8f26ef72fe434a750a3402c998f Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Tue, 26 Oct 2010 14:23:14 -0700 Subject: checkpatch: returning errno typically should be negative Add a (strict mode only) test to check for non-negative returns of what appear to be errno values as the majority case these should indeed be negative. Suggested-by: Andrew Morton Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 3cec2990d51e..bcdb54bd61a0 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2204,6 +2204,13 @@ sub process { ERROR("space required before the open parenthesis '('\n" . $herecurr); } } +# Return of what appears to be an errno should normally be -'ve + if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) { + my $name = $1; + if ($name ne 'EOF' && $name ne 'ERROR') { + WARN("return of an errno should typically be -ve (return -$1)\n" . $herecurr); + } + } # Need a space before open parenthesis after if, while etc if ($line=~/\b(if|while|for|switch)\(/) { -- cgit v1.2.3 From 8cf6de7145943caa38c56c61cd83b17687afd900 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Tue, 26 Oct 2010 14:23:14 -0700 Subject: checkpatch: add check for space after struct, union, and enum Add spacing checks for struct, union, and enum definitions. Check the spacing after type and before the equals (=) and open brace ({). Based on a patch by Joe Perches. Cc: Joe Perches Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index bcdb54bd61a0..983ac1816da0 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1905,6 +1905,16 @@ sub process { ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr); } +# missing space after union or struct definition + if ($rawline =~ /^\+\s*(union|struct)\s+$Ident[=\{]/) { + WARN("Missing space after struct or union definition\n" . $herecurr); + } + +# missing space after enum definition + if ($rawline =~ /^\+\s*enum\{/) { + WARN("Missing space after enum definition\n" . $herecurr); + } + # open braces for enum, union and struct go on the same line. if ($line =~ /^.\s*{/ && $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { -- cgit v1.2.3 From 0c73b4eb7a825a5aff16d8a9701f6c28056de058 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Tue, 26 Oct 2010 14:23:15 -0700 Subject: checkpatch: simplify and consolidate "missing space after" checks Commonise the code for missing spaces after struct, union, and enum such that they share the same code. Ensure we cover all the common cases in each case. Check against the sanitised line to ensure we do not report on comments and strings. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 983ac1816da0..cb19f54b4b2a 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1905,22 +1905,17 @@ sub process { ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr); } -# missing space after union or struct definition - if ($rawline =~ /^\+\s*(union|struct)\s+$Ident[=\{]/) { - WARN("Missing space after struct or union definition\n" . $herecurr); - } - -# missing space after enum definition - if ($rawline =~ /^\+\s*enum\{/) { - WARN("Missing space after enum definition\n" . $herecurr); - } - # open braces for enum, union and struct go on the same line. if ($line =~ /^.\s*{/ && $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { ERROR("open brace '{' following $1 go on the same line\n" . $hereprev); } +# missing space after union, struct or enum definition + if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?(?:\s+$Ident)?[=\{]/) { + WARN("missing space after $1 definition\n" . $herecurr); + } + # check for spacing round square brackets; allowed: # 1. with a type on the left -- int [] a; # 2. at the beginning of a line for slice initialisers -- [0...10] = 5, -- cgit v1.2.3 From 9fe287d79b0af983050d24e7916cf3d1f019f553 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Tue, 26 Oct 2010 14:23:15 -0700 Subject: checkpatch: ensure kconfig help checks only apply when we are adding help When checking the length of the help we need to be sure we are seeing the whole story before erroring. Firstly we only want to check when adding the help in the first place. Second we need to be sure that we are seeing the end of the entry, nominally when there is no context below or that context shows the start of the next entry. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index cb19f54b4b2a..e44ff91e811d 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1400,18 +1400,34 @@ sub process { } # check for Kconfig help text having a real description +# Only applies when adding the entry originally, after that we do not have +# sufficient context to determine whether it is indeed long enough. if ($realfile =~ /Kconfig/ && - $line =~ /\+?\s*(---)?help(---)?$/) { + $line =~ /\+\s*(?:---)?help(?:---)?$/) { my $length = 0; - for (my $l = $linenr; defined($lines[$l]); $l++) { - my $f = $lines[$l]; + my $cnt = $realcnt; + my $ln = $linenr + 1; + my $f; + my $is_end = 0; + while ($cnt > 0 && defined $lines[$ln - 1]) { + $f = $lines[$ln - 1]; + $cnt-- if ($lines[$ln - 1] !~ /^-/); + $is_end = $lines[$ln - 1] =~ /^\+/; + $ln++; + + next if ($f =~ /^-/); + $f =~ s/^.//; $f =~ s/#.*//; $f =~ s/^\s+//; next if ($f =~ /^$/); - last if ($f =~ /^\s*config\s/); + if ($f =~ /^\s*config\s/) { + $is_end = 1; + last; + } $length++; } - WARN("please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($length < 4); + WARN("please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_end && $length < 4); + #print "is_end<$is_end> length<$length>\n"; } # check we are in a valid source file if not then ignore this hunk -- cgit v1.2.3 From 3bf9a009fccea422bc355414a3bdf5f35fff9f36 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Tue, 26 Oct 2010 14:23:16 -0700 Subject: checkpatch: check for incorrect permissions Throw an error when a source file has been given execute permissions using the mode change line present in git diffs. Also alow the filename matching to use the "diff" line in addition to the "+++" line, since the mode change lines appear before any "+++" lines. [apw@canonical.com: simplified filename logic slightly, added tests] Cc: Andy Whitcroft Acked-by: Linus Walleij Signed-off-by: Rabin Vincent Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index e44ff91e811d..93fa145671a0 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1315,7 +1315,11 @@ sub process { $here = "#$realline: " if ($file); # extract the filename as it passes - if ($line=~/^\+\+\+\s+(\S+)/) { + if ($line =~ /^diff --git.*?(\S+)$/) { + $realfile = $1; + $realfile =~ s@^([^/]*)/@@; + + } elsif ($line =~ /^\+\+\+\s+(\S+)/) { $realfile = $1; $realfile =~ s@^([^/]*)/@@; @@ -1339,6 +1343,14 @@ sub process { $cnt_lines++ if ($realcnt != 0); +# Check for incorrect file permissions + if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { + my $permhere = $here . "FILE: $realfile\n"; + if ($realfile =~ /(Makefile|Kconfig|\.c|\.h|\.S|\.tmpl)$/) { + ERROR("do not set execute permissions for source files\n" . $permhere); + } + } + #check the patch for a signoff: if ($line =~ /^\s*signed-off-by:/i) { # This is a signoff, if ugly, so do not double report. -- cgit v1.2.3 From 03f1df7da5696ddfa6e167b37e0c0ce5aad3de79 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 26 Oct 2010 14:23:16 -0700 Subject: checkpatch: Add additional attribute #defines On Wed, 2010-08-11 at 12:35 -0400, Dave Jones wrote: > I just got this from a patch I merged.. > > ERROR: need consistent spacing around '*' (ctx:WxV) > #121: FILE: arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c:113: > +static struct pcc_cpu __percpu *pcc_cpu_info; > ^ > which doesn't seem right. Perhaps these need to be added to checkpatch. [apw@canonical.com: added tests] Signed-off-by: Joe Perches Signed-off-by: Andy Whitcroft Cc: Dave Jones Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 93fa145671a0..c151c9e142ad 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -152,6 +152,20 @@ our $Sparse = qr{ # We need \b after 'init' otherwise 'initconst' will cause a false positive in a check our $Attribute = qr{ const| + __percpu| + __nocast| + __safe| + __bitwise__| + __packed__| + __packed2__| + __naked| + __maybe_unused| + __always_unused| + __noreturn| + __used| + __cold| + __noclone| + __deprecated| __read_mostly| __kprobes| __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)| -- cgit v1.2.3 From 015830be9779aeae7de7060b07a3157a8e41bcb4 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Tue, 26 Oct 2010 14:23:17 -0700 Subject: checkpatch: update copyright dates Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index c151c9e142ad..53b2eaecba0c 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2,7 +2,7 @@ # (c) 2001, Dave Jones. (the file handling bit) # (c) 2005, Joel Schopp (the ugly bit) # (c) 2007,2008, Andy Whitcroft (new conditions, test suite) -# (c) 2008,2009, Andy Whitcroft +# (c) 2008-2010 Andy Whitcroft # Licensed under the terms of the GNU GPL License version 2 use strict; -- cgit v1.2.3 From 5eaa20b984eb316533b4a098d8de3912e434df6a Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Tue, 26 Oct 2010 14:23:18 -0700 Subject: checkpatch: clean up structure definition macro handline Handle definitions such as the following correctly, it is not a complex statement: #define PREALLOC(NAME, START, END, FLAGS) { \ .name = (NAME), \ .start = (START), \ .end = (END), \ .flags = (FLAGS) \ }, Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 53b2eaecba0c..d5361e49abad 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2476,8 +2476,8 @@ sub process { \.$Ident\s*=\s*| ^\"|\"$ }x; - #print "REST<$rest> dstat<$dstat>\n"; - if ($rest ne '') { + #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; + if ($rest ne '' && $rest ne ',') { if ($rest !~ /while\s*\(/ && $dstat !~ /$exceptions/) { -- cgit v1.2.3 From 3cbf62df3a8ce61cb1aa20b7dae964058988bfdd Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Tue, 26 Oct 2010 14:23:18 -0700 Subject: checkpatch: handle EXPORT_SYMBOL for DEVICE_ATTR and similar Handly definitions similar to below. The definition macro spits out a symbol with a prefix. Add matching of any identifier prefix: DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, ata_scsi_lpm_show, ata_scsi_lpm_put); EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy); Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index d5361e49abad..8ab45b72b396 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1822,8 +1822,17 @@ sub process { !defined $suppress_export{$realline_next} && ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { + # Handle definitions which produce identifiers with + # a prefix: + # XXX(foo); + # EXPORT_SYMBOL(something_foo); my $name = $1; - if ($stat !~ /(?: + if ($stat =~ /^.([A-Z_]+)\s*\(\s*($Ident)/ && + $name =~ /^${Ident}_$2/) { +#print "FOO C name<$name>\n"; + $suppress_export{$realline_next} = 1; + + } elsif ($stat !~ /(?: \n.}\s*$| ^.DEFINE_$Ident\(\Q$name\E\)| ^.DECLARE_$Ident\(\Q$name\E\)| -- cgit v1.2.3 From 01464f30a97c5c30bf9633309b27cce055cef8fd Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Tue, 26 Oct 2010 14:23:19 -0700 Subject: checkpatch: statement/block context analyser should look at sanitised lines When tracking context to find a block or statement we need to use the sanitised lines, else perentheses '(' & ')' and braces '{' & '}' can throw the scanner out. Also fix up a couple of error outputs which include those sanitised lines incorrectly. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 8ab45b72b396..d086ffe377d5 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -691,15 +691,15 @@ sub ctx_block_get { $blk .= $rawlines[$line]; # Handle nested #if/#else. - if ($rawlines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { + if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { push(@stack, $level); - } elsif ($rawlines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { + } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { $level = $stack[$#stack - 1]; - } elsif ($rawlines[$line] =~ /^.\s*#\s*endif\b/) { + } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { $level = pop(@stack); } - foreach my $c (split(//, $rawlines[$line])) { + foreach my $c (split(//, $lines[$line])) { ##print "C<$c>L<$level><$open$close>O<$off>\n"; if ($off > 0) { $off--; @@ -1652,7 +1652,7 @@ sub process { if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { ERROR("that open brace { should be on the previous line\n" . - "$here\n$ctx\n$lines[$ctx_ln - 1]\n"); + "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); } if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && $ctx =~ /\)\s*\;\s*$/ && @@ -1661,7 +1661,7 @@ sub process { my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); if ($nindent > $indent) { WARN("trailing semicolon indicates no statements, indent implies otherwise\n" . - "$here\n$ctx\n$lines[$ctx_ln - 1]\n"); + "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); } } } -- cgit v1.2.3 From 267ad8f42644c2fa4ff6c2e7596d2b02c7397c85 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Tue, 26 Oct 2010 14:23:19 -0700 Subject: checkpatch: version 0.31 Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index d086ffe377d5..c1e7fb3eab44 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -10,7 +10,7 @@ use strict; my $P = $0; $P =~ s@.*/@@g; -my $V = '0.30'; +my $V = '0.31'; use Getopt::Long qw(:config no_auto_abbrev); -- cgit v1.2.3 From cb710eca6820493add0ddd3d7e8e3ee53f2b6e57 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 26 Oct 2010 14:23:20 -0700 Subject: scripts/checkpatch.pl: add warnings for static char that could be static const char Add warnings for possible missing const uses of static char foo[] = "bar" that could be static const char foo[] = "bar" and static const char *foo[] = {"bar", "baz"} that could be static const char * const foo[] = {"bar", "baz"} Signed-off-by: Joe Perches Cc: Mike Frysinger Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index c1e7fb3eab44..2ec5fc6a4046 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1869,6 +1869,18 @@ sub process { $herecurr); } +# check for static const char * arrays. + if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { + WARN("static const char * array should probably be static const char * const\n" . + $herecurr); + } + +# check for static char foo[] = "bar" declarations. + if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { + WARN("static char array declaration should probably be static const char\n" . + $herecurr); + } + # check for new typedefs, only function parameters and sparse annotations # make sense. if ($line =~ /\btypedef\s/ && -- cgit v1.2.3 From 93ed0e2d07b25aff4db1d61bfbcd1e82074c0ad5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 26 Oct 2010 14:23:21 -0700 Subject: scripts/checkpatch.pl: add check for declaration of pci_device_id Signed-off-by: Joe Perches Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 2ec5fc6a4046..90b54d4697fd 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1881,6 +1881,11 @@ sub process { $herecurr); } +# check for declarations of struct pci_device_id + if ($line =~ /\bstruct\s+pci_device_id\s+\w+\s*\[\s*\]\s*\=\s*\{/) { + WARN("Use DEFINE_PCI_DEVICE_TABLE for struct pci_device_id\n" . $herecurr); + } + # check for new typedefs, only function parameters and sparse annotations # make sense. if ($line =~ /\btypedef\s/ && -- cgit v1.2.3 From c25f415751c0c5507561d997fe5f7f05f4342912 Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Wed, 27 Oct 2010 12:42:00 -0700 Subject: scripts/namespace.pl: fix wrong source path File::Find will do chdir automatically, so we need to get the absolute patch with $File::Find::dir. Reported-by: Stephen Hemminger Signed-off-by: Amerigo Wang Cc: Michal Marek Signed-off-by: Andrew Morton Signed-off-by: Michal Marek --- scripts/namespace.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/namespace.pl b/scripts/namespace.pl index 361d0f71184b..fb4e24560736 100755 --- a/scripts/namespace.pl +++ b/scripts/namespace.pl @@ -167,11 +167,11 @@ sub do_nm printf STDERR "$fullname is not an object file\n"; return; } - ($source = $fullname) =~ s/\.o$//; - if (-e "$objtree$source.c" || -e "$objtree$source.S") { - $source = "$objtree$source"; + ($source = $basename) =~ s/\.o$//; + if (-e "$source.c" || -e "$source.S") { + $source = "$objtree$File::Find::dir/$source"; } else { - $source = "$srctree$source"; + $source = "$srctree$File::Find::dir/$source"; } if (! -e "$source.c" && ! -e "$source.S") { # No obvious source, exclude the object if it is conglomerate -- cgit v1.2.3 From 43f683c9e465a64259c6058a7c313facc697b203 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 27 Oct 2010 12:42:00 -0700 Subject: scripts/namespace.pl: update file exclusion list Signed-off-by: Stephen Hemminger Signed-off-by: Amerigo Wang Cc: Michal Marek Signed-off-by: Andrew Morton Signed-off-by: Michal Marek --- scripts/namespace.pl | 103 ++++++++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 47 deletions(-) (limited to 'scripts') diff --git a/scripts/namespace.pl b/scripts/namespace.pl index fb4e24560736..c8d0922c3b4f 100755 --- a/scripts/namespace.pl +++ b/scripts/namespace.pl @@ -84,6 +84,58 @@ my %ksymtab = (); # names that appear in __ksymtab_ my %ref = (); # $ref{$name} exists if there is a true external reference to $name my %export = (); # $export{$name} exists if there is an EXPORT_... of $name +my %nmexception = ( + 'fs/ext3/bitmap' => 1, + 'fs/ext4/bitmap' => 1, + 'arch/x86/lib/thunk_32' => 1, + 'arch/x86/lib/cmpxchg' => 1, + 'arch/x86/vdso/vdso32/note' => 1, + 'lib/irq_regs' => 1, + 'usr/initramfs_data' => 1, + 'drivers/scsi/aic94xx/aic94xx_dump' => 1, + 'drivers/scsi/libsas/sas_dump' => 1, + 'lib/dec_and_lock' => 1, + 'drivers/ide/ide-probe-mini' => 1, + 'usr/initramfs_data' => 1, + 'drivers/acpi/acpia/exdump' => 1, + 'drivers/acpi/acpia/rsdump' => 1, + 'drivers/acpi/acpia/nsdumpdv' => 1, + 'drivers/acpi/acpia/nsdump' => 1, + 'arch/ia64/sn/kernel/sn2/io' => 1, + 'arch/ia64/kernel/gate-data' => 1, + 'security/capability' => 1, + 'fs/ntfs/sysctl' => 1, + 'fs/jfs/jfs_debug' => 1, +); + +my %nameexception = ( + 'mod_use_count_' => 1, + '__initramfs_end' => 1, + '__initramfs_start' => 1, + '_einittext' => 1, + '_sinittext' => 1, + 'kallsyms_names' => 1, + 'kallsyms_num_syms' => 1, + 'kallsyms_addresses'=> 1, + '__this_module' => 1, + '_etext' => 1, + '_edata' => 1, + '_end' => 1, + '__bss_start' => 1, + '_text' => 1, + '_stext' => 1, + '__gp' => 1, + 'ia64_unw_start' => 1, + 'ia64_unw_end' => 1, + '__init_begin' => 1, + '__init_end' => 1, + '__bss_stop' => 1, + '__nosave_begin' => 1, + '__nosave_end' => 1, + 'pg0' => 1, +); + + &find(\&linux_objects, '.'); # find the objects and do_nm on them &list_multiply_defined(); &resolve_external_references(); @@ -270,27 +322,9 @@ sub do_nm close($nmdata); if ($#nmdata < 0) { - if ( - $fullname ne "lib/brlock.o" - && $fullname ne "lib/dec_and_lock.o" - && $fullname ne "fs/xfs/xfs_macros.o" - && $fullname ne "drivers/ide/ide-probe-mini.o" - && $fullname ne "usr/initramfs_data.o" - && $fullname ne "drivers/acpi/executer/exdump.o" - && $fullname ne "drivers/acpi/resources/rsdump.o" - && $fullname ne "drivers/acpi/namespace/nsdumpdv.o" - && $fullname ne "drivers/acpi/namespace/nsdump.o" - && $fullname ne "arch/ia64/sn/kernel/sn2/io.o" - && $fullname ne "arch/ia64/kernel/gate-data.o" - && $fullname ne "drivers/ieee1394/oui.o" - && $fullname ne "security/capability.o" - && $fullname ne "sound/core/wrappers.o" - && $fullname ne "fs/ntfs/sysctl.o" - && $fullname ne "fs/jfs/jfs_debug.o" - ) { - printf "No nm data for $fullname\n"; - } - return; + printf "No nm data for $fullname\n" + unless $nmexception{$fullname}; + return; } $nmdata{$fullname} = \@nmdata; } @@ -372,31 +406,7 @@ sub resolve_external_references $ref{$name} = "" } } - elsif ( $name ne "mod_use_count_" - && $name ne "__initramfs_end" - && $name ne "__initramfs_start" - && $name ne "_einittext" - && $name ne "_sinittext" - && $name ne "kallsyms_names" - && $name ne "kallsyms_num_syms" - && $name ne "kallsyms_addresses" - && $name ne "__this_module" - && $name ne "_etext" - && $name ne "_edata" - && $name ne "_end" - && $name ne "__bss_start" - && $name ne "_text" - && $name ne "_stext" - && $name ne "__gp" - && $name ne "ia64_unw_start" - && $name ne "ia64_unw_end" - && $name ne "__init_begin" - && $name ne "__init_end" - && $name ne "__bss_stop" - && $name ne "__nosave_begin" - && $name ne "__nosave_end" - && $name ne "pg0" - && $name ne "__module_text_address" + elsif ( ! $nameexception{$name} && $name !~ /^__sched_text_/ && $name !~ /^__start_/ && $name !~ /^__end_/ @@ -407,7 +417,6 @@ sub resolve_external_references && $name !~ /^__.*per_cpu_end/ && $name !~ /^__alt_instructions/ && $name !~ /^__setup_/ - && $name !~ /^jiffies/ && $name !~ /^__mod_timer/ && $name !~ /^__mod_page_state/ && $name !~ /^init_module/ -- cgit v1.2.3 From e8cf981346b78ee50c2bfce83be9ee55704b3d4f Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Wed, 27 Oct 2010 12:42:01 -0700 Subject: scripts/namespace.pl: some bug fixes 1. Teach namespace.pl to understand "V" and "v" 2. cond_syscalls are moved into kernel/sys_ni.c Signed-off-by: Amerigo Wang Cc: Stephen Hemminger Cc: Michal Marek Signed-off-by: Andrew Morton Signed-off-by: Michal Marek --- scripts/namespace.pl | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/namespace.pl b/scripts/namespace.pl index c8d0922c3b4f..bccf61044eda 100755 --- a/scripts/namespace.pl +++ b/scripts/namespace.pl @@ -266,6 +266,7 @@ sub do_nm # T global label/procedure # U external reference # W weak external reference to text that has been resolved + # V similar to W, but the value of the weak symbol becomes zero with no error. # a assembler equate # b static variable, uninitialised # d static variable, initialised @@ -274,8 +275,9 @@ sub do_nm # s static variable, uninitialised, small bss # t static label/procedures # w weak external reference to text that has not been resolved + # v similar to w # ? undefined type, used a lot by modules - if ($type !~ /^[ABCDGRSTUWabdgrstw?]$/) { + if ($type !~ /^[ABCDGRSTUWVabdgrstwv?]$/) { printf STDERR "nm output for $fullname contains unknown type '$_'\n"; } elsif ($name =~ /\./) { @@ -286,7 +288,7 @@ sub do_nm # binutils keeps changing the type for exported symbols, force it to R $type = 'R' if ($name =~ /^__ksymtab/ || $name =~ /^__kstrtab/); $name =~ s/_R[a-f0-9]{8}$//; # module versions adds this - if ($type =~ /[ABCDGRSTW]/ && + if ($type =~ /[ABCDGRSTWV]/ && $name ne 'init_module' && $name ne 'cleanup_module' && $name ne 'Using_Versions' && @@ -353,11 +355,12 @@ sub list_multiply_defined foreach my $name (keys(%def)) { if ($#{$def{$name}} > 0) { # Special case for cond_syscall - if ($#{$def{$name}} == 1 && $name =~ /^sys_/ && - ($def{$name}[0] eq "kernel/sys.o" || - $def{$name}[1] eq "kernel/sys.o")) { - &drop_def("kernel/sys.o", $name); - next; + if ($#{$def{$name}} == 1 && $name =~ /^sys_/) { + if($def{$name}[0] eq "kernel/sys_ni.o" || + $def{$name}[1] eq "kernel/sys_ni.o") { + &drop_def("kernel/sys_ni.o", $name); + next; + } } # Special case for i386 entry code if ($#{$def{$name}} == 1 && $name =~ /^__kernel_/ && -- cgit v1.2.3 From abb438526201c6a79949ad45375c051b6681c253 Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Wed, 27 Oct 2010 12:42:01 -0700 Subject: scripts/namespace.pl: improve to get more correct results Exclude more symbols from arch/x86/vdso/ and arch/x86/boot/; add some more linker-defined symbols into exception list; add other cond_syscalls besides "sys_*". Signed-off-by: Amerigo Wang Cc: Stephen Hemminger Cc: Michal Marek Signed-off-by: Andrew Morton Signed-off-by: Michal Marek --- scripts/namespace.pl | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/namespace.pl b/scripts/namespace.pl index bccf61044eda..a71be6b7cdec 100755 --- a/scripts/namespace.pl +++ b/scripts/namespace.pl @@ -133,6 +133,12 @@ my %nameexception = ( '__nosave_begin' => 1, '__nosave_end' => 1, 'pg0' => 1, + 'vdso_enabled' => 1, + '__stack_chk_fail' => 1, + 'VDSO32_PRELINK' => 1, + 'VDSO32_vsyscall' => 1, + 'VDSO32_rt_sigreturn'=>1, + 'VDSO32_sigreturn' => 1, ); @@ -157,7 +163,8 @@ sub linux_objects if (/.*\.o$/ && ! ( m:/built-in.o$: - || m:arch/x86/kernel/vsyscall-syms.o$: + || m:arch/x86/vdso/: + || m:arch/x86/boot/: || m:arch/ia64/ia32/ia32.o$: || m:arch/ia64/kernel/gate-syms.o$: || m:arch/ia64/lib/__divdi3.o$: @@ -200,6 +207,7 @@ sub linux_objects || m:^.*/\.tmp_: || m:^\.tmp_: || m:/vmlinux-obj.o$: + || m:^tools/: ) ) { do_nm($basename, $_); @@ -355,20 +363,15 @@ sub list_multiply_defined foreach my $name (keys(%def)) { if ($#{$def{$name}} > 0) { # Special case for cond_syscall - if ($#{$def{$name}} == 1 && $name =~ /^sys_/) { + if ($#{$def{$name}} == 1 && + ($name =~ /^sys_/ || $name =~ /^compat_sys_/ || + $name =~ /^sys32_/)) { if($def{$name}[0] eq "kernel/sys_ni.o" || $def{$name}[1] eq "kernel/sys_ni.o") { &drop_def("kernel/sys_ni.o", $name); next; } } - # Special case for i386 entry code - if ($#{$def{$name}} == 1 && $name =~ /^__kernel_/ && - $def{$name}[0] eq "arch/x86/kernel/vsyscall-int80_32.o" && - $def{$name}[1] eq "arch/x86/kernel/vsyscall-sysenter_32.o") { - &drop_def("arch/x86/kernel/vsyscall-sysenter_32.o", $name); - next; - } printf "$name is multiply defined in :-\n"; foreach my $module (@{$def{$name}}) { -- cgit v1.2.3 From d0f95c782686dbfbb415d533881a06c2bde17ee0 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 22 Oct 2010 23:32:10 +0900 Subject: kbuild: check return value of asprintf() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check return value of asprintf() in docsect() and exit if error occurs. This removes following warning: HOSTCC scripts/basic/docproc scripts/basic/docproc.c: In function ‘docsect’: scripts/basic/docproc.c:336: warning: ignoring return value of ‘asprintf’, declared with attribute warn_unused_result Signed-off-by: Namhyung Kim Acked-by: Randy Dunlap Signed-off-by: Michal Marek --- scripts/basic/docproc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c index fc3b18d844af..98dec87974d0 100644 --- a/scripts/basic/docproc.c +++ b/scripts/basic/docproc.c @@ -333,7 +333,10 @@ static void docsect(char *filename, char *line) if (*s == '\n') *s = '\0'; - asprintf(&s, "DOC: %s", line); + if (asprintf(&s, "DOC: %s", line) < 0) { + perror("asprintf"); + exit(1); + } consume_symbol(s); free(s); -- cgit v1.2.3 From 532cf2907ac3b9c2345d76251764f4f4e602c921 Mon Sep 17 00:00:00 2001 From: Dick Streefland Date: Sat, 23 Oct 2010 00:02:44 +0200 Subject: scripts/extract-ikconfig: add support for bzip2, lzma and lzo Add support for kernels compressed with bzip2, lzma or lzo to the extract-ikconfig script. Fixes kernel bugzilla #19852: https://bugzilla.kernel.org/show_bug.cgi?id=19852 Signed-off-by: Dick Streefland Tested-by: Justin Signed-off-by: Michal Marek --- scripts/extract-ikconfig | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'scripts') diff --git a/scripts/extract-ikconfig b/scripts/extract-ikconfig index 37f30d36c944..1512c0a755ac 100755 --- a/scripts/extract-ikconfig +++ b/scripts/extract-ikconfig @@ -7,12 +7,10 @@ # The obscure use of the "tr" filter is to work around older versions of # "grep" that report the byte offset of the line instead of the pattern. # -# (c) 2009, Dick Streefland +# (c) 2009,2010 Dick Streefland # Licensed under the terms of the GNU General Public License. # ---------------------------------------------------------------------- -gz1='\037\213\010' -gz2='01' cf1='IKCFG_ST\037\213\010' cf2='0123456789' @@ -21,11 +19,25 @@ dump_config() if pos=`tr "$cf1\n$cf2" "\n$cf2=" < "$1" | grep -abo "^$cf2"` then pos=${pos%%:*} - tail -c+$(($pos+8)) "$1" | zcat -q - exit 0 + tail -c+$(($pos+8)) "$1" | zcat > $tmp1 2> /dev/null + if [ $? != 1 ] + then # exit status must be 0 or 2 (trailing garbage warning) + cat $tmp1 + exit 0 + fi fi } +try_decompress() +{ + for pos in `tr "$1\n$2" "\n$2=" < "$img" | grep -abo "^$2"` + do + pos=${pos%%:*} + tail -c+$pos "$img" | $3 > $tmp2 2> /dev/null + dump_config $tmp2 + done +} + # Check invocation: me=${0##*/} img=$1 @@ -35,18 +47,19 @@ then exit 2 fi +# Prepare temp files: +tmp1=/tmp/ikconfig$$.1 +tmp2=/tmp/ikconfig$$.2 +trap "rm -f $tmp1 $tmp2" 0 + # Initial attempt for uncompressed images or objects: dump_config "$img" -# That didn't work, so decompress and try again: -tmp=/tmp/ikconfig$$ -trap "rm -f $tmp" 0 -for pos in `tr "$gz1\n$gz2" "\n$gz2=" < "$img" | grep -abo "^$gz2"` -do - pos=${pos%%:*} - tail -c+$pos "$img" | zcat 2> /dev/null > $tmp - dump_config $tmp -done +# That didn't work, so retry after decompression. +try_decompress '\037\213\010' xy gunzip +try_decompress 'BZh' xy bunzip2 +try_decompress '\135\0\0\0' xxx unlzma +try_decompress '\211\114\132' xy 'lzop -d' # Bail out: echo "$me: Cannot find kernel config." >&2 -- cgit v1.2.3 From 24a54f7974a616385b96cd939e004592e2cea484 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 13 Oct 2010 15:58:30 -0700 Subject: namespace: add source file location exceptions Teach namespace checker about some special case files where the source is in unusual location. This fixes many of the source file not found errors (more can be added), and also prevents false positives for functions not being used. Signed-off-by: Stephen Hemminger Signed-off-by: Michal Marek --- scripts/namespace.pl | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'scripts') diff --git a/scripts/namespace.pl b/scripts/namespace.pl index a71be6b7cdec..fd2d946fae23 100755 --- a/scripts/namespace.pl +++ b/scripts/namespace.pl @@ -141,6 +141,26 @@ my %nameexception = ( 'VDSO32_sigreturn' => 1, ); +# Files with exceptions to source file location +my %sourceloc = ( + 'net/dccp/dccp_probe.o' => 'probe', + 'net/dccp/dccp_ipv4.o' => 'ipv4', + 'net/dccp/dccp_ipv6.o' => 'ipv6', + 'net/dccp/dccp_diag.o' => 'diag', + 'drivers/char/hw_random/rng-core.o' => 'core', + 'fs/fat/msdos.o' => 'namei_msdos', + 'fs/fat/vfat.o' => 'namei_vfat', + 'fs/nfs_common/nfs_acl.o' => 'nfsacl', + 'sound/soundcore.o' => 'sound_core', + 'drivers/md/dm-mirror.o' => 'dm-raid1', + 'drivers/message/i2o/i2o_bus.o' => 'bus-osm', + 'arch/x86/kvm/kvm-amd.o' => 'svm', + 'arch/x86/kvm/kvm-intel.o' => 'vmx', + 'arch/x86/crypto/twofish-x86_64.o' => 'twofish-x86_64-asm_64', + 'arch/x86/crypto/aes-x86_64.o' => 'aes-x86_64-asm_64', + 'arch/x86/crypto/aesni-intel.o' => 'aesni-intel_asm', + 'arch/x86/crypto/salsa20-x86_64.o' => 'salsa20-x86_64-asm_64', +); &find(\&linux_objects, '.'); # find the objects and do_nm on them &list_multiply_defined(); @@ -228,11 +248,15 @@ sub do_nm return; } ($source = $basename) =~ s/\.o$//; + + $source = $sourceloc{$fullname} if ($sourceloc{$fullname}); + if (-e "$source.c" || -e "$source.S") { $source = "$objtree$File::Find::dir/$source"; } else { $source = "$srctree$File::Find::dir/$source"; } + if (! -e "$source.c" && ! -e "$source.S") { # No obvious source, exclude the object if it is conglomerate open(my $objdumpdata, "$objdump $basename|") -- cgit v1.2.3 From 10247179a7af4f000468e12ae73f3cf657b66235 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 24 Oct 2010 23:37:31 +0200 Subject: Coccinelle: Find nested lock+irqsave functions that use the same flags variables. Signed-off-by: Julia Lawall Signed-off-by: Nicolas Palix Signed-off-by: Michal Marek --- scripts/coccinelle/locks/flags.cocci | 80 ++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 scripts/coccinelle/locks/flags.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/locks/flags.cocci b/scripts/coccinelle/locks/flags.cocci new file mode 100644 index 000000000000..b4344d838097 --- /dev/null +++ b/scripts/coccinelle/locks/flags.cocci @@ -0,0 +1,80 @@ +/// 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. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual context +virtual org +virtual report + +@r@ +expression lock1,lock2,flags; +position p1,p2; +@@ + +( +spin_lock_irqsave@p1(lock1,flags) +| +read_lock_irqsave@p1(lock1,flags) +| +write_lock_irqsave@p1(lock1,flags) +) +... when != flags +( +spin_lock_irqsave(lock1,flags) +| +read_lock_irqsave(lock1,flags) +| +write_lock_irqsave(lock1,flags) +| +spin_lock_irqsave@p2(lock2,flags) +| +read_lock_irqsave@p2(lock2,flags) +| +write_lock_irqsave@p2(lock2,flags) +) + +@d@ +expression f <= r.flags; +expression lock1,lock2,flags; +position r.p1, r.p2; +@@ + +( +*spin_lock_irqsave@p1(lock1,flags) +| +*read_lock_irqsave@p1(lock1,flags) +| +*write_lock_irqsave@p1(lock1,flags) +) +... when != f +( +*spin_lock_irqsave@p2(lock2,flags) +| +*read_lock_irqsave@p2(lock2,flags) +| +*write_lock_irqsave@p2(lock2,flags) +) + +// ---------------------------------------------------------------------- + +@script:python depends on d && org@ +p1 << r.p1; +p2 << r.p2; +@@ + +cocci.print_main("original lock",p1) +cocci.print_secs("nested lock+irqsave that reuses flags",p2) + +@script:python depends on d && report@ +p1 << r.p1; +p2 << r.p2; +@@ + +msg="ERROR: nested lock+irqsave that reuses flags from %s." % (p1[0].line) +coccilib.report.print_report(p2[0], msg) -- cgit v1.2.3 From 97c1cf8fdbce332bfacc3e38aae3fe2af1369906 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 24 Oct 2010 23:37:32 +0200 Subject: Coccinelle: Find doubled arguments to boolean or bit operators. Signed-off-by: Julia Lawall Signed-off-by: Nicolas Palix Signed-off-by: Michal Marek --- scripts/coccinelle/tests/doublebitand.cocci | 54 +++++++++++++++++++++++++++++ scripts/coccinelle/tests/doubletest.cocci | 40 +++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 scripts/coccinelle/tests/doublebitand.cocci create mode 100644 scripts/coccinelle/tests/doubletest.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/tests/doublebitand.cocci b/scripts/coccinelle/tests/doublebitand.cocci new file mode 100644 index 000000000000..9ba73d05a77e --- /dev/null +++ b/scripts/coccinelle/tests/doublebitand.cocci @@ -0,0 +1,54 @@ +/// Find bit operations that include the same argument more than once +//# One source of false positives is when the argument performs a side +//# effect. Another source of false positives is when a neutral value +//# such as 0 for | is used to indicate no information, to maintain the +//# same structure as other similar expressions +/// +// Confidence: Moderate +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual context +virtual org +virtual report + +@r expression@ +expression E; +position p; +@@ + +( +* E@p + & ... & E +| +* E@p + | ... | E +| +* E@p + & ... & !E +| +* E@p + | ... | !E +| +* !E@p + & ... & E +| +* !E@p + | ... | E +) + +@script:python depends on org@ +p << r.p; +@@ + +cocci.print_main("duplicated argument to & or |",p) + +@script:python depends on report@ +p << r.p; +@@ + +coccilib.report.print_report(p[0],"duplicated argument to & or |") diff --git a/scripts/coccinelle/tests/doubletest.cocci b/scripts/coccinelle/tests/doubletest.cocci new file mode 100644 index 000000000000..13a2c0e8a4bf --- /dev/null +++ b/scripts/coccinelle/tests/doubletest.cocci @@ -0,0 +1,40 @@ +/// Find &&/|| operations that include the same argument more than once +//# A common source of false positives is when the argument performs a side +//# effect. +/// +// Confidence: Moderate +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual context +virtual org +virtual report + +@r expression@ +expression E; +position p; +@@ + +( +* E@p + || ... || E +| +* E@p + && ... && E +) + +@script:python depends on org@ +p << r.p; +@@ + +cocci.print_main("duplicated argument to && or ||",p) + +@script:python depends on report@ +p << r.p; +@@ + +coccilib.report.print_report(p[0],"duplicated argument to && or ||") -- cgit v1.2.3 From 062c1825a5f6673746efe5f0a5ea3803b0c316a9 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Sun, 24 Oct 2010 23:37:34 +0200 Subject: Coccinelle: Add contextual message Change the message displayed to the user according to the current mode used. Fix trailing white-space and spelling Signed-off-by: Nicolas Palix Signed-off-by: Michal Marek --- scripts/coccicheck | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/coccicheck b/scripts/coccicheck index 7529af15672d..1bb1a1bd2daa 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -32,7 +32,7 @@ if [ "$MODE" = "" ] ; then fi MODE="chain" elif [ "$MODE" = "report" -o "$MODE" = "org" ] ; then - FLAGS="$FLAGS -no_show_diff" + FLAGS="$FLAGS -no_show_diff" fi if [ "$ONLINE" = "0" ] ; then @@ -47,7 +47,7 @@ coccinelle () { OPT=`grep "Option" $COCCI | cut -d':' -f2` -# The option '-parse_cocci' can be used to syntaxically check the SmPL files. +# The option '-parse_cocci' can be used to syntactically check the SmPL files. # # $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null @@ -62,7 +62,17 @@ coccinelle () { sed -ne 's|^///||p' $COCCI - echo ' The semantic patch that makes this change is available' + if [ "$MODE" = "patch" ] ; then + echo ' The semantic patch that makes this change is available' + elif [ "$MODE" = "report" ] ; then + echo ' The semantic patch that makes this report is available' + elif [ "$MODE" = "context" ] ; then + echo ' The semantic patch that spots this code is available' + elif [ "$MODE" = "org" ] ; then + echo ' The semantic patch that makes this Org report is available' + else + echo ' The semantic patch that makes this output is available' + fi echo " in $FILE." echo '' echo ' More information about semantic patching is available at' -- cgit v1.2.3 From 9231d9e02a1f92b52bbb1e4474bfd1903835a993 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Thu, 28 Oct 2010 00:59:56 +0200 Subject: Revert "namespace: add source file location exceptions" This reverts commit 24a54f7974a616385b96cd939e004592e2cea484. Stephen Hemminger writes: > That patch should not be included. It causes more problems than it > solves, since then there are duplicate file locations which causes > false duplicate symbol reports. Reported-by: Stephen Hemminger Signed-off-by: Michal Marek --- scripts/namespace.pl | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'scripts') diff --git a/scripts/namespace.pl b/scripts/namespace.pl index fd2d946fae23..a71be6b7cdec 100755 --- a/scripts/namespace.pl +++ b/scripts/namespace.pl @@ -141,26 +141,6 @@ my %nameexception = ( 'VDSO32_sigreturn' => 1, ); -# Files with exceptions to source file location -my %sourceloc = ( - 'net/dccp/dccp_probe.o' => 'probe', - 'net/dccp/dccp_ipv4.o' => 'ipv4', - 'net/dccp/dccp_ipv6.o' => 'ipv6', - 'net/dccp/dccp_diag.o' => 'diag', - 'drivers/char/hw_random/rng-core.o' => 'core', - 'fs/fat/msdos.o' => 'namei_msdos', - 'fs/fat/vfat.o' => 'namei_vfat', - 'fs/nfs_common/nfs_acl.o' => 'nfsacl', - 'sound/soundcore.o' => 'sound_core', - 'drivers/md/dm-mirror.o' => 'dm-raid1', - 'drivers/message/i2o/i2o_bus.o' => 'bus-osm', - 'arch/x86/kvm/kvm-amd.o' => 'svm', - 'arch/x86/kvm/kvm-intel.o' => 'vmx', - 'arch/x86/crypto/twofish-x86_64.o' => 'twofish-x86_64-asm_64', - 'arch/x86/crypto/aes-x86_64.o' => 'aes-x86_64-asm_64', - 'arch/x86/crypto/aesni-intel.o' => 'aesni-intel_asm', - 'arch/x86/crypto/salsa20-x86_64.o' => 'salsa20-x86_64-asm_64', -); &find(\&linux_objects, '.'); # find the objects and do_nm on them &list_multiply_defined(); @@ -248,15 +228,11 @@ sub do_nm return; } ($source = $basename) =~ s/\.o$//; - - $source = $sourceloc{$fullname} if ($sourceloc{$fullname}); - if (-e "$source.c" || -e "$source.S") { $source = "$objtree$File::Find::dir/$source"; } else { $source = "$srctree$File::Find::dir/$source"; } - if (! -e "$source.c" && ! -e "$source.S") { # No obvious source, exclude the object if it is conglomerate open(my $objdumpdata, "$objdump $basename|") -- cgit v1.2.3 From d63f6d1b4d3ad0d88685a5f8eb1c3cac01ddd0db Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 19 Oct 2010 16:11:53 -0400 Subject: initramfs: Fix build break on symbol-prefixed archs Signed-off-by: Mike Frysinger Signed-off-by: Michal Marek --- scripts/Makefile.lib | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 54fd1b700131..e93525c5e915 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -128,7 +128,9 @@ _c_flags += $(if $(patsubst n%,, \ endif ifdef CONFIG_SYMBOL_PREFIX -_cpp_flags += -DSYMBOL_PREFIX=$(patsubst "%",%,$(CONFIG_SYMBOL_PREFIX)) +_sym_flags = -DSYMBOL_PREFIX=$(patsubst "%",%,$(CONFIG_SYMBOL_PREFIX)) +_cpp_flags += $(_sym_flags) +_a_flags += $(_sym_flags) endif -- cgit v1.2.3 From 4908980b241bc639b71ef47b727b4bc7c0174afe Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 29 Oct 2010 00:56:46 -0400 Subject: kconfig: Make localmodconfig handle environment variables The commit 838a2e55e6a4e9e8a10451ed2ef0f7a08dabdb04 kbuild: migrate all arch to the kconfig mainmenu upgrade Broke make localmodconfig. The reason was that it added a environment variable to the kconfig source, which the streamline_config.pl could not handle. This patch changes streamline_config.pl to handle kconfig sources using environment variables in their names. Cc: Arnaud Lacombe Cc: Sam Ravnborg Cc: Michal Marek Signed-off-by: Steven Rostedt --- scripts/kconfig/streamline_config.pl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index c70a27d924f0..cc10bcfda64f 100644 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -137,7 +137,17 @@ sub read_kconfig { my $config; my @kconfigs; - open(KIN, "$ksource/$kconfig") || die "Can't open $kconfig"; + my $source = "$ksource/$kconfig"; + my $last_source = ""; + + # Check for any environment variables used + while ($source =~ /\$(\w+)/ && $last_source ne $source) { + my $env = $1; + $last_source = $source; + $source =~ s/\$$env/$ENV{$env}/; + } + + open(KIN, "$source") || die "Can't open $kconfig"; while () { chomp; -- cgit v1.2.3 From ccece60ac69608c496b07c0d31a68894db0a22b3 Mon Sep 17 00:00:00 2001 From: hiromu yagura Date: Sun, 15 Aug 2010 13:13:17 +0900 Subject: kconfig: Fix variable name typo %prompts in streamline_config.pl When I added "use strict;" to streamline_config.pl, I saw the following warnings: > Global symbol "%prompt" requires explicit package name at scripts/kconfig/streamline_config.pl line 183. > Global symbol "%prompt" requires explicit package name at scripts/kconfig/streamline_config.pl line 368. The declaration of %prompt was incorrect, and should have been %prompts. Cc: Toralf Foerster Cc: KAMEZAWA Hiroyuki Cc: YOSHIFUJI Hideaki Signed-off-by: Hiromu Yakura LKML-Reference: <1281845597.11566.5.camel@camp10-laptop> Signed-off-by: Steven Rostedt --- scripts/kconfig/streamline_config.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index cc10bcfda64f..3c63aa943ee3 100644 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -188,7 +188,7 @@ sub read_kconfig { # configs without prompts must be selected } elsif ($state ne "NONE" && /^\s*tristate\s\S/) { # note if the config has a prompt - $prompt{$config} = 1; + $prompts{$config} = 1; # Check for if statements } elsif (/^if\s+(.*\S)\s*$/) { @@ -373,7 +373,7 @@ while ($repeat) { parse_config_dep_select $depends{$config}; } - if (defined($prompt{$config}) || !defined($selects{$config})) { + if (defined($prompts{$config}) || !defined($selects{$config})) { next; } -- cgit v1.2.3 From cf5a189d4a02efb3712cfb424452f4ce3ab7c4a2 Mon Sep 17 00:00:00 2001 From: hiromu Date: Tue, 17 Aug 2010 19:49:18 +0900 Subject: kconfig: Fix missing declaration of variable $dir in streamline_config.pl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Fri, Aug 17, 2010 at 01:43PM +0800, Américo Wang wrote: > Acked-by: WANG Cong > > BTW, I think we should add "use strict;" too. Then I added "use strict;" to streamline_config.pl, I saw another warning. > Global symbol "$dir" requires explicit package name at scripts/kconfig/streamline_config.pl line 286. > Global symbol "$dir" requires explicit package name at scripts/kconfig/streamline_config.pl line 287. > Global symbol "$dir" requires explicit package name at scripts/kconfig/streamline_config.pl line 288. Then I added "my $dir;" to line 285. Cc: Américo Wang Cc: Toralf Foerster Cc: KAMEZAWA Hiroyuki Cc: YOSHIFUJI Hideaki Signed-off-by: Hiromu Yakura LKML-Reference: <1282042158.7160.9.camel@hiromu-Macbook> [ changed to just add my in front of $dir instead of new line ] Signed-off-by: Steven Rostedt --- scripts/kconfig/streamline_config.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index 3c63aa943ee3..883748c70d28 100644 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -42,6 +42,8 @@ # mv config_strip .config # make oldconfig # +use strict; + my $config = ".config"; my $uname = `uname -r`; @@ -291,7 +293,7 @@ if (defined($lsmod_file)) { # see what modules are loaded on this system my $lsmod; - foreach $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) { + foreach my $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) { if ( -x "$dir/lsmod" ) { $lsmod = "$dir/lsmod"; last; -- cgit v1.2.3 From 20d190473328b90755eb2434cf2d26b73a53ef23 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 28 Oct 2010 22:13:51 -0400 Subject: kconfig: Fix streamline_config to read multi line deps in Kconfig files I noticed that some Kconfig files have multi line dependencies that continue with a backslash. Those dependencies on the next line will be missed by streamline_config. For example: config CS89x0 tristate "CS89x0 support" depends on NET_ETHERNET && (ISA || EISA || MACH_IXDP2351 \ || ARCH_IXDP2X01 || MACH_MX31ADS) The "|| ARCH_IXDP2X01 || MACH_MX31ADS)" will not be processed. This patch adds code to handle this case. Signed-off-by: Steven Rostedt --- scripts/kconfig/streamline_config.pl | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index 883748c70d28..ebba407ac5eb 100644 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -125,7 +125,6 @@ my %selects; my %prompts; my %objects; my $var; -my $cont = 0; my $iflevel = 0; my @ifdeps; @@ -139,6 +138,9 @@ sub read_kconfig { my $config; my @kconfigs; + my $cont = 0; + my $line; + my $source = "$ksource/$kconfig"; my $last_source = ""; @@ -153,6 +155,19 @@ sub read_kconfig { while () { chomp; + # Make sure that lines ending with \ continue + if ($cont) { + $_ = $line . " " . $_; + } + + if (s/\\$//) { + $cont = 1; + $line = $_; + next; + } + + $cont = 0; + # collect any Kconfig sources if (/^source\s*"(.*)"/) { $kconfigs[$#kconfigs+1] = $1; @@ -230,6 +245,8 @@ if ($kconfig) { # Read all Makefiles to map the configs to the objects foreach my $makefile (@makefiles) { + my $cont = 0; + open(MIN,$makefile) || die "Can't open $makefile"; while () { my $objs; -- cgit v1.2.3 From 8ef17fa2ef8be74b946e725c2afb0e2a54981da1 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 28 Oct 2010 22:21:57 -0400 Subject: kconfig: Have streamline_config process menuconfigs too Some menuconfigs in the Kconfig files have prompts and dependencies. Currently, streamline_config misses these, and this can cause streamline_config to keep modules enabled that should not be, and even worse, not enable those that should. This patch makes streamline_config process menuconfigs just like it would process a config. Reported-by: member graysky Signed-off-by: Steven Rostedt --- scripts/kconfig/streamline_config.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index ebba407ac5eb..fd81fc33d633 100644 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -174,9 +174,9 @@ sub read_kconfig { } # configs found - if (/^\s*config\s+(\S+)\s*$/) { + if (/^\s*(menu)?config\s+(\S+)\s*$/) { $state = "NEW"; - $config = $1; + $config = $2; for (my $i = 0; $i < $iflevel; $i++) { if ($i) { -- cgit v1.2.3 From a2d49358ba9bc93204dc001d5568c5bdb299b77d Mon Sep 17 00:00:00 2001 From: John Reiser Date: Wed, 27 Oct 2010 18:59:07 +0800 Subject: ftrace/MIPS: Add MIPS64 support for C version of recordmcount MIPS64 has 'weird' Elf64_Rel.r_info[1,2], which must be used instead of the generic Elf64_Rel.r_info, otherwise, the C version of recordmcount will not work for "segmentation fault". Usage of "union mips_r_info" and the functions MIPS64_r_sym() and MIPS64_r_info() written by Maciej W. Rozycki ---- [1] http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf [2] arch/mips/include/asm/module.h Tested-by: Wu Zhangjin Signed-off-by: John Reiser Signed-off-by: Maciej W. Rozycki LKML-Reference: LKML-Reference: <910dc2d5ae1ed042df4f96815fe4a433078d1c2a.1288176026.git.wuzhangjin@gmail.com> Signed-off-by: Steven Rostedt Signed-off-by: Ralf Baechle --- scripts/recordmcount.c | 41 +++++++++++++++++++++++++++++++++++++++++ scripts/recordmcount.h | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 71 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index 26e1271259ba..2d32b9ced20a 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -217,6 +217,39 @@ is_mcounted_section_name(char const *const txtname) #define RECORD_MCOUNT_64 #include "recordmcount.h" +/* 64-bit EM_MIPS has weird ELF64_Rela.r_info. + * http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf + * We interpret Table 29 Relocation Operation (Elf64_Rel, Elf64_Rela) [p.40] + * to imply the order of the members; the spec does not say so. + * typedef unsigned char Elf64_Byte; + * fails on MIPS64 because their already has it! + */ + +typedef uint8_t myElf64_Byte; /* Type for a 8-bit quantity. */ + +union mips_r_info { + Elf64_Xword r_info; + struct { + Elf64_Word r_sym; /* Symbol index. */ + myElf64_Byte r_ssym; /* Special symbol. */ + myElf64_Byte r_type3; /* Third relocation. */ + myElf64_Byte r_type2; /* Second relocation. */ + myElf64_Byte r_type; /* First relocation. */ + } r_mips; +}; + +static uint64_t MIPS64_r_sym(Elf64_Rel const *rp) +{ + return w(((union mips_r_info){ .r_info = rp->r_info }).r_mips.r_sym); +} + +static void MIPS64_r_info(Elf64_Rel *const rp, unsigned sym, unsigned type) +{ + rp->r_info = ((union mips_r_info){ + .r_mips = { .r_sym = w(sym), .r_type = type } + }).r_info; +} + static void do_file(char const *const fname) { @@ -268,6 +301,7 @@ do_file(char const *const fname) case EM_386: reltype = R_386_32; break; case EM_ARM: reltype = R_ARM_ABS32; break; case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break; + case EM_MIPS: /* reltype: e_class */ gpfx = '_'; break; case EM_PPC: reltype = R_PPC_ADDR32; gpfx = '_'; break; case EM_PPC64: reltype = R_PPC64_ADDR64; gpfx = '_'; break; case EM_S390: /* reltype: e_class */ gpfx = '_'; break; @@ -291,6 +325,8 @@ do_file(char const *const fname) } if (EM_S390 == w2(ehdr->e_machine)) reltype = R_390_32; + if (EM_MIPS == w2(ehdr->e_machine)) + reltype = R_MIPS_32; do32(ehdr, fname, reltype); } break; case ELFCLASS64: { @@ -303,6 +339,11 @@ do_file(char const *const fname) } if (EM_S390 == w2(ghdr->e_machine)) reltype = R_390_64; + if (EM_MIPS == w2(ghdr->e_machine)) { + reltype = R_MIPS_64; + Elf64_r_sym = MIPS64_r_sym; + Elf64_r_info = MIPS64_r_info; + } do64(ghdr, fname, reltype); } break; } /* end switch */ diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index 7f39d0943d2d..190fd18dc853 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h @@ -31,8 +31,12 @@ #undef Elf_Rela #undef Elf_Sym #undef ELF_R_SYM +#undef Elf_r_sym #undef ELF_R_INFO +#undef Elf_r_info #undef ELF_ST_BIND +#undef fn_ELF_R_SYM +#undef fn_ELF_R_INFO #undef uint_t #undef _w #undef _align @@ -52,8 +56,12 @@ # define Elf_Rela Elf64_Rela # define Elf_Sym Elf64_Sym # define ELF_R_SYM ELF64_R_SYM +# define Elf_r_sym Elf64_r_sym # define ELF_R_INFO ELF64_R_INFO +# define Elf_r_info Elf64_r_info # define ELF_ST_BIND ELF64_ST_BIND +# define fn_ELF_R_SYM fn_ELF64_R_SYM +# define fn_ELF_R_INFO fn_ELF64_R_INFO # define uint_t uint64_t # define _w w8 # define _align 7u @@ -72,14 +80,32 @@ # define Elf_Rela Elf32_Rela # define Elf_Sym Elf32_Sym # define ELF_R_SYM ELF32_R_SYM +# define Elf_r_sym Elf32_r_sym # define ELF_R_INFO ELF32_R_INFO +# define Elf_r_info Elf32_r_info # define ELF_ST_BIND ELF32_ST_BIND +# define fn_ELF_R_SYM fn_ELF32_R_SYM +# define fn_ELF_R_INFO fn_ELF32_R_INFO # define uint_t uint32_t # define _w w # define _align 3u # define _size 4 #endif +/* Functions and pointers that 64-bit EM_MIPS can override. */ +static uint_t fn_ELF_R_SYM(Elf_Rel const *rp) +{ + return ELF_R_SYM(_w(rp->r_info)); +} +static uint_t (*Elf_r_sym)(Elf_Rel const *rp) = fn_ELF_R_SYM; + +static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type) +{ + rp->r_info = ELF_R_INFO(sym, type); +} +static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO; + + /* Append the new shstrtab, Elf_Shdr[], __mcount_loc and its relocations. */ static void append_func(Elf_Ehdr *const ehdr, Elf_Shdr *const shstr, @@ -197,22 +223,22 @@ static uint_t *sift_rel_mcount(uint_t *mlocp, for (t = nrel; t; --t) { if (!mcountsym) { Elf_Sym const *const symp = - &sym0[ELF_R_SYM(_w(relp->r_info))]; + &sym0[Elf_r_sym(relp)]; char const *symname = &str0[w(symp->st_name)]; if ('.' == symname[0]) ++symname; /* ppc64 hack */ if (0 == strcmp((('_' == gpfx) ? "_mcount" : "mcount"), symname)) - mcountsym = ELF_R_SYM(_w(relp->r_info)); + mcountsym = Elf_r_sym(relp); } - if (mcountsym == ELF_R_SYM(_w(relp->r_info))) { + if (mcountsym == Elf_r_sym(relp)) { uint_t const addend = _w(_w(relp->r_offset) - recval); mrelp->r_offset = _w(offbase + ((void *)mlocp - (void *)mloc0)); - mrelp->r_info = _w(ELF_R_INFO(recsym, reltype)); + Elf_r_info(mrelp, recsym, reltype); if (sizeof(Elf_Rela) == rel_entsize) { ((Elf_Rela *)mrelp)->r_addend = addend; *mlocp++ = 0; -- cgit v1.2.3 From 412910cd046c1f14f0fba9c0aec401d47e57dcd1 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Wed, 27 Oct 2010 18:59:08 +0800 Subject: ftrace/MIPS: Add module support for C version of recordmcount Since MIPS modules' address space differs from the core kernel space, to access the _mcount in the core kernel, the kernel functions in modules must use long call (-mlong-calls): load the _mcount address into one register and jump to the address stored by the register: c: 3c030000 lui v1,0x0 <--------> b label c: R_MIPS_HI16 _mcount c: R_MIPS_NONE *ABS* c: R_MIPS_NONE *ABS* 10: 64630000 daddiu v1,v1,0 10: R_MIPS_LO16 _mcount 10: R_MIPS_NONE *ABS* 10: R_MIPS_NONE *ABS* 14: 03e0082d move at,ra 18: 0060f809 jalr v1 label: In the old Perl version of recordmcount, we only need to record the position of the 1st R_MIPS_HI16 type of _mcount, and later, in ftrace_make_nop(), replace the instruction in this position by a "b label" and in ftrace_make_call(), replace it back. But, the default C version of recordmcount records all of the _mcount symbols, so, we must filter the 2nd _mcount like the Perl version of recordmcount does. The C version of recordmcount copes with the symbols before they are linked, So It doesn't know the type of the symbols and therefore can not filter the symbols as the Perl version of recordmcount does. But as we can see above, the 2nd _mcount symbols of the long call alawys follows the 1st _mcount symbol of the same long call, which means the offset from the 1st to the 2nd is fixed, it is 0x10-0xc = 4 here, 4 is the length of the 1st load instruciton, for MIPS has fixed length of instructions, this offset is always 4. And as we know, the _mcount is inserted into the entry of every kernel function, the offset between the other _mcount's is expected to be always bigger than 4. So, to filter the 2ns _mcount symbol of the long call, we can simply check the offset between two _mcount symbols, If it is 4, then, filter the 2nd _mcount symbol. To avoid touching too much code, an 'empty' function fn_is_fake_mcount() is added for all of the archs, and the specific archs can override it via chaning the function pointer: is_fake_mcount in do_file() with the e_machine. e.g. This patch adds MIPS_is_fake_mcount() to override the default fn_is_fake_mcount() pointed by is_fake_mcount. This fn_is_fake_mcount() checks if the _mcount symbol is fake, e.g. the 2nd _mcount symbol of the long call is fake, for there are 2 _mcount symbols mapped to one real mcount call, so, one of them is fake and must be filtered. This fn_is_fake_mcount() is called in sift_rel_mcount() after finding the _mcount symbols and before adding the _mcount symbol into mrelp, so, it can prevent the fake mcount symbol going into the last __mcount_loc table. Signed-off-by: Wu Zhangjin LKML-Reference: Signed-off-by: Steven Rostedt Signed-off-by: Ralf Baechle --- scripts/recordmcount.c | 5 ++++- scripts/recordmcount.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 57 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index 2d32b9ced20a..f2f32eee2c5b 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -325,8 +325,10 @@ do_file(char const *const fname) } if (EM_S390 == w2(ehdr->e_machine)) reltype = R_390_32; - if (EM_MIPS == w2(ehdr->e_machine)) + if (EM_MIPS == w2(ehdr->e_machine)) { reltype = R_MIPS_32; + is_fake_mcount32 = MIPS32_is_fake_mcount; + } do32(ehdr, fname, reltype); } break; case ELFCLASS64: { @@ -343,6 +345,7 @@ do_file(char const *const fname) reltype = R_MIPS_64; Elf64_r_sym = MIPS64_r_sym; Elf64_r_info = MIPS64_r_info; + is_fake_mcount64 = MIPS64_is_fake_mcount; } do64(ghdr, fname, reltype); } break; diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index 190fd18dc853..58e933a20544 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h @@ -19,12 +19,16 @@ * Licensed under the GNU General Public License, version 2 (GPLv2). */ #undef append_func +#undef is_fake_mcount +#undef fn_is_fake_mcount +#undef MIPS_is_fake_mcount #undef sift_rel_mcount #undef find_secsym_ndx #undef __has_rel_mcount #undef has_rel_mcount #undef tot_relsize #undef do_func +#undef Elf_Addr #undef Elf_Ehdr #undef Elf_Shdr #undef Elf_Rel @@ -50,6 +54,10 @@ # define has_rel_mcount has64_rel_mcount # define tot_relsize tot64_relsize # define do_func do64 +# define is_fake_mcount is_fake_mcount64 +# define fn_is_fake_mcount fn_is_fake_mcount64 +# define MIPS_is_fake_mcount MIPS64_is_fake_mcount +# define Elf_Addr Elf64_Addr # define Elf_Ehdr Elf64_Ehdr # define Elf_Shdr Elf64_Shdr # define Elf_Rel Elf64_Rel @@ -74,6 +82,10 @@ # define has_rel_mcount has32_rel_mcount # define tot_relsize tot32_relsize # define do_func do32 +# define is_fake_mcount is_fake_mcount32 +# define fn_is_fake_mcount fn_is_fake_mcount32 +# define MIPS_is_fake_mcount MIPS32_is_fake_mcount +# define Elf_Addr Elf32_Addr # define Elf_Ehdr Elf32_Ehdr # define Elf_Shdr Elf32_Shdr # define Elf_Rel Elf32_Rel @@ -92,7 +104,13 @@ # define _size 4 #endif -/* Functions and pointers that 64-bit EM_MIPS can override. */ +/* Functions and pointers that do_file() may override for specific e_machine. */ +static int fn_is_fake_mcount(Elf_Rel const *rp) +{ + return 0; +} +static int (*is_fake_mcount)(Elf_Rel const *rp) = fn_is_fake_mcount; + static uint_t fn_ELF_R_SYM(Elf_Rel const *rp) { return ELF_R_SYM(_w(rp->r_info)); @@ -105,6 +123,39 @@ static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type) } static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO; +/* + * MIPS mcount long call has 2 _mcount symbols, only the position of the 1st + * _mcount symbol is needed for dynamic function tracer, with it, to disable + * tracing(ftrace_make_nop), the instruction in the position is replaced with + * the "b label" instruction, to enable tracing(ftrace_make_call), replace the + * instruction back. So, here, we set the 2nd one as fake and filter it. + * + * c: 3c030000 lui v1,0x0 <--> b label + * c: R_MIPS_HI16 _mcount + * c: R_MIPS_NONE *ABS* + * c: R_MIPS_NONE *ABS* + * 10: 64630000 daddiu v1,v1,0 + * 10: R_MIPS_LO16 _mcount + * 10: R_MIPS_NONE *ABS* + * 10: R_MIPS_NONE *ABS* + * 14: 03e0082d move at,ra + * 18: 0060f809 jalr v1 + * label: + */ +#define MIPS_FAKEMCOUNT_OFFSET 4 + +static int MIPS_is_fake_mcount(Elf_Rel const *rp) +{ + static Elf_Addr old_r_offset; + Elf_Addr current_r_offset = _w(rp->r_offset); + int is_fake; + + is_fake = old_r_offset && + (current_r_offset - old_r_offset == MIPS_FAKEMCOUNT_OFFSET); + old_r_offset = current_r_offset; + + return is_fake; +} /* Append the new shstrtab, Elf_Shdr[], __mcount_loc and its relocations. */ static void append_func(Elf_Ehdr *const ehdr, @@ -183,7 +234,6 @@ static void append_func(Elf_Ehdr *const ehdr, uwrite(fd_map, ehdr, sizeof(*ehdr)); } - /* * Look at the relocations in order to find the calls to mcount. * Accumulate the section offsets that are found, and their relocation info, @@ -233,7 +283,7 @@ static uint_t *sift_rel_mcount(uint_t *mlocp, mcountsym = Elf_r_sym(relp); } - if (mcountsym == Elf_r_sym(relp)) { + if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) { uint_t const addend = _w(_w(relp->r_offset) - recval); mrelp->r_offset = _w(offbase -- cgit v1.2.3 From 4882720b267b7b1d1b0ce08334b205f0329d4615 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 7 Sep 2010 14:34:01 +0000 Subject: semaphore: Remove mutex emulation Semaphores used as mutexes have been deprecated for years. Now that all users are either converted to real semaphores or to mutexes remove the cruft. Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Christoph Hellwig LKML-Reference: <20100907125057.562399240@linutronix.de> --- scripts/checkpatch.pl | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 90b54d4697fd..e3c7fc0dca38 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2794,12 +2794,8 @@ sub process { WARN("__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr); } -# check for semaphores used as mutexes - if ($line =~ /^.\s*(DECLARE_MUTEX|init_MUTEX)\s*\(/) { - WARN("mutexes are preferred for single holder semaphores\n" . $herecurr); - } -# check for semaphores used as mutexes - if ($line =~ /^.\s*init_MUTEX_LOCKED\s*\(/) { +# check for semaphores initialized locked + if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { WARN("consider using a completion\n" . $herecurr); } -- cgit v1.2.3 From b595076a180a56d1bb170e6eceda6eb9d76f4cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 1 Nov 2010 15:38:34 -0400 Subject: tree-wide: fix comment/printk typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "gadget", "through", "command", "maintain", "maintain", "controller", "address", "between", "initiali[zs]e", "instead", "function", "select", "already", "equal", "access", "management", "hierarchy", "registration", "interest", "relative", "memory", "offset", "already", Signed-off-by: Uwe Kleine-König Signed-off-by: Jiri Kosina --- scripts/kconfig/confdata.c | 2 +- scripts/mod/modpost.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 9df80114b47b..c06f1503aa8b 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -946,7 +946,7 @@ static void randomize_choice_values(struct symbol *csym) int cnt, def; /* - * If choice is mod then we may have more items slected + * If choice is mod then we may have more items selected * and if no then no-one. * In both cases stop. */ diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 33122ca04e7c..6619ed8843f9 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1614,7 +1614,7 @@ static void section_rel(const char *modname, struct elf_info *elf, * A module includes a number of sections that are discarded * either when loaded or when used as built-in. * For loaded modules all functions marked __init and all data - * marked __initdata will be discarded when the module has been intialized. + * marked __initdata will be discarded when the module has been initialized. * Likewise for modules used built-in the sections marked __exit * are discarded because __exit marked function are supposed to be called * only when a module is unloaded which never happens for built-in modules. -- cgit v1.2.3 From 020e773f6b2e797a13d23723773ed1b3ba2c35dc Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Mon, 1 Nov 2010 21:01:44 +0000 Subject: kconfig: sym_expand_string_value: allow for string termination when reallocing When expanding a parameterised string we may run out of space, this triggers a realloc. When computing the new allocation size we do not allow for the terminating '\0'. Allow for this when calculating the new length. Signed-off-by: Andy Whitcroft Signed-off-by: Linus Torvalds --- scripts/kconfig/symbol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index c0efe102d655..af6e9f3de950 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -875,7 +875,7 @@ const char *sym_expand_string_value(const char *in) symval = sym_get_string_value(sym); } - newlen = strlen(res) + strlen(symval) + strlen(src); + newlen = strlen(res) + strlen(symval) + strlen(src) + 1; if (newlen > reslen) { reslen = newlen; res = realloc(res, reslen); -- cgit v1.2.3 From 8af27e1dc4e4dd7a7b04c2cd0fc3d419d91d45b0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 9 Nov 2010 16:29:27 +0100 Subject: fixdep: use hash table instead of a single array I noticed fixdep uses ~2% of cpu time in kernel build, in function use_config() fixdep spends a lot of cpu cycles in linear searches in its internal string array. With about 400 stored strings per dep file, this begins to be noticeable. Convert fixdep to use a hash table. kbuild results on my x86_64 allmodconfig Before patch : real 10m30.414s user 61m51.456s sys 8m28.200s real 10m12.334s user 61m50.236s sys 8m30.448s real 10m42.947s user 61m50.028s sys 8m32.380s After: real 10m8.180s user 61m22.506s sys 8m32.384s real 10m35.039s user 61m21.654s sys 8m32.212s real 10m14.487s user 61m23.498s sys 8m32.312s Signed-off-by: Eric Dumazet Signed-off-by: Michal Marek --- scripts/basic/fixdep.c | 109 +++++++++++++++++++++++++++---------------------- 1 file changed, 61 insertions(+), 48 deletions(-) (limited to 'scripts') diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index ea26b23de082..ed0584623690 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -138,38 +138,36 @@ static void print_cmdline(void) printf("cmd_%s := %s\n\n", target, cmdline); } -char * str_config = NULL; -int size_config = 0; -int len_config = 0; +struct item { + struct item *next; + unsigned int len; + unsigned int hash; + char name[0]; +}; -/* - * Grow the configuration string to a desired length. - * Usually the first growth is plenty. - */ -static void grow_config(int len) -{ - while (len_config + len > size_config) { - if (size_config == 0) - size_config = 2048; - str_config = realloc(str_config, size_config *= 2); - if (str_config == NULL) - { perror("fixdep:malloc"); exit(1); } - } -} +#define HASHSZ 256 +static struct item *hashtab[HASHSZ]; +static unsigned int strhash(const char *str, unsigned int sz) +{ + /* fnv32 hash */ + unsigned int i, hash = 2166136261U; + for (i = 0; i < sz; i++) + hash = (hash ^ str[i]) * 0x01000193; + return hash; +} /* * Lookup a value in the configuration string. */ -static int is_defined_config(const char * name, int len) +static int is_defined_config(const char *name, int len, unsigned int hash) { - const char * pconfig; - const char * plast = str_config + len_config - len; - for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) { - if (pconfig[ -1] == '\n' - && pconfig[len] == '\n' - && !memcmp(pconfig, name, len)) + struct item *aux; + + for (aux = hashtab[hash % HASHSZ]; aux; aux = aux->next) { + if (aux->hash == hash && aux->len == len && + memcmp(aux->name, name, len) == 0) return 1; } return 0; @@ -178,13 +176,19 @@ static int is_defined_config(const char * name, int len) /* * Add a new value to the configuration string. */ -static void define_config(const char * name, int len) +static void define_config(const char *name, int len, unsigned int hash) { - grow_config(len + 1); + struct item *aux = malloc(sizeof(*aux) + len); - memcpy(str_config+len_config, name, len); - len_config += len; - str_config[len_config++] = '\n'; + if (!aux) { + perror("fixdep:malloc"); + exit(1); + } + memcpy(aux->name, name, len); + aux->len = len; + aux->hash = hash; + aux->next = hashtab[hash % HASHSZ]; + hashtab[hash % HASHSZ] = aux; } /* @@ -192,40 +196,49 @@ static void define_config(const char * name, int len) */ static void clear_config(void) { - len_config = 0; - define_config("", 0); + struct item *aux, *next; + unsigned int i; + + for (i = 0; i < HASHSZ; i++) { + for (aux = hashtab[i]; aux; aux = next) { + next = aux->next; + free(aux); + } + hashtab[i] = NULL; + } } /* * Record the use of a CONFIG_* word. */ -static void use_config(char *m, int slen) +static void use_config(const char *m, int slen) { - char s[PATH_MAX]; - char *p; + unsigned int hash = strhash(m, slen); + int c, i; - if (is_defined_config(m, slen)) + if (is_defined_config(m, slen, hash)) return; - define_config(m, slen); - - memcpy(s, m, slen); s[slen] = 0; + define_config(m, slen, hash); - for (p = s; p < s + slen; p++) { - if (*p == '_') - *p = '/'; + printf(" $(wildcard include/config/"); + for (i = 0; i < slen; i++) { + c = m[i]; + if (c == '_') + c = '/'; else - *p = tolower((int)*p); + c = tolower(c); + putchar(c); } - printf(" $(wildcard include/config/%s.h) \\\n", s); + printf(".h) \\\n"); } -static void parse_config_file(char *map, size_t len) +static void parse_config_file(const char *map, size_t len) { - int *end = (int *) (map + len); + const int *end = (const int *) (map + len); /* start at +1, so that p can never be < map */ - int *m = (int *) map + 1; - char *p, *q; + const int *m = (const int *) map + 1; + const char *p, *q; for (; m < end; m++) { if (*m == INT_CONF) { p = (char *) m ; goto conf; } @@ -265,7 +278,7 @@ static int strrcmp(char *s, char *sub) return memcmp(s + slen - sublen, sub, sublen); } -static void do_config_file(char *filename) +static void do_config_file(const char *filename) { struct stat st; int fd; -- cgit v1.2.3 From 45677454dd6d128608117abe7dcd2bdfdd7cdf72 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Thu, 28 Oct 2010 00:24:34 +0800 Subject: ftrace: Speed up recordmcount cmd_record_mcount is used to locate the _mcount symbols in the object files, only the files compiled with -pg has the _mcount symbol, so, it is only needed for such files, but the current cmd_record_mcount is used for all of the object files, so, we need to fix it and speed it up. Since -pg may be removed by the method used in kernel/trace/Makefile: ORIG_CFLAGS := $(KBUILD_CFLAGS) KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS)) Or may be removed by the method used in arch/x86/kernel/Makefile: CFLAGS_REMOVE_file.o = -pg So, we must check the last variable stores the compiling flags, that is c_flags(Please refer to cmd_cc_o_c and rule_cc_o_c defined in scripts/Makefile.build) and since the CFLAGS_REMOVE_file.o is already filtered in _c_flags(Please refer to scripts/Makefile.lib) and _c_flags has less symbols, therefore, we only need to check _c_flags. --------------- Changes from v1: o Don't touch Makefile for CONFIG_FTRACE_MCOUNT_RECORD is enough o Use _c_flags intead of KBUILD_CFLAGS to cover CONFIG_REMOVE_file.o = -pg (feedback from Steven Rostedt ) Acked-by: Michal Marek Signed-off-by: Wu Zhangjin LKML-Reference: <3dc8cddf022eb7024f9f2cf857529a15bee8999a.1288196498.git.wuzhangjin@gmail.com> [ changed if [ .. == .. ] to if [ .. = .. ] to handle dash environments ] Signed-off-by: Steven Rostedt --- scripts/Makefile.build | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 5ad25e17b6cb..4eb99ab34053 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -214,17 +214,22 @@ ifdef BUILD_C_RECORDMCOUNT # The empty.o file is created in the make process in order to determine # the target endianness and word size. It is made before all other C # files, including recordmcount. -cmd_record_mcount = if [ $(@) != "scripts/mod/empty.o" ]; then \ - $(objtree)/scripts/recordmcount "$(@)"; \ - fi; +sub_cmd_record_mcount = \ + if [ $(@) != "scripts/mod/empty.o" ]; then \ + $(objtree)/scripts/recordmcount "$(@)"; \ + fi; else -cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ +sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \ "$(if $(CONFIG_64BIT),64,32)" \ "$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CFLAGS)" \ "$(LD)" "$(NM)" "$(RM)" "$(MV)" \ "$(if $(part-of-module),1,0)" "$(@)"; endif +cmd_record_mcount = \ + if [ "$(findstring -pg,$(_c_flags))" = "-pg" ]; then \ + $(sub_cmd_record_mcount) \ + fi; endif define rule_cc_o_c -- cgit v1.2.3 From 2b35f4d9cab365d37c7b34ce51e1c1144c312d05 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 18 Nov 2010 12:27:31 -0800 Subject: kernel-doc: escape xml for structs scripts/kernel-doc was leaving unescaped '<', '>', and '&' in generated xml output for structs. This causes xml parser errors. Convert these characters to "<", ">", and "&" as needed to prevent errors. Most of the conversion was already done; complete it just before output. Documentation/DocBook/device-drivers.xml:41883: parser error : StartTag: invalid element name #define INPUT_KEYMAP_BY_INDEX (1 << 0) Signed-off-by: Randy Dunlap Signed-off-by: Linus Torvalds --- scripts/kernel-doc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index cdb6dc1f6458..39580a5dc5df 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 ## ## Copyright (C) 2001 Simon Huggins ## -## Copyright (C) 2005-2009 Randy Dunlap ## +## Copyright (C) 2005-2010 Randy Dunlap ## ## ## ## #define enhancements by Armin Kuster ## ## Copyright (c) 2000 MontaVista Software, Inc. ## @@ -453,7 +453,7 @@ sub output_highlight { if ($output_mode eq "html" || $output_mode eq "xml") { $contents = local_unescape($contents); # convert data read & converted thru xml_escape() into &xyz; format: - $contents =~ s/\\\\\\/&/g; + $contents =~ s/\\\\\\/\&/g; } # print STDERR "contents b4:$contents\n"; eval $dohighlight; @@ -770,7 +770,11 @@ sub output_struct_xml(%) { print $args{'type'} . " " . $args{'struct'} . " {\n"; foreach $parameter (@{$args{'parameterlist'}}) { if ($parameter =~ /^#/) { - print "$parameter\n"; + my $prm = $parameter; + # convert data read & converted thru xml_escape() into &xyz; format: + # This allows us to have #define macros interspersed in a struct. + $prm =~ s/\\\\\\/\&/g; + print "$prm\n"; next; } @@ -1701,6 +1705,8 @@ sub push_parameter($$$) { } } + $param = xml_escape($param); + # strip spaces from $param so that it is one continous string # on @parameterlist; # this fixes a problem where check_sections() cannot find -- cgit v1.2.3 From 86e187ff9bce9fbed7bfed92ae34f491cf1af50f Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sat, 6 Nov 2010 18:30:23 -0300 Subject: kconfig: add an option to determine a menu's visibility This option is aimed to add the possibility to control a menu's visibility without adding dependency to the expression to all the submenu. Signed-off-by: Arnaud Lacombe Acked-by: Mauro Carvalho Chehab Tested-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- scripts/kconfig/expr.h | 1 + scripts/kconfig/lkc.h | 1 + scripts/kconfig/menu.c | 11 +++++++++++ scripts/kconfig/zconf.gperf | 1 + scripts/kconfig/zconf.y | 21 ++++++++++++++++++--- 5 files changed, 32 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 184eb6a0b505..e57826ced380 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -164,6 +164,7 @@ struct menu { struct menu *list; struct symbol *sym; struct property *prompt; + struct expr *visibility; struct expr *dep; unsigned int flags; char *help; diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 753cdbd7b805..3f7240df0f3b 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -107,6 +107,7 @@ void menu_end_menu(void); void menu_add_entry(struct symbol *sym); void menu_end_entry(void); void menu_add_dep(struct expr *dep); +void menu_add_visibility(struct expr *dep); struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep); struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 7e83aef42c6d..b9d9aa18e6d6 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -152,6 +152,12 @@ struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr return menu_add_prop(type, prompt, NULL, dep); } +void menu_add_visibility(struct expr *expr) +{ + current_entry->visibility = expr_alloc_and(current_entry->visibility, + expr); +} + void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep) { menu_add_prop(type, NULL, expr, dep); @@ -410,6 +416,11 @@ bool menu_is_visible(struct menu *menu) if (!menu->prompt) return false; + if (menu->visibility) { + if (expr_calc_value(menu->visibility) == no) + return no; + } + sym = menu->sym; if (sym) { sym_calc_value(sym); diff --git a/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf index d8bc74249622..c9e690eb7545 100644 --- a/scripts/kconfig/zconf.gperf +++ b/scripts/kconfig/zconf.gperf @@ -38,6 +38,7 @@ hex, T_TYPE, TF_COMMAND, S_HEX string, T_TYPE, TF_COMMAND, S_STRING select, T_SELECT, TF_COMMAND range, T_RANGE, TF_COMMAND +visible, T_VISIBLE, TF_COMMAND option, T_OPTION, TF_COMMAND on, T_ON, TF_PARAM modules, T_OPT_MODULES, TF_OPTION diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y index 2abd3c7ff15d..49fb4ab664c3 100644 --- a/scripts/kconfig/zconf.y +++ b/scripts/kconfig/zconf.y @@ -36,7 +36,7 @@ static struct menu *current_menu, *current_entry; #define YYERROR_VERBOSE #endif %} -%expect 28 +%expect 30 %union { @@ -68,6 +68,7 @@ static struct menu *current_menu, *current_entry; %token T_DEFAULT %token T_SELECT %token T_RANGE +%token T_VISIBLE %token T_OPTION %token T_ON %token T_WORD @@ -123,7 +124,7 @@ stmt_list: ; option_name: - T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT + T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE ; common_stmt: @@ -359,7 +360,7 @@ menu: T_MENU prompt T_EOL printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); }; -menu_entry: menu depends_list +menu_entry: menu visibility_list depends_list { $$ = menu_add_menu(); }; @@ -430,6 +431,19 @@ depends: T_DEPENDS T_ON expr T_EOL printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); }; +/* visibility option */ + +visibility_list: + /* empty */ + | visibility_list visible + | visibility_list T_EOL +; + +visible: T_VISIBLE if_expr +{ + menu_add_visibility($2); +}; + /* prompt statement */ prompt_stmt_opt: @@ -526,6 +540,7 @@ static const char *zconf_tokenname(int token) case T_IF: return "if"; case T_ENDIF: return "endif"; case T_DEPENDS: return "depends"; + case T_VISIBLE: return "visible"; } return ""; } -- cgit v1.2.3 From 09899c93b183870b122c94317f63344df43368e9 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sat, 6 Nov 2010 18:30:24 -0300 Subject: kconfig: regen parser Signed-off-by: Arnaud Lacombe Signed-off-by: Mauro Carvalho Chehab --- scripts/kconfig/zconf.hash.c_shipped | 122 ++++---- scripts/kconfig/zconf.tab.c_shipped | 570 ++++++++++++++++++----------------- 2 files changed, 358 insertions(+), 334 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped index c1748faf4634..4055d5de1750 100644 --- a/scripts/kconfig/zconf.hash.c_shipped +++ b/scripts/kconfig/zconf.hash.c_shipped @@ -32,7 +32,7 @@ struct kconf_id; static struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len); -/* maximum key range = 47, duplicates = 0 */ +/* maximum key range = 50, duplicates = 0 */ #ifdef __GNUC__ __inline @@ -46,32 +46,32 @@ kconf_id_hash (register const char *str, register unsigned int len) { static unsigned char asso_values[] = { - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 11, 5, - 0, 0, 5, 49, 5, 20, 49, 49, 5, 20, - 5, 0, 30, 49, 0, 15, 0, 10, 0, 49, - 25, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49 + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 40, 5, + 0, 0, 5, 52, 0, 20, 52, 52, 10, 20, + 5, 0, 35, 52, 0, 30, 0, 15, 0, 52, + 15, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52 }; register int hval = len; @@ -102,25 +102,26 @@ struct kconf_id_strings_t char kconf_id_strings_str12[sizeof("default")]; char kconf_id_strings_str13[sizeof("def_bool")]; char kconf_id_strings_str14[sizeof("help")]; - char kconf_id_strings_str15[sizeof("bool")]; char kconf_id_strings_str16[sizeof("config")]; char kconf_id_strings_str17[sizeof("def_tristate")]; - char kconf_id_strings_str18[sizeof("boolean")]; + char kconf_id_strings_str18[sizeof("hex")]; char kconf_id_strings_str19[sizeof("defconfig_list")]; - char kconf_id_strings_str21[sizeof("string")]; char kconf_id_strings_str22[sizeof("if")]; char kconf_id_strings_str23[sizeof("int")]; - char kconf_id_strings_str26[sizeof("select")]; char kconf_id_strings_str27[sizeof("modules")]; char kconf_id_strings_str28[sizeof("tristate")]; char kconf_id_strings_str29[sizeof("menu")]; - char kconf_id_strings_str31[sizeof("source")]; char kconf_id_strings_str32[sizeof("comment")]; - char kconf_id_strings_str33[sizeof("hex")]; char kconf_id_strings_str35[sizeof("menuconfig")]; - char kconf_id_strings_str36[sizeof("prompt")]; - char kconf_id_strings_str37[sizeof("depends")]; + char kconf_id_strings_str36[sizeof("string")]; + char kconf_id_strings_str37[sizeof("visible")]; + char kconf_id_strings_str41[sizeof("prompt")]; + char kconf_id_strings_str42[sizeof("depends")]; + char kconf_id_strings_str44[sizeof("bool")]; + char kconf_id_strings_str46[sizeof("select")]; + char kconf_id_strings_str47[sizeof("boolean")]; char kconf_id_strings_str48[sizeof("mainmenu")]; + char kconf_id_strings_str51[sizeof("source")]; }; static struct kconf_id_strings_t kconf_id_strings_contents = { @@ -136,25 +137,26 @@ static struct kconf_id_strings_t kconf_id_strings_contents = "default", "def_bool", "help", - "bool", "config", "def_tristate", - "boolean", + "hex", "defconfig_list", - "string", "if", "int", - "select", "modules", "tristate", "menu", - "source", "comment", - "hex", "menuconfig", + "string", + "visible", "prompt", "depends", - "mainmenu" + "bool", + "select", + "boolean", + "mainmenu", + "source" }; #define kconf_id_strings ((const char *) &kconf_id_strings_contents) #ifdef __GNUC__ @@ -168,11 +170,11 @@ kconf_id_lookup (register const char *str, register unsigned int len) { enum { - TOTAL_KEYWORDS = 31, + TOTAL_KEYWORDS = 32, MIN_WORD_LENGTH = 2, MAX_WORD_LENGTH = 14, MIN_HASH_VALUE = 2, - MAX_HASH_VALUE = 48 + MAX_HASH_VALUE = 51 }; static struct kconf_id wordlist[] = @@ -191,31 +193,35 @@ kconf_id_lookup (register const char *str, register unsigned int len) {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_HELP, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str15, T_TYPE, TF_COMMAND, S_BOOLEAN}, + {-1}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_CONFIG, TF_COMMAND}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_TYPE, TF_COMMAND, S_BOOLEAN}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_TYPE, TF_COMMAND, S_HEX}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str19, T_OPT_DEFCONFIG_LIST,TF_OPTION}, - {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_TYPE, TF_COMMAND, S_STRING}, + {-1}, {-1}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_IF, TF_COMMAND|TF_PARAM}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_INT}, - {-1}, {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SELECT, TF_COMMAND}, + {-1}, {-1}, {-1}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_TYPE, TF_COMMAND, S_TRISTATE}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND}, - {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SOURCE, TF_COMMAND}, + {-1}, {-1}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_TYPE, TF_COMMAND, S_HEX}, - {-1}, + {-1}, {-1}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_MENUCONFIG, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_PROMPT, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_DEPENDS, TF_COMMAND}, - {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_TYPE, TF_COMMAND, S_STRING}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_VISIBLE, TF_COMMAND}, + {-1}, {-1}, {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_PROMPT, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42, T_DEPENDS, TF_COMMAND}, {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48, T_MAINMENU, TF_COMMAND} + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str44, T_TYPE, TF_COMMAND, S_BOOLEAN}, + {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_SELECT, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str47, T_TYPE, TF_COMMAND, S_BOOLEAN}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48, T_MAINMENU, TF_COMMAND}, + {-1}, {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str51, T_SOURCE, TF_COMMAND} }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped index 699d4b265186..4c5495ea205e 100644 --- a/scripts/kconfig/zconf.tab.c_shipped +++ b/scripts/kconfig/zconf.tab.c_shipped @@ -160,18 +160,19 @@ static struct menu *current_menu, *current_entry; T_DEFAULT = 275, T_SELECT = 276, T_RANGE = 277, - T_OPTION = 278, - T_ON = 279, - T_WORD = 280, - T_WORD_QUOTE = 281, - T_UNEQUAL = 282, - T_CLOSE_PAREN = 283, - T_OPEN_PAREN = 284, - T_EOL = 285, - T_OR = 286, - T_AND = 287, - T_EQUAL = 288, - T_NOT = 289 + T_VISIBLE = 278, + T_OPTION = 279, + T_ON = 280, + T_WORD = 281, + T_WORD_QUOTE = 282, + T_UNEQUAL = 283, + T_CLOSE_PAREN = 284, + T_OPEN_PAREN = 285, + T_EOL = 286, + T_OR = 287, + T_AND = 288, + T_EQUAL = 289, + T_NOT = 290 }; #endif @@ -419,20 +420,20 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 11 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 277 +#define YYLAST 290 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 35 +#define YYNTOKENS 36 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 48 +#define YYNNTS 50 /* YYNRULES -- Number of rules. */ -#define YYNRULES 113 +#define YYNRULES 118 /* YYNRULES -- Number of states. */ -#define YYNSTATES 185 +#define YYNSTATES 191 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 289 +#define YYMAXUTOK 290 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -468,7 +469,8 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35 }; #if YYDEBUG @@ -478,72 +480,73 @@ static const yytype_uint16 yyprhs[] = { 0, 0, 3, 6, 8, 11, 13, 14, 17, 20, 23, 26, 31, 36, 40, 42, 44, 46, 48, 50, - 52, 54, 56, 58, 60, 62, 64, 66, 70, 73, - 77, 80, 84, 87, 88, 91, 94, 97, 100, 103, - 106, 110, 115, 120, 125, 131, 135, 136, 140, 141, - 144, 148, 151, 153, 157, 158, 161, 164, 167, 170, - 173, 178, 182, 185, 190, 191, 194, 198, 200, 204, - 205, 208, 211, 214, 218, 222, 225, 227, 231, 232, - 235, 238, 241, 245, 249, 252, 255, 258, 259, 262, - 265, 268, 273, 274, 277, 279, 281, 284, 287, 290, - 292, 295, 296, 299, 301, 305, 309, 313, 316, 320, - 324, 326, 328, 329 + 52, 54, 56, 58, 60, 62, 64, 66, 68, 72, + 75, 79, 82, 86, 89, 90, 93, 96, 99, 102, + 105, 108, 112, 117, 122, 127, 133, 137, 138, 142, + 143, 146, 150, 153, 155, 159, 160, 163, 166, 169, + 172, 175, 180, 184, 187, 192, 193, 196, 200, 202, + 206, 207, 210, 213, 216, 220, 224, 228, 230, 234, + 235, 238, 241, 244, 248, 252, 255, 258, 261, 262, + 265, 268, 271, 276, 277, 280, 283, 286, 287, 290, + 292, 294, 297, 300, 303, 305, 308, 309, 312, 314, + 318, 322, 326, 329, 333, 337, 339, 341, 342 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 36, 0, -1, 78, 37, -1, 37, -1, 62, 38, - -1, 38, -1, -1, 38, 40, -1, 38, 54, -1, - 38, 66, -1, 38, 77, -1, 38, 25, 1, 30, - -1, 38, 39, 1, 30, -1, 38, 1, 30, -1, + 37, 0, -1, 81, 38, -1, 38, -1, 63, 39, + -1, 39, -1, -1, 39, 41, -1, 39, 55, -1, + 39, 67, -1, 39, 80, -1, 39, 26, 1, 31, + -1, 39, 40, 1, 31, -1, 39, 1, 31, -1, 16, -1, 18, -1, 19, -1, 21, -1, 17, -1, - 22, -1, 20, -1, 30, -1, 60, -1, 70, -1, - 43, -1, 45, -1, 68, -1, 25, 1, 30, -1, - 1, 30, -1, 10, 25, 30, -1, 42, 46, -1, - 11, 25, 30, -1, 44, 46, -1, -1, 46, 47, - -1, 46, 48, -1, 46, 74, -1, 46, 72, -1, - 46, 41, -1, 46, 30, -1, 19, 75, 30, -1, - 18, 76, 79, 30, -1, 20, 80, 79, 30, -1, - 21, 25, 79, 30, -1, 22, 81, 81, 79, 30, - -1, 23, 49, 30, -1, -1, 49, 25, 50, -1, - -1, 33, 76, -1, 7, 82, 30, -1, 51, 55, - -1, 77, -1, 52, 57, 53, -1, -1, 55, 56, - -1, 55, 74, -1, 55, 72, -1, 55, 30, -1, - 55, 41, -1, 18, 76, 79, 30, -1, 19, 75, - 30, -1, 17, 30, -1, 20, 25, 79, 30, -1, - -1, 57, 40, -1, 14, 80, 78, -1, 77, -1, - 58, 61, 59, -1, -1, 61, 40, -1, 61, 66, - -1, 61, 54, -1, 3, 76, 78, -1, 4, 76, - 30, -1, 63, 73, -1, 77, -1, 64, 67, 65, - -1, -1, 67, 40, -1, 67, 66, -1, 67, 54, - -1, 6, 76, 30, -1, 9, 76, 30, -1, 69, - 73, -1, 12, 30, -1, 71, 13, -1, -1, 73, - 74, -1, 73, 30, -1, 73, 41, -1, 16, 24, - 80, 30, -1, -1, 76, 79, -1, 25, -1, 26, - -1, 5, 30, -1, 8, 30, -1, 15, 30, -1, - 30, -1, 78, 30, -1, -1, 14, 80, -1, 81, - -1, 81, 33, 81, -1, 81, 27, 81, -1, 29, - 80, 28, -1, 34, 80, -1, 80, 31, 80, -1, - 80, 32, 80, -1, 25, -1, 26, -1, -1, 25, - -1 + 22, -1, 20, -1, 23, -1, 31, -1, 61, -1, + 71, -1, 44, -1, 46, -1, 69, -1, 26, 1, + 31, -1, 1, 31, -1, 10, 26, 31, -1, 43, + 47, -1, 11, 26, 31, -1, 45, 47, -1, -1, + 47, 48, -1, 47, 49, -1, 47, 75, -1, 47, + 73, -1, 47, 42, -1, 47, 31, -1, 19, 78, + 31, -1, 18, 79, 82, 31, -1, 20, 83, 82, + 31, -1, 21, 26, 82, 31, -1, 22, 84, 84, + 82, 31, -1, 24, 50, 31, -1, -1, 50, 26, + 51, -1, -1, 34, 79, -1, 7, 85, 31, -1, + 52, 56, -1, 80, -1, 53, 58, 54, -1, -1, + 56, 57, -1, 56, 75, -1, 56, 73, -1, 56, + 31, -1, 56, 42, -1, 18, 79, 82, 31, -1, + 19, 78, 31, -1, 17, 31, -1, 20, 26, 82, + 31, -1, -1, 58, 41, -1, 14, 83, 81, -1, + 80, -1, 59, 62, 60, -1, -1, 62, 41, -1, + 62, 67, -1, 62, 55, -1, 3, 79, 81, -1, + 4, 79, 31, -1, 64, 76, 74, -1, 80, -1, + 65, 68, 66, -1, -1, 68, 41, -1, 68, 67, + -1, 68, 55, -1, 6, 79, 31, -1, 9, 79, + 31, -1, 70, 74, -1, 12, 31, -1, 72, 13, + -1, -1, 74, 75, -1, 74, 31, -1, 74, 42, + -1, 16, 25, 83, 31, -1, -1, 76, 77, -1, + 76, 31, -1, 23, 82, -1, -1, 79, 82, -1, + 26, -1, 27, -1, 5, 31, -1, 8, 31, -1, + 15, 31, -1, 31, -1, 81, 31, -1, -1, 14, + 83, -1, 84, -1, 84, 34, 84, -1, 84, 28, + 84, -1, 30, 83, 29, -1, 35, 83, -1, 83, + 32, 83, -1, 83, 33, 83, -1, 26, -1, 27, + -1, -1, 26, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 107, 107, 107, 109, 109, 111, 113, 114, 115, - 116, 117, 118, 122, 126, 126, 126, 126, 126, 126, - 126, 130, 131, 132, 133, 134, 135, 139, 140, 146, - 154, 160, 168, 178, 180, 181, 182, 183, 184, 185, - 188, 196, 202, 212, 218, 224, 227, 229, 240, 241, - 246, 255, 260, 268, 271, 273, 274, 275, 276, 277, - 280, 286, 297, 303, 313, 315, 320, 328, 336, 339, - 341, 342, 343, 348, 355, 362, 367, 375, 378, 380, - 381, 382, 385, 393, 400, 407, 413, 420, 422, 423, - 424, 427, 435, 437, 442, 443, 446, 447, 448, 452, - 453, 456, 457, 460, 461, 462, 463, 464, 465, 466, - 469, 470, 473, 474 + 0, 108, 108, 108, 110, 110, 112, 114, 115, 116, + 117, 118, 119, 123, 127, 127, 127, 127, 127, 127, + 127, 127, 131, 132, 133, 134, 135, 136, 140, 141, + 147, 155, 161, 169, 179, 181, 182, 183, 184, 185, + 186, 189, 197, 203, 213, 219, 225, 228, 230, 241, + 242, 247, 256, 261, 269, 272, 274, 275, 276, 277, + 278, 281, 287, 298, 304, 314, 316, 321, 329, 337, + 340, 342, 343, 344, 349, 356, 363, 368, 376, 379, + 381, 382, 383, 386, 394, 401, 408, 414, 421, 423, + 424, 425, 428, 436, 438, 439, 442, 449, 451, 456, + 457, 460, 461, 462, 466, 467, 470, 471, 474, 475, + 476, 477, 478, 479, 480, 483, 484, 487, 488 }; #endif @@ -556,7 +559,7 @@ static const char *const yytname[] = "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG", "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS", "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_RANGE", - "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", + "T_VISIBLE", "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL", "T_NOT", "$accept", "input", "start", "stmt_list", "option_name", "common_stmt", "option_error", "config_entry_start", "config_stmt", @@ -567,8 +570,8 @@ static const char *const yytname[] = "if_entry", "if_end", "if_stmt", "if_block", "mainmenu_stmt", "menu", "menu_entry", "menu_end", "menu_stmt", "menu_block", "source_stmt", "comment", "comment_stmt", "help_start", "help", "depends_list", - "depends", "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr", - "symbol", "word_opt", 0 + "depends", "visibility_list", "visible", "prompt_stmt_opt", "prompt", + "end", "nl", "if_expr", "expr", "symbol", "word_opt", 0 }; #endif @@ -580,25 +583,25 @@ static const yytype_uint16 yytoknum[] = 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289 + 285, 286, 287, 288, 289, 290 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 35, 36, 36, 37, 37, 38, 38, 38, 38, - 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, - 39, 40, 40, 40, 40, 40, 40, 41, 41, 42, - 43, 44, 45, 46, 46, 46, 46, 46, 46, 46, - 47, 47, 47, 47, 47, 48, 49, 49, 50, 50, - 51, 52, 53, 54, 55, 55, 55, 55, 55, 55, - 56, 56, 56, 56, 57, 57, 58, 59, 60, 61, - 61, 61, 61, 62, 63, 64, 65, 66, 67, 67, - 67, 67, 68, 69, 70, 71, 72, 73, 73, 73, - 73, 74, 75, 75, 76, 76, 77, 77, 77, 78, - 78, 79, 79, 80, 80, 80, 80, 80, 80, 80, - 81, 81, 82, 82 + 0, 36, 37, 37, 38, 38, 39, 39, 39, 39, + 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, + 40, 40, 41, 41, 41, 41, 41, 41, 42, 42, + 43, 44, 45, 46, 47, 47, 47, 47, 47, 47, + 47, 48, 48, 48, 48, 48, 49, 50, 50, 51, + 51, 52, 53, 54, 55, 56, 56, 56, 56, 56, + 56, 57, 57, 57, 57, 58, 58, 59, 60, 61, + 62, 62, 62, 62, 63, 64, 65, 66, 67, 68, + 68, 68, 68, 69, 70, 71, 72, 73, 74, 74, + 74, 74, 75, 76, 76, 76, 77, 78, 78, 79, + 79, 80, 80, 80, 81, 81, 82, 82, 83, 83, + 83, 83, 83, 83, 83, 84, 84, 85, 85 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -606,16 +609,16 @@ static const yytype_uint8 yyr2[] = { 0, 2, 2, 1, 2, 1, 0, 2, 2, 2, 2, 4, 4, 3, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 3, 2, 3, - 2, 3, 2, 0, 2, 2, 2, 2, 2, 2, - 3, 4, 4, 4, 5, 3, 0, 3, 0, 2, - 3, 2, 1, 3, 0, 2, 2, 2, 2, 2, - 4, 3, 2, 4, 0, 2, 3, 1, 3, 0, - 2, 2, 2, 3, 3, 2, 1, 3, 0, 2, - 2, 2, 3, 3, 2, 2, 2, 0, 2, 2, - 2, 4, 0, 2, 1, 1, 2, 2, 2, 1, - 2, 0, 2, 1, 3, 3, 3, 2, 3, 3, - 1, 1, 0, 1 + 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, + 3, 2, 3, 2, 0, 2, 2, 2, 2, 2, + 2, 3, 4, 4, 4, 5, 3, 0, 3, 0, + 2, 3, 2, 1, 3, 0, 2, 2, 2, 2, + 2, 4, 3, 2, 4, 0, 2, 3, 1, 3, + 0, 2, 2, 2, 3, 3, 3, 1, 3, 0, + 2, 2, 2, 3, 3, 2, 2, 2, 0, 2, + 2, 2, 4, 0, 2, 2, 2, 0, 2, 1, + 1, 2, 2, 2, 1, 2, 0, 2, 1, 3, + 3, 3, 2, 3, 3, 1, 1, 0, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -623,165 +626,172 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 6, 0, 99, 0, 3, 0, 6, 6, 94, 95, - 0, 1, 0, 0, 0, 0, 112, 0, 0, 0, + 6, 0, 104, 0, 3, 0, 6, 6, 99, 100, + 0, 1, 0, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 14, 18, 15, 16, 20, 17, 19, - 0, 21, 0, 7, 33, 24, 33, 25, 54, 64, - 8, 69, 22, 87, 78, 9, 26, 87, 23, 10, - 0, 100, 2, 73, 13, 0, 96, 0, 113, 0, - 97, 0, 0, 0, 110, 111, 0, 0, 0, 103, - 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 74, 82, 50, 83, 29, 31, 0, 107, 0, - 0, 66, 0, 0, 11, 12, 0, 0, 0, 0, - 92, 0, 0, 0, 46, 0, 39, 38, 34, 35, - 0, 37, 36, 0, 0, 92, 0, 58, 59, 55, - 57, 56, 65, 53, 52, 70, 72, 68, 71, 67, - 89, 90, 88, 79, 81, 77, 80, 76, 106, 108, - 109, 105, 104, 28, 85, 0, 101, 0, 101, 101, - 101, 0, 0, 0, 86, 62, 101, 0, 101, 0, - 0, 0, 40, 93, 0, 0, 101, 48, 45, 27, - 0, 61, 0, 91, 102, 41, 42, 43, 0, 0, - 47, 60, 63, 44, 49 + 21, 0, 22, 0, 7, 34, 25, 34, 26, 55, + 65, 8, 70, 23, 93, 79, 9, 27, 88, 24, + 10, 0, 105, 2, 74, 13, 0, 101, 0, 118, + 0, 102, 0, 0, 0, 115, 116, 0, 0, 0, + 108, 103, 0, 0, 0, 0, 0, 0, 0, 88, + 0, 0, 75, 83, 51, 84, 30, 32, 0, 112, + 0, 0, 67, 0, 0, 11, 12, 0, 0, 0, + 0, 97, 0, 0, 0, 47, 0, 40, 39, 35, + 36, 0, 38, 37, 0, 0, 97, 0, 59, 60, + 56, 58, 57, 66, 54, 53, 71, 73, 69, 72, + 68, 106, 95, 0, 94, 80, 82, 78, 81, 77, + 90, 91, 89, 111, 113, 114, 110, 109, 29, 86, + 0, 106, 0, 106, 106, 106, 0, 0, 0, 87, + 63, 106, 0, 106, 0, 96, 0, 0, 41, 98, + 0, 0, 106, 49, 46, 28, 0, 62, 0, 107, + 92, 42, 43, 44, 0, 0, 48, 61, 64, 45, + 50 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 3, 4, 5, 32, 33, 107, 34, 35, 36, - 37, 73, 108, 109, 152, 180, 38, 39, 123, 40, - 75, 119, 76, 41, 127, 42, 77, 6, 43, 44, - 135, 45, 79, 46, 47, 48, 110, 111, 78, 112, - 147, 148, 49, 7, 161, 68, 69, 59 + -1, 3, 4, 5, 33, 34, 108, 35, 36, 37, + 38, 74, 109, 110, 157, 186, 39, 40, 124, 41, + 76, 120, 77, 42, 128, 43, 78, 6, 44, 45, + 137, 46, 80, 47, 48, 49, 111, 112, 81, 113, + 79, 134, 152, 153, 50, 7, 165, 69, 70, 60 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -89 +#define YYPACT_NINF -90 static const yytype_int16 yypact[] = { - 3, 4, -89, 20, -89, 100, -89, 7, -89, -89, - -8, -89, 17, 4, 28, 4, 37, 36, 4, 68, - 87, -18, 69, -89, -89, -89, -89, -89, -89, -89, - 128, -89, 138, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - 127, -89, -89, 110, -89, 126, -89, 136, -89, 137, - -89, 147, 150, 152, -89, -89, -18, -18, 171, -14, - -89, 153, 157, 34, 67, 180, 233, 220, 207, 220, - 154, -89, -89, -89, -89, -89, -89, 0, -89, -18, - -18, 110, 44, 44, -89, -89, 163, 174, 182, 4, - 4, -18, 194, 44, -89, 219, -89, -89, -89, -89, - 223, -89, -89, 203, 4, 4, 215, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, 213, - -89, -89, -89, -89, -89, -18, 232, 227, 232, -5, - 232, 44, 35, 234, -89, -89, 232, 235, 232, 224, - -18, 236, -89, -89, 237, 238, 232, 216, -89, -89, - 240, -89, 241, -89, 71, -89, -89, -89, 242, 4, - -89, -89, -89, -89, -89 + 4, 42, -90, 96, -90, 111, -90, 15, -90, -90, + 75, -90, 82, 42, 104, 42, 110, 107, 42, 115, + 125, -4, 121, -90, -90, -90, -90, -90, -90, -90, + -90, 162, -90, 163, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, 139, -90, -90, 138, -90, 142, -90, 143, -90, + 152, -90, 164, 167, 168, -90, -90, -4, -4, 77, + -18, -90, 177, 185, 33, 71, 195, 247, 236, -2, + 236, 171, -90, -90, -90, -90, -90, -90, 41, -90, + -4, -4, 138, 97, 97, -90, -90, 186, 187, 194, + 42, 42, -4, 196, 97, -90, 219, -90, -90, -90, + -90, 210, -90, -90, 204, 42, 42, 199, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, 222, -90, 223, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, 215, -90, -90, -90, -90, -90, + -4, 222, 228, 222, -5, 222, 97, 35, 229, -90, + -90, 222, 232, 222, -4, -90, 135, 233, -90, -90, + 234, 235, 222, 240, -90, -90, 237, -90, 239, -13, + -90, -90, -90, -90, 244, 42, -90, -90, -90, -90, + -90 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -89, -89, 255, 267, -89, 47, -57, -89, -89, -89, - -89, 239, -89, -89, -89, -89, -89, -89, -89, 130, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, 181, -89, -89, -89, -89, -89, 199, 229, 16, - 162, -1, 74, -7, 103, -65, -88, -89 + -90, -90, 269, 271, -90, 23, -70, -90, -90, -90, + -90, 243, -90, -90, -90, -90, -90, -90, -90, -48, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -20, -90, -90, -90, -90, -90, 206, 205, -68, + -90, -90, 169, -1, 27, -7, 118, -66, -89, -90 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -85 +#define YYTABLE_NINF -86 static const yytype_int16 yytable[] = { - 10, 87, 88, 53, 141, 142, 1, 64, 65, 160, - 1, 66, 55, 92, 57, 151, 67, 61, 118, 93, - 11, 131, 2, 131, 139, 140, 89, 90, 138, 8, - 9, 89, 90, 2, -30, 96, 149, 51, -30, -30, - -30, -30, -30, -30, -30, -30, 97, 54, -30, -30, - 98, -30, 99, 100, 101, 102, 103, 104, 56, 105, - 167, 91, 58, 166, 106, 168, 60, -32, 96, 64, - 65, -32, -32, -32, -32, -32, -32, -32, -32, 97, - 159, -32, -32, 98, -32, 99, 100, 101, 102, 103, - 104, 121, 105, 62, 132, 174, 132, 106, 146, 70, - -5, 12, 89, 90, 13, 14, 15, 16, 17, 18, - 19, 20, 63, 156, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 122, 125, 30, 133, -4, 12, 71, - 31, 13, 14, 15, 16, 17, 18, 19, 20, 72, - 51, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 124, 129, 30, 137, -84, 96, 81, 31, -84, -84, - -84, -84, -84, -84, -84, -84, 82, 83, -84, -84, - 98, -84, -84, -84, -84, -84, -84, 84, 184, 105, - 85, 96, 86, 94, 130, -51, -51, 95, -51, -51, - -51, -51, 97, 143, -51, -51, 98, 113, 114, 115, - 116, 2, 89, 90, 144, 105, 145, 126, 96, 134, - 117, -75, -75, -75, -75, -75, -75, -75, -75, 150, - 153, -75, -75, 98, 13, 14, 15, 16, 17, 18, - 19, 20, 105, 155, 21, 22, 154, 130, 14, 15, - 158, 17, 18, 19, 20, 90, 160, 21, 22, 179, - 31, 163, 164, 165, 173, 89, 90, 162, 128, 170, - 136, 172, 52, 31, 169, 171, 175, 176, 177, 178, - 181, 182, 183, 50, 120, 74, 80, 157 + 10, 88, 89, 54, 146, 147, 119, 1, 122, 164, + 93, 141, 56, 142, 58, 156, 94, 62, 1, 90, + 91, 131, 65, 66, 144, 145, 67, 90, 91, 132, + 127, 68, 136, -31, 97, 2, 154, -31, -31, -31, + -31, -31, -31, -31, -31, 98, 52, -31, -31, 99, + -31, 100, 101, 102, 103, 104, -31, 105, 129, 106, + 138, 173, 92, 141, 107, 142, 174, 172, 8, 9, + 143, -33, 97, 90, 91, -33, -33, -33, -33, -33, + -33, -33, -33, 98, 166, -33, -33, 99, -33, 100, + 101, 102, 103, 104, -33, 105, 11, 106, 179, 151, + 123, 126, 107, 135, 125, 130, 2, 139, 2, 90, + 91, -5, 12, 55, 161, 13, 14, 15, 16, 17, + 18, 19, 20, 65, 66, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 57, 59, 31, 61, -4, + 12, 63, 32, 13, 14, 15, 16, 17, 18, 19, + 20, 64, 71, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 72, 73, 31, 180, 90, 91, 52, + 32, -85, 97, 82, 83, -85, -85, -85, -85, -85, + -85, -85, -85, 84, 190, -85, -85, 99, -85, -85, + -85, -85, -85, -85, -85, 85, 97, 106, 86, 87, + -52, -52, 140, -52, -52, -52, -52, 98, 95, -52, + -52, 99, 114, 115, 116, 117, 96, 148, 149, 150, + 158, 106, 155, 159, 97, 163, 118, -76, -76, -76, + -76, -76, -76, -76, -76, 160, 164, -76, -76, 99, + 13, 14, 15, 16, 17, 18, 19, 20, 91, 106, + 21, 22, 14, 15, 140, 17, 18, 19, 20, 168, + 175, 21, 22, 177, 181, 182, 183, 32, 187, 167, + 188, 169, 170, 171, 185, 189, 53, 51, 32, 176, + 75, 178, 121, 0, 133, 162, 0, 0, 0, 0, + 184 }; -static const yytype_uint8 yycheck[] = +static const yytype_int16 yycheck[] = { - 1, 66, 67, 10, 92, 93, 3, 25, 26, 14, - 3, 29, 13, 27, 15, 103, 34, 18, 75, 33, - 0, 78, 30, 80, 89, 90, 31, 32, 28, 25, - 26, 31, 32, 30, 0, 1, 101, 30, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 30, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 30, 25, - 25, 68, 25, 151, 30, 30, 30, 0, 1, 25, - 26, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 145, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 75, 25, 25, 78, 160, 80, 30, 99, 30, - 0, 1, 31, 32, 4, 5, 6, 7, 8, 9, - 10, 11, 25, 114, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 76, 77, 25, 79, 0, 1, 1, - 30, 4, 5, 6, 7, 8, 9, 10, 11, 1, - 30, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 76, 77, 25, 79, 0, 1, 30, 30, 4, 5, - 6, 7, 8, 9, 10, 11, 30, 30, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 30, 179, 25, - 30, 1, 30, 30, 30, 5, 6, 30, 8, 9, - 10, 11, 12, 30, 14, 15, 16, 17, 18, 19, - 20, 30, 31, 32, 30, 25, 24, 77, 1, 79, - 30, 4, 5, 6, 7, 8, 9, 10, 11, 25, - 1, 14, 15, 16, 4, 5, 6, 7, 8, 9, - 10, 11, 25, 30, 14, 15, 13, 30, 5, 6, - 25, 8, 9, 10, 11, 32, 14, 14, 15, 33, - 30, 148, 149, 150, 30, 31, 32, 30, 77, 156, - 79, 158, 7, 30, 30, 30, 30, 30, 30, 166, - 30, 30, 30, 6, 75, 36, 47, 115 + 1, 67, 68, 10, 93, 94, 76, 3, 76, 14, + 28, 81, 13, 81, 15, 104, 34, 18, 3, 32, + 33, 23, 26, 27, 90, 91, 30, 32, 33, 31, + 78, 35, 80, 0, 1, 31, 102, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 31, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 78, 26, + 80, 26, 69, 133, 31, 133, 31, 156, 26, 27, + 29, 0, 1, 32, 33, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 150, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 0, 26, 164, 100, + 77, 78, 31, 80, 77, 78, 31, 80, 31, 32, + 33, 0, 1, 31, 115, 4, 5, 6, 7, 8, + 9, 10, 11, 26, 27, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 31, 26, 26, 31, 0, + 1, 26, 31, 4, 5, 6, 7, 8, 9, 10, + 11, 26, 31, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 1, 1, 26, 31, 32, 33, 31, + 31, 0, 1, 31, 31, 4, 5, 6, 7, 8, + 9, 10, 11, 31, 185, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 31, 1, 26, 31, 31, + 5, 6, 31, 8, 9, 10, 11, 12, 31, 14, + 15, 16, 17, 18, 19, 20, 31, 31, 31, 25, + 1, 26, 26, 13, 1, 26, 31, 4, 5, 6, + 7, 8, 9, 10, 11, 31, 14, 14, 15, 16, + 4, 5, 6, 7, 8, 9, 10, 11, 33, 26, + 14, 15, 5, 6, 31, 8, 9, 10, 11, 31, + 31, 14, 15, 31, 31, 31, 31, 31, 31, 151, + 31, 153, 154, 155, 34, 31, 7, 6, 31, 161, + 37, 163, 76, -1, 79, 116, -1, -1, -1, -1, + 172 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 3, 30, 36, 37, 38, 62, 78, 25, 26, - 76, 0, 1, 4, 5, 6, 7, 8, 9, 10, + 0, 3, 31, 37, 38, 39, 63, 81, 26, 27, + 79, 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 25, 30, 39, 40, 42, 43, 44, 45, 51, 52, - 54, 58, 60, 63, 64, 66, 68, 69, 70, 77, - 38, 30, 37, 78, 30, 76, 30, 76, 25, 82, - 30, 76, 25, 25, 25, 26, 29, 34, 80, 81, - 30, 1, 1, 46, 46, 55, 57, 61, 73, 67, - 73, 30, 30, 30, 30, 30, 30, 80, 80, 31, - 32, 78, 27, 33, 30, 30, 1, 12, 16, 18, - 19, 20, 21, 22, 23, 25, 30, 41, 47, 48, - 71, 72, 74, 17, 18, 19, 20, 30, 41, 56, - 72, 74, 40, 53, 77, 40, 54, 59, 66, 77, - 30, 41, 74, 40, 54, 65, 66, 77, 28, 80, - 80, 81, 81, 30, 30, 24, 76, 75, 76, 80, - 25, 81, 49, 1, 13, 30, 76, 75, 25, 80, - 14, 79, 30, 79, 79, 79, 81, 25, 30, 30, - 79, 30, 79, 30, 80, 30, 30, 30, 79, 33, - 50, 30, 30, 30, 76 + 23, 26, 31, 40, 41, 43, 44, 45, 46, 52, + 53, 55, 59, 61, 64, 65, 67, 69, 70, 71, + 80, 39, 31, 38, 81, 31, 79, 31, 79, 26, + 85, 31, 79, 26, 26, 26, 27, 30, 35, 83, + 84, 31, 1, 1, 47, 47, 56, 58, 62, 76, + 68, 74, 31, 31, 31, 31, 31, 31, 83, 83, + 32, 33, 81, 28, 34, 31, 31, 1, 12, 16, + 18, 19, 20, 21, 22, 24, 26, 31, 42, 48, + 49, 72, 73, 75, 17, 18, 19, 20, 31, 42, + 57, 73, 75, 41, 54, 80, 41, 55, 60, 67, + 80, 23, 31, 74, 77, 41, 55, 66, 67, 80, + 31, 42, 75, 29, 83, 83, 84, 84, 31, 31, + 25, 79, 78, 79, 83, 26, 84, 50, 1, 13, + 31, 79, 78, 26, 14, 82, 83, 82, 31, 82, + 82, 82, 84, 26, 31, 31, 82, 31, 82, 83, + 31, 31, 31, 31, 82, 34, 51, 31, 31, 31, + 79 }; #define yyerrok (yyerrstatus = 0) @@ -1292,7 +1302,7 @@ yydestruct (yymsg, yytype, yyvaluep) switch (yytype) { - case 52: /* "choice_entry" */ + case 53: /* "choice_entry" */ { fprintf(stderr, "%s:%d: missing end statement for this entry\n", @@ -1302,7 +1312,7 @@ yydestruct (yymsg, yytype, yyvaluep) }; break; - case 58: /* "if_entry" */ + case 59: /* "if_entry" */ { fprintf(stderr, "%s:%d: missing end statement for this entry\n", @@ -1312,7 +1322,7 @@ yydestruct (yymsg, yytype, yyvaluep) }; break; - case 64: /* "menu_entry" */ + case 65: /* "menu_entry" */ { fprintf(stderr, "%s:%d: missing end statement for this entry\n", @@ -1644,17 +1654,17 @@ yyreduce: { zconf_error("invalid statement"); ;} break; - case 27: + case 28: { zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); ;} break; - case 28: + case 29: { zconf_error("invalid option"); ;} break; - case 29: + case 30: { struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0); @@ -1664,7 +1674,7 @@ yyreduce: ;} break; - case 30: + case 31: { menu_end_entry(); @@ -1672,7 +1682,7 @@ yyreduce: ;} break; - case 31: + case 32: { struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0); @@ -1682,7 +1692,7 @@ yyreduce: ;} break; - case 32: + case 33: { if (current_entry->prompt) @@ -1694,7 +1704,7 @@ yyreduce: ;} break; - case 40: + case 41: { menu_set_type((yyvsp[(1) - (3)].id)->stype); @@ -1704,7 +1714,7 @@ yyreduce: ;} break; - case 41: + case 42: { menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr)); @@ -1712,7 +1722,7 @@ yyreduce: ;} break; - case 42: + case 43: { menu_add_expr(P_DEFAULT, (yyvsp[(2) - (4)].expr), (yyvsp[(3) - (4)].expr)); @@ -1724,7 +1734,7 @@ yyreduce: ;} break; - case 43: + case 44: { menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr)); @@ -1732,7 +1742,7 @@ yyreduce: ;} break; - case 44: + case 45: { menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[(2) - (5)].symbol), (yyvsp[(3) - (5)].symbol)), (yyvsp[(4) - (5)].expr)); @@ -1740,7 +1750,7 @@ yyreduce: ;} break; - case 47: + case 48: { struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string))); @@ -1752,17 +1762,17 @@ yyreduce: ;} break; - case 48: + case 49: { (yyval.string) = NULL; ;} break; - case 49: + case 50: { (yyval.string) = (yyvsp[(2) - (2)].string); ;} break; - case 50: + case 51: { struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), SYMBOL_CHOICE); @@ -1773,14 +1783,14 @@ yyreduce: ;} break; - case 51: + case 52: { (yyval.menu) = menu_add_menu(); ;} break; - case 52: + case 53: { if (zconf_endtoken((yyvsp[(1) - (1)].id), T_CHOICE, T_ENDCHOICE)) { @@ -1790,7 +1800,7 @@ yyreduce: ;} break; - case 60: + case 61: { menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr)); @@ -1798,7 +1808,7 @@ yyreduce: ;} break; - case 61: + case 62: { if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) { @@ -1811,7 +1821,7 @@ yyreduce: ;} break; - case 62: + case 63: { current_entry->sym->flags |= SYMBOL_OPTIONAL; @@ -1819,7 +1829,7 @@ yyreduce: ;} break; - case 63: + case 64: { if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) { @@ -1831,7 +1841,7 @@ yyreduce: ;} break; - case 66: + case 67: { printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); @@ -1841,7 +1851,7 @@ yyreduce: ;} break; - case 67: + case 68: { if (zconf_endtoken((yyvsp[(1) - (1)].id), T_IF, T_ENDIF)) { @@ -1851,14 +1861,14 @@ yyreduce: ;} break; - case 73: + case 74: { menu_add_prompt(P_MENU, (yyvsp[(2) - (3)].string), NULL); ;} break; - case 74: + case 75: { menu_add_entry(NULL); @@ -1867,14 +1877,14 @@ yyreduce: ;} break; - case 75: + case 76: { (yyval.menu) = menu_add_menu(); ;} break; - case 76: + case 77: { if (zconf_endtoken((yyvsp[(1) - (1)].id), T_MENU, T_ENDMENU)) { @@ -1884,7 +1894,7 @@ yyreduce: ;} break; - case 82: + case 83: { printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); @@ -1892,7 +1902,7 @@ yyreduce: ;} break; - case 83: + case 84: { menu_add_entry(NULL); @@ -1901,14 +1911,14 @@ yyreduce: ;} break; - case 84: + case 85: { menu_end_entry(); ;} break; - case 85: + case 86: { printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); @@ -1916,14 +1926,14 @@ yyreduce: ;} break; - case 86: + case 87: { current_entry->help = (yyvsp[(2) - (2)].string); ;} break; - case 91: + case 92: { menu_add_dep((yyvsp[(3) - (4)].expr)); @@ -1931,84 +1941,91 @@ yyreduce: ;} break; - case 93: + case 96: + + { + menu_add_visibility((yyvsp[(2) - (2)].expr)); +;} + break; + + case 98: { menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr)); ;} break; - case 96: + case 101: { (yyval.id) = (yyvsp[(1) - (2)].id); ;} break; - case 97: + case 102: { (yyval.id) = (yyvsp[(1) - (2)].id); ;} break; - case 98: + case 103: { (yyval.id) = (yyvsp[(1) - (2)].id); ;} break; - case 101: + case 106: { (yyval.expr) = NULL; ;} break; - case 102: + case 107: { (yyval.expr) = (yyvsp[(2) - (2)].expr); ;} break; - case 103: + case 108: { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); ;} break; - case 104: + case 109: { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;} break; - case 105: + case 110: { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;} break; - case 106: + case 111: { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;} break; - case 107: + case 112: { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); ;} break; - case 108: + case 113: { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; - case 109: + case 114: { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; - case 110: + case 115: { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); ;} break; - case 111: + case 116: { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); ;} break; - case 112: + case 117: { (yyval.string) = NULL; ;} break; @@ -2278,6 +2295,7 @@ static const char *zconf_tokenname(int token) case T_IF: return "if"; case T_ENDIF: return "endif"; case T_DEPENDS: return "depends"; + case T_VISIBLE: return "visible"; } return ""; } -- cgit v1.2.3 From 27af038494ef2f3f3a23aa040bfc1ea29d99d76d Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Wed, 24 Nov 2010 12:57:17 -0800 Subject: scripts: fix gfp-translate for recent changes to gfp.h The recent changes to gfp.h to satisfy sparse broke scripts/gfp-translate. This patch fixes it up to work with old and new versions of gfp.h . [akpm@linux-foundation.org: use `grep -q', per WANG Cong] Signed-off-by: Mel Gorman Cc: Namhyung Kim Reviewed-by: WANG Cong Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/gfp-translate | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/gfp-translate b/scripts/gfp-translate index d81b968d864e..c9230e158a8f 100644 --- a/scripts/gfp-translate +++ b/scripts/gfp-translate @@ -63,7 +63,12 @@ fi # Extract GFP flags from the kernel source TMPFILE=`mktemp -t gfptranslate-XXXXXX` || exit 1 -grep "^#define __GFP" $SOURCE/include/linux/gfp.h | sed -e 's/(__force gfp_t)//' | sed -e 's/u)/)/' | grep -v GFP_BITS | sed -e 's/)\//) \//' > $TMPFILE +grep -q ___GFP $SOURCE/include/linux/gfp.h +if [ $? -eq 0 ]; then + grep "^#define ___GFP" $SOURCE/include/linux/gfp.h | sed -e 's/u$//' | grep -v GFP_BITS > $TMPFILE +else + grep "^#define __GFP" $SOURCE/include/linux/gfp.h | sed -e 's/(__force gfp_t)//' | sed -e 's/u)/)/' | grep -v GFP_BITS | sed -e 's/)\//) \//' > $TMPFILE +fi # Parse the flags IFS=" -- cgit v1.2.3 From 6e5b86924a633f5b6eefb051404339a5a7bb005e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Am=C3=A9rico=20Wang?= Date: Fri, 5 Nov 2010 14:16:10 +0800 Subject: gitignore: add scripts/recordmcount This file is generated, should be ignored by git. Signed-off-by: WANG Cong Signed-off-by: Michal Marek --- scripts/.gitignore | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/.gitignore b/scripts/.gitignore index c5d5db54c009..e2741d23bab8 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -7,3 +7,4 @@ pnmtologo bin2c unifdef ihex2fw +recordmcount -- cgit v1.2.3 From 45f53cc90e8f0e46ab024d0bc1de49ebee0dc583 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 5 Nov 2010 12:06:05 +0100 Subject: Kconfig: fix single letter command in scripts/config The one letter commands in scripts/config didn't work and always printed usage. Fix this here. Cc: erick@openchill.org Reported-by: erick@openchill.org Signed-off-by: Andi Kleen Signed-off-by: Michal Marek --- scripts/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/config b/scripts/config index 608d7fdb13e8..dfd4732f7099 100755 --- a/scripts/config +++ b/scripts/config @@ -86,7 +86,7 @@ while [ "$1" != "" ] ; do B=$ARG shift 2 ;; - --*) + -*) checkarg "$1" shift ;; -- cgit v1.2.3 From 01660dfc37933c92dbb7c5718aea61f88025d71f Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Mon, 8 Nov 2010 18:31:53 -0500 Subject: scripts/genksyms: fix header usage FreeBSD does not like when __STDC__ is defined, use the standard instead. Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/genksyms/parse.c_shipped | 2 +- scripts/genksyms/parse.y | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/genksyms/parse.c_shipped b/scripts/genksyms/parse.c_shipped index eaee44e66a43..809b949e495b 100644 --- a/scripts/genksyms/parse.c_shipped +++ b/scripts/genksyms/parse.c_shipped @@ -160,7 +160,7 @@ #include -#include +#include #include "genksyms.h" static int is_typedef; diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index 10d7dc724b6d..09a265cd7193 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -24,7 +24,7 @@ %{ #include -#include +#include #include "genksyms.h" static int is_typedef; -- cgit v1.2.3 From 0a18a9386c056028799938960f91be338c4ff349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 4 Nov 2010 10:24:16 +0100 Subject: tags: put function prototypes back! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 7db86dc (ctags: usability fix) removed function prototypes from tags file claiming "It makes no real sense to include function prototypes". But it is useful for quickly determining which header file developer needs to include to fix compilation. Now if someone wants to remove forward declarations (which I agree are baggage), write a postprocessing script. Signed-off-by: Alexey Dobriyan Signed-off-by: Uwe Kleine-König Signed-off-by: Michal Marek --- scripts/tags.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/tags.sh b/scripts/tags.sh index 8509bb512935..e091db312ddb 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -123,7 +123,7 @@ exuberant() -I ____cacheline_internodealigned_in_smp \ -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \ - --extra=+f --c-kinds=-px \ + --extra=+f --c-kinds=+px \ --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' -- cgit v1.2.3 From 15664125f7cadcb6d725cb2d9b90f9715397848d Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 24 Nov 2010 10:43:55 +0100 Subject: scripts/tags.sh: Add magic for trace-events Make tags find the trace-event definitions Acked-by: WANG Cong Signed-off-by: Peter Zijlstra LKML-Reference: <1290591835.2072.438.camel@laptop> Signed-off-by: Steven Rostedt --- scripts/tags.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/tags.sh b/scripts/tags.sh index 8509bb512935..bbbe584d4494 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -125,7 +125,9 @@ exuberant() -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \ --extra=+f --c-kinds=-px \ --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ - --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' + --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ + --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ + --regex-c++='/^DEFINE_EVENT\(([^,)]*).*/trace_\1/' all_kconfigs | xargs $1 -a \ --langdef=kconfig --language-force=kconfig \ -- cgit v1.2.3 From e63233f75a1a6bfa97ffb52a20cc6801a4c63fb2 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Mon, 22 Nov 2010 19:41:44 -0800 Subject: ftrace: Have recordmcount honor endianness in fn_ELF_R_INFO It looks to me like the change which introduced "virtual functions" forgot about cross-platform endianness. Thank you to Arnaud for supplying before+after data files do_mounts*.o. This fixes a MIPS build failure triggered by recordmcount. Reported-by: Arnaud Lacombe Tested-by: Arnaud Lacombe Acked-by: Wu Zhangjin Acked-by: Ralf Baechle Signed-off-by: John Reiser Signed-off-by: Steven Rostedt --- scripts/recordmcount.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index 58e933a20544..39667174971d 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h @@ -119,7 +119,7 @@ static uint_t (*Elf_r_sym)(Elf_Rel const *rp) = fn_ELF_R_SYM; static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type) { - rp->r_info = ELF_R_INFO(sym, type); + rp->r_info = _w(ELF_R_INFO(sym, type)); } static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO; -- cgit v1.2.3 From a1087ef6abedf0bfd60e5e3fddf33192cb2c1325 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 24 Nov 2010 15:54:18 +0100 Subject: scripts/coccinelle: update for compatability with Coccinelle 0.2.4 For doubleinit.cocci, Coccinelle 0.2.4 requires a comma after ... in a field list. Coccinelle also now behaves gracefully when a definition is provided for a virtual that doesn't exist, so there is no need for the semantic patch code to check for this case. Updated the documentation to reflect the fact that the best results will now be obtained with Coccinelle version 0.2.4 or later. Signed-off-by: Julia Lawall --- scripts/coccinelle/misc/doubleinit.cocci | 6 ++--- scripts/coccinelle/null/deref_null.cocci | 39 ++++++++++++-------------------- 2 files changed, 17 insertions(+), 28 deletions(-) (limited to 'scripts') diff --git a/scripts/coccinelle/misc/doubleinit.cocci b/scripts/coccinelle/misc/doubleinit.cocci index 55d7dc19dfe0..156b20adb351 100644 --- a/scripts/coccinelle/misc/doubleinit.cocci +++ b/scripts/coccinelle/misc/doubleinit.cocci @@ -7,7 +7,7 @@ // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. // URL: http://coccinelle.lip6.fr/ -// Comments: +// Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise // Options: -no_includes -include_headers virtual org @@ -19,7 +19,7 @@ position p0,p; expression E; @@ -struct I s =@p0 { ... .fld@p = E, ...}; +struct I s =@p0 { ..., .fld@p = E, ...}; @s@ identifier I, s, r.fld; @@ -27,7 +27,7 @@ position r.p0,p; expression E; @@ -struct I s =@p0 { ... .fld@p = E, ...}; +struct I s =@p0 { ..., .fld@p = E, ...}; @script:python depends on org@ p0 << r.p0; diff --git a/scripts/coccinelle/null/deref_null.cocci b/scripts/coccinelle/null/deref_null.cocci index 9969d76d0f4b..cdac6cfcce92 100644 --- a/scripts/coccinelle/null/deref_null.cocci +++ b/scripts/coccinelle/null/deref_null.cocci @@ -11,21 +11,10 @@ // Options: virtual context -virtual patch virtual org virtual report -@initialize:python depends on !context && patch && !org && !report@ - -import sys -print >> sys.stderr, "This semantic patch does not support the 'patch' mode." - -@depends on patch@ -@@ - -this_rule_should_never_matches(); - -@ifm depends on !patch@ +@ifm@ expression *E; statement S1,S2; position p1; @@ -35,7 +24,7 @@ if@p1 ((E == NULL && ...) || ...) S1 else S2 // The following two rules are separate, because both can match a single // expression in different ways -@pr1 depends on !patch expression@ +@pr1 expression@ expression *ifm.E; identifier f; position p1; @@ -43,7 +32,7 @@ position p1; (E != NULL && ...) ? <+...E->f@p1...+> : ... -@pr2 depends on !patch expression@ +@pr2 expression@ expression *ifm.E; identifier f; position p2; @@ -59,7 +48,7 @@ position p2; // For org and report modes -@r depends on !context && !patch && (org || report) exists@ +@r depends on !context && (org || report) exists@ expression subE <= ifm.E; expression *ifm.E; expression E1,E2; @@ -99,7 +88,7 @@ if@p1 ((E == NULL && ...) || ...) } else S3 -@script:python depends on !context && !patch && !org && report@ +@script:python depends on !context && !org && report@ p << r.p; p1 << ifm.p1; x << ifm.E; @@ -109,7 +98,7 @@ msg="ERROR: %s is NULL but dereferenced." % (x) coccilib.report.print_report(p[0], msg) cocci.include_match(False) -@script:python depends on !context && !patch && org && !report@ +@script:python depends on !context && org && !report@ p << r.p; p1 << ifm.p1; x << ifm.E; @@ -120,7 +109,7 @@ msg_safe=msg.replace("[","@(").replace("]",")") cocci.print_main(msg_safe,p) cocci.include_match(False) -@s depends on !context && !patch && (org || report) exists@ +@s depends on !context && (org || report) exists@ expression subE <= ifm.E; expression *ifm.E; expression E1,E2; @@ -159,7 +148,7 @@ if@p1 ((E == NULL && ...) || ...) } else S3 -@script:python depends on !context && !patch && !org && report@ +@script:python depends on !context && !org && report@ p << s.p; p1 << ifm.p1; x << ifm.E; @@ -168,7 +157,7 @@ x << ifm.E; msg="ERROR: %s is NULL but dereferenced." % (x) coccilib.report.print_report(p[0], msg) -@script:python depends on !context && !patch && org && !report@ +@script:python depends on !context && org && !report@ p << s.p; p1 << ifm.p1; x << ifm.E; @@ -180,7 +169,7 @@ cocci.print_main(msg_safe,p) // For context mode -@depends on context && !patch && !org && !report exists@ +@depends on context && !org && !report exists@ expression subE <= ifm.E; expression *ifm.E; expression E1,E2; @@ -223,7 +212,7 @@ else S3 // The following three rules are duplicates of ifm, pr1 and pr2 respectively. // It is need because the previous rule as already made a "change". -@ifm1 depends on !patch@ +@ifm1@ expression *E; statement S1,S2; position p1; @@ -231,7 +220,7 @@ position p1; if@p1 ((E == NULL && ...) || ...) S1 else S2 -@pr11 depends on !patch expression@ +@pr11 expression@ expression *ifm1.E; identifier f; position p1; @@ -239,7 +228,7 @@ position p1; (E != NULL && ...) ? <+...E->f@p1...+> : ... -@pr12 depends on !patch expression@ +@pr12 expression@ expression *ifm1.E; identifier f; position p2; @@ -253,7 +242,7 @@ position p2; sizeof(<+...E->f@p2...+>) ) -@depends on context && !patch && !org && !report exists@ +@depends on context && !org && !report exists@ expression subE <= ifm1.E; expression *ifm1.E; expression E1,E2; -- cgit v1.2.3 From cd3478f2bd8f2cec19f9247a8a9cd711cbe37683 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Tue, 30 Nov 2010 17:33:53 +0100 Subject: ARM: 6509/1: ftrace: ignore any ftrace.o in C version of recordmcount arch/arm/kernel/ftrace.c references mcount like kernel/tracing/ftrace.c, so change the exclusion filter to match any ftrace.o. Acked-by: Steven Rostedt Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- scripts/recordmcount.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index f2f32eee2c5b..ac6e51ceed50 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -357,7 +357,7 @@ do_file(char const *const fname) int main(int argc, char const *argv[]) { - const char ftrace[] = "kernel/trace/ftrace.o"; + const char ftrace[] = "/ftrace.o"; int ftrace_size = sizeof(ftrace) - 1; int n_error = 0; /* gcc-4.3.0 false positive complaint */ -- cgit v1.2.3 From ed60453fa8f8fc3d034dfdf10371a99cc6905626 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Tue, 30 Nov 2010 17:36:48 +0100 Subject: ARM: 6511/1: ftrace: add ARM support for C version of recordmcount Depending on the compiler version, ARM GCC calls the mcount function either __gnu_mcount_nc or mcount. Acked-by: Steven Rostedt Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- scripts/recordmcount.c | 5 ++++- scripts/recordmcount.h | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index ac6e51ceed50..038b3d1e2981 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -38,6 +38,7 @@ static void *ehdr_curr; /* current ElfXX_Ehdr * for resource cleanup */ static char gpfx; /* prefix for global symbol name (sometimes '_') */ static struct stat sb; /* Remember .st_size, etc. */ static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */ +static const char *altmcount; /* alternate mcount symbol name */ /* setjmp() return values */ enum { @@ -299,7 +300,9 @@ do_file(char const *const fname) fail_file(); } break; case EM_386: reltype = R_386_32; break; - case EM_ARM: reltype = R_ARM_ABS32; break; + case EM_ARM: reltype = R_ARM_ABS32; + altmcount = "__gnu_mcount_nc"; + break; case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break; case EM_MIPS: /* reltype: e_class */ gpfx = '_'; break; case EM_PPC: reltype = R_PPC_ADDR32; gpfx = '_'; break; diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index 58e933a20544..8087bc8cd2d1 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h @@ -275,11 +275,12 @@ static uint_t *sift_rel_mcount(uint_t *mlocp, Elf_Sym const *const symp = &sym0[Elf_r_sym(relp)]; char const *symname = &str0[w(symp->st_name)]; + char const *mcount = '_' == gpfx ? "_mcount" : "mcount"; if ('.' == symname[0]) ++symname; /* ppc64 hack */ - if (0 == strcmp((('_' == gpfx) ? "_mcount" : "mcount"), - symname)) + if (0 == strcmp(mcount, symname) || + (altmcount && 0 == strcmp(altmcount, symname))) mcountsym = Elf_r_sym(relp); } -- cgit v1.2.3 From 2979076fbf17a0947d6eba367b0cac19c907c160 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 23 Nov 2010 19:54:02 -0500 Subject: headers_install: check exit status of unifdef MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If unifdef fails for any reason (like segfaulting), we should be aborting the install steps. So check its exit status in this unlikely scenario. Reported-by: Diego Elio Pettenò Signed-off-by: Mike Frysinger Signed-off-by: Michal Marek --- scripts/headers_install.pl | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'scripts') diff --git a/scripts/headers_install.pl b/scripts/headers_install.pl index 4ca3be3b2e50..efb3be10d428 100644 --- a/scripts/headers_install.pl +++ b/scripts/headers_install.pl @@ -45,6 +45,13 @@ foreach my $file (@files) { close $in; system $unifdef . " $tmpfile > $installdir/$file"; + # unifdef will exit 0 on success, and will exit 1 when the + # file was processed successfully but no changes were made, + # so abort only when it's higher than that. + my $e = $? >> 8; + if ($e > 1) { + die "$tmpfile: $!\n"; + } unlink $tmpfile; } exit 0; -- cgit v1.2.3 From de323f22a83b024b7432e813609c6efb74b1bbfc Mon Sep 17 00:00:00 2001 From: "akpm@linux-foundation.org" Date: Tue, 30 Nov 2010 13:51:13 -0800 Subject: headers_check: better search for functions in headers Some headers don't bother with "extern" in function prototypes, which results in said prototypes being unnoticed and exported to userland. This patch slightly improves detection of such cases by checking for C type names as well in the beginning of a line. Signed-off-by: Alexander Shishkin Cc: Stephen Hemminger Cc: Michal Marek Cc: WANG Cong Cc: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Michal Marek --- scripts/headers_check.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl index 50d6cfd1fa77..e0e25a1c2c12 100644 --- a/scripts/headers_check.pl +++ b/scripts/headers_check.pl @@ -64,7 +64,7 @@ sub check_include sub check_declarations { - if ($line =~m/^\s*extern\b/) { + if ($line =~m/^(\s*extern|unsigned|char|short|int|long|void)\b/) { printf STDERR "$filename:$lineno: " . "userspace cannot call function or variable " . "defined in the kernel\n"; -- cgit v1.2.3 From d52784eb3607bf887628742f99041b4f18d7d1de Mon Sep 17 00:00:00 2001 From: "akpm@linux-foundation.org" Date: Tue, 30 Nov 2010 13:52:14 -0800 Subject: headers_check: Fix warning text Fix the warning text too, per Randy. Cc: Alexander Shishkin Cc: Michal Marek Cc: Randy Dunlap Cc: Stephen Hemminger Cc: WANG Cong Signed-off-by: Andrew Morton Signed-off-by: Michal Marek --- scripts/headers_check.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl index e0e25a1c2c12..7957e7a5166a 100644 --- a/scripts/headers_check.pl +++ b/scripts/headers_check.pl @@ -66,8 +66,8 @@ sub check_declarations { if ($line =~m/^(\s*extern|unsigned|char|short|int|long|void)\b/) { printf STDERR "$filename:$lineno: " . - "userspace cannot call function or variable " . - "defined in the kernel\n"; + "userspace cannot reference function or " . + "variable defined in the kernel\n"; } } -- cgit v1.2.3 From f6820308e025d645d9d766c97586badd4ddb8754 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Mon, 13 Dec 2010 19:10:28 +0200 Subject: kbuild: introduce HDR_ARCH_LIST for headers_install_all Using HDR_ARCH_LIST you can specify subset of architectures you want to get headers for. Signed-off-by: Kirill A. Shutemov Signed-off-by: Michal Marek --- scripts/headers.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/headers.sh b/scripts/headers.sh index 1ddcdd38d97f..978b42b3acd7 100755 --- a/scripts/headers.sh +++ b/scripts/headers.sh @@ -13,7 +13,7 @@ do_command() fi } -archs=$(ls ${srctree}/arch) +archs=${HDR_ARCH_LIST:-$(ls ${srctree}/arch)} for arch in ${archs}; do case ${arch} in -- cgit v1.2.3 From 6e71fabe9e60b1c6db587fbeac349848647920ab Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 5 Dec 2010 01:31:57 -0500 Subject: kconfig: do not define AUTOCONF_INCLUDED AUTOCONF_INCLUDED is not checked is not used within the tree and its parent header, `autoconf.h', is safe to be re-included. Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 9df80114b47b..f349bdcffa98 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -833,8 +833,7 @@ int conf_write_autoconf(void) " * Automatically generated C config: don't edit\n" " * %s\n" " * %s" - " */\n" - "#define AUTOCONF_INCLUDED\n", + " */\n", rootmenu.prompt->text, ctime(&now)); for_all_symbols(i, sym) { -- cgit v1.2.3 From 0dce631092f410bb22b21b3d47ef20d69389dfd9 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 5 Dec 2010 01:33:16 -0500 Subject: kconfig: nuke second argument of conf_write_symbol() Replacing S_TRISTATE by S_BOOLEAN is a no-op for conf_write_symbol(). Signed-off-by: Arnaud Lacombe [mmarek: Fix unused variable warning in conf_write()] Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index f349bdcffa98..d1bab0f42d10 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -440,12 +440,11 @@ static void conf_write_string(bool headerfile, const char *name, fputs("\"\n", out); } -static void conf_write_symbol(struct symbol *sym, enum symbol_type type, - FILE *out, bool write_no) +static void conf_write_symbol(struct symbol *sym, FILE *out, bool write_no) { const char *str; - switch (type) { + switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: switch (sym_get_tristate_value(sym)) { @@ -532,7 +531,7 @@ int conf_write_defconfig(const char *filename) goto next_menu; } } - conf_write_symbol(sym, sym->type, out, true); + conf_write_symbol(sym, out, true); } next_menu: if (menu->list != NULL) { @@ -561,7 +560,6 @@ int conf_write(const char *name) const char *basename; const char *str; char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1]; - enum symbol_type type; time_t now; int use_timestamp = 1; char *env; @@ -633,14 +631,8 @@ int conf_write(const char *name) if (!(sym->flags & SYMBOL_WRITE)) goto next; sym->flags &= ~SYMBOL_WRITE; - type = sym->type; - if (type == S_TRISTATE) { - sym_calc_value(modules_sym); - if (modules_sym->curr.tri == no) - type = S_BOOLEAN; - } /* Write config symbol to file */ - conf_write_symbol(sym, type, out, true); + conf_write_symbol(sym, out, true); } next: @@ -842,7 +834,7 @@ int conf_write_autoconf(void) continue; /* write symbol to config file */ - conf_write_symbol(sym, sym->type, out, false); + conf_write_symbol(sym, out, false); /* update autoconf and tristate files */ switch (sym->type) { -- cgit v1.2.3 From fe04ce0bf955eaf53f7e4cd6bb35976fa94e0925 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 5 Dec 2010 01:41:14 -0500 Subject: kbuild/nconf: fix spaces damage Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/nconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 272a987f23e0..eda49ffc1c8c 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -248,7 +248,7 @@ search_help[] = N_( "Only relevant lines are shown.\n" "\n\n" "Search examples:\n" -"Examples: USB = > find all symbols containing USB\n" +"Examples: USB => find all symbols containing USB\n" " ^USB => find all symbols starting with USB\n" " USB$ => find all symbols ending with USB\n" "\n"); -- cgit v1.2.3 From 1ebfa5198ee96f34f2ee4ae95c92318f07341fbd Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 5 Dec 2010 01:41:15 -0500 Subject: kbuild/gconf: add dummy inline for bind_textdomain_codeset() This symbols is used by gconf. Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/lkc.h | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 753cdbd7b805..a542c6ba84b3 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -14,6 +14,7 @@ static inline const char *gettext(const char *txt) { return txt; } static inline void textdomain(const char *domainname) {} static inline void bindtextdomain(const char *name, const char *dir) {} +static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c; } #endif #ifdef __cplusplus -- cgit v1.2.3 From 579fb8e741fecef7dfd64afcc7b0b0c68ea207cc Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 5 Dec 2010 01:41:16 -0500 Subject: kconfig: fix typos Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 6 +++--- scripts/kconfig/symbol.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index d1bab0f42d10..61c35bf2d9cb 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -937,7 +937,7 @@ static void randomize_choice_values(struct symbol *csym) int cnt, def; /* - * If choice is mod then we may have more items slected + * If choice is mod then we may have more items selected * and if no then no-one. * In both cases stop. */ @@ -1033,10 +1033,10 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) /* * We have different type of choice blocks. - * If curr.tri equal to mod then we can select several + * If curr.tri equals to mod then we can select several * choice symbols in one block. * In this case we do nothing. - * If curr.tri equal yes then only one symbol can be + * If curr.tri equals yes then only one symbol can be * selected in a choice block and we set it to yes, * and the rest to no. */ diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index c0efe102d655..60830ce4a0a9 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -686,7 +686,7 @@ const char *sym_get_string_default(struct symbol *sym) switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: - /* The visibility imay limit the value from yes => mod */ + /* The visibility may limit the value from yes => mod */ val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri); break; default: -- cgit v1.2.3 From bf128f5265625b8015789ea8f12b3582dc29faa3 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 5 Dec 2010 01:41:17 -0500 Subject: kconfig/conf: merge duplicate switch's case Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/conf.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 5459a38be866..659326c3e895 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -529,8 +529,6 @@ int main(int ac, char **av) } break; case savedefconfig: - conf_read(NULL); - break; case silentoldconfig: case oldaskconfig: case oldconfig: -- cgit v1.2.3 From 4ce2c1e8e899831dd152bd0d534a60da6fb1582a Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 5 Dec 2010 01:41:18 -0500 Subject: kconfig: fix `zconfdebug' extern declaration This symbol is only exist if YYDEBUG is defined. Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/lkc.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index a542c6ba84b3..6d38b7c9c824 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -68,10 +68,12 @@ struct kconf_id { enum symbol_type stype; }; +#ifdef YYDEBUG +extern int zconfdebug; +#endif + int zconfparse(void); void zconfdump(FILE *out); - -extern int zconfdebug; void zconf_starthelp(void); FILE *zconf_fopen(const char *name); void zconf_initscan(const char *name); -- cgit v1.2.3 From f0a6332ce221614fbd0731af92f668892fa4b700 Mon Sep 17 00:00:00 2001 From: Jonas Aaberg Date: Wed, 15 Dec 2010 08:37:00 +0100 Subject: kbuild: add numeric --set-val option to scripts/config Add new option to scripts/config for changing .config numeric values Acked-by: Linus Walleij Signed-off-by: Jonas Aaberg Signed-off-by: Michal Marek --- scripts/config | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/config b/scripts/config index dfd4732f7099..a7c7c4b8e957 100755 --- a/scripts/config +++ b/scripts/config @@ -10,8 +10,10 @@ commands: --enable|-e option Enable option --disable|-d option Disable option --module|-m option Turn option into a module - --set-str option value - Set option to "value" + --set-str option string + Set option to "string" + --set-val option value + Set option to value --state|-s option Print state of option (n,y,m,undef) --enable-after|-E beforeopt option @@ -109,6 +111,11 @@ while [ "$1" != "" ] ; do shift ;; + --set-val) + set_var "CONFIG_$ARG" "CONFIG_$ARG=$1" + shift + ;; + --state|-s) if grep -q "# CONFIG_$ARG is not set" $FN ; then echo n -- cgit v1.2.3 From ab60bd0b92ec57c98df08616b7d0664be5551eae Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 5 Dec 2010 01:29:25 -0500 Subject: kconfig: add more S_INT and S_HEX consistency checks This patch add more number consistency checkg, trying to catch the following situation: config FOO0 hex default 42 config FOO1 string config BAR0 int default FOO1 config BAR1 hex default FOO1 config FOO2 hex default 42h config FOO3 int default "1bar" Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/menu.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 7e83aef42c6d..8a8bc9be7831 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -183,7 +183,7 @@ void menu_add_option(int token, char *arg) } } -static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2) +static int menu_validate_number(struct symbol *sym, struct symbol *sym2) { return sym2->type == S_INT || sym2->type == S_HEX || (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name)); @@ -201,6 +201,15 @@ static void sym_check_prop(struct symbol *sym) prop_warn(prop, "default for config symbol '%s'" " must be a single symbol", sym->name); + if (prop->expr->type != E_SYMBOL) + break; + sym2 = prop_get_symbol(prop); + if (sym->type == S_HEX || sym->type == S_INT) { + if (!menu_validate_number(sym, sym2)) + prop_warn(prop, + "'%s': number is invalid", + sym->name); + } break; case P_SELECT: sym2 = prop_get_symbol(prop); @@ -220,8 +229,8 @@ static void sym_check_prop(struct symbol *sym) if (sym->type != S_INT && sym->type != S_HEX) prop_warn(prop, "range is only allowed " "for int or hex symbols"); - if (!menu_range_valid_sym(sym, prop->expr->left.sym) || - !menu_range_valid_sym(sym, prop->expr->right.sym)) + if (!menu_validate_number(sym, prop->expr->left.sym) || + !menu_validate_number(sym, prop->expr->right.sym)) prop_warn(prop, "range is invalid"); break; default: -- cgit v1.2.3 From 1121584f5db8a99a7ad94c6c5d62431b3187ad98 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Wed, 15 Dec 2010 17:11:22 -0800 Subject: modpost: Put .zdebug* section on white list "as --compress-debug-sections" will generate compressed debug sections with section names ".zdebug*". This patch puts .zdebug* section on white list. Signed-off-by: H.J. Lu Signed-off-by: Michal Marek --- scripts/mod/modpost.c | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 33122ca04e7c..194e2c453609 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -790,6 +790,7 @@ static const char *section_white_list[] = { ".comment*", ".debug*", + ".zdebug*", /* Compressed debug sections. */ ".GCC-command-line", /* mn10300 */ ".mdebug*", /* alpha, score, mips etc. */ ".pdr", /* alpha, score, mips etc. */ -- cgit v1.2.3 From 6e5f6856427abe5418f535cb46c454ae8ea7f8e7 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 25 Aug 2010 12:22:40 +0200 Subject: checksyscalls: Fix stand-alone usage The usage help in the comments - refers to the wrong script name, - doesn't mention that $srctree must be set. Hence correct the script name, and derive the source tree path from the script path, so we no longer need to rely on $srctree being set by the caller. Signed-off-by: Geert Uytterhoeven Acked-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/checksyscalls.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh index 6bb42e72e0e5..3ab316e52313 100755 --- a/scripts/checksyscalls.sh +++ b/scripts/checksyscalls.sh @@ -6,7 +6,7 @@ # and listed below so they are ignored. # # Usage: -# syscallchk gcc gcc-options +# checksyscalls.sh gcc gcc-options # ignore_list() { @@ -204,5 +204,5 @@ sed -n -e '/^\#define/ s/[^_]*__NR_\([^[:space:]]*\).*/\ \#endif/p' $1 } -(ignore_list && syscall_list ${srctree}/arch/x86/include/asm/unistd_32.h) | \ +(ignore_list && syscall_list $(dirname $0)/../arch/x86/include/asm/unistd_32.h) | \ $* -E -x c - > /dev/null -- cgit v1.2.3 From 1137c56b7420c801147e0863845c03b07554721a Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 26 Sep 2010 16:24:08 -0400 Subject: kconfig: simplify select-with-unmet-direct-dependency warning This is an attempt to simplify the expressing printed by kconfig when a symbol is selected but still has direct unmet dependency. First, the symbol reverse dependency is split in sub-expression. Then, each sub-expression is checked to ensure that it does not contains the unmet dependency. This removes the false-positive symbols and fixed symbol which already have the correct dependency. Finally, only the symbol responsible of the "select" is printed, instead of its full dependency tree. CC: Catalin Marinas Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/expr.c | 42 ++++++++++++++++++++++++++++++++++++++++++ scripts/kconfig/symbol.c | 6 +++++- 2 files changed, 47 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 330e7c0048a8..65531a7f28a8 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -1013,6 +1013,48 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2) #endif } +static inline struct expr * +expr_get_leftmost_symbol(const struct expr *e) +{ + + if (e == NULL) + return NULL; + + while (e->type != E_SYMBOL) + e = e->left.expr; + + return expr_copy(e); +} + +/* + * Given expression `e1' and `e2', returns the leaf of the longest + * sub-expression of `e1' not containing 'e2. + */ +struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2) +{ + struct expr *ret; + + switch (e1->type) { + case E_OR: + return expr_alloc_and( + expr_simplify_unmet_dep(e1->left.expr, e2), + expr_simplify_unmet_dep(e1->right.expr, e2)); + case E_AND: { + struct expr *e; + e = expr_alloc_and(expr_copy(e1), expr_copy(e2)); + e = expr_eliminate_dups(e); + ret = (!expr_eq(e, e1)) ? e1 : NULL; + expr_free(e); + break; + } + default: + ret = e1; + break; + } + + return expr_get_leftmost_symbol(ret); +} + void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken) { if (!e) { diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 60830ce4a0a9..fa52e6f44ac4 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -351,12 +351,16 @@ void sym_calc_value(struct symbol *sym) } calc_newval: if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { + struct expr *e; + e = expr_simplify_unmet_dep(sym->rev_dep.expr, + sym->dir_dep.expr); fprintf(stderr, "warning: ("); - expr_fprint(sym->rev_dep.expr, stderr); + expr_fprint(e, stderr); fprintf(stderr, ") selects %s which has unmet direct dependencies (", sym->name); expr_fprint(sym->dir_dep.expr, stderr); fprintf(stderr, ")\n"); + expr_free(e); } newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); } -- cgit v1.2.3 From 17742dc743716eebbf5892add0e0bf91f541fc39 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Mon, 20 Dec 2010 16:06:44 +0100 Subject: kconfig: Make expr_copy() take a const argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes scripts/kconfig/expr.c: In function ‘expr_get_leftmost_symbol’: scripts/kconfig/expr.c:1026:2: warning: passing argument 1 of ‘expr_copy’ discards qualifiers from pointer target type scripts/kconfig/expr.c:67:14: note: expected ‘struct expr *’ but argument is of type ‘const struct expr *’ Signed-off-by: Michal Marek --- scripts/kconfig/expr.c | 2 +- scripts/kconfig/expr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 65531a7f28a8..001003452f68 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -64,7 +64,7 @@ struct expr *expr_alloc_or(struct expr *e1, struct expr *e2) return e2 ? expr_alloc_two(E_OR, e1, e2) : e1; } -struct expr *expr_copy(struct expr *org) +struct expr *expr_copy(const struct expr *org) { struct expr *e; diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 184eb6a0b505..218991b26d92 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -191,7 +191,7 @@ struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); -struct expr *expr_copy(struct expr *org); +struct expr *expr_copy(const struct expr *org); void expr_free(struct expr *e); int expr_eq(struct expr *e1, struct expr *e2); void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); -- cgit v1.2.3 From a3ba81131aca243bfecfa78c42edec0cd69f72d6 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 22 Dec 2010 13:30:14 -0500 Subject: Make fixdep error handling more explicit Also add missing error handling to fstat call Signed-off-by: Ben Gamari Signed-off-by: Michal Marek --- scripts/basic/fixdep.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index ed0584623690..c9a16abacab4 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -286,7 +286,7 @@ static void do_config_file(const char *filename) fd = open(filename, O_RDONLY); if (fd < 0) { - fprintf(stderr, "fixdep: "); + fprintf(stderr, "fixdep: error opening config file: "); perror(filename); exit(2); } @@ -357,11 +357,15 @@ static void print_deps(void) fd = open(depfile, O_RDONLY); if (fd < 0) { - fprintf(stderr, "fixdep: "); + fprintf(stderr, "fixdep: error opening depfile: "); perror(depfile); exit(2); } - fstat(fd, &st); + if (fstat(fd, &st) < 0) { + fprintf(stderr, "fixdep: error fstat'ing depfile: "); + perror(depfile); + exit(2); + } if (st.st_size == 0) { fprintf(stderr,"fixdep: %s is empty\n",depfile); close(fd); -- cgit v1.2.3 From aab94339cd85d726abeae78fc02351fc1910e6a4 Mon Sep 17 00:00:00 2001 From: Dirk Brandewie Date: Wed, 22 Dec 2010 11:57:26 -0800 Subject: of: Add support for linking device tree blobs into vmlinux This patch adds support for linking device tree blob(s) into vmlinux. Modifies asm-generic/vmlinux.lds.h to add linking .dtb sections into vmlinux. To maintain compatiblity with the of/fdt driver code platforms MUST copy the blob to a non-init memory location before the kernel frees the .init.* sections in the image. Modifies scripts/Makefile.lib to add a kbuild command to compile DTS files to device tree blobs and a rule to create objects to wrap the blobs for linking. STRUCT_ALIGNMENT is defined in vmlinux.lds.h for use in the rule to create wrapper objects for the dtb in Makefile.lib. The STRUCT_ALIGN() macro in vmlinux.lds.h is modified to use the STRUCT_ALIGNMENT definition. The DTB's are placed on 32 byte boundries to allow parsing the blob with driver/of/fdt.c during early boot without having to copy the blob to get the structure alignment GCC expects. A DTB is linked in by adding the DTB object to the list of objects to be linked into vmlinux in the archtecture specific Makefile using obj-y += foo.dtb.o Signed-off-by: Dirk Brandewie Acked-by: Michal Marek [grant.likely@secretlab.ca: cleaned up whitespace inconsistencies] Signed-off-by: Grant Likely --- scripts/Makefile.lib | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 4c72c1189479..396da16aabf8 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -200,6 +200,29 @@ quiet_cmd_gzip = GZIP $@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -f -9 > $@) || \ (rm -f $@ ; false) +# DTC +# --------------------------------------------------------------------------- + +# Generate an assembly file to wrap the output of the device tree compiler +quiet_cmd_dt_S_dtb= DTB $@ +cmd_dt_S_dtb= \ +( \ + echo '\#include '; \ + echo '.section .dtb.init.rodata,"a"'; \ + echo '.balign STRUCT_ALIGNMENT'; \ + echo '.global __dtb_$(*F)_begin'; \ + echo '__dtb_$(*F)_begin:'; \ + echo '.incbin "$<" '; \ + echo '__dtb_$(*F)_end:'; \ + echo '.global __dtb_$(*F)_end'; \ + echo '.balign STRUCT_ALIGNMENT'; \ +) > $@ + +$(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) $< # Bzip2 # --------------------------------------------------------------------------- -- cgit v1.2.3 From 0597fcd08b858df83b9f20afd6035311d92c48f8 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Thu, 23 Dec 2010 03:25:16 -0500 Subject: kconfig: fix warning In file included from scripts/kconfig/zconf.tab.c:2502: scripts/kconfig/expr.c:1033: warning: no previous prototype for 'expr_simplify_unmet_dep' Reported-by: Stephen Rothwell Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/expr.h | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 218991b26d92..79ab6e746f53 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -206,6 +206,7 @@ struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2); struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2); void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2); struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); +struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2); void expr_fprint(struct expr *e, FILE *out); struct gstr; /* forward */ -- cgit v1.2.3 From 731ece41fb1047816303295a0cdfed90a528137e Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Fri, 10 Dec 2010 02:09:23 -0600 Subject: modpost: Fix address calculation in reloc_location() This patch fixes a segfault in modpost that is observed when the gold linker is used to link the input objects. The problem is that reloc_location (modpost.c) is computing the address of the relocation target incorrectly. Here, elf->hdr points to the beginning of the ELF file in memory, sechdr points to the relocation section header, section is the index of the section being relocated, and sechdrs[section].sh_offset would be the offset of that section, relative to the beginning of the ELF file. Adding elf->hdr + sechdrs[section].sh_offset gives you the address of the beginning of the section, and adding r->r_offset to that gives you the address of the location to be relocated. You do not need to subtract sechdrs[section].sh_addr from that -- the result of this is an address outside the file, and causes the segfault when addend_386_rel tries to dereference it. This bug is not observed when GNU ld is used to link the inputs. The object file ubuntu/omnibook/omnibook.o is the result of an ld -r of several other files. When GNU ld does an ld -r, it sets the vaddr field for each section to 0, but gold lays out the section addresses sequentially instead: Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .text PROGBITS 00000000 000034 004794 00 AX 0 0 4 [ 2] .data PROGBITS 0000b9d0 0047c8 0009c0 00 WA 0 0 4 [ 3] .bss NOBITS 000162f8 005188 00013c 00 WA 0 0 4 [ 4] .rodata.str1.1 PROGBITS 00004f2d 0052c4 001b1a 01 AMS 0 0 1 [ 5] .init.text PROGBITS 00004794 006dde 0005fa 00 AX 0 0 1 [ 6] .exit.text PROGBITS 00004d8e 0073d8 00018a 00 AX 0 0 1 ... So the bug in the tool remained undiscovered because the section's vaddr always happened to be 0. Signed-off-by: Raymes Khoury Signed-off-by: Olof Johansson Signed-off-by: Michal Marek --- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 194e2c453609..97d2259ae999 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1442,7 +1442,7 @@ static unsigned int *reloc_location(struct elf_info *elf, int section = shndx2secindex(sechdr->sh_info); return (void *)elf->hdr + sechdrs[section].sh_offset + - r->r_offset - sechdrs[section].sh_addr; + r->r_offset; } static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) -- cgit v1.2.3 From 7ad1227818f09242cfe9bf1845fd24211f5f99bd Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 9 Dec 2010 08:11:38 +0000 Subject: kconfig: fix undesirable side effect of adding "visible" menu attribute This lead to non-selected, non-user-selectable options to be written out to .config. This is not only pointless, but also preventing the user to be prompted should any of those options eventually become visible (e.g. by de-selecting the *_AUTO options the "visible" attribute was added for. Furthermore it is quite logical for the "visible" attribute of a menu to control the visibility of all contained prompts, which is what the patch does. Signed-off-by: Jan Beulich Signed-off-by: Michal Marek --- scripts/kconfig/menu.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index b9d9aa18e6d6..5f77dcb8977e 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -140,6 +140,20 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e } if (current_entry->prompt && current_entry != &rootmenu) prop_warn(prop, "prompt redefined"); + + /* Apply all upper menus' visibilities to actual prompts. */ + if(type == P_PROMPT) { + struct menu *menu = current_entry; + + while ((menu = menu->parent) != NULL) { + if (!menu->visibility) + continue; + prop->visible.expr + = expr_alloc_and(prop->visible.expr, + menu->visibility); + } + } + current_entry->prompt = prop; } prop->text = prompt; -- cgit v1.2.3 From 658f29a51e9830e620bb9a1ce3534b318a38bfeb Mon Sep 17 00:00:00 2001 From: John Bonesio Date: Wed, 17 Nov 2010 15:28:20 -0800 Subject: of/flattree: Update dtc to current mainline. Pull in recent changes from the main dtc repository. These changes primarily allow multiple device trees to be declared which are merged by dtc. This feature allows us to include a basic dts file and then provide more information for the specific system through the merging functionality. Changes pulled from git://git.jdl.com/software/dtc.git commit id: 37c0b6a0, "dtc: Add code to make diffing trees easier" Signed-off-by: John Bonesio Signed-off-by: Grant Likely --- scripts/dtc/Makefile | 3 +- scripts/dtc/checks.c | 105 ++++- scripts/dtc/dtc-lexer.l | 175 +------ scripts/dtc/dtc-lexer.lex.c_shipped | 551 +++++++--------------- scripts/dtc/dtc-parser.tab.c_shipped | 892 +++++++++++++++++------------------ scripts/dtc/dtc-parser.tab.h_shipped | 82 ++-- scripts/dtc/dtc-parser.y | 160 +++---- scripts/dtc/dtc.c | 57 ++- scripts/dtc/dtc.h | 77 ++- scripts/dtc/flattree.c | 192 ++++---- scripts/dtc/fstree.c | 12 +- scripts/dtc/livetree.c | 345 +++++++++++++- scripts/dtc/srcpos.c | 258 +++++++--- scripts/dtc/srcpos.h | 99 ++-- scripts/dtc/treesource.c | 48 +- scripts/dtc/util.c | 59 +++ scripts/dtc/util.h | 56 +++ scripts/dtc/version_gen.h | 2 +- 18 files changed, 1721 insertions(+), 1452 deletions(-) create mode 100644 scripts/dtc/util.c create mode 100644 scripts/dtc/util.h (limited to 'scripts') diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile index 01cdb36fc583..04a31c17639f 100644 --- a/scripts/dtc/Makefile +++ b/scripts/dtc/Makefile @@ -4,7 +4,7 @@ hostprogs-y := dtc always := $(hostprogs-y) dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \ - srcpos.o checks.o + srcpos.o checks.o util.o dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o # Source files need to get at the userspace version of libfdt_env.h to compile @@ -19,6 +19,7 @@ HOSTCFLAGS_fstree.o := $(HOSTCFLAGS_DTC) HOSTCFLAGS_livetree.o := $(HOSTCFLAGS_DTC) HOSTCFLAGS_srcpos.o := $(HOSTCFLAGS_DTC) HOSTCFLAGS_treesource.o := $(HOSTCFLAGS_DTC) +HOSTCFLAGS_util.o := $(HOSTCFLAGS_DTC) HOSTCFLAGS_dtc-lexer.lex.o := $(HOSTCFLAGS_DTC) HOSTCFLAGS_dtc-parser.tab.o := $(HOSTCFLAGS_DTC) diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c index 95485796f253..a662a0044798 100644 --- a/scripts/dtc/checks.c +++ b/scripts/dtc/checks.c @@ -278,32 +278,112 @@ static void check_property_name_chars(struct check *c, struct node *dt, } PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR); +#define DESCLABEL_FMT "%s%s%s%s%s" +#define DESCLABEL_ARGS(node,prop,mark) \ + ((mark) ? "value of " : ""), \ + ((prop) ? "'" : ""), \ + ((prop) ? (prop)->name : ""), \ + ((prop) ? "' in " : ""), (node)->fullpath + +static void check_duplicate_label(struct check *c, struct node *dt, + const char *label, struct node *node, + struct property *prop, struct marker *mark) +{ + struct node *othernode = NULL; + struct property *otherprop = NULL; + struct marker *othermark = NULL; + + othernode = get_node_by_label(dt, label); + + if (!othernode) + otherprop = get_property_by_label(dt, label, &othernode); + if (!othernode) + othermark = get_marker_label(dt, label, &othernode, + &otherprop); + + if (!othernode) + return; + + if ((othernode != node) || (otherprop != prop) || (othermark != mark)) + FAIL(c, "Duplicate label '%s' on " DESCLABEL_FMT + " and " DESCLABEL_FMT, + label, DESCLABEL_ARGS(node, prop, mark), + DESCLABEL_ARGS(othernode, otherprop, othermark)); +} + +static void check_duplicate_label_node(struct check *c, struct node *dt, + struct node *node) +{ + struct label *l; + + for_each_label(node->labels, l) + check_duplicate_label(c, dt, l->label, node, NULL, NULL); +} +static void check_duplicate_label_prop(struct check *c, struct node *dt, + struct node *node, struct property *prop) +{ + struct marker *m = prop->val.markers; + struct label *l; + + for_each_label(prop->labels, l) + check_duplicate_label(c, dt, l->label, node, prop, NULL); + + for_each_marker_of_type(m, LABEL) + check_duplicate_label(c, dt, m->ref, node, prop, m); +} +CHECK(duplicate_label, NULL, check_duplicate_label_node, + check_duplicate_label_prop, NULL, ERROR); + static void check_explicit_phandles(struct check *c, struct node *root, - struct node *node) + struct node *node, struct property *prop) { - struct property *prop; + struct marker *m; struct node *other; cell_t phandle; - prop = get_property(node, "linux,phandle"); - if (! prop) - return; /* No phandle, that's fine */ + if (!streq(prop->name, "phandle") + && !streq(prop->name, "linux,phandle")) + return; if (prop->val.len != sizeof(cell_t)) { - FAIL(c, "%s has bad length (%d) linux,phandle property", - node->fullpath, prop->val.len); + FAIL(c, "%s has bad length (%d) %s property", + node->fullpath, prop->val.len, prop->name); + return; + } + + m = prop->val.markers; + for_each_marker_of_type(m, REF_PHANDLE) { + assert(m->offset == 0); + if (node != get_node_by_ref(root, m->ref)) + /* "Set this node's phandle equal to some + * other node's phandle". That's nonsensical + * by construction. */ { + FAIL(c, "%s in %s is a reference to another node", + prop->name, node->fullpath); + return; + } + /* But setting this node's phandle equal to its own + * phandle is allowed - that means allocate a unique + * phandle for this node, even if it's not otherwise + * referenced. The value will be filled in later, so + * no further checking for now. */ return; } phandle = propval_cell(prop); + if ((phandle == 0) || (phandle == -1)) { - FAIL(c, "%s has invalid linux,phandle value 0x%x", - node->fullpath, phandle); + FAIL(c, "%s has bad value (0x%x) in %s property", + node->fullpath, phandle, prop->name); return; } + if (node->phandle && (node->phandle != phandle)) + FAIL(c, "%s has %s property which replaces existing phandle information", + node->fullpath, prop->name); + other = get_node_by_phandle(root, phandle); - if (other) { + if (other && (other != node)) { FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)", node->fullpath, phandle, other->fullpath); return; @@ -311,7 +391,7 @@ static void check_explicit_phandles(struct check *c, struct node *root, node->phandle = phandle; } -NODE_CHECK(explicit_phandles, NULL, ERROR); +PROP_CHECK(explicit_phandles, NULL, ERROR); static void check_name_properties(struct check *c, struct node *root, struct node *node) @@ -549,6 +629,9 @@ static struct check *check_table[] = { &duplicate_node_names, &duplicate_property_names, &node_name_chars, &node_name_format, &property_name_chars, &name_is_string, &name_properties, + + &duplicate_label, + &explicit_phandles, &phandle_references, &path_references, diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l index a627bbee91d4..e866ea5166ac 100644 --- a/scripts/dtc/dtc-lexer.l +++ b/scripts/dtc/dtc-lexer.l @@ -18,7 +18,7 @@ * USA */ -%option noyywrap noinput nounput yylineno +%option noyywrap nounput noinput never-interactive %x INCLUDE %x BYTESTRING @@ -38,6 +38,13 @@ LINECOMMENT "//".*\n #include "srcpos.h" #include "dtc-parser.tab.h" +YYLTYPE yylloc; + +/* CAUTION: this will stop working if we ever use yyless() or yyunput() */ +#define YY_USER_ACTION \ + { \ + srcpos_update(&yylloc, yytext, yyleng); \ + } /*#define LEXDEBUG 1*/ @@ -47,15 +54,10 @@ LINECOMMENT "//".*\n #define DPRINT(fmt, ...) do { } while (0) #endif -static int dts_version; /* = 0 */ +static int dts_version = 1; -#define BEGIN_DEFAULT() if (dts_version == 0) { \ - DPRINT("\n"); \ - BEGIN(INITIAL); \ - } else { \ - DPRINT("\n"); \ +#define BEGIN_DEFAULT() DPRINT("\n"); \ BEGIN(V1); \ - } static void push_input_file(const char *filename); static int pop_input_file(void); @@ -75,18 +77,13 @@ static int pop_input_file(void); } <*>{STRING} { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; DPRINT("String: %s\n", yytext); yylval.data = data_copy_escape_string(yytext+1, yyleng-2); - yylloc.first_line = yylineno; return DT_STRING; } <*>"/dts-v1/" { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; DPRINT("Keyword: /dts-v1/\n"); dts_version = 1; BEGIN_DEFAULT(); @@ -94,106 +91,57 @@ static int pop_input_file(void); } <*>"/memreserve/" { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; DPRINT("Keyword: /memreserve/\n"); BEGIN_DEFAULT(); return DT_MEMRESERVE; } <*>{LABEL}: { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; DPRINT("Label: %s\n", yytext); - yylval.labelref = strdup(yytext); + yylval.labelref = xstrdup(yytext); yylval.labelref[yyleng-1] = '\0'; return DT_LABEL; } -[bodh]# { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; - if (*yytext == 'b') - yylval.cbase = 2; - else if (*yytext == 'o') - yylval.cbase = 8; - else if (*yytext == 'd') - yylval.cbase = 10; - else - yylval.cbase = 16; - DPRINT("Base: %d\n", yylval.cbase); - return DT_BASE; - } - -[0-9a-fA-F]+ { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; - yylval.literal = strdup(yytext); - DPRINT("Literal: '%s'\n", yylval.literal); - return DT_LEGACYLITERAL; - } - [0-9]+|0[xX][0-9a-fA-F]+ { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; - yylval.literal = strdup(yytext); + yylval.literal = xstrdup(yytext); DPRINT("Literal: '%s'\n", yylval.literal); return DT_LITERAL; } -\&{LABEL} { /* label reference */ - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; +<*>\&{LABEL} { /* label reference */ DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = strdup(yytext+1); + yylval.labelref = xstrdup(yytext+1); return DT_REF; } -"&{/"{PATHCHAR}+\} { /* new-style path reference */ - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; +<*>"&{/"{PATHCHAR}+\} { /* new-style path reference */ yytext[yyleng-1] = '\0'; DPRINT("Ref: %s\n", yytext+2); - yylval.labelref = strdup(yytext+2); - return DT_REF; - } - -"&/"{PATHCHAR}+ { /* old-style path reference */ - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; - DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = strdup(yytext+1); + yylval.labelref = xstrdup(yytext+2); return DT_REF; } [0-9a-fA-F]{2} { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; yylval.byte = strtol(yytext, NULL, 16); DPRINT("Byte: %02x\n", (int)yylval.byte); return DT_BYTE; } "]" { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; DPRINT("/BYTESTRING\n"); BEGIN_DEFAULT(); return ']'; } {PROPNODECHAR}+ { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; DPRINT("PropNodeName: %s\n", yytext); - yylval.propnodename = strdup(yytext); + yylval.propnodename = xstrdup(yytext); BEGIN_DEFAULT(); return DT_PROPNODENAME; } "/incbin/" { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; DPRINT("Binary Include\n"); return DT_INCBIN; } @@ -203,8 +151,6 @@ static int pop_input_file(void); <*>{LINECOMMENT}+ /* eat C++-style comments */ <*>. { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; DPRINT("Char: %c (\\x%02x)\n", yytext[0], (unsigned)yytext[0]); if (yytext[0] == '[') { @@ -221,100 +167,25 @@ static int pop_input_file(void); %% - -/* - * Stack of nested include file contexts. - */ - -struct incl_file { - struct dtc_file *file; - YY_BUFFER_STATE yy_prev_buf; - int yy_prev_lineno; - struct incl_file *prev; -}; - -static struct incl_file *incl_file_stack; - - -/* - * Detect infinite include recursion. - */ -#define MAX_INCLUDE_DEPTH (100) - -static int incl_depth = 0; - - static void push_input_file(const char *filename) { - struct incl_file *incl_file; - struct dtc_file *newfile; - struct search_path search, *searchptr = NULL; - assert(filename); - if (incl_depth++ >= MAX_INCLUDE_DEPTH) - die("Includes nested too deeply"); - - if (srcpos_file) { - search.dir = srcpos_file->dir; - search.next = NULL; - search.prev = NULL; - searchptr = &search; - } - - newfile = dtc_open_file(filename, searchptr); + srcfile_push(filename); - incl_file = xmalloc(sizeof(struct incl_file)); + yyin = current_srcfile->f; - /* - * Save current context. - */ - incl_file->yy_prev_buf = YY_CURRENT_BUFFER; - incl_file->yy_prev_lineno = yylineno; - incl_file->file = srcpos_file; - incl_file->prev = incl_file_stack; - - incl_file_stack = incl_file; - - /* - * Establish new context. - */ - srcpos_file = newfile; - yylineno = 1; - yyin = newfile->file; - yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); + yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE)); } static int pop_input_file(void) { - struct incl_file *incl_file; - - if (incl_file_stack == 0) + if (srcfile_pop() == 0) return 0; - dtc_close_file(srcpos_file); - - /* - * Pop. - */ - --incl_depth; - incl_file = incl_file_stack; - incl_file_stack = incl_file->prev; - - /* - * Recover old context. - */ - yy_delete_buffer(YY_CURRENT_BUFFER); - yy_switch_to_buffer(incl_file->yy_prev_buf); - yylineno = incl_file->yy_prev_lineno; - srcpos_file = incl_file->file; - yyin = incl_file->file ? incl_file->file->file : NULL; - - /* - * Free old state. - */ - free(incl_file); + yypop_buffer_state(); + yyin = current_srcfile->f; return 1; } diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped index e27cc636e326..50c4420b4b2c 100644 --- a/scripts/dtc/dtc-lexer.lex.c_shipped +++ b/scripts/dtc/dtc-lexer.lex.c_shipped @@ -170,20 +170,7 @@ extern FILE *yyin, *yyout; #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 - /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires - * access to the local variable yy_act. Since yyless() is a macro, it would break - * existing scanners that call yyless() from OUTSIDE yylex. - * One obvious solution it to make yy_act a global. I tried that, and saw - * a 5% performance hit in a non-yylineno scanner, because yy_act is - * normally declared as a register variable-- so it is not worth it. - */ - #define YY_LESS_LINENO(n) \ - do { \ - int yyl;\ - for ( yyl = n; yyl < yyleng; ++yyl )\ - if ( yytext[yyl] == '\n' )\ - --yylineno;\ - }while(0) + #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ @@ -385,8 +372,8 @@ static void yy_fatal_error (yyconst char msg[] ); *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 20 -#define YY_END_OF_BUFFER 21 +#define YY_NUM_RULES 17 +#define YY_END_OF_BUFFER 18 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -394,20 +381,19 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[104] = +static yyconst flex_int16_t yy_accept[94] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 21, 19, 16, 16, 19, 19, 19, 7, 7, 19, - 7, 19, 19, 19, 19, 13, 14, 14, 19, 8, - 8, 16, 0, 2, 0, 0, 9, 0, 0, 0, - 0, 0, 0, 7, 7, 5, 0, 6, 0, 12, - 12, 14, 14, 8, 0, 11, 9, 0, 0, 0, - 0, 18, 0, 0, 0, 0, 8, 0, 17, 0, - 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3, 15, + 18, 16, 13, 13, 16, 16, 16, 16, 16, 16, + 16, 10, 11, 11, 6, 6, 13, 0, 2, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 5, 0, + 9, 9, 11, 11, 6, 0, 7, 0, 0, 0, + 0, 15, 0, 0, 0, 0, 6, 0, 14, 0, + 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 4, 0 + } ; static yyconst flex_int32_t yy_ec[256] = @@ -416,16 +402,16 @@ static yyconst flex_int32_t yy_ec[256] = 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 4, 5, 1, 1, 6, 1, 1, - 1, 7, 8, 8, 9, 8, 10, 11, 12, 13, - 13, 13, 13, 13, 13, 13, 13, 14, 1, 1, - 1, 1, 8, 8, 15, 15, 15, 15, 15, 15, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 17, 16, 16, - 1, 18, 19, 1, 16, 1, 15, 20, 21, 22, - - 23, 15, 16, 24, 25, 16, 16, 26, 27, 28, - 24, 16, 16, 29, 30, 31, 32, 33, 16, 17, - 16, 16, 34, 1, 35, 1, 1, 1, 1, 1, + 1, 7, 5, 5, 8, 5, 9, 10, 11, 12, + 12, 12, 12, 12, 12, 12, 12, 13, 1, 1, + 1, 1, 5, 5, 14, 14, 14, 14, 14, 14, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 16, 15, 15, + 1, 17, 18, 1, 15, 1, 14, 19, 20, 21, + + 22, 14, 15, 15, 23, 15, 15, 24, 25, 26, + 15, 15, 15, 27, 28, 29, 30, 31, 15, 16, + 15, 15, 32, 1, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -442,136 +428,114 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[36] = +static yyconst flex_int32_t yy_meta[34] = { 0, - 1, 1, 1, 1, 2, 1, 2, 2, 2, 3, - 4, 4, 4, 5, 6, 7, 7, 1, 1, 6, - 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 8, 1 + 1, 1, 1, 1, 2, 1, 2, 2, 3, 4, + 4, 4, 5, 6, 7, 7, 1, 1, 6, 6, + 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 8, 1 } ; -static yyconst flex_int16_t yy_base[117] = +static yyconst flex_int16_t yy_base[106] = { 0, - 0, 0, 30, 0, 44, 0, 67, 0, 97, 105, - 302, 303, 35, 44, 40, 94, 112, 0, 129, 152, - 296, 295, 159, 0, 176, 303, 0, 116, 95, 165, - 49, 46, 102, 303, 296, 0, 0, 288, 290, 293, - 264, 266, 270, 0, 0, 303, 0, 303, 264, 303, - 0, 0, 195, 101, 0, 0, 0, 0, 284, 125, - 277, 265, 225, 230, 216, 218, 0, 202, 224, 221, - 217, 107, 196, 188, 303, 206, 179, 186, 178, 185, - 183, 162, 161, 150, 169, 160, 145, 125, 303, 303, - 137, 109, 190, 103, 203, 167, 108, 197, 303, 123, - - 29, 303, 303, 215, 221, 226, 229, 234, 240, 246, - 250, 257, 265, 270, 275, 282 + 0, 0, 237, 236, 25, 0, 47, 0, 30, 71, + 244, 247, 82, 84, 84, 211, 95, 229, 218, 0, + 111, 247, 0, 84, 83, 95, 106, 86, 247, 237, + 0, 230, 231, 234, 207, 209, 212, 220, 247, 206, + 247, 218, 0, 106, 116, 0, 0, 0, 223, 89, + 226, 219, 199, 206, 200, 204, 0, 190, 213, 212, + 202, 91, 178, 161, 247, 172, 144, 150, 140, 130, + 140, 124, 128, 120, 138, 137, 123, 122, 247, 247, + 134, 114, 132, 86, 135, 125, 90, 136, 247, 97, + 29, 247, 247, 153, 156, 161, 165, 170, 176, 180, + + 187, 195, 200, 205, 212 } ; -static yyconst flex_int16_t yy_def[117] = +static yyconst flex_int16_t yy_def[106] = { 0, - 103, 1, 1, 3, 3, 5, 103, 7, 3, 3, - 103, 103, 103, 103, 104, 105, 103, 106, 103, 19, - 19, 20, 103, 107, 20, 103, 108, 109, 105, 103, - 103, 103, 104, 103, 104, 110, 111, 103, 112, 113, - 103, 103, 103, 106, 19, 103, 20, 103, 103, 103, - 20, 108, 109, 103, 114, 110, 111, 115, 112, 112, - 113, 103, 103, 103, 103, 103, 114, 115, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 116, 103, 116, 103, 116, - - 103, 103, 0, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103 + 93, 1, 1, 1, 1, 5, 93, 7, 1, 1, + 93, 93, 93, 93, 94, 95, 93, 96, 17, 97, + 96, 93, 98, 99, 93, 93, 93, 94, 93, 94, + 100, 93, 101, 102, 93, 93, 93, 96, 93, 93, + 93, 96, 98, 99, 93, 103, 100, 104, 101, 101, + 102, 93, 93, 93, 93, 93, 103, 104, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 105, 93, 105, 93, 105, + 93, 93, 0, 93, 93, 93, 93, 93, 93, 93, + + 93, 93, 93, 93, 93 } ; -static yyconst flex_int16_t yy_nxt[339] = +static yyconst flex_int16_t yy_nxt[281] = { 0, - 12, 13, 14, 15, 12, 16, 12, 12, 12, 17, - 18, 18, 18, 12, 19, 20, 20, 12, 12, 21, - 19, 21, 19, 22, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 12, 12, 12, 32, 32, 102, 23, - 12, 12, 12, 34, 20, 32, 32, 32, 32, 20, - 20, 20, 20, 20, 24, 24, 24, 35, 25, 54, - 54, 54, 26, 25, 25, 25, 25, 12, 13, 14, - 15, 27, 12, 27, 27, 27, 23, 27, 27, 27, - 12, 28, 28, 28, 12, 12, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - - 12, 12, 29, 36, 103, 34, 17, 30, 31, 31, - 29, 54, 54, 54, 17, 30, 31, 31, 39, 35, - 52, 40, 52, 52, 52, 103, 78, 38, 38, 46, - 101, 60, 79, 41, 69, 97, 42, 94, 43, 45, - 45, 45, 46, 45, 47, 47, 93, 92, 45, 45, - 45, 45, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 39, 47, 91, 40, 90, - 99, 47, 47, 47, 47, 54, 54, 54, 89, 88, - 41, 55, 87, 49, 100, 43, 51, 51, 51, 86, - 51, 95, 95, 96, 85, 51, 51, 51, 51, 52, - - 99, 52, 52, 52, 95, 95, 96, 84, 46, 83, - 82, 81, 39, 79, 100, 33, 33, 33, 33, 33, - 33, 33, 33, 37, 80, 77, 37, 37, 37, 44, - 40, 44, 50, 76, 50, 52, 75, 52, 74, 52, - 52, 53, 73, 53, 53, 53, 53, 56, 56, 56, - 72, 56, 56, 57, 71, 57, 57, 59, 59, 59, - 59, 59, 59, 59, 59, 61, 61, 61, 61, 61, - 61, 61, 61, 67, 70, 67, 68, 68, 68, 62, - 68, 68, 98, 98, 98, 98, 98, 98, 98, 98, - 60, 66, 65, 64, 63, 62, 60, 58, 103, 48, - - 48, 103, 11, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103 + 12, 13, 14, 15, 12, 16, 12, 12, 17, 12, + 12, 12, 12, 18, 18, 18, 12, 12, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 12, 12, 19, 20, 20, 20, 92, 21, 25, + 26, 26, 22, 21, 21, 21, 21, 12, 13, 14, + 15, 23, 16, 23, 23, 19, 23, 23, 23, 12, + 24, 24, 24, 12, 12, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 12, 12, + 25, 26, 26, 27, 27, 27, 27, 29, 43, 29, + 43, 43, 45, 45, 45, 50, 39, 59, 46, 93, + + 30, 33, 30, 34, 45, 45, 45, 27, 27, 68, + 43, 91, 43, 43, 69, 35, 87, 36, 39, 37, + 42, 42, 42, 39, 42, 45, 45, 45, 89, 42, + 42, 42, 42, 85, 85, 86, 85, 85, 86, 89, + 84, 90, 83, 82, 81, 80, 79, 78, 77, 76, + 75, 74, 90, 28, 28, 28, 28, 28, 28, 28, + 28, 31, 31, 31, 38, 38, 38, 38, 41, 73, + 41, 43, 72, 43, 71, 43, 43, 44, 33, 44, + 44, 44, 44, 47, 69, 47, 47, 49, 49, 49, + 49, 49, 49, 49, 49, 51, 51, 51, 51, 51, + + 51, 51, 51, 57, 70, 57, 58, 58, 58, 67, + 58, 58, 88, 88, 88, 88, 88, 88, 88, 88, + 34, 66, 65, 64, 63, 62, 61, 60, 52, 50, + 39, 56, 39, 55, 54, 53, 52, 50, 48, 93, + 40, 39, 32, 93, 19, 19, 11, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93 } ; -static yyconst flex_int16_t yy_chk[339] = +static yyconst flex_int16_t yy_chk[281] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 13, 13, 101, 3, - 3, 3, 3, 15, 3, 14, 14, 32, 32, 3, - 3, 3, 3, 3, 5, 5, 5, 15, 5, 31, - 31, 31, 5, 5, 5, 5, 5, 7, 7, 7, + 1, 1, 1, 5, 5, 5, 5, 91, 5, 9, + 9, 9, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - - 7, 7, 9, 16, 29, 33, 9, 9, 9, 9, - 10, 54, 54, 54, 10, 10, 10, 10, 17, 33, - 28, 17, 28, 28, 28, 100, 72, 16, 29, 28, - 97, 60, 72, 17, 60, 94, 17, 92, 17, 19, - 19, 19, 19, 19, 19, 19, 91, 88, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 20, 20, 20, 23, 20, 87, 23, 86, - 96, 20, 20, 20, 20, 30, 30, 30, 85, 84, - 23, 30, 83, 23, 96, 23, 25, 25, 25, 82, - 25, 93, 93, 93, 81, 25, 25, 25, 25, 53, - - 98, 53, 53, 53, 95, 95, 95, 80, 53, 79, - 78, 77, 76, 74, 98, 104, 104, 104, 104, 104, - 104, 104, 104, 105, 73, 71, 105, 105, 105, 106, - 70, 106, 107, 69, 107, 108, 68, 108, 66, 108, - 108, 109, 65, 109, 109, 109, 109, 110, 110, 110, - 64, 110, 110, 111, 63, 111, 111, 112, 112, 112, - 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, - 113, 113, 113, 114, 62, 114, 115, 115, 115, 61, - 115, 115, 116, 116, 116, 116, 116, 116, 116, 116, - 59, 49, 43, 42, 41, 40, 39, 38, 35, 22, - - 21, 11, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103 + 10, 10, 10, 13, 13, 14, 14, 15, 24, 28, + 24, 24, 25, 25, 25, 50, 24, 50, 25, 90, + + 15, 17, 28, 17, 26, 26, 26, 27, 27, 62, + 44, 87, 44, 44, 62, 17, 84, 17, 44, 17, + 21, 21, 21, 21, 21, 45, 45, 45, 86, 21, + 21, 21, 21, 83, 83, 83, 85, 85, 85, 88, + 82, 86, 81, 78, 77, 76, 75, 74, 73, 72, + 71, 70, 88, 94, 94, 94, 94, 94, 94, 94, + 94, 95, 95, 95, 96, 96, 96, 96, 97, 69, + 97, 98, 68, 98, 67, 98, 98, 99, 66, 99, + 99, 99, 99, 100, 64, 100, 100, 101, 101, 101, + 101, 101, 101, 101, 101, 102, 102, 102, 102, 102, + + 102, 102, 102, 103, 63, 103, 104, 104, 104, 61, + 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, + 60, 59, 58, 56, 55, 54, 53, 52, 51, 49, + 42, 40, 38, 37, 36, 35, 34, 33, 32, 30, + 19, 18, 16, 11, 4, 3, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93 } ; -/* Table of booleans, true if rule could match eol. */ -static yyconst flex_int32_t yy_rule_can_match_eol[21] = - { 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, }; - static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; @@ -616,6 +580,13 @@ char *yytext; #include "srcpos.h" #include "dtc-parser.tab.h" +YYLTYPE yylloc; + +/* CAUTION: this will stop working if we ever use yyless() or yyunput() */ +#define YY_USER_ACTION \ + { \ + srcpos_update(&yylloc, yytext, yyleng); \ + } /*#define LEXDEBUG 1*/ @@ -625,19 +596,14 @@ char *yytext; #define DPRINT(fmt, ...) do { } while (0) #endif -static int dts_version; /* = 0 */ +static int dts_version = 1; -#define BEGIN_DEFAULT() if (dts_version == 0) { \ - DPRINT("\n"); \ - BEGIN(INITIAL); \ - } else { \ - DPRINT("\n"); \ +#define BEGIN_DEFAULT() DPRINT("\n"); \ BEGIN(V1); \ - } static void push_input_file(const char *filename); static int pop_input_file(void); -#line 641 "dtc-lexer.lex.c" +#line 607 "dtc-lexer.lex.c" #define INITIAL 0 #define INCLUDE 1 @@ -826,9 +792,9 @@ YY_DECL register char *yy_cp, *yy_bp; register int yy_act; -#line 64 "dtc-lexer.l" +#line 66 "dtc-lexer.l" -#line 832 "dtc-lexer.lex.c" +#line 798 "dtc-lexer.lex.c" if ( !(yy_init) ) { @@ -881,35 +847,21 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 104 ) + if ( yy_current_state >= 94 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 303 ); + while ( yy_current_state != 93 ); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); yy_find_action: yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - yy_act = yy_accept[yy_current_state]; - } YY_DO_BEFORE_ACTION; - if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) - { - int yyl; - for ( yyl = 0; yyl < yyleng; ++yyl ) - if ( yytext[yyl] == '\n' ) - - yylineno++; -; - } - do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) @@ -924,7 +876,7 @@ do_action: /* This label is used only to access EOF actions. */ case 1: /* rule 1 can match eol */ YY_RULE_SETUP -#line 65 "dtc-lexer.l" +#line 67 "dtc-lexer.l" { char *name = strchr(yytext, '\"') + 1; yytext[yyleng-1] = '\0'; @@ -936,7 +888,7 @@ case YY_STATE_EOF(INCLUDE): case YY_STATE_EOF(BYTESTRING): case YY_STATE_EOF(PROPNODENAME): case YY_STATE_EOF(V1): -#line 71 "dtc-lexer.l" +#line 73 "dtc-lexer.l" { if (!pop_input_file()) { yyterminate(); @@ -946,23 +898,18 @@ case YY_STATE_EOF(V1): case 2: /* rule 2 can match eol */ YY_RULE_SETUP -#line 77 "dtc-lexer.l" +#line 79 "dtc-lexer.l" { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; DPRINT("String: %s\n", yytext); yylval.data = data_copy_escape_string(yytext+1, yyleng-2); - yylloc.first_line = yylineno; return DT_STRING; } YY_BREAK case 3: YY_RULE_SETUP -#line 87 "dtc-lexer.l" +#line 86 "dtc-lexer.l" { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; DPRINT("Keyword: /dts-v1/\n"); dts_version = 1; BEGIN_DEFAULT(); @@ -971,10 +918,8 @@ YY_RULE_SETUP YY_BREAK case 4: YY_RULE_SETUP -#line 96 "dtc-lexer.l" +#line 93 "dtc-lexer.l" { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; DPRINT("Keyword: /memreserve/\n"); BEGIN_DEFAULT(); return DT_MEMRESERVE; @@ -982,158 +927,100 @@ YY_RULE_SETUP YY_BREAK case 5: YY_RULE_SETUP -#line 104 "dtc-lexer.l" +#line 99 "dtc-lexer.l" { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; DPRINT("Label: %s\n", yytext); - yylval.labelref = strdup(yytext); + yylval.labelref = xstrdup(yytext); yylval.labelref[yyleng-1] = '\0'; return DT_LABEL; } YY_BREAK case 6: YY_RULE_SETUP -#line 113 "dtc-lexer.l" -{ - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; - if (*yytext == 'b') - yylval.cbase = 2; - else if (*yytext == 'o') - yylval.cbase = 8; - else if (*yytext == 'd') - yylval.cbase = 10; - else - yylval.cbase = 16; - DPRINT("Base: %d\n", yylval.cbase); - return DT_BASE; - } - YY_BREAK -case 7: -YY_RULE_SETUP -#line 128 "dtc-lexer.l" +#line 106 "dtc-lexer.l" { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; - yylval.literal = strdup(yytext); - DPRINT("Literal: '%s'\n", yylval.literal); - return DT_LEGACYLITERAL; - } - YY_BREAK -case 8: -YY_RULE_SETUP -#line 136 "dtc-lexer.l" -{ - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; - yylval.literal = strdup(yytext); + yylval.literal = xstrdup(yytext); DPRINT("Literal: '%s'\n", yylval.literal); return DT_LITERAL; } YY_BREAK -case 9: +case 7: YY_RULE_SETUP -#line 144 "dtc-lexer.l" +#line 112 "dtc-lexer.l" { /* label reference */ - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = strdup(yytext+1); + yylval.labelref = xstrdup(yytext+1); return DT_REF; } YY_BREAK -case 10: +case 8: YY_RULE_SETUP -#line 152 "dtc-lexer.l" +#line 118 "dtc-lexer.l" { /* new-style path reference */ - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; yytext[yyleng-1] = '\0'; DPRINT("Ref: %s\n", yytext+2); - yylval.labelref = strdup(yytext+2); + yylval.labelref = xstrdup(yytext+2); return DT_REF; } YY_BREAK -case 11: -YY_RULE_SETUP -#line 161 "dtc-lexer.l" -{ /* old-style path reference */ - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; - DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = strdup(yytext+1); - return DT_REF; - } - YY_BREAK -case 12: +case 9: YY_RULE_SETUP -#line 169 "dtc-lexer.l" +#line 125 "dtc-lexer.l" { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; yylval.byte = strtol(yytext, NULL, 16); DPRINT("Byte: %02x\n", (int)yylval.byte); return DT_BYTE; } YY_BREAK -case 13: +case 10: YY_RULE_SETUP -#line 177 "dtc-lexer.l" +#line 131 "dtc-lexer.l" { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; DPRINT("/BYTESTRING\n"); BEGIN_DEFAULT(); return ']'; } YY_BREAK -case 14: +case 11: YY_RULE_SETUP -#line 185 "dtc-lexer.l" +#line 137 "dtc-lexer.l" { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; DPRINT("PropNodeName: %s\n", yytext); - yylval.propnodename = strdup(yytext); + yylval.propnodename = xstrdup(yytext); BEGIN_DEFAULT(); return DT_PROPNODENAME; } YY_BREAK -case 15: +case 12: YY_RULE_SETUP -#line 194 "dtc-lexer.l" +#line 144 "dtc-lexer.l" { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; DPRINT("Binary Include\n"); return DT_INCBIN; } YY_BREAK -case 16: -/* rule 16 can match eol */ +case 13: +/* rule 13 can match eol */ YY_RULE_SETUP -#line 201 "dtc-lexer.l" +#line 149 "dtc-lexer.l" /* eat whitespace */ YY_BREAK -case 17: -/* rule 17 can match eol */ +case 14: +/* rule 14 can match eol */ YY_RULE_SETUP -#line 202 "dtc-lexer.l" +#line 150 "dtc-lexer.l" /* eat C-style comments */ YY_BREAK -case 18: -/* rule 18 can match eol */ +case 15: +/* rule 15 can match eol */ YY_RULE_SETUP -#line 203 "dtc-lexer.l" +#line 151 "dtc-lexer.l" /* eat C++-style comments */ YY_BREAK -case 19: +case 16: YY_RULE_SETUP -#line 205 "dtc-lexer.l" +#line 153 "dtc-lexer.l" { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; DPRINT("Char: %c (\\x%02x)\n", yytext[0], (unsigned)yytext[0]); if (yytext[0] == '[') { @@ -1148,12 +1035,12 @@ YY_RULE_SETUP return yytext[0]; } YY_BREAK -case 20: +case 17: YY_RULE_SETUP -#line 222 "dtc-lexer.l" +#line 168 "dtc-lexer.l" ECHO; YY_BREAK -#line 1157 "dtc-lexer.lex.c" +#line 1044 "dtc-lexer.lex.c" case YY_END_OF_BUFFER: { @@ -1218,7 +1105,8 @@ ECHO; else { - yy_cp = (yy_c_buf_p); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); goto yy_find_action; } } @@ -1443,7 +1331,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 104 ) + if ( yy_current_state >= 94 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1471,11 +1359,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 104 ) + if ( yy_current_state >= 94 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 103); + yy_is_jam = (yy_current_state == 93); return yy_is_jam ? 0 : yy_current_state; } @@ -1550,11 +1438,6 @@ static int yy_get_next_buffer (void) *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); - if ( c == '\n' ) - - yylineno++; -; - return c; } #endif /* ifndef YY_NO_INPUT */ @@ -1669,10 +1552,6 @@ static void yy_load_buffer_state (void) yyfree((void *) b ); } -#ifndef __cplusplus -extern int isatty (int ); -#endif /* __cplusplus */ - /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. @@ -1696,7 +1575,7 @@ extern int isatty (int ); b->yy_bs_column = 0; } - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + b->yy_is_interactive = 0; errno = oerrno; } @@ -2025,9 +1904,6 @@ static int yy_init_globals (void) * This function is called from yylex_destroy(), so don't allocate here. */ - /* We do not touch yylineno unless the option is enabled. */ - yylineno = 1; - (yy_buffer_stack) = 0; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; @@ -2120,104 +1996,29 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 222 "dtc-lexer.l" - - - - -/* - * Stack of nested include file contexts. - */ - -struct incl_file { - struct dtc_file *file; - YY_BUFFER_STATE yy_prev_buf; - int yy_prev_lineno; - struct incl_file *prev; -}; - -static struct incl_file *incl_file_stack; +#line 168 "dtc-lexer.l" -/* - * Detect infinite include recursion. - */ -#define MAX_INCLUDE_DEPTH (100) - -static int incl_depth = 0; - static void push_input_file(const char *filename) { - struct incl_file *incl_file; - struct dtc_file *newfile; - struct search_path search, *searchptr = NULL; - assert(filename); - if (incl_depth++ >= MAX_INCLUDE_DEPTH) - die("Includes nested too deeply"); - - if (srcpos_file) { - search.dir = srcpos_file->dir; - search.next = NULL; - search.prev = NULL; - searchptr = &search; - } - - newfile = dtc_open_file(filename, searchptr); + srcfile_push(filename); - incl_file = xmalloc(sizeof(struct incl_file)); + yyin = current_srcfile->f; - /* - * Save current context. - */ - incl_file->yy_prev_buf = YY_CURRENT_BUFFER; - incl_file->yy_prev_lineno = yylineno; - incl_file->file = srcpos_file; - incl_file->prev = incl_file_stack; - - incl_file_stack = incl_file; - - /* - * Establish new context. - */ - srcpos_file = newfile; - yylineno = 1; - yyin = newfile->file; - yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE)); + yypush_buffer_state(yy_create_buffer(yyin,YY_BUF_SIZE)); } static int pop_input_file(void) { - struct incl_file *incl_file; - - if (incl_file_stack == 0) + if (srcfile_pop() == 0) return 0; - dtc_close_file(srcpos_file); - - /* - * Pop. - */ - --incl_depth; - incl_file = incl_file_stack; - incl_file_stack = incl_file->prev; - - /* - * Recover old context. - */ - yy_delete_buffer(YY_CURRENT_BUFFER); - yy_switch_to_buffer(incl_file->yy_prev_buf); - yylineno = incl_file->yy_prev_lineno; - srcpos_file = incl_file->file; - yyin = incl_file->file ? incl_file->file->file : NULL; - - /* - * Free old state. - */ - free(incl_file); + yypop_buffer_state(); + yyin = current_srcfile->f; return 1; } diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped index 27129377e5d2..9be2eea18a30 100644 --- a/scripts/dtc/dtc-parser.tab.c_shipped +++ b/scripts/dtc/dtc-parser.tab.c_shipped @@ -1,24 +1,23 @@ -/* A Bison parser, made by GNU Bison 2.3. */ -/* Skeleton implementation for Bison's Yacc-like parsers in C +/* A Bison parser, made by GNU Bison 2.4.1. */ - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + 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. - + You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -29,7 +28,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -47,7 +46,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.3" +#define YYBISON_VERSION "2.4.1" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -55,55 +54,32 @@ /* Pure parsers. */ #define YYPURE 0 -/* Using locations. */ -#define YYLSP_NEEDED 1 - +/* Push parsers. */ +#define YYPUSH 0 +/* Pull parsers. */ +#define YYPULL 1 -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - DT_V1 = 258, - DT_MEMRESERVE = 259, - DT_PROPNODENAME = 260, - DT_LITERAL = 261, - DT_LEGACYLITERAL = 262, - DT_BASE = 263, - DT_BYTE = 264, - DT_STRING = 265, - DT_LABEL = 266, - DT_REF = 267, - DT_INCBIN = 268 - }; -#endif -/* Tokens. */ -#define DT_V1 258 -#define DT_MEMRESERVE 259 -#define DT_PROPNODENAME 260 -#define DT_LITERAL 261 -#define DT_LEGACYLITERAL 262 -#define DT_BASE 263 -#define DT_BYTE 264 -#define DT_STRING 265 -#define DT_LABEL 266 -#define DT_REF 267 -#define DT_INCBIN 268 - +/* Using locations. */ +#define YYLSP_NEEDED 0 /* Copy the first part of user declarations. */ -#line 23 "dtc-parser.y" + +/* Line 189 of yacc.c */ +#line 21 "dtc-parser.y" #include #include "dtc.h" #include "srcpos.h" +YYLTYPE yylloc; + extern int yylex(void); +extern void print_error(char const *fmt, ...); +extern void yyerror(char const *s); extern struct boot_info *the_boot_info; extern int treesource_error; @@ -111,6 +87,9 @@ extern int treesource_error; static unsigned long long eval_literal(const char *s, int base, int bits); +/* Line 189 of yacc.c */ +#line 92 "dtc-parser.tab.c" + /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -129,10 +108,35 @@ static unsigned long long eval_literal(const char *s, int base, int bits); # define YYTOKEN_TABLE 0 #endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + DT_V1 = 258, + DT_MEMRESERVE = 259, + DT_PROPNODENAME = 260, + DT_LITERAL = 261, + DT_BASE = 262, + DT_BYTE = 263, + DT_STRING = 264, + DT_LABEL = 265, + DT_REF = 266, + DT_INCBIN = 267 + }; +#endif + + + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 37 "dtc-parser.y" { + +/* Line 214 of yacc.c */ +#line 39 "dtc-parser.y" + char *propnodename; char *literal; char *labelref; @@ -147,34 +151,23 @@ typedef union YYSTYPE struct node *node; struct node *nodelist; struct reserve_info *re; -} -/* Line 187 of yacc.c. */ -#line 153 "dtc-parser.tab.c" - YYSTYPE; + + + +/* Line 214 of yacc.c */ +#line 159 "dtc-parser.tab.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ -/* Line 216 of yacc.c. */ -#line 178 "dtc-parser.tab.c" +/* Line 264 of yacc.c */ +#line 171 "dtc-parser.tab.c" #ifdef short # undef short @@ -249,14 +242,14 @@ typedef short int yytype_int16; #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int -YYID (int i) +YYID (int yyi) #else static int -YYID (i) - int i; +YYID (yyi) + int yyi; #endif { - return i; + return yyi; } #endif @@ -332,15 +325,13 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss; - YYSTYPE yyvs; - YYLTYPE yyls; + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ @@ -349,8 +340,8 @@ union yyalloc /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAXIMUM) + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ @@ -375,12 +366,12 @@ union yyalloc elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack) \ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ @@ -389,22 +380,22 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 9 +#define YYFINAL 4 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 73 +#define YYLAST 56 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 27 +#define YYNTOKENS 25 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 20 +#define YYNNTS 16 /* YYNRULES -- Number of rules. */ -#define YYNRULES 45 +#define YYNRULES 39 /* YYNRULES -- Number of states. */ -#define YYNSTATES 76 +#define YYNSTATES 67 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 268 +#define YYMAXUTOK 267 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -416,15 +407,15 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 24, 26, 2, 2, 25, 15, 2, 16, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 14, - 20, 19, 21, 2, 2, 2, 2, 2, 2, 2, + 22, 24, 2, 2, 23, 2, 2, 14, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, + 18, 17, 19, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 22, 2, 23, 2, 2, 2, 2, 2, 2, + 2, 20, 2, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 17, 2, 18, 2, 2, 2, 2, + 2, 2, 2, 15, 2, 16, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -438,7 +429,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13 + 5, 6, 7, 8, 9, 10, 11, 12 }; #if YYDEBUG @@ -446,41 +437,37 @@ static const yytype_uint8 yytranslate[] = YYRHS. */ static const yytype_uint8 yyprhs[] = { - 0, 0, 3, 8, 11, 12, 15, 21, 22, 25, - 27, 34, 36, 38, 41, 47, 48, 51, 57, 61, - 64, 69, 74, 77, 87, 93, 96, 97, 100, 103, - 104, 107, 110, 113, 114, 116, 118, 121, 122, 125, - 128, 129, 132, 135, 139, 140 + 0, 0, 3, 8, 9, 12, 17, 20, 22, 25, + 29, 33, 39, 40, 43, 48, 51, 54, 57, 62, + 67, 70, 80, 86, 89, 90, 93, 96, 97, 100, + 103, 106, 108, 109, 112, 115, 116, 119, 122, 125 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 28, 0, -1, 3, 14, 29, 34, -1, 31, 34, - -1, -1, 30, 29, -1, 46, 4, 33, 33, 14, - -1, -1, 32, 31, -1, 30, -1, 46, 4, 33, - 15, 33, 14, -1, 6, -1, 7, -1, 16, 35, - -1, 17, 36, 44, 18, 14, -1, -1, 36, 37, - -1, 46, 5, 19, 38, 14, -1, 46, 5, 14, - -1, 39, 10, -1, 39, 20, 40, 21, -1, 39, - 22, 43, 23, -1, 39, 12, -1, 39, 13, 24, - 10, 25, 33, 25, 33, 26, -1, 39, 13, 24, - 10, 26, -1, 38, 11, -1, -1, 38, 25, -1, - 39, 11, -1, -1, 40, 42, -1, 40, 12, -1, - 40, 11, -1, -1, 8, -1, 6, -1, 41, 7, - -1, -1, 43, 9, -1, 43, 11, -1, -1, 45, - 44, -1, 45, 37, -1, 46, 5, 35, -1, -1, - 11, -1 + 26, 0, -1, 3, 13, 27, 30, -1, -1, 28, + 27, -1, 4, 29, 29, 13, -1, 10, 28, -1, + 6, -1, 14, 31, -1, 30, 14, 31, -1, 30, + 11, 31, -1, 15, 32, 39, 16, 13, -1, -1, + 32, 33, -1, 5, 17, 34, 13, -1, 5, 13, + -1, 10, 33, -1, 35, 9, -1, 35, 18, 36, + 19, -1, 35, 20, 38, 21, -1, 35, 11, -1, + 35, 12, 22, 9, 23, 29, 23, 29, 24, -1, + 35, 12, 22, 9, 24, -1, 34, 10, -1, -1, + 34, 23, -1, 35, 10, -1, -1, 36, 37, -1, + 36, 11, -1, 36, 10, -1, 6, -1, -1, 38, + 8, -1, 38, 10, -1, -1, 40, 39, -1, 40, + 33, -1, 5, 31, -1, 10, 40, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 89, 89, 93, 101, 104, 111, 119, 122, 129, - 133, 140, 144, 151, 158, 166, 169, 176, 180, 187, - 191, 195, 199, 203, 220, 231, 239, 242, 246, 254, - 257, 261, 266, 274, 277, 281, 285, 293, 296, 300, - 308, 311, 315, 323, 331, 334 + 0, 86, 86, 95, 98, 105, 109, 117, 124, 128, + 132, 145, 153, 156, 163, 167, 171, 179, 183, 187, + 191, 195, 212, 222, 230, 233, 237, 245, 248, 252, + 257, 264, 272, 275, 279, 287, 290, 294, 302, 306 }; #endif @@ -490,13 +477,12 @@ static const yytype_uint16 yyrline[] = static const char *const yytname[] = { "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", - "DT_PROPNODENAME", "DT_LITERAL", "DT_LEGACYLITERAL", "DT_BASE", - "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", "DT_INCBIN", "';'", "'-'", - "'/'", "'{'", "'}'", "'='", "'<'", "'>'", "'['", "']'", "'('", "','", - "')'", "$accept", "sourcefile", "memreserves", "memreserve", - "v0_memreserves", "v0_memreserve", "addr", "devicetree", "nodedef", - "proplist", "propdef", "propdata", "propdataprefix", "celllist", - "cellbase", "cellval", "bytestring", "subnodes", "subnode", "label", 0 + "DT_PROPNODENAME", "DT_LITERAL", "DT_BASE", "DT_BYTE", "DT_STRING", + "DT_LABEL", "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", + "'<'", "'>'", "'['", "']'", "'('", "','", "')'", "$accept", "sourcefile", + "memreserves", "memreserve", "addr", "devicetree", "nodedef", "proplist", + "propdef", "propdata", "propdataprefix", "celllist", "cellval", + "bytestring", "subnodes", "subnode", 0 }; #endif @@ -506,29 +492,27 @@ static const char *const yytname[] = static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 59, 45, 47, 123, 125, 61, - 60, 62, 91, 93, 40, 44, 41 + 265, 266, 267, 59, 47, 123, 125, 61, 60, 62, + 91, 93, 40, 44, 41 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 27, 28, 28, 29, 29, 30, 31, 31, 32, - 32, 33, 33, 34, 35, 36, 36, 37, 37, 38, - 38, 38, 38, 38, 38, 38, 39, 39, 39, 40, - 40, 40, 40, 41, 41, 42, 42, 43, 43, 43, - 44, 44, 44, 45, 46, 46 + 0, 25, 26, 27, 27, 28, 28, 29, 30, 30, + 30, 31, 32, 32, 33, 33, 33, 34, 34, 34, + 34, 34, 34, 34, 35, 35, 35, 36, 36, 36, + 36, 37, 38, 38, 38, 39, 39, 39, 40, 40 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 4, 2, 0, 2, 5, 0, 2, 1, - 6, 1, 1, 2, 5, 0, 2, 5, 3, 2, - 4, 4, 2, 9, 5, 2, 0, 2, 2, 0, - 2, 2, 2, 0, 1, 1, 2, 0, 2, 2, - 0, 2, 2, 3, 0, 1 + 0, 2, 4, 0, 2, 4, 2, 1, 2, 3, + 3, 5, 0, 2, 4, 2, 2, 2, 4, 4, + 2, 9, 5, 2, 0, 2, 2, 0, 2, 2, + 2, 1, 0, 2, 2, 0, 2, 2, 2, 2 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -536,86 +520,79 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 7, 0, 45, 0, 9, 0, 7, 0, 4, 1, - 0, 3, 8, 0, 0, 4, 0, 15, 13, 11, - 12, 0, 2, 5, 0, 40, 0, 0, 0, 16, - 0, 40, 0, 0, 6, 0, 42, 41, 0, 10, - 14, 18, 26, 43, 0, 0, 25, 17, 27, 19, - 28, 22, 0, 29, 37, 0, 33, 0, 0, 35, - 34, 32, 31, 20, 0, 30, 38, 39, 21, 0, - 24, 36, 0, 0, 0, 23 + 0, 0, 0, 3, 1, 0, 0, 0, 3, 7, + 0, 6, 0, 2, 4, 0, 12, 8, 0, 0, + 5, 35, 10, 9, 0, 0, 13, 0, 35, 15, + 24, 38, 16, 39, 0, 37, 36, 0, 0, 11, + 23, 14, 25, 17, 26, 20, 0, 27, 32, 0, + 0, 0, 0, 31, 30, 29, 18, 28, 33, 34, + 19, 0, 22, 0, 0, 0, 21 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 3, 14, 4, 5, 6, 27, 11, 18, 25, - 29, 44, 45, 56, 64, 65, 57, 30, 31, 7 + -1, 2, 7, 8, 10, 13, 17, 21, 26, 37, + 38, 50, 57, 51, 27, 28 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -14 +#define YYPACT_NINF -12 static const yytype_int8 yypact[] = { - 30, -11, -14, 7, -14, -1, 27, 13, 27, -14, - 8, -14, -14, 40, -1, 27, 35, -14, -14, -14, - -14, 21, -14, -14, 40, 24, 40, 28, 40, -14, - 32, 24, 46, 38, -14, 39, -14, -14, 26, -14, - -14, -14, -14, -14, -9, 10, -14, -14, -14, -14, - -14, -14, 31, -14, -14, 44, -2, 3, 23, -14, - -14, -14, -14, -14, 50, -14, -14, -14, -14, 40, - -14, -14, 33, 40, 36, -14 + 10, -11, 18, -1, -12, 22, -1, 15, -1, -12, + 22, -12, 20, 1, -12, 17, -12, -12, 20, 20, + -12, 6, -12, -12, 21, 6, -12, 23, 6, -12, + -12, -12, -12, -12, 28, -12, -12, -6, 13, -12, + -12, -12, -12, -12, -12, -12, 24, -12, -12, 33, + -5, 0, -4, -12, -12, -12, -12, -12, -12, -12, + -12, 22, -12, 25, 22, 19, -12 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -14, -14, 48, 29, 53, -14, -13, 47, 34, -14, - 37, -14, -14, -14, -14, -14, -14, 42, -14, -7 + -12, -12, 36, 39, -10, -12, 8, -12, 12, -12, + -12, -12, -12, -12, 27, 31 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -45 -static const yytype_int8 yytable[] = +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = { - 21, 16, 46, 8, 59, 47, 60, 9, 16, 61, - 62, 28, 66, 33, 67, 10, 48, 13, 32, 63, - 49, 50, 51, 52, 32, 17, 68, 19, 20, -44, - 53, -44, 54, 1, -44, 2, 26, 15, 2, 24, - 41, 2, 34, 17, 15, 42, 19, 20, 69, 70, - 35, 38, 39, 40, 58, 55, 72, 71, 73, 12, - 74, 22, 75, 23, 0, 0, 0, 0, 36, 0, - 0, 0, 43, 37 + 15, 53, 3, 5, 40, 54, 55, 41, 58, 6, + 59, 24, 18, 1, 56, 19, 25, 42, 4, 61, + 62, 60, 43, 44, 45, 46, 22, 23, 9, 12, + 20, 47, 31, 48, 29, 16, 16, 32, 30, 34, + 35, 39, 52, 66, 14, 11, 49, 0, 64, 0, + 0, 63, 0, 0, 65, 36, 33 }; static const yytype_int8 yycheck[] = { - 13, 8, 11, 14, 6, 14, 8, 0, 15, 11, - 12, 24, 9, 26, 11, 16, 25, 4, 25, 21, - 10, 11, 12, 13, 31, 17, 23, 6, 7, 5, - 20, 4, 22, 3, 4, 11, 15, 8, 11, 4, - 14, 11, 14, 17, 15, 19, 6, 7, 25, 26, - 18, 5, 14, 14, 10, 24, 69, 7, 25, 6, - 73, 14, 26, 15, -1, -1, -1, -1, 31, -1, - -1, -1, 38, 31 + 10, 6, 13, 4, 10, 10, 11, 13, 8, 10, + 10, 5, 11, 3, 19, 14, 10, 23, 0, 23, + 24, 21, 9, 10, 11, 12, 18, 19, 6, 14, + 13, 18, 24, 20, 13, 15, 15, 25, 17, 16, + 28, 13, 9, 24, 8, 6, 22, -1, 23, -1, + -1, 61, -1, -1, 64, 28, 25 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 3, 11, 28, 30, 31, 32, 46, 14, 0, - 16, 34, 31, 4, 29, 30, 46, 17, 35, 6, - 7, 33, 34, 29, 4, 36, 15, 33, 33, 37, - 44, 45, 46, 33, 14, 18, 37, 44, 5, 14, - 14, 14, 19, 35, 38, 39, 11, 14, 25, 10, - 11, 12, 13, 20, 22, 24, 40, 43, 10, 6, - 8, 11, 12, 21, 41, 42, 9, 11, 23, 25, - 26, 7, 33, 25, 33, 26 + 0, 3, 26, 13, 0, 4, 10, 27, 28, 6, + 29, 28, 14, 30, 27, 29, 15, 31, 11, 14, + 13, 32, 31, 31, 5, 10, 33, 39, 40, 13, + 17, 31, 33, 40, 16, 33, 39, 34, 35, 13, + 10, 13, 23, 9, 10, 11, 12, 18, 20, 22, + 36, 38, 9, 6, 10, 11, 19, 37, 8, 10, + 21, 23, 24, 29, 23, 29, 24 }; #define yyerrok (yyerrstatus = 0) @@ -728,7 +705,7 @@ do { \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ - Type, Value, Location); \ + Type, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) @@ -742,19 +719,17 @@ do { \ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) #else static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp) +yy_symbol_value_print (yyoutput, yytype, yyvaluep) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; #endif { if (!yyvaluep) return; - YYUSE (yylocationp); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); @@ -776,14 +751,13 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) #else static void -yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) +yy_symbol_print (yyoutput, yytype, yyvaluep) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; #endif { if (yytype < YYNTOKENS) @@ -791,9 +765,7 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp); + yy_symbol_value_print (yyoutput, yytype, yyvaluep); YYFPRINTF (yyoutput, ")"); } @@ -805,17 +777,20 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) #else static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; #endif { YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } YYFPRINTF (stderr, "\n"); } @@ -833,12 +808,11 @@ do { \ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) #else static void -yy_reduce_print (yyvsp, yylsp, yyrule) +yy_reduce_print (yyvsp, yyrule) YYSTYPE *yyvsp; - YYLTYPE *yylsp; int yyrule; #endif { @@ -850,18 +824,18 @@ yy_reduce_print (yyvsp, yylsp, yyrule) /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { - fprintf (stderr, " $%d = ", yyi + 1); + YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) - , &(yylsp[(yyi + 1) - (yynrhs)]) ); - fprintf (stderr, "\n"); + ); + YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ - yy_reduce_print (yyvsp, yylsp, Rule); \ + yy_reduce_print (yyvsp, Rule); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that @@ -1112,18 +1086,16 @@ yysyntax_error (char *yyresult, int yystate, int yychar) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp) +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) #else static void -yydestruct (yymsg, yytype, yyvaluep, yylocationp) +yydestruct (yymsg, yytype, yyvaluep) const char *yymsg; int yytype; YYSTYPE *yyvaluep; - YYLTYPE *yylocationp; #endif { YYUSE (yyvaluep); - YYUSE (yylocationp); if (!yymsg) yymsg = "Deleting"; @@ -1136,10 +1108,8 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp) break; } } - /* Prevent warnings from -Wmissing-prototypes. */ - #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); @@ -1155,23 +1125,20 @@ int yyparse (); #endif /* ! YYPARSE_PARAM */ - -/* The look-ahead symbol. */ +/* The lookahead symbol. */ int yychar; -/* The semantic value of the look-ahead symbol. */ +/* The semantic value of the lookahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; -/* Location data for the look-ahead symbol. */ -YYLTYPE yylloc; -/*----------. -| yyparse. | -`----------*/ +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -1195,79 +1162,70 @@ yyparse () #endif #endif { - - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[2]; + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; - YYSIZE_T yystacksize = YYINITDEPTH; + YYSIZE_T yystacksize; + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; - YYLTYPE yyloc; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ - yyssp = yyss; yyvsp = yyvs; - yylsp = yyls; -#if YYLTYPE_IS_TRIVIAL - /* Initialize the default location before parsing starts. */ - yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = 0; -#endif goto yysetstate; @@ -1294,7 +1252,6 @@ yyparse () memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; - YYLTYPE *yyls1 = yyls; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a @@ -1303,9 +1260,8 @@ yyparse () yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), &yystacksize); - yyls = yyls1; + yyss = yyss1; yyvs = yyvs1; } @@ -1326,9 +1282,8 @@ yyparse () (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - YYSTACK_RELOCATE (yyls); + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); @@ -1338,7 +1293,6 @@ yyparse () yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; - yylsp = yyls + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); @@ -1349,6 +1303,9 @@ yyparse () YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + if (yystate == YYFINAL) + YYACCEPT; + goto yybackup; /*-----------. @@ -1357,16 +1314,16 @@ yyparse () yybackup: /* Do appropriate processing given the current state. Read a - look-ahead token if we need one and don't already have one. */ + lookahead token if we need one and don't already have one. */ - /* First try to decide what to do without reference to look-ahead token. */ + /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; - /* Not known => get a look-ahead token if don't already have one. */ + /* Not known => get a lookahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); @@ -1398,24 +1355,20 @@ yybackup: goto yyreduce; } - if (yyn == YYFINAL) - YYACCEPT; - /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; - /* Shift the look-ahead token. */ + /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; + /* Discard the shifted token. */ + yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; - *++yylsp = yylloc; + goto yynewstate; @@ -1446,337 +1399,387 @@ yyreduce: GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; - /* Default location. */ - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); + YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: -#line 90 "dtc-parser.y" + +/* Line 1455 of yacc.c */ +#line 87 "dtc-parser.y" { - the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node), 0); + the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node), + guess_boot_cpuid((yyvsp[(4) - (4)].node))); ;} break; case 3: -#line 94 "dtc-parser.y" + +/* Line 1455 of yacc.c */ +#line 95 "dtc-parser.y" { - the_boot_info = build_boot_info((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].node), 0); + (yyval.re) = NULL; ;} break; case 4: -#line 101 "dtc-parser.y" + +/* Line 1455 of yacc.c */ +#line 99 "dtc-parser.y" { - (yyval.re) = NULL; + (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); ;} break; case 5: -#line 105 "dtc-parser.y" + +/* Line 1455 of yacc.c */ +#line 106 "dtc-parser.y" { - (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); + (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].addr), (yyvsp[(3) - (4)].addr)); ;} break; case 6: -#line 112 "dtc-parser.y" + +/* Line 1455 of yacc.c */ +#line 110 "dtc-parser.y" { - (yyval.re) = build_reserve_entry((yyvsp[(3) - (5)].addr), (yyvsp[(4) - (5)].addr), (yyvsp[(1) - (5)].labelref)); + add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref)); + (yyval.re) = (yyvsp[(2) - (2)].re); ;} break; case 7: -#line 119 "dtc-parser.y" + +/* Line 1455 of yacc.c */ +#line 118 "dtc-parser.y" { - (yyval.re) = NULL; + (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64); ;} break; case 8: -#line 123 "dtc-parser.y" + +/* Line 1455 of yacc.c */ +#line 125 "dtc-parser.y" { - (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); + (yyval.node) = name_node((yyvsp[(2) - (2)].node), ""); ;} break; case 9: -#line 130 "dtc-parser.y" + +/* Line 1455 of yacc.c */ +#line 129 "dtc-parser.y" { - (yyval.re) = (yyvsp[(1) - (1)].re); + (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); ;} break; case 10: -#line 134 "dtc-parser.y" + +/* Line 1455 of yacc.c */ +#line 133 "dtc-parser.y" { - (yyval.re) = build_reserve_entry((yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].addr) - (yyvsp[(3) - (6)].addr) + 1, (yyvsp[(1) - (6)].labelref)); + struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref)); + + if (target) + merge_nodes(target, (yyvsp[(3) - (3)].node)); + else + print_error("label or path, '%s', not found", (yyvsp[(2) - (3)].labelref)); + (yyval.node) = (yyvsp[(1) - (3)].node); ;} break; case 11: -#line 141 "dtc-parser.y" + +/* Line 1455 of yacc.c */ +#line 146 "dtc-parser.y" { - (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64); + (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); ;} break; case 12: -#line 145 "dtc-parser.y" + +/* Line 1455 of yacc.c */ +#line 153 "dtc-parser.y" { - (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 16, 64); + (yyval.proplist) = NULL; ;} break; case 13: -#line 152 "dtc-parser.y" + +/* Line 1455 of yacc.c */ +#line 157 "dtc-parser.y" { - (yyval.node) = name_node((yyvsp[(2) - (2)].node), "", NULL); + (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); ;} break; case 14: -#line 159 "dtc-parser.y" + +/* Line 1455 of yacc.c */ +#line 164 "dtc-parser.y" { - (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); + (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data)); ;} break; case 15: -#line 166 "dtc-parser.y" + +/* Line 1455 of yacc.c */ +#line 168 "dtc-parser.y" { - (yyval.proplist) = NULL; + (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data); ;} break; case 16: -#line 170 "dtc-parser.y" + +/* Line 1455 of yacc.c */ +#line 172 "dtc-parser.y" { - (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); + add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref)); + (yyval.prop) = (yyvsp[(2) - (2)].prop); ;} break; case 17: -#line 177 "dtc-parser.y" + +/* Line 1455 of yacc.c */ +#line 180 "dtc-parser.y" { - (yyval.prop) = build_property((yyvsp[(2) - (5)].propnodename), (yyvsp[(4) - (5)].data), (yyvsp[(1) - (5)].labelref)); + (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); ;} break; case 18: -#line 181 "dtc-parser.y" + +/* Line 1455 of yacc.c */ +#line 184 "dtc-parser.y" { - (yyval.prop) = build_property((yyvsp[(2) - (3)].propnodename), empty_data, (yyvsp[(1) - (3)].labelref)); + (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); ;} break; case 19: + +/* Line 1455 of yacc.c */ #line 188 "dtc-parser.y" { - (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); + (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); ;} break; case 20: + +/* Line 1455 of yacc.c */ #line 192 "dtc-parser.y" { - (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); + (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); ;} break; case 21: -#line 196 "dtc-parser.y" - { - (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); - ;} - break; - - case 22: -#line 200 "dtc-parser.y" - { - (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); - ;} - break; - case 23: -#line 204 "dtc-parser.y" +/* Line 1455 of yacc.c */ +#line 196 "dtc-parser.y" { - struct search_path path = { srcpos_file->dir, NULL, NULL }; - struct dtc_file *file = dtc_open_file((yyvsp[(4) - (9)].data).val, &path); - struct data d = empty_data; + FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL); + struct data d; if ((yyvsp[(6) - (9)].addr) != 0) - if (fseek(file->file, (yyvsp[(6) - (9)].addr), SEEK_SET) != 0) - yyerrorf("Couldn't seek to offset %llu in \"%s\": %s", - (unsigned long long)(yyvsp[(6) - (9)].addr), - (yyvsp[(4) - (9)].data).val, strerror(errno)); + if (fseek(f, (yyvsp[(6) - (9)].addr), SEEK_SET) != 0) + print_error("Couldn't seek to offset %llu in \"%s\": %s", + (unsigned long long)(yyvsp[(6) - (9)].addr), + (yyvsp[(4) - (9)].data).val, + strerror(errno)); - d = data_copy_file(file->file, (yyvsp[(8) - (9)].addr)); + d = data_copy_file(f, (yyvsp[(8) - (9)].addr)); (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d); - dtc_close_file(file); + fclose(f); ;} break; - case 24: -#line 221 "dtc-parser.y" + case 22: + +/* Line 1455 of yacc.c */ +#line 213 "dtc-parser.y" { - struct search_path path = { srcpos_file->dir, NULL, NULL }; - struct dtc_file *file = dtc_open_file((yyvsp[(4) - (5)].data).val, &path); + FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL); struct data d = empty_data; - d = data_copy_file(file->file, -1); + d = data_copy_file(f, -1); (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d); - dtc_close_file(file); + fclose(f); ;} break; - case 25: -#line 232 "dtc-parser.y" + case 23: + +/* Line 1455 of yacc.c */ +#line 223 "dtc-parser.y" { (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ;} break; - case 26: -#line 239 "dtc-parser.y" + case 24: + +/* Line 1455 of yacc.c */ +#line 230 "dtc-parser.y" { (yyval.data) = empty_data; ;} break; - case 27: -#line 243 "dtc-parser.y" + case 25: + +/* Line 1455 of yacc.c */ +#line 234 "dtc-parser.y" { (yyval.data) = (yyvsp[(1) - (2)].data); ;} break; - case 28: -#line 247 "dtc-parser.y" + case 26: + +/* Line 1455 of yacc.c */ +#line 238 "dtc-parser.y" { (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ;} break; - case 29: -#line 254 "dtc-parser.y" + case 27: + +/* Line 1455 of yacc.c */ +#line 245 "dtc-parser.y" { (yyval.data) = empty_data; ;} break; - case 30: -#line 258 "dtc-parser.y" + case 28: + +/* Line 1455 of yacc.c */ +#line 249 "dtc-parser.y" { (yyval.data) = data_append_cell((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].cell)); ;} break; - case 31: -#line 262 "dtc-parser.y" + case 29: + +/* Line 1455 of yacc.c */ +#line 253 "dtc-parser.y" { (yyval.data) = data_append_cell(data_add_marker((yyvsp[(1) - (2)].data), REF_PHANDLE, (yyvsp[(2) - (2)].labelref)), -1); ;} break; - case 32: -#line 267 "dtc-parser.y" + case 30: + +/* Line 1455 of yacc.c */ +#line 258 "dtc-parser.y" { (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ;} break; - case 33: -#line 274 "dtc-parser.y" - { - (yyval.cbase) = 16; - ;} - break; + case 31: - case 35: -#line 282 "dtc-parser.y" +/* Line 1455 of yacc.c */ +#line 265 "dtc-parser.y" { (yyval.cell) = eval_literal((yyvsp[(1) - (1)].literal), 0, 32); ;} break; - case 36: -#line 286 "dtc-parser.y" - { - (yyval.cell) = eval_literal((yyvsp[(2) - (2)].literal), (yyvsp[(1) - (2)].cbase), 32); - ;} - break; + case 32: - case 37: -#line 293 "dtc-parser.y" +/* Line 1455 of yacc.c */ +#line 272 "dtc-parser.y" { (yyval.data) = empty_data; ;} break; - case 38: -#line 297 "dtc-parser.y" + case 33: + +/* Line 1455 of yacc.c */ +#line 276 "dtc-parser.y" { (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); ;} break; - case 39: -#line 301 "dtc-parser.y" + case 34: + +/* Line 1455 of yacc.c */ +#line 280 "dtc-parser.y" { (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ;} break; - case 40: -#line 308 "dtc-parser.y" + case 35: + +/* Line 1455 of yacc.c */ +#line 287 "dtc-parser.y" { (yyval.nodelist) = NULL; ;} break; - case 41: -#line 312 "dtc-parser.y" + case 36: + +/* Line 1455 of yacc.c */ +#line 291 "dtc-parser.y" { (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); ;} break; - case 42: -#line 316 "dtc-parser.y" + case 37: + +/* Line 1455 of yacc.c */ +#line 295 "dtc-parser.y" { - yyerror("syntax error: properties must precede subnodes"); + print_error("syntax error: properties must precede subnodes"); YYERROR; ;} break; - case 43: -#line 324 "dtc-parser.y" - { - (yyval.node) = name_node((yyvsp[(3) - (3)].node), (yyvsp[(2) - (3)].propnodename), (yyvsp[(1) - (3)].labelref)); - ;} - break; + case 38: - case 44: -#line 331 "dtc-parser.y" +/* Line 1455 of yacc.c */ +#line 303 "dtc-parser.y" { - (yyval.labelref) = NULL; + (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename)); ;} break; - case 45: -#line 335 "dtc-parser.y" + case 39: + +/* Line 1455 of yacc.c */ +#line 307 "dtc-parser.y" { - (yyval.labelref) = (yyvsp[(1) - (1)].labelref); + add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref)); + (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; -/* Line 1267 of yacc.c. */ -#line 1780 "dtc-parser.tab.c" + +/* Line 1455 of yacc.c */ +#line 1783 "dtc-parser.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -1786,7 +1789,6 @@ yyreduce: YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; - *++yylsp = yyloc; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule @@ -1848,11 +1850,11 @@ yyerrlab: #endif } - yyerror_range[0] = yylloc; + if (yyerrstatus == 3) { - /* If just tried and failed to reuse look-ahead token after an + /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) @@ -1864,12 +1866,12 @@ yyerrlab: else { yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc); + yytoken, &yylval); yychar = YYEMPTY; } } - /* Else will try to reuse look-ahead token after shifting the error + /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; @@ -1885,7 +1887,6 @@ yyerrorlab: if (/*CONSTCOND*/ 0) goto yyerrorlab; - yyerror_range[0] = yylsp[1-yylen]; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); @@ -1919,24 +1920,16 @@ yyerrlab1: if (yyssp == yyss) YYABORT; - yyerror_range[0] = *yylsp; + yydestruct ("Error: popping", - yystos[yystate], yyvsp, yylsp); + yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } - if (yyn == YYFINAL) - YYACCEPT; - *++yyvsp = yylval; - yyerror_range[1] = yylloc; - /* Using YYLLOC is tempting, but would change the location of - the look-ahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); - *++yylsp = yyloc; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); @@ -1959,7 +1952,7 @@ yyabortlab: yyresult = 1; goto yyreturn; -#ifndef yyoverflow +#if !defined(yyoverflow) || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ @@ -1970,9 +1963,9 @@ yyexhaustedlab: #endif yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) + if (yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc); + yytoken, &yylval); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); @@ -1980,7 +1973,7 @@ yyreturn: while (yyssp != yyss) { yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, yylsp); + yystos[*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow @@ -1996,29 +1989,24 @@ yyreturn: } -#line 340 "dtc-parser.y" + +/* Line 1675 of yacc.c */ +#line 313 "dtc-parser.y" -void yyerrorf(char const *s, ...) +void print_error(char const *fmt, ...) { - const char *fname = srcpos_file ? srcpos_file->name : ""; va_list va; - va_start(va, s); - - if (strcmp(fname, "-") == 0) - fname = "stdin"; - fprintf(stderr, "%s:%d ", fname, yylloc.first_line); - vfprintf(stderr, s, va); - fprintf(stderr, "\n"); + va_start(va, fmt); + srcpos_verror(&yylloc, fmt, va); + va_end(va); treesource_error = 1; - va_end(va); } -void yyerror (char const *s) -{ - yyerrorf("%s", s); +void yyerror(char const *s) { + print_error("%s", s); } static unsigned long long eval_literal(const char *s, int base, int bits) @@ -2029,12 +2017,12 @@ static unsigned long long eval_literal(const char *s, int base, int bits) errno = 0; val = strtoull(s, &e, base); if (*e) - yyerror("bad characters in literal"); + print_error("bad characters in literal"); else if ((errno == ERANGE) || ((bits < 64) && (val >= (1ULL << bits)))) - yyerror("literal out of range"); + print_error("literal out of range"); else if (errno != 0) - yyerror("bad literal"); + print_error("bad literal"); return val; } diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped index ba99100d55c9..95c9547adea5 100644 --- a/scripts/dtc/dtc-parser.tab.h_shipped +++ b/scripts/dtc/dtc-parser.tab.h_shipped @@ -1,24 +1,23 @@ -/* A Bison parser, made by GNU Bison 2.3. */ -/* Skeleton interface for Bison's Yacc-like parsers in C +/* A Bison parser, made by GNU Bison 2.4.1. */ - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + 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. - + You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -29,10 +28,11 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ + /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE @@ -43,35 +43,24 @@ DT_MEMRESERVE = 259, DT_PROPNODENAME = 260, DT_LITERAL = 261, - DT_LEGACYLITERAL = 262, - DT_BASE = 263, - DT_BYTE = 264, - DT_STRING = 265, - DT_LABEL = 266, - DT_REF = 267, - DT_INCBIN = 268 + DT_BASE = 262, + DT_BYTE = 263, + DT_STRING = 264, + DT_LABEL = 265, + DT_REF = 266, + DT_INCBIN = 267 }; #endif -/* Tokens. */ -#define DT_V1 258 -#define DT_MEMRESERVE 259 -#define DT_PROPNODENAME 260 -#define DT_LITERAL 261 -#define DT_LEGACYLITERAL 262 -#define DT_BASE 263 -#define DT_BYTE 264 -#define DT_STRING 265 -#define DT_LABEL 266 -#define DT_REF 267 -#define DT_INCBIN 268 - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 37 "dtc-parser.y" { + +/* Line 1676 of yacc.c */ +#line 39 "dtc-parser.y" + char *propnodename; char *literal; char *labelref; @@ -86,28 +75,17 @@ typedef union YYSTYPE struct node *node; struct node *nodelist; struct reserve_info *re; -} -/* Line 1489 of yacc.c. */ -#line 92 "dtc-parser.tab.h" - YYSTYPE; + + + +/* Line 1676 of yacc.c */ +#line 83 "dtc-parser.tab.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 #endif extern YYSTYPE yylval; -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif -extern YYLTYPE yylloc; diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y index b2ab562420ea..5e84a67fc1d2 100644 --- a/scripts/dtc/dtc-parser.y +++ b/scripts/dtc/dtc-parser.y @@ -18,15 +18,17 @@ * USA */ -%locations - %{ #include #include "dtc.h" #include "srcpos.h" +YYLTYPE yylloc; + extern int yylex(void); +extern void print_error(char const *fmt, ...); +extern void yyerror(char const *s); extern struct boot_info *the_boot_info; extern int treesource_error; @@ -55,7 +57,6 @@ static unsigned long long eval_literal(const char *s, int base, int bits); %token DT_MEMRESERVE %token DT_PROPNODENAME %token DT_LITERAL -%token DT_LEGACYLITERAL %token DT_BASE %token DT_BYTE %token DT_STRING @@ -67,11 +68,8 @@ static unsigned long long eval_literal(const char *s, int base, int bits); %type propdataprefix %type memreserve %type memreserves -%type v0_memreserve -%type v0_memreserves %type addr %type celllist -%type cellbase %type cellval %type bytestring %type propdef @@ -81,18 +79,14 @@ static unsigned long long eval_literal(const char *s, int base, int bits); %type nodedef %type subnode %type subnodes -%type label %% sourcefile: DT_V1 ';' memreserves devicetree { - the_boot_info = build_boot_info($3, $4, 0); - } - | v0_memreserves devicetree - { - the_boot_info = build_boot_info($1, $2, 0); + the_boot_info = build_boot_info($3, $4, + guess_boot_cpuid($4)); } ; @@ -108,31 +102,14 @@ memreserves: ; memreserve: - label DT_MEMRESERVE addr addr ';' + DT_MEMRESERVE addr addr ';' { - $$ = build_reserve_entry($3, $4, $1); + $$ = build_reserve_entry($2, $3); } - ; - -v0_memreserves: - /* empty */ + | DT_LABEL memreserve { - $$ = NULL; - } - | v0_memreserve v0_memreserves - { - $$ = chain_reserve_entry($1, $2); - }; - ; - -v0_memreserve: - memreserve - { - $$ = $1; - } - | label DT_MEMRESERVE addr '-' addr ';' - { - $$ = build_reserve_entry($3, $5 - $3 + 1, $1); + add_label(&$2->labels, $1); + $$ = $2; } ; @@ -141,16 +118,26 @@ addr: { $$ = eval_literal($1, 0, 64); } - | DT_LEGACYLITERAL - { - $$ = eval_literal($1, 16, 64); - } ; devicetree: '/' nodedef { - $$ = name_node($2, "", NULL); + $$ = name_node($2, ""); + } + | devicetree '/' nodedef + { + $$ = merge_nodes($1, $3); + } + | devicetree DT_REF nodedef + { + struct node *target = get_node_by_ref($1, $2); + + if (target) + merge_nodes(target, $3); + else + print_error("label or path, '%s', not found", $2); + $$ = $1; } ; @@ -173,13 +160,18 @@ proplist: ; propdef: - label DT_PROPNODENAME '=' propdata ';' + DT_PROPNODENAME '=' propdata ';' + { + $$ = build_property($1, $3); + } + | DT_PROPNODENAME ';' { - $$ = build_property($2, $4, $1); + $$ = build_property($1, empty_data); } - | label DT_PROPNODENAME ';' + | DT_LABEL propdef { - $$ = build_property($2, empty_data, $1); + add_label(&$2->labels, $1); + $$ = $2; } ; @@ -202,31 +194,30 @@ propdata: } | propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')' { - struct search_path path = { srcpos_file->dir, NULL, NULL }; - struct dtc_file *file = dtc_open_file($4.val, &path); - struct data d = empty_data; + FILE *f = srcfile_relative_open($4.val, NULL); + struct data d; if ($6 != 0) - if (fseek(file->file, $6, SEEK_SET) != 0) - yyerrorf("Couldn't seek to offset %llu in \"%s\": %s", - (unsigned long long)$6, - $4.val, strerror(errno)); + if (fseek(f, $6, SEEK_SET) != 0) + print_error("Couldn't seek to offset %llu in \"%s\": %s", + (unsigned long long)$6, + $4.val, + strerror(errno)); - d = data_copy_file(file->file, $8); + d = data_copy_file(f, $8); $$ = data_merge($1, d); - dtc_close_file(file); + fclose(f); } | propdataprefix DT_INCBIN '(' DT_STRING ')' { - struct search_path path = { srcpos_file->dir, NULL, NULL }; - struct dtc_file *file = dtc_open_file($4.val, &path); + FILE *f = srcfile_relative_open($4.val, NULL); struct data d = empty_data; - d = data_copy_file(file->file, -1); + d = data_copy_file(f, -1); $$ = data_merge($1, d); - dtc_close_file(file); + fclose(f); } | propdata DT_LABEL { @@ -269,23 +260,11 @@ celllist: } ; -cellbase: - /* empty */ - { - $$ = 16; - } - | DT_BASE - ; - cellval: DT_LITERAL { $$ = eval_literal($1, 0, 32); } - | cellbase DT_LEGACYLITERAL - { - $$ = eval_literal($2, $1, 32); - } ; bytestring: @@ -308,57 +287,44 @@ subnodes: { $$ = NULL; } - | subnode subnodes + | subnode subnodes { $$ = chain_node($1, $2); } | subnode propdef { - yyerror("syntax error: properties must precede subnodes"); + print_error("syntax error: properties must precede subnodes"); YYERROR; } ; subnode: - label DT_PROPNODENAME nodedef + DT_PROPNODENAME nodedef { - $$ = name_node($3, $2, $1); + $$ = name_node($2, $1); } - ; - -label: - /* empty */ + | DT_LABEL subnode { - $$ = NULL; - } - | DT_LABEL - { - $$ = $1; + add_label(&$2->labels, $1); + $$ = $2; } ; %% -void yyerrorf(char const *s, ...) +void print_error(char const *fmt, ...) { - const char *fname = srcpos_file ? srcpos_file->name : ""; va_list va; - va_start(va, s); - - if (strcmp(fname, "-") == 0) - fname = "stdin"; - fprintf(stderr, "%s:%d ", fname, yylloc.first_line); - vfprintf(stderr, s, va); - fprintf(stderr, "\n"); + va_start(va, fmt); + srcpos_verror(&yylloc, fmt, va); + va_end(va); treesource_error = 1; - va_end(va); } -void yyerror (char const *s) -{ - yyerrorf("%s", s); +void yyerror(char const *s) { + print_error("%s", s); } static unsigned long long eval_literal(const char *s, int base, int bits) @@ -369,11 +335,11 @@ static unsigned long long eval_literal(const char *s, int base, int bits) errno = 0; val = strtoull(s, &e, base); if (*e) - yyerror("bad characters in literal"); + print_error("bad characters in literal"); else if ((errno == ERANGE) || ((bits < 64) && (val >= (1ULL << bits)))) - yyerror("literal out of range"); + print_error("literal out of range"); else if (errno != 0) - yyerror("bad literal"); + print_error("bad literal"); return val; } diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c index d8fd43b4ac1a..cbc0193098e4 100644 --- a/scripts/dtc/dtc.c +++ b/scripts/dtc/dtc.c @@ -30,30 +30,7 @@ int quiet; /* Level of quietness */ int reservenum; /* Number of memory reservation slots */ int minsize; /* Minimum blob size */ int padsize; /* Additional padding to blob */ - -char *join_path(const char *path, const char *name) -{ - int lenp = strlen(path); - int lenn = strlen(name); - int len; - int needslash = 1; - char *str; - - len = lenp + lenn + 2; - if ((lenp > 0) && (path[lenp-1] == '/')) { - needslash = 0; - len--; - } - - str = xmalloc(len); - memcpy(str, path, lenp); - if (needslash) { - str[lenp] = '/'; - lenp++; - } - memcpy(str+lenp, name, lenn+1); - return str; -} +int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ static void fill_fullpaths(struct node *tree, const char *prefix) { @@ -104,8 +81,15 @@ static void __attribute__ ((noreturn)) usage(void) fprintf(stderr, "\t\tSet the physical boot cpu\n"); fprintf(stderr, "\t-f\n"); fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n"); + fprintf(stderr, "\t-s\n"); + fprintf(stderr, "\t\tSort nodes and properties before outputting (only useful for\n\t\tcomparing trees)\n"); fprintf(stderr, "\t-v\n"); fprintf(stderr, "\t\tPrint DTC version and exit\n"); + fprintf(stderr, "\t-H \n"); + fprintf(stderr, "\t\tphandle formats are:\n"); + fprintf(stderr, "\t\t\tlegacy - \"linux,phandle\" properties only\n"); + fprintf(stderr, "\t\t\tepapr - \"phandle\" properties only\n"); + fprintf(stderr, "\t\t\tboth - Both \"linux,phandle\" and \"phandle\" properties\n"); exit(3); } @@ -115,7 +99,7 @@ int main(int argc, char *argv[]) const char *inform = "dts"; const char *outform = "dts"; const char *outname = "-"; - int force = 0, check = 0; + int force = 0, check = 0, sort = 0; const char *arg; int opt; FILE *outf = NULL; @@ -127,7 +111,7 @@ int main(int argc, char *argv[]) minsize = 0; padsize = 0; - while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:v")) != EOF) { + while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:vH:s")) != EOF) { switch (opt) { case 'I': inform = optarg; @@ -165,6 +149,22 @@ int main(int argc, char *argv[]) case 'v': printf("Version: %s\n", DTC_VERSION); exit(0); + case 'H': + if (streq(optarg, "legacy")) + phandle_format = PHANDLE_LEGACY; + else if (streq(optarg, "epapr")) + phandle_format = PHANDLE_EPAPR; + else if (streq(optarg, "both")) + phandle_format = PHANDLE_BOTH; + else + die("Invalid argument \"%s\" to -H option\n", + optarg); + break; + + case 's': + sort = 1; + break; + case 'h': default: usage(); @@ -182,6 +182,9 @@ int main(int argc, char *argv[]) if (minsize && padsize) die("Can't set both -p and -S\n"); + if (minsize) + fprintf(stderr, "DTC: Use of \"-S\" is deprecated; it will be removed soon, use \"-p\" instead\n"); + fprintf(stderr, "DTC: %s->%s on file \"%s\"\n", inform, outform, arg); @@ -200,6 +203,8 @@ int main(int argc, char *argv[]) fill_fullpaths(bi->dt, ""); process_checks(force, bi); + if (sort) + sort_tree(bi); if (streq(outname, "-")) { outf = stdout; diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h index 08d54c870086..f37c97eb3dfc 100644 --- a/scripts/dtc/dtc.h +++ b/scripts/dtc/dtc.h @@ -34,7 +34,17 @@ #include #include +#include "util.h" + +#ifdef DEBUG +#define debug(fmt,args...) printf(fmt, ##args) +#else +#define debug(fmt,args...) +#endif + + #define DEFAULT_FDT_VERSION 17 + /* * Command line options */ @@ -42,36 +52,11 @@ extern int quiet; /* Level of quietness */ extern int reservenum; /* Number of memory reservation slots */ extern int minsize; /* Minimum blob size */ extern int padsize; /* Additional padding to blob */ +extern int phandle_format; /* Use linux,phandle or phandle properties */ -static inline void __attribute__((noreturn)) die(char * str, ...) -{ - va_list ap; - - va_start(ap, str); - fprintf(stderr, "FATAL ERROR: "); - vfprintf(stderr, str, ap); - exit(1); -} - -static inline void *xmalloc(size_t len) -{ - void *new = malloc(len); - - if (! new) - die("malloc() failed\n"); - - return new; -} - -static inline void *xrealloc(void *p, size_t len) -{ - void *new = realloc(p, len); - - if (! new) - die("realloc() failed (len=%d)\n", len); - - return new; -} +#define PHANDLE_LEGACY 0x1 +#define PHANDLE_EPAPR 0x2 +#define PHANDLE_BOTH 0x3 typedef uint32_t cell_t; @@ -140,13 +125,18 @@ int data_is_one_string(struct data d); #define MAX_NODENAME_LEN 31 /* Live trees */ +struct label { + char *label; + struct label *next; +}; + struct property { char *name; struct data val; struct property *next; - char *label; + struct label *labels; }; struct node { @@ -163,22 +153,28 @@ struct node { cell_t phandle; int addr_cells, size_cells; - char *label; + struct label *labels; }; +#define for_each_label(l0, l) \ + for ((l) = (l0); (l); (l) = (l)->next) + #define for_each_property(n, p) \ for ((p) = (n)->proplist; (p); (p) = (p)->next) #define for_each_child(n, c) \ for ((c) = (n)->children; (c); (c) = (c)->next_sibling) -struct property *build_property(char *name, struct data val, char *label); +void add_label(struct label **labels, char *label); + +struct property *build_property(char *name, struct data val); struct property *chain_property(struct property *first, struct property *list); struct property *reverse_properties(struct property *first); struct node *build_node(struct property *proplist, struct node *children); -struct node *name_node(struct node *node, char *name, char *label); +struct node *name_node(struct node *node, char *name); struct node *chain_node(struct node *first, struct node *list); +struct node *merge_nodes(struct node *old_node, struct node *new_node); void add_property(struct node *node, struct property *prop); void add_child(struct node *parent, struct node *child); @@ -186,6 +182,10 @@ void add_child(struct node *parent, struct node *child); const char *get_unitname(struct node *node); struct property *get_property(struct node *node, const char *propname); cell_t propval_cell(struct property *prop); +struct property *get_property_by_label(struct node *tree, const char *label, + struct node **node); +struct marker *get_marker_label(struct node *tree, const char *label, + struct node **node, struct property **prop); struct node *get_subnode(struct node *node, const char *nodename); struct node *get_node_by_path(struct node *tree, const char *path); struct node *get_node_by_label(struct node *tree, const char *label); @@ -193,6 +193,8 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle); struct node *get_node_by_ref(struct node *tree, const char *ref); cell_t get_node_phandle(struct node *root, struct node *node); +uint32_t guess_boot_cpuid(struct node *tree); + /* Boot info (tree plus memreserve information */ struct reserve_info { @@ -200,10 +202,10 @@ struct reserve_info { struct reserve_info *next; - char *label; + struct label *labels; }; -struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len, char *label); +struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len); struct reserve_info *chain_reserve_entry(struct reserve_info *first, struct reserve_info *list); struct reserve_info *add_reserve_entry(struct reserve_info *list, @@ -218,6 +220,7 @@ struct boot_info { struct boot_info *build_boot_info(struct reserve_info *reservelist, struct node *tree, uint32_t boot_cpuid_phys); +void sort_tree(struct boot_info *bi); /* Checks */ @@ -239,8 +242,4 @@ struct boot_info *dt_from_source(const char *f); struct boot_info *dt_from_fs(const char *dirname); -/* misc */ - -char *join_path(const char *path, const char *name); - #endif /* _DTC_H */ diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c index 76acd28c068d..ead0332c87e1 100644 --- a/scripts/dtc/flattree.c +++ b/scripts/dtc/flattree.c @@ -52,9 +52,9 @@ struct emitter { void (*string)(void *, char *, int); void (*align)(void *, int); void (*data)(void *, struct data); - void (*beginnode)(void *, const char *); - void (*endnode)(void *, const char *); - void (*property)(void *, const char *); + void (*beginnode)(void *, struct label *labels); + void (*endnode)(void *, struct label *labels); + void (*property)(void *, struct label *labels); }; static void bin_emit_cell(void *e, cell_t val) @@ -89,17 +89,17 @@ static void bin_emit_data(void *e, struct data d) *dtbuf = data_append_data(*dtbuf, d.val, d.len); } -static void bin_emit_beginnode(void *e, const char *label) +static void bin_emit_beginnode(void *e, struct label *labels) { bin_emit_cell(e, FDT_BEGIN_NODE); } -static void bin_emit_endnode(void *e, const char *label) +static void bin_emit_endnode(void *e, struct label *labels) { bin_emit_cell(e, FDT_END_NODE); } -static void bin_emit_property(void *e, const char *label) +static void bin_emit_property(void *e, struct label *labels) { bin_emit_cell(e, FDT_PROP); } @@ -127,11 +127,21 @@ static void emit_offset_label(FILE *f, const char *label, int offset) fprintf(f, "%s\t= . + %d\n", label, offset); } +#define ASM_EMIT_BELONG(f, fmt, ...) \ + { \ + fprintf((f), "\t.byte\t((" fmt ") >> 24) & 0xff\n", __VA_ARGS__); \ + fprintf((f), "\t.byte\t((" fmt ") >> 16) & 0xff\n", __VA_ARGS__); \ + fprintf((f), "\t.byte\t((" fmt ") >> 8) & 0xff\n", __VA_ARGS__); \ + fprintf((f), "\t.byte\t(" fmt ") & 0xff\n", __VA_ARGS__); \ + } + static void asm_emit_cell(void *e, cell_t val) { FILE *f = e; - fprintf(f, "\t.long\t0x%x\n", val); + fprintf(f, "\t.byte 0x%02x; .byte 0x%02x; .byte 0x%02x; .byte 0x%02x\n", + (val >> 24) & 0xff, (val >> 16) & 0xff, + (val >> 8) & 0xff, val & 0xff); } static void asm_emit_string(void *e, char *str, int len) @@ -156,7 +166,7 @@ static void asm_emit_align(void *e, int a) { FILE *f = e; - fprintf(f, "\t.balign\t%d\n", a); + fprintf(f, "\t.balign\t%d, 0\n", a); } static void asm_emit_data(void *e, struct data d) @@ -169,8 +179,7 @@ static void asm_emit_data(void *e, struct data d) emit_offset_label(f, m->ref, m->offset); while ((d.len - off) >= sizeof(uint32_t)) { - fprintf(f, "\t.long\t0x%x\n", - fdt32_to_cpu(*((uint32_t *)(d.val+off)))); + asm_emit_cell(e, fdt32_to_cpu(*((uint32_t *)(d.val+off)))); off += sizeof(uint32_t); } @@ -182,37 +191,43 @@ static void asm_emit_data(void *e, struct data d) assert(off == d.len); } -static void asm_emit_beginnode(void *e, const char *label) +static void asm_emit_beginnode(void *e, struct label *labels) { FILE *f = e; + struct label *l; - if (label) { - fprintf(f, "\t.globl\t%s\n", label); - fprintf(f, "%s:\n", label); + for_each_label(labels, l) { + fprintf(f, "\t.globl\t%s\n", l->label); + fprintf(f, "%s:\n", l->label); } - fprintf(f, "\t.long\tFDT_BEGIN_NODE\n"); + fprintf(f, "\t/* FDT_BEGIN_NODE */\n"); + asm_emit_cell(e, FDT_BEGIN_NODE); } -static void asm_emit_endnode(void *e, const char *label) +static void asm_emit_endnode(void *e, struct label *labels) { FILE *f = e; + struct label *l; - fprintf(f, "\t.long\tFDT_END_NODE\n"); - if (label) { - fprintf(f, "\t.globl\t%s_end\n", label); - fprintf(f, "%s_end:\n", label); + fprintf(f, "\t/* FDT_END_NODE */\n"); + asm_emit_cell(e, FDT_END_NODE); + for_each_label(labels, l) { + fprintf(f, "\t.globl\t%s_end\n", l->label); + fprintf(f, "%s_end:\n", l->label); } } -static void asm_emit_property(void *e, const char *label) +static void asm_emit_property(void *e, struct label *labels) { FILE *f = e; + struct label *l; - if (label) { - fprintf(f, "\t.globl\t%s\n", label); - fprintf(f, "%s:\n", label); + for_each_label(labels, l) { + fprintf(f, "\t.globl\t%s\n", l->label); + fprintf(f, "%s:\n", l->label); } - fprintf(f, "\t.long\tFDT_PROP\n"); + fprintf(f, "\t/* FDT_PROP */\n"); + asm_emit_cell(e, FDT_PROP); } static struct emitter asm_emitter = { @@ -248,7 +263,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit, struct node *child; int seen_name_prop = 0; - emit->beginnode(etarget, tree->label); + emit->beginnode(etarget, tree->labels); if (vi->flags & FTF_FULLPATH) emit->string(etarget, tree->fullpath, 0); @@ -265,7 +280,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit, nameoff = stringtable_insert(strbuf, prop->name); - emit->property(etarget, prop->label); + emit->property(etarget, prop->labels); emit->cell(etarget, prop->val.len); emit->cell(etarget, nameoff); @@ -292,7 +307,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit, flatten_tree(child, emit, etarget, strbuf, vi); } - emit->endnode(etarget, tree->label); + emit->endnode(etarget, tree->labels); } static struct data flatten_reserve_list(struct reserve_info *reservelist, @@ -413,10 +428,13 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version) if (padlen > 0) blob = data_append_zeroes(blob, padlen); - fwrite(blob.val, blob.len, 1, f); - - if (ferror(f)) - die("Error writing device tree blob: %s\n", strerror(errno)); + if (fwrite(blob.val, blob.len, 1, f) != 1) { + if (ferror(f)) + die("Error writing device tree blob: %s\n", + strerror(errno)); + else + die("Short write on device tree blob\n"); + } /* * data_merge() frees the right-hand element so only the blob @@ -455,39 +473,44 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) die("Unknown device tree blob version %d\n", version); fprintf(f, "/* autogenerated by dtc, do not edit */\n\n"); - fprintf(f, "#define FDT_MAGIC 0x%x\n", FDT_MAGIC); - fprintf(f, "#define FDT_BEGIN_NODE 0x%x\n", FDT_BEGIN_NODE); - fprintf(f, "#define FDT_END_NODE 0x%x\n", FDT_END_NODE); - fprintf(f, "#define FDT_PROP 0x%x\n", FDT_PROP); - fprintf(f, "#define FDT_END 0x%x\n", FDT_END); - fprintf(f, "\n"); emit_label(f, symprefix, "blob_start"); emit_label(f, symprefix, "header"); - fprintf(f, "\t.long\tFDT_MAGIC\t\t\t\t/* magic */\n"); - fprintf(f, "\t.long\t_%s_blob_abs_end - _%s_blob_start\t/* totalsize */\n", - symprefix, symprefix); - fprintf(f, "\t.long\t_%s_struct_start - _%s_blob_start\t/* off_dt_struct */\n", + fprintf(f, "\t/* magic */\n"); + asm_emit_cell(f, FDT_MAGIC); + fprintf(f, "\t/* totalsize */\n"); + ASM_EMIT_BELONG(f, "_%s_blob_abs_end - _%s_blob_start", + symprefix, symprefix); + fprintf(f, "\t/* off_dt_struct */\n"); + ASM_EMIT_BELONG(f, "_%s_struct_start - _%s_blob_start", symprefix, symprefix); - fprintf(f, "\t.long\t_%s_strings_start - _%s_blob_start\t/* off_dt_strings */\n", + fprintf(f, "\t/* off_dt_strings */\n"); + ASM_EMIT_BELONG(f, "_%s_strings_start - _%s_blob_start", symprefix, symprefix); - fprintf(f, "\t.long\t_%s_reserve_map - _%s_blob_start\t/* off_dt_strings */\n", + fprintf(f, "\t/* off_mem_rsvmap */\n"); + ASM_EMIT_BELONG(f, "_%s_reserve_map - _%s_blob_start", symprefix, symprefix); - fprintf(f, "\t.long\t%d\t\t\t\t\t/* version */\n", vi->version); - fprintf(f, "\t.long\t%d\t\t\t\t\t/* last_comp_version */\n", - vi->last_comp_version); - - if (vi->flags & FTF_BOOTCPUID) - fprintf(f, "\t.long\t%i\t\t\t\t\t/* boot_cpuid_phys */\n", - bi->boot_cpuid_phys); + fprintf(f, "\t/* version */\n"); + asm_emit_cell(f, vi->version); + fprintf(f, "\t/* last_comp_version */\n"); + asm_emit_cell(f, vi->last_comp_version); + + if (vi->flags & FTF_BOOTCPUID) { + fprintf(f, "\t/* boot_cpuid_phys */\n"); + asm_emit_cell(f, bi->boot_cpuid_phys); + } - if (vi->flags & FTF_STRTABSIZE) - fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n", - symprefix, symprefix); + if (vi->flags & FTF_STRTABSIZE) { + fprintf(f, "\t/* size_dt_strings */\n"); + ASM_EMIT_BELONG(f, "_%s_strings_end - _%s_strings_start", + symprefix, symprefix); + } - if (vi->flags & FTF_STRUCTSIZE) - fprintf(f, "\t.long\t_%s_struct_end - _%s_struct_start\t/* size_dt_struct */\n", + if (vi->flags & FTF_STRUCTSIZE) { + fprintf(f, "\t/* size_dt_struct */\n"); + ASM_EMIT_BELONG(f, "_%s_struct_end - _%s_struct_start", symprefix, symprefix); + } /* * Reserve map entries. @@ -505,16 +528,17 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) * as it appears .quad isn't available in some assemblers. */ for (re = bi->reservelist; re; re = re->next) { - if (re->label) { - fprintf(f, "\t.globl\t%s\n", re->label); - fprintf(f, "%s:\n", re->label); + struct label *l; + + for_each_label(re->labels, l) { + fprintf(f, "\t.globl\t%s\n", l->label); + fprintf(f, "%s:\n", l->label); } - fprintf(f, "\t.long\t0x%08x, 0x%08x\n", - (unsigned int)(re->re.address >> 32), - (unsigned int)(re->re.address & 0xffffffff)); - fprintf(f, "\t.long\t0x%08x, 0x%08x\n", - (unsigned int)(re->re.size >> 32), - (unsigned int)(re->re.size & 0xffffffff)); + ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.address >> 32)); + ASM_EMIT_BELONG(f, "0x%08x", + (unsigned int)(re->re.address & 0xffffffff)); + ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size >> 32)); + ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size & 0xffffffff)); } for (i = 0; i < reservenum; i++) { fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n"); @@ -524,7 +548,9 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) emit_label(f, symprefix, "struct_start"); flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi); - fprintf(f, "\t.long\tFDT_END\n"); + + fprintf(f, "\t/* FDT_END */\n"); + asm_emit_cell(f, FDT_END); emit_label(f, symprefix, "struct_end"); emit_label(f, symprefix, "strings_start"); @@ -601,7 +627,7 @@ static char *flat_read_string(struct inbuf *inb) len++; } while ((*p++) != '\0'); - str = strdup(inb->ptr); + str = xstrdup(inb->ptr); inb->ptr += len; @@ -643,7 +669,7 @@ static char *flat_read_stringtable(struct inbuf *inb, int offset) p++; } - return strdup(inb->base + offset); + return xstrdup(inb->base + offset); } static struct property *flat_read_property(struct inbuf *dtbuf, @@ -663,7 +689,7 @@ static struct property *flat_read_property(struct inbuf *dtbuf, val = flat_read_data(dtbuf, proplen); - return build_property(name, val, NULL); + return build_property(name, val); } @@ -688,7 +714,7 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) if (re.size == 0) break; - new = build_reserve_entry(re.address, re.size, NULL); + new = build_reserve_entry(re.address, re.size); reservelist = add_reserve_entry(reservelist, new); } @@ -710,7 +736,7 @@ static char *nodename_from_path(const char *ppath, const char *cpath) if (!streq(ppath, "/")) plen++; - return strdup(cpath + plen); + return xstrdup(cpath + plen); } static struct node *unflatten_tree(struct inbuf *dtbuf, @@ -776,7 +802,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, struct boot_info *dt_from_blob(const char *fname) { - struct dtc_file *dtcf; + FILE *f; uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys; uint32_t off_dt, off_str, off_mem_rsvmap; int rc; @@ -791,14 +817,14 @@ struct boot_info *dt_from_blob(const char *fname) uint32_t val; int flags = 0; - dtcf = dtc_open_file(fname, NULL); + f = srcfile_relative_open(fname, NULL); - rc = fread(&magic, sizeof(magic), 1, dtcf->file); - if (ferror(dtcf->file)) + rc = fread(&magic, sizeof(magic), 1, f); + if (ferror(f)) die("Error reading DT blob magic number: %s\n", strerror(errno)); if (rc < 1) { - if (feof(dtcf->file)) + if (feof(f)) die("EOF reading DT blob magic number\n"); else die("Mysterious short read reading magic number\n"); @@ -808,11 +834,11 @@ struct boot_info *dt_from_blob(const char *fname) if (magic != FDT_MAGIC) die("Blob has incorrect magic number\n"); - rc = fread(&totalsize, sizeof(totalsize), 1, dtcf->file); - if (ferror(dtcf->file)) + rc = fread(&totalsize, sizeof(totalsize), 1, f); + if (ferror(f)) die("Error reading DT blob size: %s\n", strerror(errno)); if (rc < 1) { - if (feof(dtcf->file)) + if (feof(f)) die("EOF reading DT blob size\n"); else die("Mysterious short read reading blob size\n"); @@ -832,12 +858,12 @@ struct boot_info *dt_from_blob(const char *fname) p = blob + sizeof(magic) + sizeof(totalsize); while (sizeleft) { - if (feof(dtcf->file)) + if (feof(f)) die("EOF before reading %d bytes of DT blob\n", totalsize); - rc = fread(p, 1, sizeleft, dtcf->file); - if (ferror(dtcf->file)) + rc = fread(p, 1, sizeleft, f); + if (ferror(f)) die("Error reading DT blob: %s\n", strerror(errno)); @@ -900,7 +926,7 @@ struct boot_info *dt_from_blob(const char *fname) free(blob); - dtc_close_file(dtcf); + fclose(f); return build_boot_info(reservelist, tree, boot_cpuid_phys); } diff --git a/scripts/dtc/fstree.c b/scripts/dtc/fstree.c index 8fe1bdf239f0..f3774530170a 100644 --- a/scripts/dtc/fstree.c +++ b/scripts/dtc/fstree.c @@ -58,10 +58,9 @@ static struct node *read_fstree(const char *dirname) "WARNING: Cannot open %s: %s\n", tmpnam, strerror(errno)); } else { - prop = build_property(strdup(de->d_name), + prop = build_property(xstrdup(de->d_name), data_copy_file(pfile, - st.st_size), - NULL); + st.st_size)); add_property(tree, prop); fclose(pfile); } @@ -69,8 +68,7 @@ static struct node *read_fstree(const char *dirname) struct node *newchild; newchild = read_fstree(tmpnam); - newchild = name_node(newchild, strdup(de->d_name), - NULL); + newchild = name_node(newchild, xstrdup(de->d_name)); add_child(tree, newchild); } @@ -86,8 +84,8 @@ struct boot_info *dt_from_fs(const char *dirname) struct node *tree; tree = read_fstree(dirname); - tree = name_node(tree, "", NULL); + tree = name_node(tree, ""); - return build_boot_info(NULL, tree, 0); + return build_boot_info(NULL, tree, guess_boot_cpuid(tree)); } diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c index 0ca3de550b3f..c9209d5c999e 100644 --- a/scripts/dtc/livetree.c +++ b/scripts/dtc/livetree.c @@ -24,17 +24,30 @@ * Tree building functions */ -struct property *build_property(char *name, struct data val, char *label) +void add_label(struct label **labels, char *label) +{ + struct label *new; + + /* Make sure the label isn't already there */ + for_each_label(*labels, new) + if (streq(new->label, label)) + return; + + new = xmalloc(sizeof(*new)); + new->label = label; + new->next = *labels; + *labels = new; +} + +struct property *build_property(char *name, struct data val) { struct property *new = xmalloc(sizeof(*new)); + memset(new, 0, sizeof(*new)); + new->name = name; new->val = val; - new->next = NULL; - - new->label = label; - return new; } @@ -78,17 +91,82 @@ struct node *build_node(struct property *proplist, struct node *children) return new; } -struct node *name_node(struct node *node, char *name, char * label) +struct node *name_node(struct node *node, char *name) { assert(node->name == NULL); node->name = name; - node->label = label; - return node; } +struct node *merge_nodes(struct node *old_node, struct node *new_node) +{ + struct property *new_prop, *old_prop; + struct node *new_child, *old_child; + struct label *l; + + /* Add new node labels to old node */ + for_each_label(new_node->labels, l) + add_label(&old_node->labels, l->label); + + /* Move properties from the new node to the old node. If there + * is a collision, replace the old value with the new */ + while (new_node->proplist) { + /* Pop the property off the list */ + new_prop = new_node->proplist; + new_node->proplist = new_prop->next; + new_prop->next = NULL; + + /* Look for a collision, set new value if there is */ + for_each_property(old_node, old_prop) { + if (streq(old_prop->name, new_prop->name)) { + /* Add new labels to old property */ + for_each_label(new_prop->labels, l) + add_label(&old_prop->labels, l->label); + + old_prop->val = new_prop->val; + free(new_prop); + new_prop = NULL; + break; + } + } + + /* if no collision occurred, add property to the old node. */ + if (new_prop) + add_property(old_node, new_prop); + } + + /* Move the override child nodes into the primary node. If + * there is a collision, then merge the nodes. */ + while (new_node->children) { + /* Pop the child node off the list */ + new_child = new_node->children; + new_node->children = new_child->next_sibling; + new_child->parent = NULL; + new_child->next_sibling = NULL; + + /* Search for a collision. Merge if there is */ + for_each_child(old_node, old_child) { + if (streq(old_child->name, new_child->name)) { + merge_nodes(old_child, new_child); + new_child = NULL; + break; + } + } + + /* if no collision occured, add child to the old node. */ + if (new_child) + add_child(old_node, new_child); + } + + /* The new node contents are now merged into the old node. Free + * the new node. */ + free(new_node); + + return old_node; +} + struct node *chain_node(struct node *first, struct node *list) { assert(first->next_sibling == NULL); @@ -124,18 +202,15 @@ void add_child(struct node *parent, struct node *child) *p = child; } -struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size, - char *label) +struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size) { struct reserve_info *new = xmalloc(sizeof(*new)); + memset(new, 0, sizeof(*new)); + new->re.address = address; new->re.size = size; - new->next = NULL; - - new->label = label; - return new; } @@ -208,6 +283,60 @@ cell_t propval_cell(struct property *prop) return fdt32_to_cpu(*((cell_t *)prop->val.val)); } +struct property *get_property_by_label(struct node *tree, const char *label, + struct node **node) +{ + struct property *prop; + struct node *c; + + *node = tree; + + for_each_property(tree, prop) { + struct label *l; + + for_each_label(prop->labels, l) + if (streq(l->label, label)) + return prop; + } + + for_each_child(tree, c) { + prop = get_property_by_label(c, label, node); + if (prop) + return prop; + } + + *node = NULL; + return NULL; +} + +struct marker *get_marker_label(struct node *tree, const char *label, + struct node **node, struct property **prop) +{ + struct marker *m; + struct property *p; + struct node *c; + + *node = tree; + + for_each_property(tree, p) { + *prop = p; + m = p->val.markers; + for_each_marker_of_type(m, LABEL) + if (streq(m->ref, label)) + return m; + } + + for_each_child(tree, c) { + m = get_marker_label(c, label, node, prop); + if (m) + return m; + } + + *prop = NULL; + *node = NULL; + return NULL; +} + struct node *get_subnode(struct node *node, const char *nodename) { struct node *child; @@ -245,11 +374,13 @@ struct node *get_node_by_path(struct node *tree, const char *path) struct node *get_node_by_label(struct node *tree, const char *label) { struct node *child, *node; + struct label *l; assert(label && (strlen(label) > 0)); - if (tree->label && streq(tree->label, label)) - return tree; + for_each_label(tree->labels, l) + if (streq(l->label, label)) + return tree; for_each_child(tree, child) { node = get_node_by_label(child, label); @@ -293,16 +424,186 @@ cell_t get_node_phandle(struct node *root, struct node *node) if ((node->phandle != 0) && (node->phandle != -1)) return node->phandle; - assert(! get_property(node, "linux,phandle")); - while (get_node_by_phandle(root, phandle)) phandle++; node->phandle = phandle; - add_property(node, - build_property("linux,phandle", - data_append_cell(empty_data, phandle), - NULL)); + + if (!get_property(node, "linux,phandle") + && (phandle_format & PHANDLE_LEGACY)) + add_property(node, + build_property("linux,phandle", + data_append_cell(empty_data, phandle))); + + if (!get_property(node, "phandle") + && (phandle_format & PHANDLE_EPAPR)) + add_property(node, + build_property("phandle", + data_append_cell(empty_data, phandle))); + + /* If the node *does* have a phandle property, we must + * be dealing with a self-referencing phandle, which will be + * fixed up momentarily in the caller */ return node->phandle; } + +uint32_t guess_boot_cpuid(struct node *tree) +{ + struct node *cpus, *bootcpu; + struct property *reg; + + cpus = get_node_by_path(tree, "/cpus"); + if (!cpus) + return 0; + + + bootcpu = cpus->children; + if (!bootcpu) + return 0; + + reg = get_property(bootcpu, "reg"); + if (!reg || (reg->val.len != sizeof(uint32_t))) + return 0; + + /* FIXME: Sanity check node? */ + + return propval_cell(reg); +} + +static int cmp_reserve_info(const void *ax, const void *bx) +{ + const struct reserve_info *a, *b; + + a = *((const struct reserve_info * const *)ax); + b = *((const struct reserve_info * const *)bx); + + if (a->re.address < b->re.address) + return -1; + else if (a->re.address > b->re.address) + return 1; + else if (a->re.size < b->re.size) + return -1; + else if (a->re.size > b->re.size) + return 1; + else + return 0; +} + +static void sort_reserve_entries(struct boot_info *bi) +{ + struct reserve_info *ri, **tbl; + int n = 0, i = 0; + + for (ri = bi->reservelist; + ri; + ri = ri->next) + n++; + + if (n == 0) + return; + + tbl = xmalloc(n * sizeof(*tbl)); + + for (ri = bi->reservelist; + ri; + ri = ri->next) + tbl[i++] = ri; + + qsort(tbl, n, sizeof(*tbl), cmp_reserve_info); + + bi->reservelist = tbl[0]; + for (i = 0; i < (n-1); i++) + tbl[i]->next = tbl[i+1]; + tbl[n-1]->next = NULL; + + free(tbl); +} + +static int cmp_prop(const void *ax, const void *bx) +{ + const struct property *a, *b; + + a = *((const struct property * const *)ax); + b = *((const struct property * const *)bx); + + return strcmp(a->name, b->name); +} + +static void sort_properties(struct node *node) +{ + int n = 0, i = 0; + struct property *prop, **tbl; + + for_each_property(node, prop) + n++; + + if (n == 0) + return; + + tbl = xmalloc(n * sizeof(*tbl)); + + for_each_property(node, prop) + tbl[i++] = prop; + + qsort(tbl, n, sizeof(*tbl), cmp_prop); + + node->proplist = tbl[0]; + for (i = 0; i < (n-1); i++) + tbl[i]->next = tbl[i+1]; + tbl[n-1]->next = NULL; + + free(tbl); +} + +static int cmp_subnode(const void *ax, const void *bx) +{ + const struct node *a, *b; + + a = *((const struct node * const *)ax); + b = *((const struct node * const *)bx); + + return strcmp(a->name, b->name); +} + +static void sort_subnodes(struct node *node) +{ + int n = 0, i = 0; + struct node *subnode, **tbl; + + for_each_child(node, subnode) + n++; + + if (n == 0) + return; + + tbl = xmalloc(n * sizeof(*tbl)); + + for_each_child(node, subnode) + tbl[i++] = subnode; + + qsort(tbl, n, sizeof(*tbl), cmp_subnode); + + node->children = tbl[0]; + for (i = 0; i < (n-1); i++) + tbl[i]->next_sibling = tbl[i+1]; + tbl[n-1]->next_sibling = NULL; + + free(tbl); +} + +static void sort_node(struct node *node) +{ + struct node *c; + + sort_properties(node); + sort_subnodes(node); + for_each_child(node, c) + sort_node(c); +} + +void sort_tree(struct boot_info *bi) +{ + sort_reserve_entries(bi); + sort_node(bi->dt); +} diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c index 9641b7628b4d..2dbc874288ca 100644 --- a/scripts/dtc/srcpos.c +++ b/scripts/dtc/srcpos.c @@ -17,100 +17,232 @@ * USA */ +#define _GNU_SOURCE + +#include + #include "dtc.h" #include "srcpos.h" -/* - * Like yylineno, this is the current open file pos. - */ -struct dtc_file *srcpos_file; +static char *dirname(const char *path) +{ + const char *slash = strrchr(path, '/'); + + if (slash) { + int len = slash - path; + char *dir = xmalloc(len + 1); + + memcpy(dir, path, len); + dir[len] = '\0'; + return dir; + } + return NULL; +} + +struct srcfile_state *current_srcfile; /* = NULL */ -static int dtc_open_one(struct dtc_file *file, - const char *search, - const char *fname) +/* Detect infinite include recursion. */ +#define MAX_SRCFILE_DEPTH (100) +static int srcfile_depth; /* = 0 */ + +FILE *srcfile_relative_open(const char *fname, char **fullnamep) { + FILE *f; char *fullname; - if (search) { - fullname = xmalloc(strlen(search) + strlen(fname) + 2); - - strcpy(fullname, search); - strcat(fullname, "/"); - strcat(fullname, fname); + if (streq(fname, "-")) { + f = stdin; + fullname = xstrdup(""); } else { - fullname = strdup(fname); + if (!current_srcfile || !current_srcfile->dir + || (fname[0] == '/')) + fullname = xstrdup(fname); + else + fullname = join_path(current_srcfile->dir, fname); + + f = fopen(fullname, "r"); + if (!f) + die("Couldn't open \"%s\": %s\n", fname, + strerror(errno)); } - file->file = fopen(fullname, "r"); - if (!file->file) { + if (fullnamep) + *fullnamep = fullname; + else free(fullname); - return 0; - } - file->name = fullname; - return 1; + return f; } +void srcfile_push(const char *fname) +{ + struct srcfile_state *srcfile; + + if (srcfile_depth++ >= MAX_SRCFILE_DEPTH) + die("Includes nested too deeply"); + + srcfile = xmalloc(sizeof(*srcfile)); + + srcfile->f = srcfile_relative_open(fname, &srcfile->name); + srcfile->dir = dirname(srcfile->name); + srcfile->prev = current_srcfile; + + srcfile->lineno = 1; + srcfile->colno = 1; + + current_srcfile = srcfile; +} -struct dtc_file *dtc_open_file(const char *fname, - const struct search_path *search) +int srcfile_pop(void) { - static const struct search_path default_search = { NULL, NULL, NULL }; + struct srcfile_state *srcfile = current_srcfile; - struct dtc_file *file; - const char *slash; + assert(srcfile); - file = xmalloc(sizeof(struct dtc_file)); + current_srcfile = srcfile->prev; - slash = strrchr(fname, '/'); - if (slash) { - char *dir = xmalloc(slash - fname + 1); + if (fclose(srcfile->f)) + die("Error closing \"%s\": %s\n", srcfile->name, + strerror(errno)); - memcpy(dir, fname, slash - fname); - dir[slash - fname] = 0; - file->dir = dir; - } else { - file->dir = NULL; - } + /* FIXME: We allow the srcfile_state structure to leak, + * because it could still be referenced from a location + * variable being carried through the parser somewhere. To + * fix this we could either allocate all the files from a + * table, or use a pool allocator. */ - if (streq(fname, "-")) { - file->name = "stdin"; - file->file = stdin; - return file; - } + return current_srcfile ? 1 : 0; +} - if (fname[0] == '/') { - file->file = fopen(fname, "r"); - if (!file->file) - goto fail; +/* + * The empty source position. + */ - file->name = strdup(fname); - return file; - } +struct srcpos srcpos_empty = { + .first_line = 0, + .first_column = 0, + .last_line = 0, + .last_column = 0, + .file = NULL, +}; - if (!search) - search = &default_search; +#define TAB_SIZE 8 - while (search) { - if (dtc_open_one(file, search->dir, fname)) - return file; +void srcpos_update(struct srcpos *pos, const char *text, int len) +{ + int i; + + pos->file = current_srcfile; + + pos->first_line = current_srcfile->lineno; + pos->first_column = current_srcfile->colno; + + for (i = 0; i < len; i++) + if (text[i] == '\n') { + current_srcfile->lineno++; + current_srcfile->colno = 1; + } else if (text[i] == '\t') { + current_srcfile->colno = + ALIGN(current_srcfile->colno, TAB_SIZE); + } else { + current_srcfile->colno++; + } + + pos->last_line = current_srcfile->lineno; + pos->last_column = current_srcfile->colno; +} - if (errno != ENOENT) - goto fail; +struct srcpos * +srcpos_copy(struct srcpos *pos) +{ + struct srcpos *pos_new; - search = search->next; - } + pos_new = xmalloc(sizeof(struct srcpos)); + memcpy(pos_new, pos, sizeof(struct srcpos)); + + return pos_new; +} + + + +void +srcpos_dump(struct srcpos *pos) +{ + printf("file : \"%s\"\n", + pos->file ? (char *) pos->file : ""); + printf("first_line : %d\n", pos->first_line); + printf("first_column: %d\n", pos->first_column); + printf("last_line : %d\n", pos->last_line); + printf("last_column : %d\n", pos->last_column); + printf("file : %s\n", pos->file->name); +} -fail: - die("Couldn't open \"%s\": %s\n", fname, strerror(errno)); + +char * +srcpos_string(struct srcpos *pos) +{ + const char *fname = ""; + char *pos_str; + int rc; + + if (pos) + fname = pos->file->name; + + + if (pos->first_line != pos->last_line) + rc = asprintf(&pos_str, "%s:%d.%d-%d.%d", fname, + pos->first_line, pos->first_column, + pos->last_line, pos->last_column); + else if (pos->first_column != pos->last_column) + rc = asprintf(&pos_str, "%s:%d.%d-%d", fname, + pos->first_line, pos->first_column, + pos->last_column); + else + rc = asprintf(&pos_str, "%s:%d.%d", fname, + pos->first_line, pos->first_column); + + if (rc == -1) + die("Couldn't allocate in srcpos string"); + + return pos_str; +} + +void +srcpos_verror(struct srcpos *pos, char const *fmt, va_list va) +{ + const char *srcstr; + + srcstr = srcpos_string(pos); + + fprintf(stdout, "Error: %s ", srcstr); + vfprintf(stdout, fmt, va); + fprintf(stdout, "\n"); } -void dtc_close_file(struct dtc_file *file) +void +srcpos_error(struct srcpos *pos, char const *fmt, ...) { - if (fclose(file->file)) - die("Error closing \"%s\": %s\n", file->name, strerror(errno)); + va_list va; + + va_start(va, fmt); + srcpos_verror(pos, fmt, va); + va_end(va); +} + + +void +srcpos_warn(struct srcpos *pos, char const *fmt, ...) +{ + const char *srcstr; + va_list va; + va_start(va, fmt); + + srcstr = srcpos_string(pos); + + fprintf(stderr, "Warning: %s ", srcstr); + vfprintf(stderr, fmt, va); + fprintf(stderr, "\n"); - free(file->dir); - free(file); + va_end(va); } diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h index e17c7c04db8e..bd7966e56a53 100644 --- a/scripts/dtc/srcpos.h +++ b/scripts/dtc/srcpos.h @@ -17,69 +17,70 @@ * USA */ -/* - * Augment the standard YYLTYPE with a filenum index into an - * array of all opened filenames. - */ +#ifndef _SRCPOS_H_ +#define _SRCPOS_H_ #include -struct dtc_file { +struct srcfile_state { + FILE *f; + char *name; char *dir; - const char *name; - FILE *file; + int lineno, colno; + struct srcfile_state *prev; }; -#if ! defined(YYLTYPE) && ! defined(YYLTYPE_IS_DECLARED) -typedef struct YYLTYPE { +extern struct srcfile_state *current_srcfile; /* = NULL */ + +FILE *srcfile_relative_open(const char *fname, char **fullnamep); +void srcfile_push(const char *fname); +int srcfile_pop(void); + +struct srcpos { int first_line; int first_column; int last_line; int last_column; - struct dtc_file *file; -} YYLTYPE; - -#define YYLTYPE_IS_DECLARED 1 -#define YYLTYPE_IS_TRIVIAL 1 -#endif - -/* Cater to old parser templates. */ -#ifndef YYID -#define YYID(n) (n) -#endif + struct srcfile_state *file; +}; -#define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - (Current).file = YYRHSLOC (Rhs, N).file; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - (Current).file = YYRHSLOC (Rhs, 0).file; \ - } \ - while (YYID (0)) +#define YYLTYPE struct srcpos +#define YYLLOC_DEFAULT(Current, Rhs, N) \ + do { \ + if (N) { \ + (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + (Current).file = YYRHSLOC(Rhs, N).file; \ + } else { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC(Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC(Rhs, 0).last_column; \ + (Current).file = YYRHSLOC (Rhs, 0).file; \ + } \ + } while (0) -extern void yyerror(char const *); -extern void yyerrorf(char const *, ...) __attribute__((format(printf, 1, 2))); +/* + * Fictional source position used for IR nodes that are + * created without otherwise knowing a true source position. + * For example,constant definitions from the command line. + */ +extern struct srcpos srcpos_empty; -extern struct dtc_file *srcpos_file; +extern void srcpos_update(struct srcpos *pos, const char *text, int len); +extern struct srcpos *srcpos_copy(struct srcpos *pos); +extern char *srcpos_string(struct srcpos *pos); +extern void srcpos_dump(struct srcpos *pos); -struct search_path { - const char *dir; /* NULL for current directory */ - struct search_path *prev, *next; -}; +extern void srcpos_verror(struct srcpos *pos, char const *, va_list va) + __attribute__((format(printf, 2, 0))); +extern void srcpos_error(struct srcpos *pos, char const *, ...) + __attribute__((format(printf, 2, 3))); +extern void srcpos_warn(struct srcpos *pos, char const *, ...) + __attribute__((format(printf, 2, 3))); -extern struct dtc_file *dtc_open_file(const char *fname, - const struct search_path *search); -extern void dtc_close_file(struct dtc_file *file); +#endif /* _SRCPOS_H_ */ diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c index 1521ff11bb97..c09aafade313 100644 --- a/scripts/dtc/treesource.c +++ b/scripts/dtc/treesource.c @@ -32,8 +32,8 @@ struct boot_info *dt_from_source(const char *fname) the_boot_info = NULL; treesource_error = 0; - srcpos_file = dtc_open_file(fname, NULL); - yyin = srcpos_file->file; + srcfile_push(fname); + yyin = current_srcfile->f; if (yyparse() != 0) die("Unable to parse input tree\n"); @@ -63,26 +63,20 @@ static void write_propval_string(FILE *f, struct data val) { const char *str = val.val; int i; - int newchunk = 1; struct marker *m = val.markers; assert(str[val.len-1] == '\0'); + while (m && (m->offset == 0)) { + if (m->type == LABEL) + fprintf(f, "%s: ", m->ref); + m = m->next; + } + fprintf(f, "\""); + for (i = 0; i < (val.len-1); i++) { char c = str[i]; - if (newchunk) { - while (m && (m->offset <= i)) { - if (m->type == LABEL) { - assert(m->offset == i); - fprintf(f, "%s: ", m->ref); - } - m = m->next; - } - fprintf(f, "\""); - newchunk = 0; - } - switch (c) { case '\a': fprintf(f, "\\a"); @@ -113,7 +107,14 @@ static void write_propval_string(FILE *f, struct data val) break; case '\0': fprintf(f, "\", "); - newchunk = 1; + while (m && (m->offset < i)) { + if (m->type == LABEL) { + assert(m->offset == (i+1)); + fprintf(f, "%s: ", m->ref); + } + m = m->next; + } + fprintf(f, "\""); break; default: if (isprint(c)) @@ -234,10 +235,11 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level) { struct property *prop; struct node *child; + struct label *l; write_prefix(f, level); - if (tree->label) - fprintf(f, "%s: ", tree->label); + for_each_label(tree->labels, l) + fprintf(f, "%s: ", l->label); if (tree->name && (*tree->name)) fprintf(f, "%s {\n", tree->name); else @@ -245,8 +247,8 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level) for_each_property(tree, prop) { write_prefix(f, level+1); - if (prop->label) - fprintf(f, "%s: ", prop->label); + for_each_label(prop->labels, l) + fprintf(f, "%s: ", l->label); fprintf(f, "%s", prop->name); write_propval(f, prop); } @@ -266,8 +268,10 @@ void dt_to_source(FILE *f, struct boot_info *bi) fprintf(f, "/dts-v1/;\n\n"); for (re = bi->reservelist; re; re = re->next) { - if (re->label) - fprintf(f, "%s: ", re->label); + struct label *l; + + for_each_label(re->labels, l) + fprintf(f, "%s: ", l->label); fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n", (unsigned long long)re->re.address, (unsigned long long)re->re.size); diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c new file mode 100644 index 000000000000..d7ac27d2ae15 --- /dev/null +++ b/scripts/dtc/util.c @@ -0,0 +1,59 @@ +/* + * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include +#include +#include +#include + +#include "util.h" + +char *xstrdup(const char *s) +{ + int len = strlen(s) + 1; + char *dup = xmalloc(len); + + memcpy(dup, s, len); + + return dup; +} + +char *join_path(const char *path, const char *name) +{ + int lenp = strlen(path); + int lenn = strlen(name); + int len; + int needslash = 1; + char *str; + + len = lenp + lenn + 2; + if ((lenp > 0) && (path[lenp-1] == '/')) { + needslash = 0; + len--; + } + + str = xmalloc(len); + memcpy(str, path, lenp); + if (needslash) { + str[lenp] = '/'; + lenp++; + } + memcpy(str+lenp, name, lenn+1); + return str; +} diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h new file mode 100644 index 000000000000..9cead842c11e --- /dev/null +++ b/scripts/dtc/util.h @@ -0,0 +1,56 @@ +#ifndef _UTIL_H +#define _UTIL_H + +/* + * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +static inline void __attribute__((noreturn)) die(char * str, ...) +{ + va_list ap; + + va_start(ap, str); + fprintf(stderr, "FATAL ERROR: "); + vfprintf(stderr, str, ap); + exit(1); +} + +static inline void *xmalloc(size_t len) +{ + void *new = malloc(len); + + if (!new) + die("malloc() failed\n"); + + return new; +} + +static inline void *xrealloc(void *p, size_t len) +{ + void *new = realloc(p, len); + + if (!new) + die("realloc() failed (len=%d)\n", len); + + return new; +} + +extern char *xstrdup(const char *s); +extern char *join_path(const char *path, const char *name); + +#endif /* _UTIL_H */ diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h index 658ff42429d6..6158b867df99 100644 --- a/scripts/dtc/version_gen.h +++ b/scripts/dtc/version_gen.h @@ -1 +1 @@ -#define DTC_VERSION "DTC 1.2.0" +#define DTC_VERSION "DTC 1.2.0-g37c0b6a0" -- cgit v1.2.3 From 8484baaa5065b460e5eb18ee721d8417251f7897 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 5 Jan 2011 16:28:43 -0800 Subject: kernel-doc: code reorganization Move 'main' code vs. subroutines around so that they are not so intermixed, for better readability/understanding (relative to Perl). It was messy to follow the primary flow of code execution with the code being mixed. Now the code begins with data initialization, followed by all subroutines, then ends with the main code execution. This is almost totally source code movement, with a few changes as needed for forward declarations. Signed-off-by: Randy Dunlap Signed-off-by: Linus Torvalds --- scripts/kernel-doc | 102 ++++++++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 48 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 39580a5dc5df..9f85012acf0d 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -155,6 +155,8 @@ use strict; # '@parameter' - name of a parameter # '%CONST' - name of a constant. +## init lots of data + my $errors = 0; my $warnings = 0; my $anon_struct_union = 0; @@ -218,21 +220,14 @@ my %highlights_list = ( $type_constant, "\$1", $type_param, "\$1" ); my $blankline_list = ""; -sub usage { - print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -list ]\n"; - print " [ -no-doc-sections ]\n"; - print " [ -function funcname [ -function funcname ...] ]\n"; - print " [ -nofunction funcname [ -nofunction funcname ...] ]\n"; - print " c source file(s) > outputfile\n"; - print " -v : verbose output, more warnings & other info listed\n"; - exit 1; -} - # read arguments if ($#ARGV == -1) { usage(); } +my $kernelversion; +my $dohighlight = ""; + my $verbose = 0; my $output_mode = "man"; my $no_doc_sections = 0; @@ -245,7 +240,7 @@ my $man_date = ('January', 'February', 'March', 'April', 'May', 'June', 'November', 'December')[(localtime)[4]] . " " . ((localtime)[5]+1900); -# Essentially these are globals +# Essentially these are globals. # They probably want to be tidied up, made more localised or something. # CAVEAT EMPTOR! Some of the others I localised may not want to be, which # could cause "use of undefined value" or other bugs. @@ -353,6 +348,18 @@ while ($ARGV[0] =~ m/^-(.*)/) { } } +# continue execution near EOF; + +sub usage { + print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -list ]\n"; + print " [ -no-doc-sections ]\n"; + print " [ -function funcname [ -function funcname ...] ]\n"; + print " [ -nofunction funcname [ -nofunction funcname ...] ]\n"; + print " c source file(s) > outputfile\n"; + print " -v : verbose output, more warnings & other info listed\n"; + exit 1; +} + # get kernel version from env sub get_kernel_version() { my $version = 'unknown kernel version'; @@ -362,15 +369,6 @@ sub get_kernel_version() { } return $version; } -my $kernelversion = get_kernel_version(); - -# generate a sequence of code that will splice in highlighting information -# using the s// operator. -my $dohighlight = ""; -foreach my $pattern (keys %highlights) { -# print STDERR "scanning pattern:$pattern, highlight:($highlights{$pattern})\n"; - $dohighlight .= "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n"; -} ## # dumps section contents to arrays/hashes intended for that purpose. @@ -1851,34 +1849,6 @@ sub dump_function($$) { }); } -sub process_file($); - -# Read the file that maps relative names to absolute names for -# separate source and object directories and for shadow trees. -if (open(SOURCE_MAP, "<.tmp_filelist.txt")) { - my ($relname, $absname); - while() { - chop(); - ($relname, $absname) = (split())[0..1]; - $relname =~ s:^/+::; - $source_map{$relname} = $absname; - } - close(SOURCE_MAP); -} - -foreach (@ARGV) { - chomp; - process_file($_); -} -if ($verbose && $errors) { - print STDERR "$errors errors\n"; -} -if ($verbose && $warnings) { - print STDERR "$warnings warnings\n"; -} - -exit($errors); - sub reset_state { $function = ""; %constants = (); @@ -2285,3 +2255,39 @@ sub process_file($) { } } } + + +$kernelversion = get_kernel_version(); + +# generate a sequence of code that will splice in highlighting information +# using the s// operator. +foreach my $pattern (keys %highlights) { +# print STDERR "scanning pattern:$pattern, highlight:($highlights{$pattern})\n"; + $dohighlight .= "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n"; +} + +# Read the file that maps relative names to absolute names for +# separate source and object directories and for shadow trees. +if (open(SOURCE_MAP, "<.tmp_filelist.txt")) { + my ($relname, $absname); + while() { + chop(); + ($relname, $absname) = (split())[0..1]; + $relname =~ s:^/+::; + $source_map{$relname} = $absname; + } + close(SOURCE_MAP); +} + +foreach (@ARGV) { + chomp; + process_file($_); +} +if ($verbose && $errors) { + print STDERR "$errors errors\n"; +} +if ($verbose && $warnings) { + print STDERR "$warnings warnings\n"; +} + +exit($errors); -- cgit v1.2.3 From bc91c9f313309915f6ec767f56f78dcd0305b20f Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Fri, 17 Dec 2010 17:19:17 +0100 Subject: mkuboot.sh: Fail if mkimage is missing on building an uImage, I get: $ make uImage CHK include/linux/version.h CHK include/generated/utsrelease.h make[1]: `include/generated/mach-types.h' is up to date. CALL scripts/checksyscalls.sh CHK include/generated/compile.h Kernel: arch/arm/boot/Image is ready SHIPPED arch/arm/boot/compressed/lib1funcs.S AS arch/arm/boot/compressed/lib1funcs.o LD arch/arm/boot/compressed/vmlinux OBJCOPY arch/arm/boot/zImage Kernel: arch/arm/boot/zImage is ready UIMAGE arch/arm/boot/uImage "mkimage" command not found - U-Boot images will not be built Image arch/arm/boot/uImage is ready $ I.e. it says: "uImage is ready" even though the uImage file doesn't exist because mkimage is missing. I propose the attached patch. Signed-off-by: Roland Stigge Signed-off-by: Michal Marek --- scripts/mkuboot.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mkuboot.sh b/scripts/mkuboot.sh index 2e3d3cd916b8..446739c7843a 100755 --- a/scripts/mkuboot.sh +++ b/scripts/mkuboot.sh @@ -11,7 +11,7 @@ if [ -z "${MKIMAGE}" ]; then if [ -z "${MKIMAGE}" ]; then # Doesn't exist echo '"mkimage" command not found - U-Boot images will not be built' >&2 - exit 0; + exit 1; fi fi -- cgit v1.2.3 From 39177ec36236fb71257e51d0d198437b84170911 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Thu, 6 Jan 2011 16:42:45 +0100 Subject: nconf: handle comment entries within choice/endchoice Equivalent to af6c1598 (kconfig: handle comment entries within choice/endchoice), but for nconfig instead. Implement support for comment entries within choice groups. Comment entries are displayed visually distinct from normal configs, and selecting them is a no-op. Signed-off-by: Peter Korsgaard Signed-off-by: Michal Marek --- scripts/kconfig/nconf.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index eda49ffc1c8c..db56377393d7 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -1266,9 +1266,13 @@ static void conf_choice(struct menu *menu) if (child->sym == sym_get_choice_value(menu->sym)) item_make(child, ':', " %s", _(menu_get_prompt(child))); - else + else if (child->sym) item_make(child, ':', " %s", _(menu_get_prompt(child))); + else + item_make(child, ':', "*** %s ***", + _(menu_get_prompt(child))); + if (child->sym == active){ last_top_row = top_row(curses_menu); selected_index = i; @@ -1334,7 +1338,7 @@ static void conf_choice(struct menu *menu) break; child = item_data(); - if (!child || !menu_is_visible(child)) + if (!child || !menu_is_visible(child) || !child->sym) continue; switch (res) { case ' ': -- cgit v1.2.3 From 7e1863af1636b304a5f59aab6fb78d38e4079875 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 12 Jan 2011 16:59:49 -0800 Subject: scripts/get_maintainer.pl: make --rolestats the default This script now requires a user to add --norolestats to the command line so it's harder to feed the output of this script to programs that send mass emails. Update --help to correct command line defaults. Change version to 0.26. Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index d21ec3a89603..43bace2f4ac8 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -13,7 +13,7 @@ use strict; my $P = $0; -my $V = '0.26-beta6'; +my $V = '0.26'; use Getopt::Long qw(:config no_auto_abbrev); @@ -40,7 +40,7 @@ my $email_use_mailmap = 1; my $output_multiline = 1; my $output_separator = ", "; my $output_roles = 0; -my $output_rolestats = 0; +my $output_rolestats = 1; my $scm = 0; my $web = 0; my $subsystem = 0; @@ -720,7 +720,8 @@ Other options: --help => show this help information Default options: - [--email --git --m --n --l --multiline --pattern-depth=0 --remove-duplicates] + [--email --nogit --git-fallback --m --n --l --multiline -pattern-depth=0 + --remove-duplicates --rolestats] Notes: Using "-f directory" may give unexpected results: -- cgit v1.2.3 From ab6c937dbadf4797484d00d2815e1e3b0ec54397 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 12 Jan 2011 16:59:50 -0800 Subject: scripts/get_maintainer.pl: use --git-fallback more often On Fri, 2010-11-05 at 13:50 -0700, Andrew Morton wrote: > z:/usr/src/git26> perl scripts/get_maintainer.pl -file mm/mempolicy.c > linux-mm@kvack.org > linux-kernel@vger.kernel.org Turns out this is an arguable defect in the script. The MAINTAINERS entry for mm is: MEMORY MANAGEMENT L: linux-mm@kvack.org W: http://www.linux-mm.org S: Maintained F: include/linux/mm.h F: mm/ There's a maintainer entry, but no named individual, so the script doesn't use git history via --git-fallback. This is also a defect for MAINTAINERS with status entries marked "Orphan" or "Odd fixes". The script now checks a section for any "M:" entry and that an "S:" entry is supported or maintained. If both those conditions are not satisified, use --git-fallback as appropriate. Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/get_maintainer.pl | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 43bace2f4ac8..139e0fff8e31 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -494,6 +494,40 @@ if ($web) { exit($exit); +sub range_is_maintained { + my ($start, $end) = @_; + + for (my $i = $start; $i < $end; $i++) { + my $line = $typevalue[$i]; + if ($line =~ m/^(\C):\s*(.*)/) { + my $type = $1; + my $value = $2; + if ($type eq 'S') { + if ($value =~ /(maintain|support)/i) { + return 1; + } + } + } + } + return 0; +} + +sub range_has_maintainer { + my ($start, $end) = @_; + + for (my $i = $start; $i < $end; $i++) { + my $line = $typevalue[$i]; + if ($line =~ m/^(\C):\s*(.*)/) { + my $type = $1; + my $value = $2; + if ($type eq 'M') { + return 1; + } + } + } + return 0; +} + sub get_maintainers { %email_hash_name = (); %email_hash_address = (); @@ -556,7 +590,9 @@ sub get_maintainers { my $file_pd = ($file =~ tr@/@@); $value_pd++ if (substr($value,-1,1) ne "/"); $value_pd = -1 if ($value =~ /^\.\*/); - if ($value_pd >= $file_pd) { + if ($value_pd >= $file_pd && + range_is_maintained($start, $end) && + range_has_maintainer($start, $end)) { $exact_pattern_match_hash{$file} = 1; } if ($pattern_depth == 0 || -- cgit v1.2.3 From caf2a54f101a55ec318c2a20253a1977802f7de4 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 12 Jan 2011 16:59:56 -0800 Subject: scripts/checkpatch.pl: add check for multiple terminating semicolons and casts of vmalloc Signed-off-by: Joe Perches Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index e3c7fc0dca38..36d6851f97d0 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2785,10 +2785,15 @@ sub process { } # check for pointless casting of kmalloc return - if ($line =~ /\*\s*\)\s*k[czm]alloc\b/) { + if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) { WARN("unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); } +# check for multiple semicolons + if ($line =~ /;\s*;\s*$/) { + WARN("Statements terminations use 1 semicolon\n" . $herecurr); + } + # check for gcc specific __FUNCTION__ if ($line =~ /__FUNCTION__/) { WARN("__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr); -- cgit v1.2.3 From c023e4734c3e8801e0ecb5e81b831d42a374d861 Mon Sep 17 00:00:00 2001 From: Florian Mickler Date: Wed, 12 Jan 2011 16:59:58 -0800 Subject: checkpatch.pl: fix CAST detection We should only claim that something is a cast if we did not encouter a token before, that did set av_pending. This fixes the operator * in the line below to be detected as binary (vs unary). kmalloc(sizeof(struct alphatrack_ocmd) * true_size, GFP_KERNEL); Reported-by: Audun Hoem Signed-off-by: Florian Mickler Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 36d6851f97d0..ddd27d8e6312 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -859,7 +859,7 @@ sub annotate_values { $av_preprocessor = 0; } - } elsif ($cur =~ /^(\(\s*$Type\s*)\)/) { + } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { print "CAST($1)\n" if ($dbg_values > 1); push(@av_paren_type, $type); $type = 'C'; -- cgit v1.2.3 From 88f8831c055858179a7844d9dd4ddd7d3621322e Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 12 Jan 2011 16:59:59 -0800 Subject: checkpatch: check for world-writeable sysfs/debugfs files Exporting world writable sysfs/debugfs files is usually a bad thing. Warn about it. Signed-off-by: Dave Jones Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index ddd27d8e6312..fd9560ea976c 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2897,6 +2897,11 @@ sub process { ERROR("lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); } } + + if ($line =~ /debugfs_create_file.*S_IWUGO/ || + $line =~ /DEVICE_ATTR.*S_IWUGO/ ) { + WARN("Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); + } } # If we have no input at all, then there is nothing to report on -- cgit v1.2.3 From 3d130fd03e06672f7700e2cb694b29f9a98227ca Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 12 Jan 2011 17:00:00 -0800 Subject: checkpatch.pl: add "prefer __packed" check There's a __packed #define for __attribute__((packed)). Add a checkpatch to tell people about it. Signed-off-by: Joe Perches Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index fd9560ea976c..4c0383da1c9a 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2743,6 +2743,11 @@ sub process { WARN("plain inline is preferred over $1\n" . $herecurr); } +# Check for __attribute__ packed, prefer __packed + if ($line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { + WARN("__packed is preferred over __attribute__((packed))\n" . $herecurr); + } + # check for sizeof(&) if ($line =~ /\bsizeof\s*\(\s*\&/) { WARN("sizeof(& should be avoided\n" . $herecurr); -- cgit v1.2.3 From 24fa0402a9b6a537e87e38341e78b7da86486846 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Wed, 12 Jan 2011 17:01:22 -0800 Subject: decompressors: add XZ decompressor module In userspace, the .lzma format has become mostly a legacy file format that got superseded by the .xz format. Similarly, LZMA Utils was superseded by XZ Utils. These patches add support for XZ decompression into the kernel. Most of the code is as is from XZ Embedded . It was written for the Linux kernel but is usable in other projects too. Advantages of XZ over the current LZMA code in the kernel: - Nice API that can be used by other kernel modules; it's not limited to kernel, initramfs, and initrd decompression. - Integrity check support (CRC32) - BCJ filters improve compression of executable code on certain architectures. These together with LZMA2 can produce a few percent smaller kernel or Squashfs images than plain LZMA without making the decompression slower. This patch: Add the main decompression code (xz_dec), testing module (xz_dec_test), wrapper script (xz_wrap.sh) for the xz command line tool, and documentation. The xz_dec module is enough to have a usable XZ decompressor e.g. for Squashfs. Signed-off-by: Lasse Collin Cc: "H. Peter Anvin" Cc: Alain Knaff Cc: Albin Tonnerre Cc: Phillip Lougher Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/Makefile.lib | 28 ++++++++++++++++++++++++++++ scripts/xz_wrap.sh | 23 +++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 scripts/xz_wrap.sh (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 396da16aabf8..1c702ca8aac8 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -262,6 +262,34 @@ cmd_lzo = (cat $(filter-out FORCE,$^) | \ lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ (rm -f $@ ; false) +# XZ +# --------------------------------------------------------------------------- +# Use xzkern to compress the kernel image and xzmisc to compress other things. +# +# xzkern uses a big LZMA2 dictionary since it doesn't increase memory usage +# of the kernel decompressor. A BCJ filter is used if it is available for +# the target architecture. xzkern also appends uncompressed size of the data +# using size_append. The .xz format has the size information available at +# the end of the file too, but it's in more complex format and it's good to +# avoid changing the part of the boot code that reads the uncompressed size. +# Note that the bytes added by size_append will make the xz tool think that +# the file is corrupt. This is expected. +# +# xzmisc doesn't use size_append, so it can be used to create normal .xz +# files. xzmisc uses smaller LZMA2 dictionary than xzkern, because a very +# big dictionary would increase the memory usage too much in the multi-call +# decompression mode. A BCJ filter isn't used either. +quiet_cmd_xzkern = XZKERN $@ +cmd_xzkern = (cat $(filter-out FORCE,$^) | \ + sh $(srctree)/scripts/xz_wrap.sh && \ + $(call size_append, $(filter-out FORCE,$^))) > $@ || \ + (rm -f $@ ; false) + +quiet_cmd_xzmisc = XZMISC $@ +cmd_xzmisc = (cat $(filter-out FORCE,$^) | \ + xz --check=crc32 --lzma2=dict=1MiB) > $@ || \ + (rm -f $@ ; false) + # misc stuff # --------------------------------------------------------------------------- quote:=" diff --git a/scripts/xz_wrap.sh b/scripts/xz_wrap.sh new file mode 100644 index 000000000000..17a5798c29da --- /dev/null +++ b/scripts/xz_wrap.sh @@ -0,0 +1,23 @@ +#!/bin/sh +# +# This is a wrapper for xz to compress the kernel image using appropriate +# compression options depending on the architecture. +# +# Author: Lasse Collin +# +# This file has been put into the public domain. +# You can do whatever you want with this file. +# + +BCJ= +LZMA2OPTS= + +case $ARCH in + x86|x86_64) BCJ=--x86 ;; + powerpc) BCJ=--powerpc ;; + ia64) BCJ=--ia64; LZMA2OPTS=pb=4 ;; + arm) BCJ=--arm ;; + sparc) BCJ=--sparc ;; +esac + +exec xz --check=crc32 $BCJ --lzma2=$LZMA2OPTS,dict=32MiB -- cgit v1.2.3 From 3ebe12439ba7fc62e1d6ecb569b7287771716ca1 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Wed, 12 Jan 2011 17:01:23 -0800 Subject: decompressors: add boot-time XZ support This implements the API defined in which is used for kernel, initramfs, and initrd decompression. This patch together with the first patch is enough for XZ-compressed initramfs and initrd; XZ-compressed kernel will need arch-specific changes. The buffering requirements described in decompress_unxz.c are stricter than with gzip, so the relevant changes should be done to the arch-specific code when adding support for XZ-compressed kernel. Similarly, the heap size in arch-specific pre-boot code may need to be increased (30 KiB is enough). The XZ decompressor needs memmove(), memeq() (memcmp() == 0), and memzero() (memset(ptr, 0, size)), which aren't available in all arch-specific pre-boot environments. I'm including simple versions in decompress_unxz.c, but a cleaner solution would naturally be nicer. Signed-off-by: Lasse Collin Cc: "H. Peter Anvin" Cc: Alain Knaff Cc: Albin Tonnerre Cc: Phillip Lougher Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/gen_initramfs_list.sh | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh index 5958fffb2114..55caecdad995 100644 --- a/scripts/gen_initramfs_list.sh +++ b/scripts/gen_initramfs_list.sh @@ -243,6 +243,8 @@ case "$arg" in echo "$output_file" | grep -q "\.gz$" && compr="gzip -9 -f" echo "$output_file" | grep -q "\.bz2$" && compr="bzip2 -9 -f" echo "$output_file" | grep -q "\.lzma$" && compr="lzma -9 -f" + echo "$output_file" | grep -q "\.xz$" && \ + compr="xz --check=crc32 --lzma2=dict=1MiB" echo "$output_file" | grep -q "\.lzo$" && compr="lzop -9 -f" echo "$output_file" | grep -q "\.cpio$" && compr="cat" shift -- cgit v1.2.3