diff options
Diffstat (limited to 'scripts')
52 files changed, 1302 insertions, 1016 deletions
diff --git a/scripts/.gitignore b/scripts/.gitignore index e063daa3ec4a..0442c06eefcb 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -7,7 +7,6 @@ pnmtologo unifdef ihex2fw recordmcount -docproc check-lc_ctype sortextable asn1_compiler diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 61f87a99bf0a..dd8e2dde0b34 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -108,6 +108,11 @@ as-option = $(call try-run,\ as-instr = $(call try-run,\ printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3)) +# __cc-option +# Usage: MY_CFLAGS += $(call __cc-option,$(CC),$(MY_CFLAGS),-march=winchip-c6,-march=i586) +__cc-option = $(call try-run,\ + $(1) -Werror $(2) $(3) -c -x c /dev/null -o "$$TMP",$(3),$(4)) + # Do not attempt to build with gcc plugins during cc-option tests. # (And this uses delayed resolution so the flags will be up to date.) CC_OPTION_CFLAGS = $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS)) @@ -115,19 +120,19 @@ CC_OPTION_CFLAGS = $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS)) # cc-option # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) -cc-option = $(call try-run,\ - $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2)) +cc-option = $(call __cc-option, $(CC),\ + $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS),$(1),$(2)) + +# hostcc-option +# Usage: cflags-y += $(call hostcc-option,-march=winchip-c6,-march=i586) +hostcc-option = $(call __cc-option, $(HOSTCC),\ + $(HOSTCFLAGS) $(HOST_EXTRACFLAGS),$(1),$(2)) # cc-option-yn # Usage: flag := $(call cc-option-yn,-march=winchip-c6) cc-option-yn = $(call try-run,\ $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n) -# cc-option-align -# Prefix align with either -falign or -malign -cc-option-align = $(subst -functions=0,,\ - $(call cc-option,-falign-functions=0,-malign-functions=0)) - # cc-disable-warning # Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable) cc-disable-warning = $(call try-run,\ diff --git a/scripts/Makefile b/scripts/Makefile index 1d80897a9644..c06f4997d700 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -6,8 +6,6 @@ # pnmttologo: Convert pnm files to logo files # conmakehash: Create chartable # conmakehash: Create arrays for initializing the kernel console tables -# docproc: Used in Documentation/DocBook -# check-lc_ctype: Used in Documentation/DocBook HOST_EXTRACFLAGS += -I$(srctree)/tools/include @@ -29,16 +27,12 @@ HOSTLOADLIBES_extract-cert = -lcrypto always := $(hostprogs-y) $(hostprogs-m) # The following hostprogs-y programs are only build on demand -hostprogs-y += unifdef docproc check-lc_ctype +hostprogs-y += unifdef # These targets are used internally to avoid "is up to date" messages -PHONY += build_unifdef build_docproc build_check-lc_ctype +PHONY += build_unifdef build_unifdef: $(obj)/unifdef @: -build_docproc: $(obj)/docproc - @: -build_check-lc_ctype: $(obj)/check-lc_ctype - @: subdir-$(CONFIG_MODVERSIONS) += genksyms subdir-y += mod diff --git a/scripts/Makefile.asm-generic b/scripts/Makefile.asm-generic index e4d017d53819..95f7d8090152 100644 --- a/scripts/Makefile.asm-generic +++ b/scripts/Makefile.asm-generic @@ -15,7 +15,7 @@ _dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj)) # Stale wrappers when the corresponding files are removed from generic-y # need removing. -generated-y := $(generic-y) $(genhdr-y) $(generated-y) +generated-y := $(generic-y) $(generated-y) all-files := $(patsubst %, $(obj)/%, $(generated-y)) old-headers := $(wildcard $(obj)/*.h) unwanted := $(filter-out $(all-files),$(old-headers)) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 733e044fff8b..4a9a2cec0a1b 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -437,8 +437,8 @@ $(sort $(subdir-obj-y)): $(subdir-ym) ; ifdef builtin-target ifdef CONFIG_THIN_ARCHIVES - cmd_make_builtin = rm -f $@; $(AR) rcST$(KBUILD_ARFLAGS) - cmd_make_empty_builtin = rm -f $@; $(AR) rcST$(KBUILD_ARFLAGS) + cmd_make_builtin = rm -f $@; $(AR) rcSTP$(KBUILD_ARFLAGS) + cmd_make_empty_builtin = rm -f $@; $(AR) rcSTP$(KBUILD_ARFLAGS) quiet_cmd_link_o_target = AR $@ else cmd_make_builtin = $(LD) $(ld_flags) -r -o @@ -478,7 +478,7 @@ ifdef lib-target quiet_cmd_link_l_target = AR $@ ifdef CONFIG_THIN_ARCHIVES - cmd_link_l_target = rm -f $@; $(AR) rcsT$(KBUILD_ARFLAGS) $@ $(lib-y) + cmd_link_l_target = rm -f $@; $(AR) rcsTP$(KBUILD_ARFLAGS) $@ $(lib-y) else cmd_link_l_target = rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) $@ $(lib-y) endif @@ -531,7 +531,7 @@ cmd_link_multi-link = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) $(cmd_secana ifdef CONFIG_THIN_ARCHIVES quiet_cmd_link_multi-y = AR $@ - cmd_link_multi-y = rm -f $@; $(AR) rcST$(KBUILD_ARFLAGS) $@ $(link_multi_deps) + cmd_link_multi-y = rm -f $@; $(AR) rcSTP$(KBUILD_ARFLAGS) $@ $(link_multi_deps) else quiet_cmd_link_multi-y = LD $@ cmd_link_multi-y = $(cmd_link_multi-link) diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 82335533620e..2e0e2eaa397f 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -29,6 +29,10 @@ ifdef CONFIG_GCC_PLUGINS gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) += -fplugin-arg-structleak_plugin-verbose gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += -DSTRUCTLEAK_PLUGIN + gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so + gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += -DRANDSTRUCT_PLUGIN + gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE) += -fplugin-arg-randomize_layout_plugin-performance-mode + GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN GCC_PLUGIN_SUBDIR diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst index ce753a408c56..c583a1e1bd3c 100644 --- a/scripts/Makefile.headersinst +++ b/scripts/Makefile.headersinst @@ -14,7 +14,15 @@ __headers: include scripts/Kbuild.include srcdir := $(srctree)/$(obj) -subdirs := $(patsubst $(srcdir)/%/.,%,$(wildcard $(srcdir)/*/.)) + +# When make is run under a fakechroot environment, the function +# $(wildcard $(srcdir)/*/.) doesn't only return directories, but also regular +# files. So, we are using a combination of sort/dir/wildcard which works +# with fakechroot. +subdirs := $(patsubst $(srcdir)/%/,%,\ + $(filter-out $(srcdir)/,\ + $(sort $(dir $(wildcard $(srcdir)/*/))))) + # caller may set destination dir (when installing to asm/) _dst := $(if $(dst),$(dst),$(obj)) diff --git a/scripts/Makefile.host b/scripts/Makefile.host index 45b5b1aaedbd..9cfd5c84d76f 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -20,12 +20,6 @@ # Will compile qconf as a C++ program, and menu as a C program. # They are linked as C++ code to the executable qconf -# hostcc-option -# Usage: cflags-y += $(call hostcc-option,-march=winchip-c6,-march=i586) - -hostcc-option = $(call try-run,\ - $(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2)) - __hostprogs := $(sort $(hostprogs-y) $(hostprogs-m)) host-cshlib := $(sort $(hostlibs-y) $(hostlibs-m)) host-cxxshlib := $(sort $(hostcxxlibs-y) $(hostcxxlibs-m)) diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl index 9ca667bcaee9..594c55541b16 100755 --- a/scripts/bootgraph.pl +++ b/scripts/bootgraph.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Copyright 2008, Intel Corporation # diff --git a/scripts/check-lc_ctype.c b/scripts/check-lc_ctype.c deleted file mode 100644 index 9097ff5449fb..000000000000 --- a/scripts/check-lc_ctype.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Check that a specified locale works as LC_CTYPE. Used by the - * DocBook build system to probe for C.UTF-8 support. - */ - -#include <locale.h> - -int main(void) -{ - return !setlocale(LC_CTYPE, ""); -} diff --git a/scripts/checkincludes.pl b/scripts/checkincludes.pl index 381c018a4612..ce9edefd6e0b 100755 --- a/scripts/checkincludes.pl +++ b/scripts/checkincludes.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # # checkincludes: find/remove files included more than once # diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 4b9569fa931b..8f940c09918f 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # (c) 2001, Dave Jones. (the file handling bit) # (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) # (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite) @@ -6,6 +6,7 @@ # Licensed under the terms of the GNU GPL License version 2 use strict; +use warnings; use POSIX; use File::Basename; use Cwd 'abs_path'; @@ -56,7 +57,7 @@ my $codespell = 0; my $codespellfile = "/usr/share/codespell/dictionary.txt"; my $conststructsfile = "$D/const_structs.checkpatch"; my $typedefsfile = ""; -my $color = 1; +my $color = "auto"; my $allow_c99_comments = 1; sub help { @@ -115,7 +116,8 @@ Options: (default:/usr/share/codespell/dictionary.txt) --codespellfile Use this codespell dictionary --typedefsfile Read additional types from this file - --color Use colors when output is STDOUT (default: on) + --color[=WHEN] Use colors 'always', 'never', or only when output + is a terminal ('auto'). Default is 'auto'. -h, --help, --version display this help and exit When FILE is - read standard input. @@ -181,6 +183,14 @@ if (-f $conf) { unshift(@ARGV, @conf_args) if @conf_args; } +# Perl's Getopt::Long allows options to take optional arguments after a space. +# Prevent --color by itself from consuming other arguments +foreach (@ARGV) { + if ($_ eq "--color" || $_ eq "-color") { + $_ = "--color=$color"; + } +} + GetOptions( 'q|quiet+' => \$quiet, 'tree!' => \$tree, @@ -211,7 +221,9 @@ GetOptions( 'codespell!' => \$codespell, 'codespellfile=s' => \$codespellfile, 'typedefsfile=s' => \$typedefsfile, - 'color!' => \$color, + 'color=s' => \$color, + 'no-color' => \$color, #keep old behaviors of -nocolor + 'nocolor' => \$color, #keep old behaviors of -nocolor 'h|help' => \$help, 'version' => \$help ) or help(1); @@ -237,6 +249,18 @@ if ($#ARGV < 0) { push(@ARGV, '-'); } +if ($color =~ /^[01]$/) { + $color = !$color; +} elsif ($color =~ /^always$/i) { + $color = 1; +} elsif ($color =~ /^never$/i) { + $color = 0; +} elsif ($color =~ /^auto$/i) { + $color = (-t STDOUT); +} else { + die "Invalid color mode: $color\n"; +} + sub hash_save_array_words { my ($hashRef, $arrayRef) = @_; @@ -732,7 +756,7 @@ our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; our $declaration_macros = qr{(?x: (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| - (?:$Storage\s+)?LIST_HEAD\s*\(| + (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\( )}; @@ -866,6 +890,7 @@ sub git_commit_info { # echo "commit $(cut -c 1-12,41-)" # done } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) { + $id = undef; } else { $id = substr($lines[0], 0, 12); $desc = substr($lines[0], 41); @@ -1881,7 +1906,7 @@ sub report { return 0; } my $output = ''; - if (-t STDOUT && $color) { + if ($color) { if ($level eq 'ERROR') { $output .= RED; } elsif ($level eq 'WARNING') { @@ -1892,10 +1917,10 @@ sub report { } $output .= $prefix . $level . ':'; if ($show_types) { - $output .= BLUE if (-t STDOUT && $color); + $output .= BLUE if ($color); $output .= "$type:"; } - $output .= RESET if (-t STDOUT && $color); + $output .= RESET if ($color); $output .= ' ' . $msg . "\n"; if ($showfile) { @@ -2605,7 +2630,8 @@ sub process { ($id, $description) = git_commit_info($orig_commit, $id, $orig_desc); - if ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens) { + if (defined($id) && + ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) { ERROR("GIT_COMMIT_ID", "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr); } @@ -2775,6 +2801,17 @@ sub process { #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; } +# check for MAINTAINERS entries that don't have the right form + if ($realfile =~ /^MAINTAINERS$/ && + $rawline =~ /^\+[A-Z]:/ && + $rawline !~ /^\+[A-Z]:\t\S/) { + if (WARN("MAINTAINERS_STYLE", + "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; + } + } + # discourage the use of boolean for type definition attributes of Kconfig options if ($realfile =~ /Kconfig/ && $line =~ /^\+\s*\bboolean\b/) { @@ -2956,7 +2993,7 @@ sub process { # check multi-line statement indentation matches previous line if ($^V && $^V ge 5.10.0 && - $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|$Ident\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { + $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { $prevline =~ /^\+(\t*)(.*)$/; my $oldindent = $1; my $rest = $2; @@ -3207,7 +3244,7 @@ sub process { my ($stat, $cond, $line_nr_next, $remain_next, $off_next, $realline_next); #print "LINE<$line>\n"; - if ($linenr >= $suppress_statement && + if ($linenr > $suppress_statement && $realcnt && $sline =~ /.\s*\S/) { ($stat, $cond, $line_nr_next, $remain_next, $off_next) = ctx_statement_block($linenr, $realcnt, 0); @@ -3541,7 +3578,7 @@ sub process { $fixedline =~ s/\s*=\s*$/ = {/; fix_insert_line($fixlinenr, $fixedline); $fixedline = $line; - $fixedline =~ s/^(.\s*){\s*/$1/; + $fixedline =~ s/^(.\s*)\{\s*/$1/; fix_insert_line($fixlinenr, $fixedline); } } @@ -3882,7 +3919,7 @@ sub process { my $fixedline = rtrim($prevrawline) . " {"; fix_insert_line($fixlinenr, $fixedline); $fixedline = $rawline; - $fixedline =~ s/^(.\s*){\s*/$1\t/; + $fixedline =~ s/^(.\s*)\{\s*/$1\t/; if ($fixedline !~ /^\+\s*$/) { fix_insert_line($fixlinenr, $fixedline); } @@ -4371,7 +4408,7 @@ sub process { if (ERROR("SPACING", "space required before the open brace '{'\n" . $herecurr) && $fix) { - $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\))){/$1 {/; + $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\)))\{/$1 {/; } } @@ -4903,17 +4940,17 @@ sub process { foreach my $arg (@def_args) { next if ($arg =~ /\.\.\./); next if ($arg =~ /^type$/i); - my $tmp = $define_stmt; - $tmp =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; - $tmp =~ s/\#+\s*$arg\b//g; - $tmp =~ s/\b$arg\s*\#\#//g; - my $use_cnt = $tmp =~ s/\b$arg\b//g; + my $tmp_stmt = $define_stmt; + $tmp_stmt =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; + $tmp_stmt =~ s/\#+\s*$arg\b//g; + $tmp_stmt =~ s/\b$arg\s*\#\#//g; + my $use_cnt = $tmp_stmt =~ s/\b$arg\b//g; if ($use_cnt > 1) { CHK("MACRO_ARG_REUSE", "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); } # check if any macro arguments may have other precedence issues - if ($define_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && + if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && ((defined($1) && $1 ne ',') || (defined($2) && $2 ne ','))) { CHK("MACRO_ARG_PRECEDENCE", @@ -5310,7 +5347,7 @@ sub process { my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); # print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); - if ($c =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|(?:dev_)?alloc_skb)/) { + if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|kmemdup|(?:dev_)?alloc_skb)/) { WARN("OOM_MESSAGE", "Possible unnecessary 'out of memory' message\n" . $hereprev); } @@ -5533,23 +5570,6 @@ sub process { } } -# Check for expedited grace periods that interrupt non-idle non-nohz -# online CPUs. These expedited can therefore degrade real-time response -# if used carelessly, and should be avoided where not absolutely -# needed. It is always OK to use synchronize_rcu_expedited() and -# synchronize_sched_expedited() at boot time (before real-time applications -# start) and in error situations where real-time response is compromised in -# any case. Note that synchronize_srcu_expedited() does -not- interrupt -# other CPUs, so don't warn on uses of synchronize_srcu_expedited(). -# Of course, nothing comes for free, and srcu_read_lock() and -# srcu_read_unlock() do contain full memory barriers in payment for -# synchronize_srcu_expedited() non-interruption properties. - if ($line =~ /\b(synchronize_rcu_expedited|synchronize_sched_expedited)\(/) { - WARN("EXPEDITED_RCU_GRACE_PERIOD", - "expedited RCU grace periods should be avoided where they can degrade real-time response\n" . $herecurr); - - } - # check of hardware specific defines if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { CHK("ARCH_DEFINES", @@ -5709,7 +5729,7 @@ sub process { for (my $count = $linenr; $count <= $lc; $count++) { my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); $fmt =~ s/%%//g; - if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGN]).)/) { + if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) { $bad_extension = $1; last; } @@ -5902,7 +5922,8 @@ sub process { "externs should be avoided in .c files\n" . $herecurr); } - if ($realfile =~ /\.[ch]$/ && defined $stat && +# check for function declarations that have arguments without identifier names + if (defined $stat && $stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s && $1 ne "void") { my $args = trim($1); @@ -5915,6 +5936,29 @@ sub process { } } +# check for function definitions + if ($^V && $^V ge 5.10.0 && + defined $stat && + $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { + $context_function = $1; + +# check for multiline function definition with misplaced open brace + my $ok = 0; + my $cnt = statement_rawlines($stat); + my $herectx = $here . "\n"; + for (my $n = 0; $n < $cnt; $n++) { + my $rl = raw_line($linenr, $n); + $herectx .= $rl . "\n"; + $ok = 1 if ($rl =~ /^[ \+]\{/); + $ok = 1 if ($rl =~ /\{/ && $n == 0); + last if $rl =~ /^[ \+].*\{/; + } + if (!$ok) { + ERROR("OPEN_BRACE", + "open brace '{' following function definitions go on the next line\n" . $herectx); + } + } + # checks for new __setup's if ($rawline =~ /\b__setup\("([^"]*)"/) { my $name = $1; diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl index 9d37aa4faf5c..7f4c41717e26 100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Check the stack usage of functions # diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh index 116b7735ee9f..5a387a264201 100755 --- a/scripts/checksyscalls.sh +++ b/scripts/checksyscalls.sh @@ -202,15 +202,12 @@ EOF } syscall_list() { - grep '^[0-9]' "$1" | sort -n | ( + grep '^[0-9]' "$1" | sort -n | while read nr abi name entry ; do - cat <<EOF -#if !defined(__NR_${name}) && !defined(__IGNORE_${name}) -#warning syscall ${name} not implemented -#endif -EOF + echo "#if !defined(__NR_${name}) && !defined(__IGNORE_${name})" + echo "#warning syscall ${name} not implemented" + echo "#endif" done - ) } (ignore_list && syscall_list $(dirname $0)/../arch/x86/entry/syscalls/syscall_32.tbl) | \ diff --git a/scripts/checkversion.pl b/scripts/checkversion.pl index 5e490a8ceca5..8b4f205234b5 100755 --- a/scripts/checkversion.pl +++ b/scripts/checkversion.pl @@ -1,4 +1,4 @@ -#! /usr/bin/perl +#! /usr/bin/env perl # # checkversion find uses of LINUX_VERSION_CODE or KERNEL_VERSION # without including <linux/version.h>, or cases of diff --git a/scripts/cleanfile b/scripts/cleanfile index cefd29e52298..72e3755327ae 100755 --- a/scripts/cleanfile +++ b/scripts/cleanfile @@ -1,9 +1,10 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # # Clean a text file -- or directory of text files -- of stealth whitespace. # WARNING: this can be a highly destructive operation. Use with caution. # +use warnings; use bytes; use File::Basename; diff --git a/scripts/cleanpatch b/scripts/cleanpatch index 9680d03ad2b8..3e5a2303dc0e 100755 --- a/scripts/cleanpatch +++ b/scripts/cleanpatch @@ -1,9 +1,10 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # # Clean a patch file -- or directory of patch files -- of stealth whitespace. # WARNING: this can be a highly destructive operation. Use with caution. # +use warnings; use bytes; use File::Basename; diff --git a/scripts/docproc.c b/scripts/docproc.c deleted file mode 100644 index 0a12593b9041..000000000000 --- a/scripts/docproc.c +++ /dev/null @@ -1,681 +0,0 @@ -/* - * docproc is a simple preprocessor for the template files - * used as placeholders for the kernel internal documentation. - * docproc is used for documentation-frontend and - * dependency-generator. - * The two usages have in common that they require - * some knowledge of the .tmpl syntax, therefore they - * are kept together. - * - * documentation-frontend - * Scans the template file and call kernel-doc for - * all occurrences of ![EIF]file - * Beforehand each referenced file is scanned for - * any symbols that are exported via these macros: - * EXPORT_SYMBOL(), EXPORT_SYMBOL_GPL(), & - * EXPORT_SYMBOL_GPL_FUTURE() - * This is used to create proper -function and - * -nofunction arguments in calls to kernel-doc. - * Usage: docproc doc file.tmpl - * - * dependency-generator: - * Scans the template file and list all files - * referenced in a format recognized by make. - * Usage: docproc depend file.tmpl - * Writes dependency information to stdout - * in the following format: - * file.tmpl src.c src2.c - * The filenames are obtained from the following constructs: - * !Efilename - * !Ifilename - * !Dfilename - * !Ffilename - * !Pfilename - * - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> -#include <limits.h> -#include <errno.h> -#include <getopt.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <time.h> - -/* exitstatus is used to keep track of any failing calls to kernel-doc, - * but execution continues. */ -int exitstatus = 0; - -typedef void DFL(char *); -DFL *defaultline; - -typedef void FILEONLY(char * file); -FILEONLY *internalfunctions; -FILEONLY *externalfunctions; -FILEONLY *symbolsonly; -FILEONLY *findall; - -typedef void FILELINE(char * file, char * line); -FILELINE * singlefunctions; -FILELINE * entity_system; -FILELINE * docsection; - -#define MAXLINESZ 2048 -#define MAXFILES 250 -#define KERNELDOCPATH "scripts/" -#define KERNELDOC "kernel-doc" -#define DOCBOOK "-docbook" -#define RST "-rst" -#define LIST "-list" -#define FUNCTION "-function" -#define NOFUNCTION "-nofunction" -#define NODOCSECTIONS "-no-doc-sections" -#define SHOWNOTFOUND "-show-not-found" - -enum file_format { - FORMAT_AUTO, - FORMAT_DOCBOOK, - FORMAT_RST, -}; - -static enum file_format file_format = FORMAT_AUTO; - -#define KERNELDOC_FORMAT (file_format == FORMAT_RST ? RST : DOCBOOK) - -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 [{--docbook|--rst}] {doc|depend} file\n"); - fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n"); - fprintf(stderr, "doc: frontend when generating kernel documentation\n"); - fprintf(stderr, "depend: generate list of files referenced within file\n"); - fprintf(stderr, "Environment variable SRCTREE: absolute path to sources.\n"); - fprintf(stderr, " KBUILD_SRC: absolute path to kernel source tree.\n"); -} - -/* - * Execute kernel-doc with parameters given in svec - */ -static void exec_kernel_doc(char **svec) -{ - pid_t pid; - int ret; - char real_filename[PATH_MAX + 1]; - /* Make sure output generated so far are flushed */ - fflush(stdout); - switch (pid=fork()) { - case -1: - perror("fork"); - exit(1); - case 0: - 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, svec); - fprintf(stderr, "exec "); - perror(real_filename); - exit(1); - default: - waitpid(pid, &ret ,0); - } - if (WIFEXITED(ret)) - exitstatus |= WEXITSTATUS(ret); - else - exitstatus = 0xff; -} - -/* Types used to create list of all exported symbols in a number of files */ -struct symbols -{ - char *name; -}; - -struct symfile -{ - char *filename; - struct symbols *symbollist; - int symbolcnt; -}; - -struct symfile symfilelist[MAXFILES]; -int symfilecnt = 0; - -static void add_new_symbol(struct symfile *sym, char * symname) -{ - sym->symbollist = - realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *)); - sym->symbollist[sym->symbolcnt++].name = strdup(symname); -} - -/* Add a filename to the list */ -static struct symfile * add_new_file(char * filename) -{ - symfilelist[symfilecnt++].filename = strdup(filename); - return &symfilelist[symfilecnt - 1]; -} - -/* Check if file already are present in the list */ -static struct symfile * filename_exist(char * filename) -{ - int i; - for (i=0; i < symfilecnt; i++) - if (strcmp(symfilelist[i].filename, filename) == 0) - return &symfilelist[i]; - return NULL; -} - -/* - * List all files referenced within the template file. - * Files are separated by tabs. - */ -static void adddep(char * file) { printf("\t%s", file); } -static void adddep2(char * file, char * line) { line = line; adddep(file); } -static void noaction(char * line) { line = line; } -static void noaction2(char * file, char * line) { file = file; line = line; } - -/* Echo the line without further action */ -static void printline(char * line) { printf("%s", line); } - -/* - * Find all symbols in filename that are exported with EXPORT_SYMBOL & - * EXPORT_SYMBOL_GPL (& EXPORT_SYMBOL_GPL_FUTURE implicitly). - * All symbols located are stored in symfilelist. - */ -static void find_export_symbols(char * filename) -{ - FILE * fp; - struct symfile *sym; - char line[MAXLINESZ]; - if (filename_exist(filename) == NULL) { - char real_filename[PATH_MAX + 1]; - memset(real_filename, 0, sizeof(real_filename)); - strncat(real_filename, srctree, PATH_MAX); - strncat(real_filename, "/", PATH_MAX - strlen(real_filename)); - strncat(real_filename, filename, - PATH_MAX - strlen(real_filename)); - sym = add_new_file(filename); - fp = fopen(real_filename, "r"); - if (fp == NULL) { - fprintf(stderr, "docproc: "); - perror(real_filename); - exit(1); - } - while (fgets(line, MAXLINESZ, fp)) { - char *p; - char *e; - if (((p = strstr(line, "EXPORT_SYMBOL_GPL")) != NULL) || - ((p = strstr(line, "EXPORT_SYMBOL")) != NULL)) { - /* Skip EXPORT_SYMBOL{_GPL} */ - while (isalnum(*p) || *p == '_') - p++; - /* Remove parentheses & additional whitespace */ - while (isspace(*p)) - p++; - if (*p != '(') - continue; /* Syntax error? */ - else - p++; - while (isspace(*p)) - p++; - e = p; - while (isalnum(*e) || *e == '_') - e++; - *e = '\0'; - add_new_symbol(sym, p); - } - } - fclose(fp); - } -} - -/* - * Document all external or internal functions in a file. - * Call kernel-doc with following parameters: - * kernel-doc [-docbook|-rst] -nofunction function_name1 filename - * Function names are obtained from all the src files - * by find_export_symbols. - * intfunc uses -nofunction - * extfunc uses -function - */ -static void docfunctions(char * filename, char * type) -{ - int i,j; - int symcnt = 0; - int idx = 0; - char **vec; - - for (i=0; i <= symfilecnt; i++) - symcnt += symfilelist[i].symbolcnt; - vec = malloc((2 + 2 * symcnt + 3) * sizeof(char *)); - if (vec == NULL) { - perror("docproc: "); - exit(1); - } - vec[idx++] = KERNELDOC; - vec[idx++] = KERNELDOC_FORMAT; - vec[idx++] = NODOCSECTIONS; - for (i=0; i < symfilecnt; i++) { - 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; - } - } - vec[idx++] = filename; - vec[idx] = NULL; - if (file_format == FORMAT_RST) - printf(".. %s\n", filename); - else - printf("<!-- %s -->\n", filename); - exec_kernel_doc(vec); - fflush(stdout); - free(vec); -} -static void intfunc(char * filename) { docfunctions(filename, NOFUNCTION); } -static void extfunc(char * filename) { docfunctions(filename, FUNCTION); } - -/* - * Document specific function(s) in a file. - * Call kernel-doc with the following parameters: - * kernel-doc -docbook -function function1 [-function function2] - */ -static void singfunc(char * filename, char * line) -{ - char *vec[200]; /* Enough for specific functions */ - int i, idx = 0; - int startofsym = 1; - vec[idx++] = KERNELDOC; - vec[idx++] = KERNELDOC_FORMAT; - vec[idx++] = SHOWNOTFOUND; - - /* Split line up in individual parameters preceded by FUNCTION */ - for (i=0; line[i]; i++) { - if (isspace(line[i])) { - line[i] = '\0'; - startofsym = 1; - continue; - } - if (startofsym) { - startofsym = 0; - vec[idx++] = FUNCTION; - 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); -} - -/* - * Insert specific documentation section from a file. - * Call kernel-doc with the following parameters: - * kernel-doc -docbook -function "doc section" filename - */ -static void docsect(char *filename, char *line) -{ - /* kerneldoc -docbook -show-not-found -function "section" file NULL */ - char *vec[7]; - char *s; - - for (s = line; *s; s++) - if (*s == '\n') - *s = '\0'; - - if (asprintf(&s, "DOC: %s", line) < 0) { - perror("asprintf"); - exit(1); - } - consume_symbol(s); - free(s); - - vec[0] = KERNELDOC; - vec[1] = KERNELDOC_FORMAT; - vec[2] = SHOWNOTFOUND; - vec[3] = FUNCTION; - vec[4] = line; - vec[5] = filename; - vec[6] = NULL; - 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++; - } - } -} - -/* - * Terminate s at first space, if any. If there was a space, return pointer to - * the character after that. Otherwise, return pointer to the terminating NUL. - */ -static char *chomp(char *s) -{ - while (*s && !isspace(*s)) - s++; - - if (*s) - *s++ = '\0'; - - return s; -} - -/* Return pointer to directive content, or NULL if not a directive. */ -static char *is_directive(char *line) -{ - if (file_format == FORMAT_DOCBOOK && line[0] == '!') - return line + 1; - else if (file_format == FORMAT_RST && !strncmp(line, ".. !", 4)) - return line + 4; - - return NULL; -} - -/* - * Parse file, calling action specific functions for: - * 1) Lines containing !E - * 2) Lines containing !I - * 3) Lines containing !D - * 4) Lines containing !F - * 5) Lines containing !P - * 6) Lines containing !C - * 7) Default lines - lines not matching the above - */ -static void parse_file(FILE *infile) -{ - char line[MAXLINESZ]; - char *p, *s; - while (fgets(line, MAXLINESZ, infile)) { - p = is_directive(line); - if (!p) { - defaultline(line); - continue; - } - - switch (*p++) { - case 'E': - chomp(p); - externalfunctions(p); - break; - case 'I': - chomp(p); - internalfunctions(p); - break; - case 'D': - chomp(p); - symbolsonly(p); - break; - case 'F': - /* filename */ - s = chomp(p); - /* function names */ - while (isspace(*s)) - s++; - singlefunctions(p, s); - break; - case 'P': - /* filename */ - s = chomp(p); - /* DOC: section name */ - while (isspace(*s)) - s++; - docsection(p, s); - break; - case 'C': - chomp(p); - if (findall) - findall(p); - break; - default: - defaultline(line); - } - } - fflush(stdout); -} - -/* - * Is this a RestructuredText template? Answer the question by seeing if its - * name ends in ".rst". - */ -static int is_rst(const char *file) -{ - char *dot = strrchr(file, '.'); - - return dot && !strcmp(dot + 1, "rst"); -} - -enum opts { - OPT_DOCBOOK, - OPT_RST, - OPT_HELP, -}; - -int main(int argc, char *argv[]) -{ - const char *subcommand, *filename; - FILE * infile; - int i; - - srctree = getenv("SRCTREE"); - if (!srctree) - srctree = getcwd(NULL, 0); - kernsrctree = getenv("KBUILD_SRC"); - if (!kernsrctree || !*kernsrctree) - kernsrctree = srctree; - - for (;;) { - int c; - struct option opts[] = { - { "docbook", no_argument, NULL, OPT_DOCBOOK }, - { "rst", no_argument, NULL, OPT_RST }, - { "help", no_argument, NULL, OPT_HELP }, - {} - }; - - c = getopt_long_only(argc, argv, "", opts, NULL); - if (c == -1) - break; - - switch (c) { - case OPT_DOCBOOK: - file_format = FORMAT_DOCBOOK; - break; - case OPT_RST: - file_format = FORMAT_RST; - break; - case OPT_HELP: - usage(); - return 0; - default: - case '?': - usage(); - return 1; - } - } - - argc -= optind; - argv += optind; - - if (argc != 2) { - usage(); - exit(1); - } - - subcommand = argv[0]; - filename = argv[1]; - - if (file_format == FORMAT_AUTO) - file_format = is_rst(filename) ? FORMAT_RST : FORMAT_DOCBOOK; - - /* Open file, exit on error */ - infile = fopen(filename, "r"); - if (infile == NULL) { - fprintf(stderr, "docproc: "); - perror(filename); - exit(2); - } - - if (strcmp("doc", subcommand) == 0) { - if (file_format == FORMAT_RST) { - time_t t = time(NULL); - printf(".. generated from %s by docproc %s\n", - filename, ctime(&t)); - } - - /* Need to do this in two passes. - * First pass is used to collect all symbols exported - * in the various files; - * Second pass generate the documentation. - * This is required because some functions are declared - * and exported in different files :-(( - */ - /* Collect symbols */ - defaultline = noaction; - internalfunctions = find_export_symbols; - externalfunctions = find_export_symbols; - symbolsonly = find_export_symbols; - singlefunctions = noaction2; - docsection = noaction2; - findall = find_all_symbols; - parse_file(infile); - - /* Rewind to start from beginning of file again */ - fseek(infile, 0, SEEK_SET); - defaultline = printline; - internalfunctions = intfunc; - externalfunctions = extfunc; - 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", subcommand) == 0) { - /* Create first part of dependency chain - * file.tmpl */ - printf("%s\t", filename); - defaultline = noaction; - internalfunctions = adddep; - externalfunctions = adddep; - symbolsonly = adddep; - singlefunctions = adddep2; - docsection = adddep2; - findall = adddep; - parse_file(infile); - printf("\n"); - } else { - fprintf(stderr, "Unknown option: %s\n", subcommand); - exit(1); - } - fclose(infile); - fflush(stdout); - return exitstatus; -} diff --git a/scripts/dtc/dt_to_config b/scripts/dtc/dt_to_config index 9a248b505c58..5dfd1bff351f 100755 --- a/scripts/dtc/dt_to_config +++ b/scripts/dtc/dt_to_config @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Copyright 2016 by Frank Rowand # Copyright 2016 by Gaurav Minocha diff --git a/scripts/dtc/dtx_diff b/scripts/dtc/dtx_diff index ec47f95991a3..fb86f3899e16 100755 --- a/scripts/dtc/dtx_diff +++ b/scripts/dtc/dtx_diff @@ -338,7 +338,7 @@ DTC="${DTC} ${dtc_flags} -O dts -qq -f ${dtc_sort} -o -" if (( ${cmd_diff} )) ; then - diff ${diff_flags} \ + diff ${diff_flags} --label "${dtx_file_1}" --label "${dtx_file_2}" \ <(compile_to_dts "${dtx_file_1}") \ <(compile_to_dts "${dtx_file_2}") diff --git a/scripts/export_report.pl b/scripts/export_report.pl index 8f79b701de87..68ff426b347c 100755 --- a/scripts/export_report.pl +++ b/scripts/export_report.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # # (C) Copyright IBM Corporation 2006. # Released under GPL v2. @@ -7,6 +7,7 @@ # Usage: export_report.pl -k Module.symvers [-o report_file ] -f *.mod.c # +use warnings; use Getopt::Std; use strict; diff --git a/scripts/extract-module-sig.pl b/scripts/extract-module-sig.pl index faac6f2e377f..0f161ea41261 100755 --- a/scripts/extract-module-sig.pl +++ b/scripts/extract-module-sig.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # # extract-mod-sig <part> <module-file> # @@ -12,6 +12,7 @@ # -k: Just the key ID # -s: Just the crypto signature or PKCS#7 message # +use warnings; use strict; die "Format: $0 -[0adnks] module-file >out\n" diff --git a/scripts/extract-sys-certs.pl b/scripts/extract-sys-certs.pl index 8227ca10a494..2aa873b944e0 100755 --- a/scripts/extract-sys-certs.pl +++ b/scripts/extract-sys-certs.pl @@ -1,5 +1,6 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # +use warnings; use strict; use Math::BigInt; use Fcntl "SEEK_SET"; diff --git a/scripts/extract_xc3028.pl b/scripts/extract_xc3028.pl index 47877deae6d7..61d9b256c658 100755 --- a/scripts/extract_xc3028.pl +++ b/scripts/extract_xc3028.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Copyright (c) Mauro Carvalho Chehab <mchehab@infradead.org> # Released under GPLv2 diff --git a/scripts/gcc-plugins/.gitignore b/scripts/gcc-plugins/.gitignore new file mode 100644 index 000000000000..de92ed9e3d83 --- /dev/null +++ b/scripts/gcc-plugins/.gitignore @@ -0,0 +1 @@ +randomize_layout_seed.h diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile index 8b29dc17c73c..214eb2335c31 100644 --- a/scripts/gcc-plugins/Makefile +++ b/scripts/gcc-plugins/Makefile @@ -18,6 +18,14 @@ endif export HOSTLIBS +$(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h +quiet_cmd_create_randomize_layout_seed = GENSEED $@ +cmd_create_randomize_layout_seed = \ + $(CONFIG_SHELL) $(srctree)/$(src)/gen-random-seed.sh $@ $(objtree)/include/generated/randomize_layout_hash.h +$(objtree)/$(obj)/randomize_layout_seed.h: FORCE + $(call if_changed,create_randomize_layout_seed) +targets = randomize_layout_seed.h randomize_layout_hash.h + $(HOSTLIBS)-y := $(foreach p,$(GCC_PLUGIN),$(if $(findstring /,$(p)),,$(p))) always := $($(HOSTLIBS)-y) diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h index b232ab15624c..6948898b3cdf 100644 --- a/scripts/gcc-plugins/gcc-common.h +++ b/scripts/gcc-plugins/gcc-common.h @@ -63,6 +63,13 @@ #endif #if BUILDING_GCC_VERSION >= 4006 +/* + * The c-family headers were moved into a subdirectory in GCC version + * 4.7, but most plugin-building users of GCC 4.6 are using the Debian + * or Ubuntu package, which has an out-of-tree patch to move this to the + * same location as found in 4.7 and later: + * https://sources.debian.net/src/gcc-4.6/4.6.3-14/debian/patches/pr45078.diff/ + */ #include "c-family/c-common.h" #else #include "c-common.h" @@ -946,4 +953,9 @@ static inline void debug_gimple_stmt(const_gimple s) get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep) #endif +#if BUILDING_GCC_VERSION < 7000 +#define SET_DECL_ALIGN(decl, align) DECL_ALIGN(decl) = (align) +#define SET_DECL_MODE(decl, mode) DECL_MODE(decl) = (mode) +#endif + #endif diff --git a/scripts/gcc-plugins/gen-random-seed.sh b/scripts/gcc-plugins/gen-random-seed.sh new file mode 100644 index 000000000000..7514850f4815 --- /dev/null +++ b/scripts/gcc-plugins/gen-random-seed.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +if [ ! -f "$1" ]; then + SEED=`od -A n -t x8 -N 32 /dev/urandom | tr -d ' \n'` + echo "const char *randstruct_seed = \"$SEED\";" > "$1" + HASH=`echo -n "$SEED" | sha256sum | cut -d" " -f1 | tr -d ' \n'` + echo "#define RANDSTRUCT_HASHED_SEED \"$HASH\"" > "$2" +fi diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c new file mode 100644 index 000000000000..cdaac8c66734 --- /dev/null +++ b/scripts/gcc-plugins/randomize_layout_plugin.c @@ -0,0 +1,1028 @@ +/* + * Copyright 2014-2016 by Open Source Security, Inc., Brad Spengler <spender@grsecurity.net> + * and PaX Team <pageexec@freemail.hu> + * Licensed under the GPL v2 + * + * Note: the choice of the license means that the compilation process is + * NOT 'eligible' as defined by gcc's library exception to the GPL v3, + * but for the kernel it doesn't matter since it doesn't link against + * any of the gcc libraries + * + * Usage: + * $ # for 4.5/4.6/C based 4.7 + * $ gcc -I`gcc -print-file-name=plugin`/include -I`gcc -print-file-name=plugin`/include/c-family -fPIC -shared -O2 -o randomize_layout_plugin.so randomize_layout_plugin.c + * $ # for C++ based 4.7/4.8+ + * $ g++ -I`g++ -print-file-name=plugin`/include -I`g++ -print-file-name=plugin`/include/c-family -fPIC -shared -O2 -o randomize_layout_plugin.so randomize_layout_plugin.c + * $ gcc -fplugin=./randomize_layout_plugin.so test.c -O2 + */ + +#include "gcc-common.h" +#include "randomize_layout_seed.h" + +#if BUILDING_GCC_MAJOR < 4 || (BUILDING_GCC_MAJOR == 4 && BUILDING_GCC_MINOR < 7) +#error "The RANDSTRUCT plugin requires GCC 4.7 or newer." +#endif + +#define ORIG_TYPE_NAME(node) \ + (TYPE_NAME(TYPE_MAIN_VARIANT(node)) != NULL_TREE ? ((const unsigned char *)IDENTIFIER_POINTER(TYPE_NAME(TYPE_MAIN_VARIANT(node)))) : (const unsigned char *)"anonymous") + +#define INFORM(loc, msg, ...) inform(loc, "randstruct: " msg, ##__VA_ARGS__) +#define MISMATCH(loc, how, ...) INFORM(loc, "casting between randomized structure pointer types (" how "): %qT and %qT\n", __VA_ARGS__) + +__visible int plugin_is_GPL_compatible; + +static int performance_mode; + +static struct plugin_info randomize_layout_plugin_info = { + .version = "201402201816vanilla", + .help = "disable\t\t\tdo not activate plugin\n" + "performance-mode\tenable cacheline-aware layout randomization\n" +}; + +struct whitelist_entry { + const char *pathname; + const char *lhs; + const char *rhs; +}; + +static const struct whitelist_entry whitelist[] = { + /* NIU overloads mapping with page struct */ + { "drivers/net/ethernet/sun/niu.c", "page", "address_space" }, + /* unix_skb_parms via UNIXCB() buffer */ + { "net/unix/af_unix.c", "unix_skb_parms", "char" }, + /* big_key payload.data struct splashing */ + { "security/keys/big_key.c", "path", "void *" }, + /* walk struct security_hook_heads as an array of struct list_head */ + { "security/security.c", "list_head", "security_hook_heads" }, + { } +}; + +/* from old Linux dcache.h */ +static inline unsigned long +partial_name_hash(unsigned long c, unsigned long prevhash) +{ + return (prevhash + (c << 4) + (c >> 4)) * 11; +} +static inline unsigned int +name_hash(const unsigned char *name) +{ + unsigned long hash = 0; + unsigned int len = strlen((const char *)name); + while (len--) + hash = partial_name_hash(*name++, hash); + return (unsigned int)hash; +} + +static tree handle_randomize_layout_attr(tree *node, tree name, tree args, int flags, bool *no_add_attrs) +{ + tree type; + + *no_add_attrs = true; + if (TREE_CODE(*node) == FUNCTION_DECL) { + error("%qE attribute does not apply to functions (%qF)", name, *node); + return NULL_TREE; + } + + if (TREE_CODE(*node) == PARM_DECL) { + error("%qE attribute does not apply to function parameters (%qD)", name, *node); + return NULL_TREE; + } + + if (TREE_CODE(*node) == VAR_DECL) { + error("%qE attribute does not apply to variables (%qD)", name, *node); + return NULL_TREE; + } + + if (TYPE_P(*node)) { + type = *node; + } else { + gcc_assert(TREE_CODE(*node) == TYPE_DECL); + type = TREE_TYPE(*node); + } + + if (TREE_CODE(type) != RECORD_TYPE) { + error("%qE attribute used on %qT applies to struct types only", name, type); + return NULL_TREE; + } + + if (lookup_attribute(IDENTIFIER_POINTER(name), TYPE_ATTRIBUTES(type))) { + error("%qE attribute is already applied to the type %qT", name, type); + return NULL_TREE; + } + + *no_add_attrs = false; + + return NULL_TREE; +} + +/* set on complete types that we don't need to inspect further at all */ +static tree handle_randomize_considered_attr(tree *node, tree name, tree args, int flags, bool *no_add_attrs) +{ + *no_add_attrs = false; + return NULL_TREE; +} + +/* + * set on types that we've performed a shuffle on, to prevent re-shuffling + * this does not preclude us from inspecting its fields for potential shuffles + */ +static tree handle_randomize_performed_attr(tree *node, tree name, tree args, int flags, bool *no_add_attrs) +{ + *no_add_attrs = false; + return NULL_TREE; +} + +/* + * 64bit variant of Bob Jenkins' public domain PRNG + * 256 bits of internal state + */ + +typedef unsigned long long u64; + +typedef struct ranctx { u64 a; u64 b; u64 c; u64 d; } ranctx; + +#define rot(x,k) (((x)<<(k))|((x)>>(64-(k)))) +static u64 ranval(ranctx *x) { + u64 e = x->a - rot(x->b, 7); + x->a = x->b ^ rot(x->c, 13); + x->b = x->c + rot(x->d, 37); + x->c = x->d + e; + x->d = e + x->a; + return x->d; +} + +static void raninit(ranctx *x, u64 *seed) { + int i; + + x->a = seed[0]; + x->b = seed[1]; + x->c = seed[2]; + x->d = seed[3]; + + for (i=0; i < 30; ++i) + (void)ranval(x); +} + +static u64 shuffle_seed[4]; + +struct partition_group { + tree tree_start; + unsigned long start; + unsigned long length; +}; + +static void partition_struct(tree *fields, unsigned long length, struct partition_group *size_groups, unsigned long *num_groups) +{ + unsigned long i; + unsigned long accum_size = 0; + unsigned long accum_length = 0; + unsigned long group_idx = 0; + + gcc_assert(length < INT_MAX); + + memset(size_groups, 0, sizeof(struct partition_group) * length); + + for (i = 0; i < length; i++) { + if (size_groups[group_idx].tree_start == NULL_TREE) { + size_groups[group_idx].tree_start = fields[i]; + size_groups[group_idx].start = i; + accum_length = 0; + accum_size = 0; + } + accum_size += (unsigned long)int_size_in_bytes(TREE_TYPE(fields[i])); + accum_length++; + if (accum_size >= 64) { + size_groups[group_idx].length = accum_length; + accum_length = 0; + group_idx++; + } + } + + if (size_groups[group_idx].tree_start != NULL_TREE && + !size_groups[group_idx].length) { + size_groups[group_idx].length = accum_length; + group_idx++; + } + + *num_groups = group_idx; +} + +static void performance_shuffle(tree *newtree, unsigned long length, ranctx *prng_state) +{ + unsigned long i, x; + struct partition_group size_group[length]; + unsigned long num_groups = 0; + unsigned long randnum; + + partition_struct(newtree, length, (struct partition_group *)&size_group, &num_groups); + for (i = num_groups - 1; i > 0; i--) { + struct partition_group tmp; + randnum = ranval(prng_state) % (i + 1); + tmp = size_group[i]; + size_group[i] = size_group[randnum]; + size_group[randnum] = tmp; + } + + for (x = 0; x < num_groups; x++) { + for (i = size_group[x].start + size_group[x].length - 1; i > size_group[x].start; i--) { + tree tmp; + if (DECL_BIT_FIELD_TYPE(newtree[i])) + continue; + randnum = ranval(prng_state) % (i + 1); + // we could handle this case differently if desired + if (DECL_BIT_FIELD_TYPE(newtree[randnum])) + continue; + tmp = newtree[i]; + newtree[i] = newtree[randnum]; + newtree[randnum] = tmp; + } + } +} + +static void full_shuffle(tree *newtree, unsigned long length, ranctx *prng_state) +{ + unsigned long i, randnum; + + for (i = length - 1; i > 0; i--) { + tree tmp; + randnum = ranval(prng_state) % (i + 1); + tmp = newtree[i]; + newtree[i] = newtree[randnum]; + newtree[randnum] = tmp; + } +} + +/* modern in-place Fisher-Yates shuffle */ +static void shuffle(const_tree type, tree *newtree, unsigned long length) +{ + unsigned long i; + u64 seed[4]; + ranctx prng_state; + const unsigned char *structname; + + if (length == 0) + return; + + gcc_assert(TREE_CODE(type) == RECORD_TYPE); + + structname = ORIG_TYPE_NAME(type); + +#ifdef __DEBUG_PLUGIN + fprintf(stderr, "Shuffling struct %s %p\n", (const char *)structname, type); +#ifdef __DEBUG_VERBOSE + debug_tree((tree)type); +#endif +#endif + + for (i = 0; i < 4; i++) { + seed[i] = shuffle_seed[i]; + seed[i] ^= name_hash(structname); + } + + raninit(&prng_state, (u64 *)&seed); + + if (performance_mode) + performance_shuffle(newtree, length, &prng_state); + else + full_shuffle(newtree, length, &prng_state); +} + +static bool is_flexible_array(const_tree field) +{ + const_tree fieldtype; + const_tree typesize; + const_tree elemtype; + const_tree elemsize; + + fieldtype = TREE_TYPE(field); + typesize = TYPE_SIZE(fieldtype); + + if (TREE_CODE(fieldtype) != ARRAY_TYPE) + return false; + + elemtype = TREE_TYPE(fieldtype); + elemsize = TYPE_SIZE(elemtype); + + /* size of type is represented in bits */ + + if (typesize == NULL_TREE && TYPE_DOMAIN(fieldtype) != NULL_TREE && + TYPE_MAX_VALUE(TYPE_DOMAIN(fieldtype)) == NULL_TREE) + return true; + + if (typesize != NULL_TREE && + (TREE_CONSTANT(typesize) && (!tree_to_uhwi(typesize) || + tree_to_uhwi(typesize) == tree_to_uhwi(elemsize)))) + return true; + + return false; +} + +static int relayout_struct(tree type) +{ + unsigned long num_fields = (unsigned long)list_length(TYPE_FIELDS(type)); + unsigned long shuffle_length = num_fields; + tree field; + tree newtree[num_fields]; + unsigned long i; + tree list; + tree variant; + tree main_variant; + expanded_location xloc; + bool has_flexarray = false; + + if (TYPE_FIELDS(type) == NULL_TREE) + return 0; + + if (num_fields < 2) + return 0; + + gcc_assert(TREE_CODE(type) == RECORD_TYPE); + + gcc_assert(num_fields < INT_MAX); + + if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(type)) || + lookup_attribute("no_randomize_layout", TYPE_ATTRIBUTES(TYPE_MAIN_VARIANT(type)))) + return 0; + + /* Workaround for 3rd-party VirtualBox source that we can't modify ourselves */ + if (!strcmp((const char *)ORIG_TYPE_NAME(type), "INTNETTRUNKFACTORY") || + !strcmp((const char *)ORIG_TYPE_NAME(type), "RAWPCIFACTORY")) + return 0; + + /* throw out any structs in uapi */ + xloc = expand_location(DECL_SOURCE_LOCATION(TYPE_FIELDS(type))); + + if (strstr(xloc.file, "/uapi/")) + error(G_("attempted to randomize userland API struct %s"), ORIG_TYPE_NAME(type)); + + for (field = TYPE_FIELDS(type), i = 0; field; field = TREE_CHAIN(field), i++) { + gcc_assert(TREE_CODE(field) == FIELD_DECL); + newtree[i] = field; + } + + /* + * enforce that we don't randomize the layout of the last + * element of a struct if it's a 0 or 1-length array + * or a proper flexible array + */ + if (is_flexible_array(newtree[num_fields - 1])) { + has_flexarray = true; + shuffle_length--; + } + + shuffle(type, (tree *)newtree, shuffle_length); + + /* + * set up a bogus anonymous struct field designed to error out on unnamed struct initializers + * as gcc provides no other way to detect such code + */ + list = make_node(FIELD_DECL); + TREE_CHAIN(list) = newtree[0]; + TREE_TYPE(list) = void_type_node; + DECL_SIZE(list) = bitsize_zero_node; + DECL_NONADDRESSABLE_P(list) = 1; + DECL_FIELD_BIT_OFFSET(list) = bitsize_zero_node; + DECL_SIZE_UNIT(list) = size_zero_node; + DECL_FIELD_OFFSET(list) = size_zero_node; + DECL_CONTEXT(list) = type; + // to satisfy the constify plugin + TREE_READONLY(list) = 1; + + for (i = 0; i < num_fields - 1; i++) + TREE_CHAIN(newtree[i]) = newtree[i+1]; + TREE_CHAIN(newtree[num_fields - 1]) = NULL_TREE; + + main_variant = TYPE_MAIN_VARIANT(type); + for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant)) { + TYPE_FIELDS(variant) = list; + TYPE_ATTRIBUTES(variant) = copy_list(TYPE_ATTRIBUTES(variant)); + TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("randomize_performed"), NULL_TREE, TYPE_ATTRIBUTES(variant)); + TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("designated_init"), NULL_TREE, TYPE_ATTRIBUTES(variant)); + if (has_flexarray) + TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("has_flexarray"), NULL_TREE, TYPE_ATTRIBUTES(type)); + } + + /* + * force a re-layout of the main variant + * the TYPE_SIZE for all variants will be recomputed + * by finalize_type_size() + */ + TYPE_SIZE(main_variant) = NULL_TREE; + layout_type(main_variant); + gcc_assert(TYPE_SIZE(main_variant) != NULL_TREE); + + return 1; +} + +/* from constify plugin */ +static const_tree get_field_type(const_tree field) +{ + return strip_array_types(TREE_TYPE(field)); +} + +/* from constify plugin */ +static bool is_fptr(const_tree fieldtype) +{ + if (TREE_CODE(fieldtype) != POINTER_TYPE) + return false; + + return TREE_CODE(TREE_TYPE(fieldtype)) == FUNCTION_TYPE; +} + +/* derived from constify plugin */ +static int is_pure_ops_struct(const_tree node) +{ + const_tree field; + + gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE); + + /* XXX: Do not apply randomization to all-ftpr structs yet. */ + return 0; + + for (field = TYPE_FIELDS(node); field; field = TREE_CHAIN(field)) { + const_tree fieldtype = get_field_type(field); + enum tree_code code = TREE_CODE(fieldtype); + + if (node == fieldtype) + continue; + + if (!is_fptr(fieldtype)) + return 0; + + if (code != RECORD_TYPE && code != UNION_TYPE) + continue; + + if (!is_pure_ops_struct(fieldtype)) + return 0; + } + + return 1; +} + +static void randomize_type(tree type) +{ + tree variant; + + gcc_assert(TREE_CODE(type) == RECORD_TYPE); + + if (lookup_attribute("randomize_considered", TYPE_ATTRIBUTES(type))) + return; + + if (lookup_attribute("randomize_layout", TYPE_ATTRIBUTES(TYPE_MAIN_VARIANT(type))) || is_pure_ops_struct(type)) + relayout_struct(type); + + for (variant = TYPE_MAIN_VARIANT(type); variant; variant = TYPE_NEXT_VARIANT(variant)) { + TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type)); + TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("randomize_considered"), NULL_TREE, TYPE_ATTRIBUTES(type)); + } +#ifdef __DEBUG_PLUGIN + fprintf(stderr, "Marking randomize_considered on struct %s\n", ORIG_TYPE_NAME(type)); +#ifdef __DEBUG_VERBOSE + debug_tree(type); +#endif +#endif +} + +static void update_decl_size(tree decl) +{ + tree lastval, lastidx, field, init, type, flexsize; + unsigned HOST_WIDE_INT len; + + type = TREE_TYPE(decl); + + if (!lookup_attribute("has_flexarray", TYPE_ATTRIBUTES(type))) + return; + + init = DECL_INITIAL(decl); + if (init == NULL_TREE || init == error_mark_node) + return; + + if (TREE_CODE(init) != CONSTRUCTOR) + return; + + len = CONSTRUCTOR_NELTS(init); + if (!len) + return; + + lastval = CONSTRUCTOR_ELT(init, CONSTRUCTOR_NELTS(init) - 1)->value; + lastidx = CONSTRUCTOR_ELT(init, CONSTRUCTOR_NELTS(init) - 1)->index; + + for (field = TYPE_FIELDS(TREE_TYPE(decl)); TREE_CHAIN(field); field = TREE_CHAIN(field)) + ; + + if (lastidx != field) + return; + + if (TREE_CODE(lastval) != STRING_CST) { + error("Only string constants are supported as initializers " + "for randomized structures with flexible arrays"); + return; + } + + flexsize = bitsize_int(TREE_STRING_LENGTH(lastval) * + tree_to_uhwi(TYPE_SIZE(TREE_TYPE(TREE_TYPE(lastval))))); + + DECL_SIZE(decl) = size_binop(PLUS_EXPR, TYPE_SIZE(type), flexsize); + + return; +} + + +static void randomize_layout_finish_decl(void *event_data, void *data) +{ + tree decl = (tree)event_data; + tree type; + + if (decl == NULL_TREE || decl == error_mark_node) + return; + + type = TREE_TYPE(decl); + + if (TREE_CODE(decl) != VAR_DECL) + return; + + if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE) + return; + + if (!lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(type))) + return; + + DECL_SIZE(decl) = 0; + DECL_SIZE_UNIT(decl) = 0; + SET_DECL_ALIGN(decl, 0); + SET_DECL_MODE (decl, VOIDmode); + SET_DECL_RTL(decl, 0); + update_decl_size(decl); + layout_decl(decl, 0); +} + +static void finish_type(void *event_data, void *data) +{ + tree type = (tree)event_data; + + if (type == NULL_TREE || type == error_mark_node) + return; + + if (TREE_CODE(type) != RECORD_TYPE) + return; + + if (TYPE_FIELDS(type) == NULL_TREE) + return; + + if (lookup_attribute("randomize_considered", TYPE_ATTRIBUTES(type))) + return; + +#ifdef __DEBUG_PLUGIN + fprintf(stderr, "Calling randomize_type on %s\n", ORIG_TYPE_NAME(type)); +#endif +#ifdef __DEBUG_VERBOSE + debug_tree(type); +#endif + randomize_type(type); + + return; +} + +static struct attribute_spec randomize_layout_attr = { + .name = "randomize_layout", + // related to args + .min_length = 0, + .max_length = 0, + .decl_required = false, + // need type declaration + .type_required = true, + .function_type_required = false, + .handler = handle_randomize_layout_attr, +#if BUILDING_GCC_VERSION >= 4007 + .affects_type_identity = true +#endif +}; + +static struct attribute_spec no_randomize_layout_attr = { + .name = "no_randomize_layout", + // related to args + .min_length = 0, + .max_length = 0, + .decl_required = false, + // need type declaration + .type_required = true, + .function_type_required = false, + .handler = handle_randomize_layout_attr, +#if BUILDING_GCC_VERSION >= 4007 + .affects_type_identity = true +#endif +}; + +static struct attribute_spec randomize_considered_attr = { + .name = "randomize_considered", + // related to args + .min_length = 0, + .max_length = 0, + .decl_required = false, + // need type declaration + .type_required = true, + .function_type_required = false, + .handler = handle_randomize_considered_attr, +#if BUILDING_GCC_VERSION >= 4007 + .affects_type_identity = false +#endif +}; + +static struct attribute_spec randomize_performed_attr = { + .name = "randomize_performed", + // related to args + .min_length = 0, + .max_length = 0, + .decl_required = false, + // need type declaration + .type_required = true, + .function_type_required = false, + .handler = handle_randomize_performed_attr, +#if BUILDING_GCC_VERSION >= 4007 + .affects_type_identity = false +#endif +}; + +static void register_attributes(void *event_data, void *data) +{ + register_attribute(&randomize_layout_attr); + register_attribute(&no_randomize_layout_attr); + register_attribute(&randomize_considered_attr); + register_attribute(&randomize_performed_attr); +} + +static void check_bad_casts_in_constructor(tree var, tree init) +{ + unsigned HOST_WIDE_INT idx; + tree field, val; + tree field_type, val_type; + + FOR_EACH_CONSTRUCTOR_ELT(CONSTRUCTOR_ELTS(init), idx, field, val) { + if (TREE_CODE(val) == CONSTRUCTOR) { + check_bad_casts_in_constructor(var, val); + continue; + } + + /* pipacs' plugin creates franken-arrays that differ from those produced by + normal code which all have valid 'field' trees. work around this */ + if (field == NULL_TREE) + continue; + field_type = TREE_TYPE(field); + val_type = TREE_TYPE(val); + + if (TREE_CODE(field_type) != POINTER_TYPE || TREE_CODE(val_type) != POINTER_TYPE) + continue; + + if (field_type == val_type) + continue; + + field_type = TYPE_MAIN_VARIANT(strip_array_types(TYPE_MAIN_VARIANT(TREE_TYPE(field_type)))); + val_type = TYPE_MAIN_VARIANT(strip_array_types(TYPE_MAIN_VARIANT(TREE_TYPE(val_type)))); + + if (field_type == void_type_node) + continue; + if (field_type == val_type) + continue; + if (TREE_CODE(val_type) != RECORD_TYPE) + continue; + + if (!lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(val_type))) + continue; + MISMATCH(DECL_SOURCE_LOCATION(var), "constructor\n", TYPE_MAIN_VARIANT(field_type), TYPE_MAIN_VARIANT(val_type)); + } +} + +/* derived from the constify plugin */ +static void check_global_variables(void *event_data, void *data) +{ + struct varpool_node *node; + tree init; + + FOR_EACH_VARIABLE(node) { + tree var = NODE_DECL(node); + init = DECL_INITIAL(var); + if (init == NULL_TREE) + continue; + + if (TREE_CODE(init) != CONSTRUCTOR) + continue; + + check_bad_casts_in_constructor(var, init); + } +} + +static bool dominated_by_is_err(const_tree rhs, basic_block bb) +{ + basic_block dom; + gimple dom_stmt; + gimple call_stmt; + const_tree dom_lhs; + const_tree poss_is_err_cond; + const_tree poss_is_err_func; + const_tree is_err_arg; + + dom = get_immediate_dominator(CDI_DOMINATORS, bb); + if (!dom) + return false; + + dom_stmt = last_stmt(dom); + if (!dom_stmt) + return false; + + if (gimple_code(dom_stmt) != GIMPLE_COND) + return false; + + if (gimple_cond_code(dom_stmt) != NE_EXPR) + return false; + + if (!integer_zerop(gimple_cond_rhs(dom_stmt))) + return false; + + poss_is_err_cond = gimple_cond_lhs(dom_stmt); + + if (TREE_CODE(poss_is_err_cond) != SSA_NAME) + return false; + + call_stmt = SSA_NAME_DEF_STMT(poss_is_err_cond); + + if (gimple_code(call_stmt) != GIMPLE_CALL) + return false; + + dom_lhs = gimple_get_lhs(call_stmt); + poss_is_err_func = gimple_call_fndecl(call_stmt); + if (!poss_is_err_func) + return false; + if (dom_lhs != poss_is_err_cond) + return false; + if (strcmp(DECL_NAME_POINTER(poss_is_err_func), "IS_ERR")) + return false; + + is_err_arg = gimple_call_arg(call_stmt, 0); + if (!is_err_arg) + return false; + + if (is_err_arg != rhs) + return false; + + return true; +} + +static void handle_local_var_initializers(void) +{ + tree var; + unsigned int i; + + FOR_EACH_LOCAL_DECL(cfun, i, var) { + tree init = DECL_INITIAL(var); + if (!init) + continue; + if (TREE_CODE(init) != CONSTRUCTOR) + continue; + check_bad_casts_in_constructor(var, init); + } +} + +static bool type_name_eq(gimple stmt, const_tree type_tree, const char *wanted_name) +{ + const char *type_name; + + if (type_tree == NULL_TREE) + return false; + + switch (TREE_CODE(type_tree)) { + case RECORD_TYPE: + type_name = TYPE_NAME_POINTER(type_tree); + break; + case INTEGER_TYPE: + if (TYPE_PRECISION(type_tree) == CHAR_TYPE_SIZE) + type_name = "char"; + else { + INFORM(gimple_location(stmt), "found non-char INTEGER_TYPE cast comparison: %qT\n", type_tree); + debug_tree(type_tree); + return false; + } + break; + case POINTER_TYPE: + if (TREE_CODE(TREE_TYPE(type_tree)) == VOID_TYPE) { + type_name = "void *"; + break; + } else { + INFORM(gimple_location(stmt), "found non-void POINTER_TYPE cast comparison %qT\n", type_tree); + debug_tree(type_tree); + return false; + } + default: + INFORM(gimple_location(stmt), "unhandled cast comparison: %qT\n", type_tree); + debug_tree(type_tree); + return false; + } + + return strcmp(type_name, wanted_name) == 0; +} + +static bool whitelisted_cast(gimple stmt, const_tree lhs_tree, const_tree rhs_tree) +{ + const struct whitelist_entry *entry; + expanded_location xloc = expand_location(gimple_location(stmt)); + + for (entry = whitelist; entry->pathname; entry++) { + if (!strstr(xloc.file, entry->pathname)) + continue; + + if (type_name_eq(stmt, lhs_tree, entry->lhs) && type_name_eq(stmt, rhs_tree, entry->rhs)) + return true; + } + + return false; +} + +/* + * iterate over all statements to find "bad" casts: + * those where the address of the start of a structure is cast + * to a pointer of a structure of a different type, or a + * structure pointer type is cast to a different structure pointer type + */ +static unsigned int find_bad_casts_execute(void) +{ + basic_block bb; + + handle_local_var_initializers(); + + FOR_EACH_BB_FN(bb, cfun) { + gimple_stmt_iterator gsi; + + for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) { + gimple stmt; + const_tree lhs; + const_tree lhs_type; + const_tree rhs1; + const_tree rhs_type; + const_tree ptr_lhs_type; + const_tree ptr_rhs_type; + const_tree op0; + const_tree op0_type; + enum tree_code rhs_code; + + stmt = gsi_stmt(gsi); + +#ifdef __DEBUG_PLUGIN +#ifdef __DEBUG_VERBOSE + debug_gimple_stmt(stmt); + debug_tree(gimple_get_lhs(stmt)); +#endif +#endif + + if (gimple_code(stmt) != GIMPLE_ASSIGN) + continue; + +#ifdef __DEBUG_PLUGIN +#ifdef __DEBUG_VERBOSE + debug_tree(gimple_assign_rhs1(stmt)); +#endif +#endif + + + rhs_code = gimple_assign_rhs_code(stmt); + + if (rhs_code != ADDR_EXPR && rhs_code != SSA_NAME) + continue; + + lhs = gimple_get_lhs(stmt); + lhs_type = TREE_TYPE(lhs); + rhs1 = gimple_assign_rhs1(stmt); + rhs_type = TREE_TYPE(rhs1); + + if (TREE_CODE(rhs_type) != POINTER_TYPE || + TREE_CODE(lhs_type) != POINTER_TYPE) + continue; + + ptr_lhs_type = TYPE_MAIN_VARIANT(strip_array_types(TYPE_MAIN_VARIANT(TREE_TYPE(lhs_type)))); + ptr_rhs_type = TYPE_MAIN_VARIANT(strip_array_types(TYPE_MAIN_VARIANT(TREE_TYPE(rhs_type)))); + + if (ptr_rhs_type == void_type_node) + continue; + + if (ptr_lhs_type == void_type_node) + continue; + + if (dominated_by_is_err(rhs1, bb)) + continue; + + if (TREE_CODE(ptr_rhs_type) != RECORD_TYPE) { +#ifndef __DEBUG_PLUGIN + if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(ptr_lhs_type))) +#endif + { + if (!whitelisted_cast(stmt, ptr_lhs_type, ptr_rhs_type)) + MISMATCH(gimple_location(stmt), "rhs", ptr_lhs_type, ptr_rhs_type); + } + continue; + } + + if (rhs_code == SSA_NAME && ptr_lhs_type == ptr_rhs_type) + continue; + + if (rhs_code == ADDR_EXPR) { + op0 = TREE_OPERAND(rhs1, 0); + + if (op0 == NULL_TREE) + continue; + + if (TREE_CODE(op0) != VAR_DECL) + continue; + + op0_type = TYPE_MAIN_VARIANT(strip_array_types(TYPE_MAIN_VARIANT(TREE_TYPE(op0)))); + if (op0_type == ptr_lhs_type) + continue; + +#ifndef __DEBUG_PLUGIN + if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(op0_type))) +#endif + { + if (!whitelisted_cast(stmt, ptr_lhs_type, op0_type)) + MISMATCH(gimple_location(stmt), "op0", ptr_lhs_type, op0_type); + } + } else { + const_tree ssa_name_var = SSA_NAME_VAR(rhs1); + /* skip bogus type casts introduced by container_of */ + if (ssa_name_var != NULL_TREE && DECL_NAME(ssa_name_var) && + !strcmp((const char *)DECL_NAME_POINTER(ssa_name_var), "__mptr")) + continue; +#ifndef __DEBUG_PLUGIN + if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(ptr_rhs_type))) +#endif + { + if (!whitelisted_cast(stmt, ptr_lhs_type, ptr_rhs_type)) + MISMATCH(gimple_location(stmt), "ssa", ptr_lhs_type, ptr_rhs_type); + } + } + + } + } + return 0; +} + +#define PASS_NAME find_bad_casts +#define NO_GATE +#define TODO_FLAGS_FINISH TODO_dump_func +#include "gcc-generate-gimple-pass.h" + +__visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) +{ + int i; + const char * const plugin_name = plugin_info->base_name; + const int argc = plugin_info->argc; + const struct plugin_argument * const argv = plugin_info->argv; + bool enable = true; + int obtained_seed = 0; + struct register_pass_info find_bad_casts_pass_info; + + find_bad_casts_pass_info.pass = make_find_bad_casts_pass(); + find_bad_casts_pass_info.reference_pass_name = "ssa"; + find_bad_casts_pass_info.ref_pass_instance_number = 1; + find_bad_casts_pass_info.pos_op = PASS_POS_INSERT_AFTER; + + if (!plugin_default_version_check(version, &gcc_version)) { + error(G_("incompatible gcc/plugin versions")); + return 1; + } + + if (strncmp(lang_hooks.name, "GNU C", 5) && !strncmp(lang_hooks.name, "GNU C+", 6)) { + inform(UNKNOWN_LOCATION, G_("%s supports C only, not %s"), plugin_name, lang_hooks.name); + enable = false; + } + + for (i = 0; i < argc; ++i) { + if (!strcmp(argv[i].key, "disable")) { + enable = false; + continue; + } + if (!strcmp(argv[i].key, "performance-mode")) { + performance_mode = 1; + continue; + } + error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); + } + + if (strlen(randstruct_seed) != 64) { + error(G_("invalid seed value supplied for %s plugin"), plugin_name); + return 1; + } + obtained_seed = sscanf(randstruct_seed, "%016llx%016llx%016llx%016llx", + &shuffle_seed[0], &shuffle_seed[1], &shuffle_seed[2], &shuffle_seed[3]); + if (obtained_seed != 4) { + error(G_("Invalid seed supplied for %s plugin"), plugin_name); + return 1; + } + + register_callback(plugin_name, PLUGIN_INFO, NULL, &randomize_layout_plugin_info); + if (enable) { + register_callback(plugin_name, PLUGIN_ALL_IPA_PASSES_START, check_global_variables, NULL); + register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &find_bad_casts_pass_info); + register_callback(plugin_name, PLUGIN_FINISH_TYPE, finish_type, NULL); + register_callback(plugin_name, PLUGIN_FINISH_DECL, randomize_layout_finish_decl, NULL); + } + register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL); + + return 0; +} diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py index f9b92ece7834..5afd1098e33a 100644 --- a/scripts/gdb/linux/dmesg.py +++ b/scripts/gdb/linux/dmesg.py @@ -23,10 +23,11 @@ class LxDmesg(gdb.Command): super(LxDmesg, self).__init__("lx-dmesg", gdb.COMMAND_DATA) def invoke(self, arg, from_tty): - log_buf_addr = int(str(gdb.parse_and_eval("log_buf")).split()[0], 16) - log_first_idx = int(gdb.parse_and_eval("log_first_idx")) - log_next_idx = int(gdb.parse_and_eval("log_next_idx")) - log_buf_len = int(gdb.parse_and_eval("log_buf_len")) + log_buf_addr = int(str(gdb.parse_and_eval( + "'printk.c'::log_buf")).split()[0], 16) + log_first_idx = int(gdb.parse_and_eval("'printk.c'::log_first_idx")) + log_next_idx = int(gdb.parse_and_eval("'printk.c'::log_next_idx")) + log_buf_len = int(gdb.parse_and_eval("'printk.c'::log_buf_len")) inf = gdb.inferiors()[0] start = log_buf_addr + log_first_idx diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh index 0055b07b03b6..86a3c0e5cfbc 100755 --- a/scripts/gen_initramfs_list.sh +++ b/scripts/gen_initramfs_list.sh @@ -174,7 +174,7 @@ dir_filelist() { ${dep_list}header "$1" srcdir=$(echo "$1" | sed -e 's://*:/:g') - dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n") + dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" | sort) # If $dirlist is only one line, then the directory is empty if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then @@ -271,10 +271,12 @@ while [ $# -gt 0 ]; do case "$arg" in "-u") # map $1 to uid=0 (root) root_uid="$1" + [ "$root_uid" = "-1" ] && root_uid=$(id -u || echo 0) shift ;; "-g") # map $1 to gid=0 (root) root_gid="$1" + [ "$root_gid" = "-1" ] && root_gid=$(id -g || echo 0) shift ;; "-d") # display default initramfs list diff --git a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h index 3bffdcaaa274..b724a0290c75 100644 --- a/scripts/genksyms/genksyms.h +++ b/scripts/genksyms/genksyms.h @@ -75,7 +75,7 @@ struct string_list *copy_list_range(struct string_list *start, int yylex(void); int yyparse(void); -void error_with_pos(const char *, ...); +void error_with_pos(const char *, ...) __attribute__ ((format(printf, 1, 2))); /*----------------------------------------------------------------------*/ #define xmalloc(size) ({ void *__ptr = malloc(size); \ diff --git a/scripts/get_dvb_firmware b/scripts/get_dvb_firmware index 1a0a04125f71..f3f230225aba 100755 --- a/scripts/get_dvb_firmware +++ b/scripts/get_dvb_firmware @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # DVB firmware extractor # # (c) 2004 Andrew de Quincey diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 633f2dd3de27..3bd5f4f30235 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # (c) 2007, Joe Perches <joe@perches.com> # created from checkpatch.pl # @@ -10,6 +10,7 @@ # # Licensed under the terms of the GNU GPL License version 2 +use warnings; use strict; my $P = $0; diff --git a/scripts/headerdep.pl b/scripts/headerdep.pl index 8dd019bc5a73..86ebb9ee7570 100755 --- a/scripts/headerdep.pl +++ b/scripts/headerdep.pl @@ -1,4 +1,4 @@ -#! /usr/bin/perl +#! /usr/bin/env perl # # Detect cycles in the header file dependency graph # Vegard Nossum <vegardno@ifi.uio.no> diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl index 8b2da054cdc3..3091e4ee6ee1 100755 --- a/scripts/headers_check.pl +++ b/scripts/headers_check.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # # headers_check.pl execute a number of trivial consistency checks # @@ -18,6 +18,7 @@ # # 3) Check for leaked CONFIG_ symbols +use warnings; use strict; use File::Basename; diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 90a091b6ae4d..eb8144643b78 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -196,7 +196,7 @@ clean-files += config.pot linux.pot # Check that we have the required ncurses stuff installed for lxdialog (menuconfig) PHONY += $(obj)/dochecklxdialog -$(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog +$(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/dochecklxdialog $(obj)/dochecklxdialog: $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTLOADLIBES_mconf) diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index a9bc5334a478..003114779815 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -271,7 +271,7 @@ static struct mitem k_menu_items[MAX_MENU_ITEMS]; static int items_num; static int global_exit; /* the currently selected button */ -const char *current_instructions = menu_instructions; +static const char *current_instructions = menu_instructions; static char *dialog_input_result; static int dialog_input_result_len; @@ -305,7 +305,7 @@ struct function_keys { }; static const int function_keys_num = 9; -struct function_keys function_keys[] = { +static struct function_keys function_keys[] = { { .key_str = "F1", .func = "Help", @@ -508,7 +508,7 @@ static int get_mext_match(const char *match_str, match_f flag) index = (index + items_num) % items_num; while (true) { char *str = k_menu_items[index].str; - if (strcasestr(str, match_str) != 0) + if (strcasestr(str, match_str) != NULL) return index; if (flag == FIND_NEXT_MATCH_UP || flag == MATCH_TINKER_PATTERN_UP) @@ -1067,7 +1067,7 @@ static int do_match(int key, struct match_state *state, int *ans) static void conf(struct menu *menu) { - struct menu *submenu = 0; + struct menu *submenu = NULL; const char *prompt = menu_get_prompt(menu); struct symbol *sym; int res; @@ -1234,7 +1234,7 @@ static void show_help(struct menu *menu) static void conf_choice(struct menu *menu) { const char *prompt = _(menu_get_prompt(menu)); - struct menu *child = 0; + struct menu *child = NULL; struct symbol *active; int selected_index = 0; int last_top_row = 0; @@ -1456,7 +1456,7 @@ static void conf_save(void) } } -void setup_windows(void) +static void setup_windows(void) { int lines, columns; diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index 4b2f44c20caf..a64b1c31253e 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -129,7 +129,7 @@ static void no_colors_theme(void) mkattrn(FUNCTION_TEXT, A_REVERSE); } -void set_colors() +void set_colors(void) { start_color(); use_default_colors(); @@ -192,7 +192,7 @@ const char *get_line(const char *text, int line_no) int lines = 0; if (!text) - return 0; + return NULL; for (i = 0; text[i] != '\0' && lines < line_no; i++) if (text[i] == '\n') diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index b8c7b29affc5..a2e83ab17de3 100755 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # # Copyright 2005-2009 - Steven Rostedt # Licensed under the terms of the GNU GPL License version 2 @@ -42,6 +42,7 @@ # mv config_strip .config # make oldconfig # +use warnings; use strict; use Getopt::Long; diff --git a/scripts/kernel-doc b/scripts/kernel-doc index a26a5f2dce39..6e36b7889001 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1,5 +1,6 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl +use warnings; use strict; ## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ## @@ -2189,6 +2190,8 @@ sub dump_struct($$) { $members =~ s/\s*CRYPTO_MINALIGN_ATTR//gos; # replace DECLARE_BITMAP $members =~ s/DECLARE_BITMAP\s*\(([^,)]+), ([^,)]+)\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos; + # replace DECLARE_HASHTABLE + $members =~ s/DECLARE_HASHTABLE\s*\(([^,)]+), ([^,)]+)\)/unsigned long $1\[1 << (($2) - 1)\]/gos; create_parameterlist($members, ';', $file); check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested); diff --git a/scripts/kernel-doc-xml-ref b/scripts/kernel-doc-xml-ref deleted file mode 100755 index 104a5a5ba2c8..000000000000 --- a/scripts/kernel-doc-xml-ref +++ /dev/null @@ -1,198 +0,0 @@ -#!/usr/bin/perl -w - -use strict; - -## Copyright (C) 2015 Intel Corporation ## -# ## -## This software falls under the GNU General Public License. ## -## Please read the COPYING file for more information ## -# -# -# This software reads a XML file and a list of valid interal -# references to replace Docbook tags with links. -# -# The list of "valid internal references" must be one-per-line in the following format: -# API-struct-foo -# API-enum-bar -# API-my-function -# -# The software walks over the XML file looking for xml tags representing possible references -# to the Document. Each reference will be cross checked against the "Valid Internal Reference" list. If -# the referece is found it replaces its content by a <link> tag. -# -# usage: -# kernel-doc-xml-ref -db filename -# xml filename > outputfile - -# read arguments -if ($#ARGV != 2) { - usage(); -} - -#Holds the database filename -my $databasefile; -my @database; - -#holds the inputfile -my $inputfile; -my $errors = 0; - -my %highlights = ( - "<function>(.*?)</function>", - "\"<function>\" . convert_function(\$1, \$line) . \"</function>\"", - "<structname>(.*?)</structname>", - "\"<structname>\" . convert_struct(\$1) . \"</structname>\"", - "<funcdef>(.*?)<function>(.*?)</function></funcdef>", - "\"<funcdef>\" . convert_param(\$1) . \"<function>\$2</function></funcdef>\"", - "<paramdef>(.*?)<parameter>(.*?)</parameter></paramdef>", - "\"<paramdef>\" . convert_param(\$1) . \"<parameter>\$2</parameter></paramdef>\""); - -while($ARGV[0] =~ m/^-(.*)/) { - my $cmd = shift @ARGV; - if ($cmd eq "-db") { - $databasefile = shift @ARGV - } else { - usage(); - } -} -$inputfile = shift @ARGV; - -sub open_database { - open (my $handle, '<', $databasefile) or die "Cannot open $databasefile"; - chomp(my @lines = <$handle>); - close $handle; - - @database = @lines; -} - -sub process_file { - open_database(); - - my $dohighlight; - foreach my $pattern (keys %highlights) { - $dohighlight .= "\$line =~ s:$pattern:$highlights{$pattern}:eg;\n"; - } - - open(FILE, $inputfile) or die("Could not open $inputfile") or die ("Cannot open $inputfile"); - foreach my $line (<FILE>) { - eval $dohighlight; - print $line; - } -} - -sub trim($_) -{ - my $str = $_[0]; - $str =~ s/^\s+|\s+$//g; - return $str -} - -sub has_key_defined($_) -{ - if ( grep( /^$_[0]$/, @database)) { - return 1; - } - return 0; -} - -# Gets a <function> content and add it a hyperlink if possible. -sub convert_function($_) -{ - my $arg = $_[0]; - my $key = $_[0]; - - my $line = $_[1]; - - $key = trim($key); - - $key =~ s/[^A-Za-z0-9]/-/g; - $key = "API-" . $key; - - # We shouldn't add links to <funcdef> prototype - if (!has_key_defined($key) || $line =~ m/\s+<funcdef/i) { - return $arg; - } - - my $head = $arg; - my $tail = ""; - if ($arg =~ /(.*?)( ?)$/) { - $head = $1; - $tail = $2; - } - return "<link linkend=\"$key\">$head</link>$tail"; -} - -# Converting a struct text to link -sub convert_struct($_) -{ - my $arg = $_[0]; - my $key = $_[0]; - $key =~ s/(struct )?(\w)/$2/g; - $key =~ s/[^A-Za-z0-9]/-/g; - $key = "API-struct-" . $key; - - if (!has_key_defined($key)) { - return $arg; - } - - my ($head, $tail) = split_pointer($arg); - return "<link linkend=\"$key\">$head</link>$tail"; -} - -# Identify "object *" elements -sub split_pointer($_) -{ - my $arg = $_[0]; - if ($arg =~ /(.*?)( ?\* ?)/) { - return ($1, $2); - } - return ($arg, ""); -} - -sub convert_param($_) -{ - my $type = $_[0]; - my $keyname = convert_key_name($type); - - if (!has_key_defined($keyname)) { - return $type; - } - - my ($head, $tail) = split_pointer($type); - return "<link linkend=\"$keyname\">$head</link>$tail"; - -} - -# DocBook links are in the API-<TYPE>-<STRUCT-NAME> format -# This method gets an element and returns a valid DocBook reference for it. -sub convert_key_name($_) -{ - #Pattern $2 is optional and might be uninitialized - no warnings 'uninitialized'; - - my $str = $_[0]; - $str =~ s/(const|static)? ?(struct)? ?([a-zA-Z0-9_]+) ?(\*|&)?/$2 $3/g ; - - # trim - $str =~ s/^\s+|\s+$//g; - - # spaces and _ to - - $str =~ s/[^A-Za-z0-9]/-/g; - - return "API-" . $str; -} - -sub usage { - print "Usage: $0 -db database filename\n"; - print " xml source file(s) > outputfile\n"; - exit 1; -} - -# starting point -process_file(); - -if ($errors) { - print STDERR "$errors errors\n"; -} - -exit($errors); diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index c80291319cb2..e7b7eee31538 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -3,9 +3,12 @@ # link vmlinux # # vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_INIT) and -# $(KBUILD_VMLINUX_MAIN). Most are built-in.o files from top-level directories -# in the kernel tree, others are specified in arch/$(ARCH)/Makefile. -# Ordering when linking is important, and $(KBUILD_VMLINUX_INIT) must be first. +# $(KBUILD_VMLINUX_MAIN) and $(KBUILD_VMLINUX_LIBS). Most are built-in.o files +# from top-level directories in the kernel tree, others are specified in +# arch/$(ARCH)/Makefile. Ordering when linking is important, and +# $(KBUILD_VMLINUX_INIT) must be first. $(KBUILD_VMLINUX_LIBS) are archives +# which are linked conditionally (not within --whole-archive), and do not +# require symbol indexes added. # # vmlinux # ^ @@ -16,6 +19,9 @@ # +--< $(KBUILD_VMLINUX_MAIN) # | +--< drivers/built-in.o mm/built-in.o + more # | +# +--< $(KBUILD_VMLINUX_LIBS) +# | +--< lib/lib.a + more +# | # +-< ${kallsymso} (see description in KALLSYMS section) # # vmlinux version (uname -v) cannot be updated during normal @@ -37,9 +43,10 @@ info() fi } -# Thin archive build here makes a final archive with -# symbol table and indexes from vmlinux objects, which can be -# used as input to linker. +# Thin archive build here makes a final archive with symbol table and indexes +# from vmlinux objects INIT and MAIN, which can be used as input to linker. +# KBUILD_VMLINUX_LIBS archives should already have symbol table and indexes +# added. # # Traditional incremental style of link does not require this step # @@ -50,7 +57,7 @@ archive_builtin() if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then info AR built-in.o rm -f built-in.o; - ${AR} rcsT${KBUILD_ARFLAGS} built-in.o \ + ${AR} rcsTP${KBUILD_ARFLAGS} built-in.o \ ${KBUILD_VMLINUX_INIT} \ ${KBUILD_VMLINUX_MAIN} fi @@ -63,11 +70,17 @@ modpost_link() local objects if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then - objects="--whole-archive built-in.o" + objects="--whole-archive \ + built-in.o \ + --no-whole-archive \ + --start-group \ + ${KBUILD_VMLINUX_LIBS} \ + --end-group" else objects="${KBUILD_VMLINUX_INIT} \ --start-group \ ${KBUILD_VMLINUX_MAIN} \ + ${KBUILD_VMLINUX_LIBS} \ --end-group" fi ${LD} ${LDFLAGS} -r -o ${1} ${objects} @@ -83,11 +96,18 @@ vmlinux_link() if [ "${SRCARCH}" != "um" ]; then if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then - objects="--whole-archive built-in.o ${1}" + objects="--whole-archive \ + built-in.o \ + --no-whole-archive \ + --start-group \ + ${KBUILD_VMLINUX_LIBS} \ + --end-group \ + ${1}" else objects="${KBUILD_VMLINUX_INIT} \ --start-group \ ${KBUILD_VMLINUX_MAIN} \ + ${KBUILD_VMLINUX_LIBS} \ --end-group \ ${1}" fi @@ -96,11 +116,18 @@ vmlinux_link() -T ${lds} ${objects} else if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then - objects="-Wl,--whole-archive built-in.o ${1}" + objects="-Wl,--whole-archive \ + built-in.o \ + -Wl,--no-whole-archive \ + -Wl,--start-group \ + ${KBUILD_VMLINUX_LIBS} \ + -Wl,--end-group \ + ${1}" else objects="${KBUILD_VMLINUX_INIT} \ -Wl,--start-group \ ${KBUILD_VMLINUX_MAIN} \ + ${KBUILD_VMLINUX_LIBS} \ -Wl,--end-group \ ${1}" fi diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl index c21d16328d3f..70dcfb6b3de1 100755 --- a/scripts/markup_oops.pl +++ b/scripts/markup_oops.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl use File::Basename; use Math::BigInt; diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index 6fdc97ef6023..fd8fdb91581d 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -76,7 +76,7 @@ UTS_TRUNCATE="cut -b -$UTS_LEN" echo \#define LINUX_COMPILE_BY \"`echo $LINUX_COMPILE_BY | $UTS_TRUNCATE`\" echo \#define LINUX_COMPILE_HOST \"`echo $LINUX_COMPILE_HOST | $UTS_TRUNCATE`\" - echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | grep ' version '`\" + echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | grep ' version ' | sed 's/[[:space:]]*$//'`\" ) > .tmpcompile # Only replace the real compile.h if the new one is different, diff --git a/scripts/namespace.pl b/scripts/namespace.pl index 9f3c9d47a4a5..729c547fc9e1 100755 --- a/scripts/namespace.pl +++ b/scripts/namespace.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # # namespace.pl. Mon Aug 30 2004 # @@ -62,7 +62,7 @@ # result. # -require 5; # at least perl 5 +use warnings; use strict; use File::Find; diff --git a/scripts/profile2linkerlist.pl b/scripts/profile2linkerlist.pl index 6943fa7cc95b..f23d7be94394 100755 --- a/scripts/profile2linkerlist.pl +++ b/scripts/profile2linkerlist.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # # Takes a (sorted) output of readprofile and turns it into a list suitable for diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 1633c3e6c0b9..2033af758173 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # (c) 2008, Steven Rostedt <srostedt@redhat.com> # Licensed under the terms of the GNU GPL License version 2 # @@ -106,6 +106,7 @@ # 9) Move the result back to the original object. # +use warnings; use strict; my $P = $0; diff --git a/scripts/selinux/README b/scripts/selinux/README index 4d020ecb7524..5ba679c5be18 100644 --- a/scripts/selinux/README +++ b/scripts/selinux/README @@ -1,2 +1,2 @@ -Please see Documentation/security/SELinux.txt for information on +Please see Documentation/admin-guide/LSM/SELinux.rst for information on installing a dummy SELinux policy. diff --git a/scripts/spelling.txt b/scripts/spelling.txt index eb38f49d4b75..400ef35169c5 100644 --- a/scripts/spelling.txt +++ b/scripts/spelling.txt @@ -54,6 +54,7 @@ adapater||adapter addional||additional additionaly||additionally addres||address +adddress||address addreses||addresses addresss||address aditional||additional @@ -130,6 +131,7 @@ arraival||arrival artifical||artificial artillary||artillery asign||assign +asser||assert assertation||assertion assiged||assigned assigment||assignment @@ -149,6 +151,7 @@ atempt||attempt attachement||attachment attched||attached attemps||attempts +attemping||attempting attruibutes||attributes authentification||authentication automaticaly||automatically @@ -205,9 +208,11 @@ callibration||calibration calucate||calculate calulate||calculate cancelation||cancellation +cancle||cancel capabilites||capabilities capabitilies||capabilities capatibilities||capabilities +capapbilities||capabilities carefuly||carefully cariage||carriage catagory||category @@ -216,6 +221,7 @@ challange||challenge challanges||challenges chanell||channel changable||changeable +chanined||chained channle||channel channnel||channel charachter||character @@ -241,6 +247,7 @@ claread||cleared clared||cleared closeing||closing clustred||clustered +coexistance||coexistence collapsable||collapsible colorfull||colorful comand||command @@ -269,6 +276,7 @@ completition||completion completly||completely complient||compliant componnents||components +compoment||component compres||compress compresion||compression comression||compression @@ -315,6 +323,7 @@ correponding||corresponding correponds||corresponds correspoding||corresponding cotrol||control +cound||could couter||counter coutner||counter cryptocraphic||cryptographic @@ -326,6 +335,7 @@ deafult||default deamon||daemon decompres||decompress decription||description +dectected||detected defailt||default defferred||deferred definate||definite @@ -343,6 +353,8 @@ delare||declare delares||declares delaring||declaring delemiter||delimiter +demodualtor||demodulator +demension||dimension dependancies||dependencies dependancy||dependency dependant||dependent @@ -357,11 +369,13 @@ descritptor||descriptor desctiptor||descriptor desriptor||descriptor desriptors||descriptors +destionation||destination destory||destroy destoryed||destroyed destorys||destroys destroied||destroyed detabase||database +deteced||detected develope||develop developement||development developped||developed @@ -419,9 +433,11 @@ enchanced||enhanced encorporating||incorporating encrupted||encrypted encrypiton||encryption +encryptio||encryption endianess||endianness enhaced||enhanced enlightnment||enlightenment +entrys||entries enocded||encoded enterily||entirely enviroiment||environment @@ -439,6 +455,7 @@ etsbalishment||establishment excecutable||executable exceded||exceeded excellant||excellent +exeed||exceed existance||existence existant||existent exixt||exist @@ -467,6 +484,7 @@ failuer||failure faireness||fairness falied||failed faliure||failure +fallbck||fallback familar||familiar fatser||faster feauture||feature @@ -564,6 +582,7 @@ independant||independent independantly||independently independed||independent indiate||indicate +indicat||indicate inexpect||inexpected infomation||information informatiom||information @@ -682,6 +701,7 @@ messags||messages messgaes||messages messsage||message messsages||messages +micropone||microphone microprocesspr||microprocessor milliseonds||milliseconds minium||minimum @@ -693,11 +713,14 @@ misformed||malformed mispelled||misspelled mispelt||misspelt mising||missing +missmanaged||mismanaged +missmatch||mismatch miximum||maximum mmnemonic||mnemonic mnay||many modulues||modules momery||memory +memomry||memory monochorome||monochrome monochromo||monochrome monocrome||monochrome @@ -798,6 +821,7 @@ permissons||permissions peroid||period persistance||persistence persistant||persistent +plalform||platform platfrom||platform plattform||platform pleaes||please @@ -810,6 +834,7 @@ posible||possible positon||position possibilites||possibilities powerfull||powerful +preapre||prepare preceeded||preceded preceeding||preceding preceed||precede @@ -868,6 +893,7 @@ psuedo||pseudo psychadelic||psychedelic pwoer||power quering||querying +randomally||randomly raoming||roaming reasearcher||researcher reasearchers||researchers @@ -895,6 +921,7 @@ refernnce||reference refrence||reference registerd||registered registeresd||registered +registerred||registered registes||registers registraration||registration regsiter||register @@ -923,6 +950,7 @@ requried||required requst||request reseting||resetting resizeable||resizable +resouce||resource resouces||resources resoures||resources responce||response @@ -938,6 +966,7 @@ reudce||reduce reuest||request reuqest||request reutnred||returned +revsion||revision rmeoved||removed rmeove||remove rmeoves||removes @@ -1099,6 +1128,7 @@ transfering||transferring transision||transition transmittd||transmitted transormed||transformed +trasfer||transfer trasmission||transmission treshold||threshold trigerring||triggering @@ -1167,6 +1197,7 @@ virtaul||virtual virtiual||virtual visiters||visitors vitual||virtual +wakeus||wakeups wating||waiting wether||whether whataver||whatever diff --git a/scripts/stackdelta b/scripts/stackdelta index 48eabf2f48f8..20a79f19a111 100755 --- a/scripts/stackdelta +++ b/scripts/stackdelta @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Read two files produced by the stackusage script, and show the # delta between them. diff --git a/scripts/tags.sh b/scripts/tags.sh index d661f2f3ef61..d23dcbf17457 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -106,6 +106,7 @@ all_compiled_sources() case "$i" in *.[cS]) j=${i/\.[cS]/\.o} + j="${j#$tree}" if [ -e $j ]; then echo $i fi |