aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Kbuild.include4
-rw-r--r--scripts/Makefile3
-rw-r--r--scripts/Makefile.build7
-rw-r--r--scripts/Makefile.lib11
-rw-r--r--scripts/basic/.gitignore2
-rw-r--r--scripts/basic/Makefile2
-rw-r--r--scripts/basic/hash.c64
-rw-r--r--scripts/bootgraph.pl149
-rwxr-xr-xscripts/checkpatch.pl390
-rwxr-xr-xscripts/checkstack.pl5
-rw-r--r--scripts/mod/file2alias.c75
-rw-r--r--scripts/mod/modpost.c9
-rwxr-xr-xscripts/recordmcount.pl395
-rw-r--r--scripts/selinux/Makefile2
-rw-r--r--scripts/selinux/README2
-rw-r--r--scripts/selinux/install_policy.sh69
-rw-r--r--scripts/selinux/mdp/.gitignore2
-rw-r--r--scripts/selinux/mdp/Makefile5
-rw-r--r--scripts/selinux/mdp/dbus_contexts6
-rw-r--r--scripts/selinux/mdp/mdp.c242
20 files changed, 1332 insertions, 112 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index d64e6badc942..982dcae7bbe2 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -105,12 +105,12 @@ as-instr = $(call try-run,\
105# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) 105# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
106 106
107cc-option = $(call try-run,\ 107cc-option = $(call try-run,\
108 $(CC) $(KBUILD_CFLAGS) $(1) -S -xc /dev/null -o "$$TMP",$(1),$(2)) 108 $(CC) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",$(1),$(2))
109 109
110# cc-option-yn 110# cc-option-yn
111# Usage: flag := $(call cc-option-yn,-march=winchip-c6) 111# Usage: flag := $(call cc-option-yn,-march=winchip-c6)
112cc-option-yn = $(call try-run,\ 112cc-option-yn = $(call try-run,\
113 $(CC) $(KBUILD_CFLAGS) $(1) -S -xc /dev/null -o "$$TMP",y,n) 113 $(CC) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",y,n)
114 114
115# cc-option-align 115# cc-option-align
116# Prefix align with either -falign or -malign 116# Prefix align with either -falign or -malign
diff --git a/scripts/Makefile b/scripts/Makefile
index 1c73c5aea66b..aafdf064feef 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -20,6 +20,7 @@ hostprogs-y += unifdef
20 20
21subdir-$(CONFIG_MODVERSIONS) += genksyms 21subdir-$(CONFIG_MODVERSIONS) += genksyms
22subdir-y += mod 22subdir-y += mod
23subdir-$(CONFIG_SECURITY_SELINUX) += selinux
23 24
24# Let clean descend into subdirs 25# Let clean descend into subdirs
25subdir- += basic kconfig package 26subdir- += basic kconfig package selinux
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 277cfe0b7100..5ed4cbf1e0e1 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -198,10 +198,17 @@ cmd_modversions = \
198 fi; 198 fi;
199endif 199endif
200 200
201ifdef CONFIG_FTRACE_MCOUNT_RECORD
202cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl \
203 "$(ARCH)" "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" \
204 "$(MV)" "$(@)";
205endif
206
201define rule_cc_o_c 207define rule_cc_o_c
202 $(call echo-cmd,checksrc) $(cmd_checksrc) \ 208 $(call echo-cmd,checksrc) $(cmd_checksrc) \
203 $(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \ 209 $(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \
204 $(cmd_modversions) \ 210 $(cmd_modversions) \
211 $(cmd_record_mcount) \
205 scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \ 212 scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \
206 $(dot-target).tmp; \ 213 $(dot-target).tmp; \
207 rm -f $(depfile); \ 214 rm -f $(depfile); \
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index ea48b82a3707..b4ca38a21158 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -96,6 +96,14 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))"
96modname_flags = $(if $(filter 1,$(words $(modname))),\ 96modname_flags = $(if $(filter 1,$(words $(modname))),\
97 -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") 97 -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
98 98
99#hash values
100ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
101debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\
102 -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))"
103else
104debug_flags =
105endif
106
99orig_c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o) 107orig_c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o)
100_c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) 108_c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
101_a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o) 109_a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o)
@@ -121,7 +129,8 @@ endif
121 129
122c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ 130c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
123 $(__c_flags) $(modkern_cflags) \ 131 $(__c_flags) $(modkern_cflags) \
124 -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) 132 -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \
133 $(debug_flags)
125 134
126a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ 135a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
127 $(__a_flags) $(modkern_aflags) 136 $(__a_flags) $(modkern_aflags)
diff --git a/scripts/basic/.gitignore b/scripts/basic/.gitignore
index 7304e19782c7..bf8b199ec598 100644
--- a/scripts/basic/.gitignore
+++ b/scripts/basic/.gitignore
@@ -1,3 +1,3 @@
1hash
1fixdep 2fixdep
2split-include
3docproc 3docproc
diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile
index 4c324a1f1e0e..09559951df12 100644
--- a/scripts/basic/Makefile
+++ b/scripts/basic/Makefile
@@ -9,7 +9,7 @@
9# fixdep: Used to generate dependency information during build process 9# fixdep: Used to generate dependency information during build process
10# docproc: Used in Documentation/DocBook 10# docproc: Used in Documentation/DocBook
11 11
12hostprogs-y := fixdep docproc 12hostprogs-y := fixdep docproc hash
13always := $(hostprogs-y) 13always := $(hostprogs-y)
14 14
15# fixdep is needed to compile other host programs 15# fixdep is needed to compile other host programs
diff --git a/scripts/basic/hash.c b/scripts/basic/hash.c
new file mode 100644
index 000000000000..3299ad7fc8c0
--- /dev/null
+++ b/scripts/basic/hash.c
@@ -0,0 +1,64 @@
1/*
2 * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
3 *
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9
10#define DYNAMIC_DEBUG_HASH_BITS 6
11
12static const char *program;
13
14static void usage(void)
15{
16 printf("Usage: %s <djb2|r5> <modname>\n", program);
17 exit(1);
18}
19
20/* djb2 hashing algorithm by Dan Bernstein. From:
21 * http://www.cse.yorku.ca/~oz/hash.html
22 */
23
24unsigned int djb2_hash(char *str)
25{
26 unsigned long hash = 5381;
27 int c;
28
29 c = *str;
30 while (c) {
31 hash = ((hash << 5) + hash) + c;
32 c = *++str;
33 }
34 return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
35}
36
37unsigned int r5_hash(char *str)
38{
39 unsigned long hash = 0;
40 int c;
41
42 c = *str;
43 while (c) {
44 hash = (hash + (c << 4) + (c >> 4)) * 11;
45 c = *++str;
46 }
47 return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
48}
49
50int main(int argc, char *argv[])
51{
52 program = argv[0];
53
54 if (argc != 3)
55 usage();
56 if (!strcmp(argv[1], "djb2"))
57 printf("%d\n", djb2_hash(argv[2]));
58 else if (!strcmp(argv[1], "r5"))
59 printf("%d\n", r5_hash(argv[2]));
60 else
61 usage();
62 exit(0);
63}
64
diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl
new file mode 100644
index 000000000000..5e7316e5aa39
--- /dev/null
+++ b/scripts/bootgraph.pl
@@ -0,0 +1,149 @@
1#!/usr/bin/perl
2
3# Copyright 2008, Intel Corporation
4#
5# This file is part of the Linux kernel
6#
7# This program file is free software; you can redistribute it and/or modify it
8# under the terms of the GNU General Public License as published by the
9# Free Software Foundation; version 2 of the License.
10#
11# This program is distributed in the hope that it will be useful, but WITHOUT
12# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14# for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program in a file named COPYING; if not, write to the
18# Free Software Foundation, Inc.,
19# 51 Franklin Street, Fifth Floor,
20# Boston, MA 02110-1301 USA
21#
22# Authors:
23# Arjan van de Ven <arjan@linux.intel.com>
24
25
26#
27# This script turns a dmesg output into a SVG graphic that shows which
28# functions take how much time. You can view SVG graphics with various
29# programs, including Inkscape, The Gimp and Firefox.
30#
31#
32# For this script to work, the kernel needs to be compiled with the
33# CONFIG_PRINTK_TIME configuration option enabled, and with
34# "initcall_debug" passed on the kernel command line.
35#
36# usage:
37# dmesg | perl scripts/bootgraph.pl > output.svg
38#
39
40my %start, %end;
41my $done = 0;
42my $maxtime = 0;
43my $firsttime = 100;
44my $count = 0;
45my %pids;
46
47while (<>) {
48 my $line = $_;
49 if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z0-9\_]+)\+/) {
50 my $func = $2;
51 if ($done == 0) {
52 $start{$func} = $1;
53 if ($1 < $firsttime) {
54 $firsttime = $1;
55 }
56 }
57 if ($line =~ /\@ ([0-9]+)/) {
58 $pids{$func} = $1;
59 }
60 $count = $count + 1;
61 }
62
63 if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z0-9\_]+)\+.*returned/) {
64 if ($done == 0) {
65 $end{$2} = $1;
66 $maxtime = $1;
67 }
68 }
69 if ($line =~ /Write protecting the/) {
70 $done = 1;
71 }
72 if ($line =~ /Freeing unused kernel memory/) {
73 $done = 1;
74 }
75}
76
77if ($count == 0) {
78 print "No data found in the dmesg. Make sure that 'printk.time=1' and\n";
79 print "'initcall_debug' are passed on the kernel command line.\n\n";
80 print "Usage: \n";
81 print " dmesg | perl scripts/bootgraph.pl > output.svg\n\n";
82 exit;
83}
84
85print "<?xml version=\"1.0\" standalone=\"no\"?> \n";
86print "<svg width=\"1000\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n";
87
88my @styles;
89
90$styles[0] = "fill:rgb(0,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
91$styles[1] = "fill:rgb(0,255,0);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
92$styles[2] = "fill:rgb(255,0,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
93$styles[3] = "fill:rgb(255,255,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
94$styles[4] = "fill:rgb(255,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
95$styles[5] = "fill:rgb(0,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
96$styles[6] = "fill:rgb(0,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
97$styles[7] = "fill:rgb(0,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
98$styles[8] = "fill:rgb(255,0,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
99$styles[9] = "fill:rgb(255,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
100$styles[10] = "fill:rgb(255,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
101$styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
102
103my $mult = 950.0 / ($maxtime - $firsttime);
104my $threshold = ($maxtime - $firsttime) / 60.0;
105my $stylecounter = 0;
106my %rows;
107my $rowscount = 1;
108while (($key,$value) = each %start) {
109 my $duration = $end{$key} - $start{$key};
110
111 if ($duration >= $threshold) {
112 my $s, $s2, $e, $y;
113 $pid = $pids{$key};
114
115 if (!defined($rows{$pid})) {
116 $rows{$pid} = $rowscount;
117 $rowscount = $rowscount + 1;
118 }
119 $s = ($value - $firsttime) * $mult;
120 $s2 = $s + 6;
121 $e = ($end{$key} - $firsttime) * $mult;
122 $w = $e - $s;
123
124 $y = $rows{$pid} * 150;
125 $y2 = $y + 4;
126
127 $style = $styles[$stylecounter];
128 $stylecounter = $stylecounter + 1;
129 if ($stylecounter > 11) {
130 $stylecounter = 0;
131 };
132
133 print "<rect x=\"$s\" width=\"$w\" y=\"$y\" height=\"145\" style=\"$style\"/>\n";
134 print "<text transform=\"translate($s2,$y2) rotate(90)\">$key</text>\n";
135 }
136}
137
138
139# print the time line on top
140my $time = $firsttime;
141my $step = ($maxtime - $firsttime) / 15;
142while ($time < $maxtime) {
143 my $s2 = ($time - $firsttime) * $mult;
144 my $tm = int($time * 100) / 100.0;
145 print "<text transform=\"translate($s2,89) rotate(90)\">$tm</text>\n";
146 $time = $time + $step;
147}
148
149print "</svg>\n";
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index bc6779398229..f88bb3e21cda 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1,5 +1,5 @@
1#!/usr/bin/perl -w 1#!/usr/bin/perl -w
2# (c) 2001, Dave Jones. <davej@codemonkey.org.uk> (the file handling bit) 2# (c) 2001, Dave Jones. <davej@redhat.com> (the file handling bit)
3# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) 3# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
4# (c) 2007, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite, etc) 4# (c) 2007, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite, etc)
5# Licensed under the terms of the GNU GPL License version 2 5# Licensed under the terms of the GNU GPL License version 2
@@ -9,7 +9,7 @@ use strict;
9my $P = $0; 9my $P = $0;
10$P =~ s@.*/@@g; 10$P =~ s@.*/@@g;
11 11
12my $V = '0.21'; 12my $V = '0.24';
13 13
14use Getopt::Long qw(:config no_auto_abbrev); 14use Getopt::Long qw(:config no_auto_abbrev);
15 15
@@ -66,6 +66,7 @@ if ($#ARGV < 0) {
66my $dbg_values = 0; 66my $dbg_values = 0;
67my $dbg_possible = 0; 67my $dbg_possible = 0;
68my $dbg_type = 0; 68my $dbg_type = 0;
69my $dbg_attr = 0;
69for my $key (keys %debug) { 70for my $key (keys %debug) {
70 eval "\${dbg_$key} = '$debug{$key}';" 71 eval "\${dbg_$key} = '$debug{$key}';"
71} 72}
@@ -112,7 +113,10 @@ our $Attribute = qr{
112 const| 113 const|
113 __read_mostly| 114 __read_mostly|
114 __kprobes| 115 __kprobes|
115 __(?:mem|cpu|dev|)(?:initdata|init) 116 __(?:mem|cpu|dev|)(?:initdata|init)|
117 ____cacheline_aligned|
118 ____cacheline_aligned_in_smp|
119 ____cacheline_internodealigned_in_smp
116 }x; 120 }x;
117our $Modifier; 121our $Modifier;
118our $Inline = qr{inline|__always_inline|noinline}; 122our $Inline = qr{inline|__always_inline|noinline};
@@ -142,6 +146,11 @@ our $UTF8 = qr {
142 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 146 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
143}x; 147}x;
144 148
149our $typeTypedefs = qr{(?x:
150 (?:__)?(?:u|s|be|le)(?:\d|\d\d)|
151 atomic_t
152)};
153
145our @typeList = ( 154our @typeList = (
146 qr{void}, 155 qr{void},
147 qr{(?:unsigned\s+)?char}, 156 qr{(?:unsigned\s+)?char},
@@ -155,7 +164,6 @@ our @typeList = (
155 qr{float}, 164 qr{float},
156 qr{double}, 165 qr{double},
157 qr{bool}, 166 qr{bool},
158 qr{(?:__)?(?:u|s|be|le)(?:8|16|32|64)},
159 qr{struct\s+$Ident}, 167 qr{struct\s+$Ident},
160 qr{union\s+$Ident}, 168 qr{union\s+$Ident},
161 qr{enum\s+$Ident}, 169 qr{enum\s+$Ident},
@@ -175,6 +183,7 @@ sub build_types {
175 (?:$Modifier\s+|const\s+)* 183 (?:$Modifier\s+|const\s+)*
176 (?: 184 (?:
177 (?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)| 185 (?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)|
186 (?:$typeTypedefs\b)|
178 (?:${all}\b) 187 (?:${all}\b)
179 ) 188 )
180 (?:\s+$Modifier|\s+const)* 189 (?:\s+$Modifier|\s+const)*
@@ -331,7 +340,7 @@ sub sanitise_line {
331 $off++; 340 $off++;
332 next; 341 next;
333 } 342 }
334 if (substr($line, $off, 2) eq '*/') { 343 if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
335 $sanitise_quote = ''; 344 $sanitise_quote = '';
336 substr($res, $off, 2, "$;$;"); 345 substr($res, $off, 2, "$;$;");
337 $off++; 346 $off++;
@@ -404,6 +413,7 @@ sub ctx_statement_block {
404 # context. 413 # context.
405 if ($off >= $len) { 414 if ($off >= $len) {
406 for (; $remain > 0; $line++) { 415 for (; $remain > 0; $line++) {
416 last if (!defined $lines[$line]);
407 next if ($lines[$line] =~ /^-/); 417 next if ($lines[$line] =~ /^-/);
408 $remain--; 418 $remain--;
409 $loff = $len; 419 $loff = $len;
@@ -669,6 +679,22 @@ sub ctx_has_comment {
669 return ($cmt ne ''); 679 return ($cmt ne '');
670} 680}
671 681
682sub raw_line {
683 my ($linenr, $cnt) = @_;
684
685 my $offset = $linenr - 1;
686 $cnt++;
687
688 my $line;
689 while ($cnt) {
690 $line = $rawlines[$offset++];
691 next if (defined($line) && $line =~ /^-/);
692 $cnt--;
693 }
694
695 return $line;
696}
697
672sub cat_vet { 698sub cat_vet {
673 my ($vet) = @_; 699 my ($vet) = @_;
674 my ($res, $coded); 700 my ($res, $coded);
@@ -782,9 +808,9 @@ sub annotate_values {
782 } 808 }
783 $type = 'N'; 809 $type = 'N';
784 810
785 } elsif ($cur =~ /^(if|while|typeof|__typeof__|for)\b/o) { 811 } elsif ($cur =~ /^(if|while|for)\b/o) {
786 print "COND($1)\n" if ($dbg_values > 1); 812 print "COND($1)\n" if ($dbg_values > 1);
787 $av_pending = 'N'; 813 $av_pending = 'E';
788 $type = 'N'; 814 $type = 'N';
789 815
790 } elsif ($cur =~/^(case)/o) { 816 } elsif ($cur =~/^(case)/o) {
@@ -792,7 +818,7 @@ sub annotate_values {
792 $av_pend_colon = 'C'; 818 $av_pend_colon = 'C';
793 $type = 'N'; 819 $type = 'N';
794 820
795 } elsif ($cur =~/^(return|else|goto)/o) { 821 } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
796 print "KEYWORD($1)\n" if ($dbg_values > 1); 822 print "KEYWORD($1)\n" if ($dbg_values > 1);
797 $type = 'N'; 823 $type = 'N';
798 824
@@ -858,7 +884,7 @@ sub annotate_values {
858 print "CLOSE($1)\n" if ($dbg_values > 1); 884 print "CLOSE($1)\n" if ($dbg_values > 1);
859 $type = 'N'; 885 $type = 'N';
860 886
861 } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&(?!\&))/o) { 887 } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
862 my $variant; 888 my $variant;
863 889
864 print "OPV($1)\n" if ($dbg_values > 1); 890 print "OPV($1)\n" if ($dbg_values > 1);
@@ -892,12 +918,22 @@ sub annotate_values {
892sub possible { 918sub possible {
893 my ($possible, $line) = @_; 919 my ($possible, $line) = @_;
894 920
895 print "CHECK<$possible> ($line)\n" if ($dbg_possible > 1); 921 print "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
896 if ($possible !~ /^(?:$Modifier|$Storage|$Type|DEFINE_\S+)$/ && 922 if ($possible !~ /(?:
897 $possible ne 'goto' && $possible ne 'return' && 923 ^(?:
898 $possible ne 'case' && $possible ne 'else' && 924 $Modifier|
899 $possible ne 'asm' && $possible ne '__asm__' && 925 $Storage|
900 $possible !~ /^(typedef|struct|enum)\b/) { 926 $Type|
927 DEFINE_\S+|
928 goto|
929 return|
930 case|
931 else|
932 asm|__asm__|
933 do
934 )$|
935 ^(?:typedef|struct|enum)\b
936 )/x) {
901 # Check for modifiers. 937 # Check for modifiers.
902 $possible =~ s/\s*$Storage\s*//g; 938 $possible =~ s/\s*$Storage\s*//g;
903 $possible =~ s/\s*$Sparse\s*//g; 939 $possible =~ s/\s*$Sparse\s*//g;
@@ -915,6 +951,8 @@ sub possible {
915 push(@typeList, $possible); 951 push(@typeList, $possible);
916 } 952 }
917 build_types(); 953 build_types();
954 } else {
955 warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
918 } 956 }
919} 957}
920 958
@@ -954,6 +992,33 @@ sub CHK {
954 } 992 }
955} 993}
956 994
995sub check_absolute_file {
996 my ($absolute, $herecurr) = @_;
997 my $file = $absolute;
998
999 ##print "absolute<$absolute>\n";
1000
1001 # See if any suffix of this path is a path within the tree.
1002 while ($file =~ s@^[^/]*/@@) {
1003 if (-f "$root/$file") {
1004 ##print "file<$file>\n";
1005 last;
1006 }
1007 }
1008 if (! -f _) {
1009 return 0;
1010 }
1011
1012 # It is, so see if the prefix is acceptable.
1013 my $prefix = $absolute;
1014 substr($prefix, -length($file)) = '';
1015
1016 ##print "prefix<$prefix>\n";
1017 if ($prefix ne ".../") {
1018 WARN("use relative pathname instead of absolute in changelog text\n" . $herecurr);
1019 }
1020}
1021
957sub process { 1022sub process {
958 my $filename = shift; 1023 my $filename = shift;
959 1024
@@ -991,6 +1056,7 @@ sub process {
991 1056
992 # suppression flags 1057 # suppression flags
993 my %suppress_ifbraces; 1058 my %suppress_ifbraces;
1059 my %suppress_whiletrailers;
994 1060
995 # Pre-scan the patch sanitizing the lines. 1061 # Pre-scan the patch sanitizing the lines.
996 # Pre-scan the patch looking for any __setup documentation. 1062 # Pre-scan the patch looking for any __setup documentation.
@@ -1025,9 +1091,14 @@ sub process {
1025 # edge is a close comment then we must be in a comment 1091 # edge is a close comment then we must be in a comment
1026 # at context start. 1092 # at context start.
1027 my $edge; 1093 my $edge;
1028 for (my $ln = $linenr + 1; $ln < ($linenr + $realcnt); $ln++) { 1094 my $cnt = $realcnt;
1029 next if ($line =~ /^-/); 1095 for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
1030 ($edge) = ($rawlines[$ln - 1] =~ m@(/\*|\*/)@); 1096 next if (defined $rawlines[$ln - 1] &&
1097 $rawlines[$ln - 1] =~ /^-/);
1098 $cnt--;
1099 #print "RAW<$rawlines[$ln - 1]>\n";
1100 ($edge) = (defined $rawlines[$ln - 1] &&
1101 $rawlines[$ln - 1] =~ m@(/\*|\*/)@);
1031 last if (defined $edge); 1102 last if (defined $edge);
1032 } 1103 }
1033 if (defined $edge && $edge eq '*/') { 1104 if (defined $edge && $edge eq '*/') {
@@ -1075,6 +1146,7 @@ sub process {
1075 $linenr++; 1146 $linenr++;
1076 1147
1077 my $rawline = $rawlines[$linenr - 1]; 1148 my $rawline = $rawlines[$linenr - 1];
1149 my $hunk_line = ($realcnt != 0);
1078 1150
1079#extract the line range in the file after the patch is applied 1151#extract the line range in the file after the patch is applied
1080 if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 1152 if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
@@ -1090,6 +1162,7 @@ sub process {
1090 $prev_values = 'E'; 1162 $prev_values = 'E';
1091 1163
1092 %suppress_ifbraces = (); 1164 %suppress_ifbraces = ();
1165 %suppress_whiletrailers = ();
1093 next; 1166 next;
1094 1167
1095# track the line number as we move through the hunk, note that 1168# track the line number as we move through the hunk, note that
@@ -1125,7 +1198,7 @@ sub process {
1125 $realfile = $1; 1198 $realfile = $1;
1126 $realfile =~ s@^[^/]*/@@; 1199 $realfile =~ s@^[^/]*/@@;
1127 1200
1128 if ($realfile =~ m@include/asm/@) { 1201 if ($realfile =~ m@^include/asm/@) {
1129 ERROR("do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 1202 ERROR("do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
1130 } 1203 }
1131 next; 1204 next;
@@ -1159,6 +1232,20 @@ sub process {
1159 $herecurr) if (!$emitted_corrupt++); 1232 $herecurr) if (!$emitted_corrupt++);
1160 } 1233 }
1161 1234
1235# Check for absolute kernel paths.
1236 if ($tree) {
1237 while ($line =~ m{(?:^|\s)(/\S*)}g) {
1238 my $file = $1;
1239
1240 if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
1241 check_absolute_file($1, $herecurr)) {
1242 #
1243 } else {
1244 check_absolute_file($file, $herecurr);
1245 }
1246 }
1247 }
1248
1162# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 1249# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
1163 if (($realfile =~ /^$/ || $line =~ /^\+/) && 1250 if (($realfile =~ /^$/ || $line =~ /^\+/) &&
1164 $rawline !~ m/^$UTF8*$/) { 1251 $rawline !~ m/^$UTF8*$/) {
@@ -1171,11 +1258,8 @@ sub process {
1171 ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 1258 ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
1172 } 1259 }
1173 1260
1174#ignore lines being removed 1261# ignore non-hunk lines and lines being removed
1175 if ($line=~/^-/) {next;} 1262 next if (!$hunk_line || $line =~ /^-/);
1176
1177# check we are in a valid source file if not then ignore this hunk
1178 next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
1179 1263
1180#trailing whitespace 1264#trailing whitespace
1181 if ($line =~ /^\+.*\015/) { 1265 if ($line =~ /^\+.*\015/) {
@@ -1186,6 +1270,10 @@ sub process {
1186 my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1270 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1187 ERROR("trailing whitespace\n" . $herevet); 1271 ERROR("trailing whitespace\n" . $herevet);
1188 } 1272 }
1273
1274# check we are in a valid source file if not then ignore this hunk
1275 next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
1276
1189#80 column limit 1277#80 column limit
1190 if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && 1278 if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
1191 $rawline !~ /^.\s*\*\s*\@$Ident\s/ && 1279 $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
@@ -1200,8 +1288,8 @@ sub process {
1200 WARN("adding a line without newline at end of file\n" . $herecurr); 1288 WARN("adding a line without newline at end of file\n" . $herecurr);
1201 } 1289 }
1202 1290
1203# check we are in a valid source file *.[hc] if not then ignore this hunk 1291# check we are in a valid source file C or perl if not then ignore this hunk
1204 next if ($realfile !~ /\.[hc]$/); 1292 next if ($realfile !~ /\.(h|c|pl)$/);
1205 1293
1206# at the beginning of a line any tabs must come first and anything 1294# at the beginning of a line any tabs must come first and anything
1207# more than 8 must use tabs. 1295# more than 8 must use tabs.
@@ -1211,15 +1299,18 @@ sub process {
1211 ERROR("code indent should use tabs where possible\n" . $herevet); 1299 ERROR("code indent should use tabs where possible\n" . $herevet);
1212 } 1300 }
1213 1301
1302# check we are in a valid C source file if not then ignore this hunk
1303 next if ($realfile !~ /\.(h|c)$/);
1304
1214# check for RCS/CVS revision markers 1305# check for RCS/CVS revision markers
1215 if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 1306 if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
1216 WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr); 1307 WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr);
1217 } 1308 }
1218 1309
1219# Check for potential 'bare' types 1310# Check for potential 'bare' types
1220 my ($stat, $cond, $line_nr_next, $remain_next); 1311 my ($stat, $cond, $line_nr_next, $remain_next, $off_next);
1221 if ($realcnt && $line =~ /.\s*\S/) { 1312 if ($realcnt && $line =~ /.\s*\S/) {
1222 ($stat, $cond, $line_nr_next, $remain_next) = 1313 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
1223 ctx_statement_block($linenr, $realcnt, 0); 1314 ctx_statement_block($linenr, $realcnt, 0);
1224 $stat =~ s/\n./\n /g; 1315 $stat =~ s/\n./\n /g;
1225 $cond =~ s/\n./\n /g; 1316 $cond =~ s/\n./\n /g;
@@ -1240,7 +1331,7 @@ sub process {
1240 possible($type, "A:" . $s); 1331 possible($type, "A:" . $s);
1241 1332
1242 # definitions in global scope can only start with types 1333 # definitions in global scope can only start with types
1243 } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/s) { 1334 } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
1244 possible($1, "B:" . $s); 1335 possible($1, "B:" . $s);
1245 } 1336 }
1246 1337
@@ -1294,10 +1385,6 @@ sub process {
1294 ERROR("switch and case should be at the same indent\n$hereline$err"); 1385 ERROR("switch and case should be at the same indent\n$hereline$err");
1295 } 1386 }
1296 } 1387 }
1297 if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
1298 $line !~ /\G(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$/g) {
1299 ERROR("trailing statements should be on next line\n" . $herecurr);
1300 }
1301 1388
1302# if/while/etc brace do not go on next line, unless defining a do while loop, 1389# if/while/etc brace do not go on next line, unless defining a do while loop,
1303# or if that brace on the next line is for something else 1390# or if that brace on the next line is for something else
@@ -1338,6 +1425,91 @@ sub process {
1338 } 1425 }
1339 } 1426 }
1340 1427
1428# Check relative indent for conditionals and blocks.
1429 if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
1430 my ($s, $c) = ($stat, $cond);
1431
1432 substr($s, 0, length($c), '');
1433
1434 # Make sure we remove the line prefixes as we have
1435 # none on the first line, and are going to readd them
1436 # where necessary.
1437 $s =~ s/\n./\n/gs;
1438
1439 # Find out how long the conditional actually is.
1440 my @newlines = ($c =~ /\n/gs);
1441 my $cond_lines = 1 + $#newlines;
1442
1443 # We want to check the first line inside the block
1444 # starting at the end of the conditional, so remove:
1445 # 1) any blank line termination
1446 # 2) any opening brace { on end of the line
1447 # 3) any do (...) {
1448 my $continuation = 0;
1449 my $check = 0;
1450 $s =~ s/^.*\bdo\b//;
1451 $s =~ s/^\s*{//;
1452 if ($s =~ s/^\s*\\//) {
1453 $continuation = 1;
1454 }
1455 if ($s =~ s/^\s*?\n//) {
1456 $check = 1;
1457 $cond_lines++;
1458 }
1459
1460 # Also ignore a loop construct at the end of a
1461 # preprocessor statement.
1462 if (($prevline =~ /^.\s*#\s*define\s/ ||
1463 $prevline =~ /\\\s*$/) && $continuation == 0) {
1464 $check = 0;
1465 }
1466
1467 my $cond_ptr = -1;
1468 $continuation = 0;
1469 while ($cond_ptr != $cond_lines) {
1470 $cond_ptr = $cond_lines;
1471
1472 # If we see an #else/#elif then the code
1473 # is not linear.
1474 if ($s =~ /^\s*\#\s*(?:else|elif)/) {
1475 $check = 0;
1476 }
1477
1478 # Ignore:
1479 # 1) blank lines, they should be at 0,
1480 # 2) preprocessor lines, and
1481 # 3) labels.
1482 if ($continuation ||
1483 $s =~ /^\s*?\n/ ||
1484 $s =~ /^\s*#\s*?/ ||
1485 $s =~ /^\s*$Ident\s*:/) {
1486 $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
1487 $s =~ s/^.*?\n//;
1488 $cond_lines++;
1489 }
1490 }
1491
1492 my (undef, $sindent) = line_stats("+" . $s);
1493 my $stat_real = raw_line($linenr, $cond_lines);
1494
1495 # Check if either of these lines are modified, else
1496 # this is not this patch's fault.
1497 if (!defined($stat_real) ||
1498 $stat !~ /^\+/ && $stat_real !~ /^\+/) {
1499 $check = 0;
1500 }
1501 if (defined($stat_real) && $cond_lines > 1) {
1502 $stat_real = "[...]\n$stat_real";
1503 }
1504
1505 #print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n";
1506
1507 if ($check && (($sindent % 8) != 0 ||
1508 ($sindent <= $indent && $s ne ''))) {
1509 WARN("suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
1510 }
1511 }
1512
1341 # Track the 'values' across context and added lines. 1513 # Track the 'values' across context and added lines.
1342 my $opline = $line; $opline =~ s/^./ /; 1514 my $opline = $line; $opline =~ s/^./ /;
1343 my ($curr_values, $curr_vars) = 1515 my ($curr_values, $curr_vars) =
@@ -1363,6 +1535,15 @@ sub process {
1363 } 1535 }
1364 next; 1536 next;
1365 } 1537 }
1538# TEST: allow direct testing of the attribute matcher.
1539 if ($dbg_attr) {
1540 if ($line =~ /^.\s*$Attribute\s*$/) {
1541 ERROR("TEST: is attr\n" . $herecurr);
1542 } elsif ($dbg_attr > 1 && $line =~ /^.+($Attribute)/) {
1543 ERROR("TEST: is not attr ($1 is)\n". $herecurr);
1544 }
1545 next;
1546 }
1366 1547
1367# check for initialisation to aggregates open brace on the next line 1548# check for initialisation to aggregates open brace on the next line
1368 if ($prevline =~ /$Declare\s*$Ident\s*=\s*$/ && 1549 if ($prevline =~ /$Declare\s*$Ident\s*=\s*$/ &&
@@ -1395,13 +1576,14 @@ sub process {
1395 if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) || 1576 if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) ||
1396 ($line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 1577 ($line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
1397 my $name = $1; 1578 my $name = $1;
1398 if (($prevline !~ /^}/) && 1579 if ($prevline !~ /(?:
1399 ($prevline !~ /^\+}/) && 1580 ^.}|
1400 ($prevline !~ /^ }/) && 1581 ^.DEFINE_$Ident\(\Q$name\E\)|
1401 ($prevline !~ /^.DECLARE_$Ident\(\Q$name\E\)/) && 1582 ^.DECLARE_$Ident\(\Q$name\E\)|
1402 ($prevline !~ /^.LIST_HEAD\(\Q$name\E\)/) && 1583 ^.LIST_HEAD\(\Q$name\E\)|
1403 ($prevline !~ /^.$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(/) && 1584 ^.$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
1404 ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[)/)) { 1585 \b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[)
1586 )/x) {
1405 WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 1587 WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
1406 } 1588 }
1407 } 1589 }
@@ -1422,6 +1604,7 @@ sub process {
1422 if ($line =~ /\btypedef\s/ && 1604 if ($line =~ /\btypedef\s/ &&
1423 $line !~ /\btypedef\s+$Type\s+\(\s*\*?$Ident\s*\)\s*\(/ && 1605 $line !~ /\btypedef\s+$Type\s+\(\s*\*?$Ident\s*\)\s*\(/ &&
1424 $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 1606 $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
1607 $line !~ /\b$typeTypedefs\b/ &&
1425 $line !~ /\b__bitwise(?:__|)\b/) { 1608 $line !~ /\b__bitwise(?:__|)\b/) {
1426 WARN("do not add new typedefs\n" . $herecurr); 1609 WARN("do not add new typedefs\n" . $herecurr);
1427 } 1610 }
@@ -1493,11 +1676,13 @@ sub process {
1493 1676
1494# check for spacing round square brackets; allowed: 1677# check for spacing round square brackets; allowed:
1495# 1. with a type on the left -- int [] a; 1678# 1. with a type on the left -- int [] a;
1496# 2. at the beginning of a line for slice initialisers -- [0..10] = 5, 1679# 2. at the beginning of a line for slice initialisers -- [0...10] = 5,
1680# 3. inside a curly brace -- = { [0...10] = 5 }
1497 while ($line =~ /(.*?\s)\[/g) { 1681 while ($line =~ /(.*?\s)\[/g) {
1498 my ($where, $prefix) = ($-[1], $1); 1682 my ($where, $prefix) = ($-[1], $1);
1499 if ($prefix !~ /$Type\s+$/ && 1683 if ($prefix !~ /$Type\s+$/ &&
1500 ($where != 0 || $prefix !~ /^.\s+$/)) { 1684 ($where != 0 || $prefix !~ /^.\s+$/) &&
1685 $prefix !~ /{\s+$/) {
1501 ERROR("space prohibited before open square bracket '['\n" . $herecurr); 1686 ERROR("space prohibited before open square bracket '['\n" . $herecurr);
1502 } 1687 }
1503 } 1688 }
@@ -1632,7 +1817,7 @@ sub process {
1632 # unary operator, or a cast 1817 # unary operator, or a cast
1633 } elsif ($op eq '!' || $op eq '~' || 1818 } elsif ($op eq '!' || $op eq '~' ||
1634 $opv eq '*U' || $opv eq '-U' || 1819 $opv eq '*U' || $opv eq '-U' ||
1635 $opv eq '&U') { 1820 $opv eq '&U' || $opv eq '&&U') {
1636 if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 1821 if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
1637 ERROR("space required before that '$op' $at\n" . $hereptr); 1822 ERROR("space required before that '$op' $at\n" . $hereptr);
1638 } 1823 }
@@ -1785,7 +1970,26 @@ sub process {
1785 1970
1786# Check for illegal assignment in if conditional -- and check for trailing 1971# Check for illegal assignment in if conditional -- and check for trailing
1787# statements after the conditional. 1972# statements after the conditional.
1788 if ($line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 1973 if ($line =~ /do\s*(?!{)/) {
1974 my ($stat_next) = ctx_statement_block($line_nr_next,
1975 $remain_next, $off_next);
1976 $stat_next =~ s/\n./\n /g;
1977 ##print "stat<$stat> stat_next<$stat_next>\n";
1978
1979 if ($stat_next =~ /^\s*while\b/) {
1980 # If the statement carries leading newlines,
1981 # then count those as offsets.
1982 my ($whitespace) =
1983 ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
1984 my $offset =
1985 statement_rawlines($whitespace) - 1;
1986
1987 $suppress_whiletrailers{$line_nr_next +
1988 $offset} = 1;
1989 }
1990 }
1991 if (!defined $suppress_whiletrailers{$linenr} &&
1992 $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
1789 my ($s, $c) = ($stat, $cond); 1993 my ($s, $c) = ($stat, $cond);
1790 1994
1791 if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/) { 1995 if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/) {
@@ -1800,57 +2004,16 @@ sub process {
1800 if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 2004 if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
1801 $c !~ /}\s*while\s*/) 2005 $c !~ /}\s*while\s*/)
1802 { 2006 {
1803 ERROR("trailing statements should be on next line\n" . $herecurr); 2007 # Find out how long the conditional actually is.
1804 } 2008 my @newlines = ($c =~ /\n/gs);
1805 } 2009 my $cond_lines = 1 + $#newlines;
1806
1807# Check relative indent for conditionals and blocks.
1808 if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
1809 my ($s, $c) = ($stat, $cond);
1810
1811 substr($s, 0, length($c), '');
1812 2010
1813 # Make sure we remove the line prefixes as we have 2011 my $stat_real = raw_line($linenr, $cond_lines);
1814 # none on the first line, and are going to readd them 2012 if (defined($stat_real) && $cond_lines > 1) {
1815 # where necessary. 2013 $stat_real = "[...]\n$stat_real";
1816 $s =~ s/\n./\n/gs; 2014 }
1817
1818 # We want to check the first line inside the block
1819 # starting at the end of the conditional, so remove:
1820 # 1) any blank line termination
1821 # 2) any opening brace { on end of the line
1822 # 3) any do (...) {
1823 my $continuation = 0;
1824 my $check = 0;
1825 $s =~ s/^.*\bdo\b//;
1826 $s =~ s/^\s*{//;
1827 if ($s =~ s/^\s*\\//) {
1828 $continuation = 1;
1829 }
1830 if ($s =~ s/^\s*\n//) {
1831 $check = 1;
1832 }
1833
1834 # Also ignore a loop construct at the end of a
1835 # preprocessor statement.
1836 if (($prevline =~ /^.\s*#\s*define\s/ ||
1837 $prevline =~ /\\\s*$/) && $continuation == 0) {
1838 $check = 0;
1839 }
1840
1841 # Ignore the current line if its is a preprocessor
1842 # line.
1843 if ($s =~ /^\s*#\s*/) {
1844 $check = 0;
1845 }
1846
1847 my (undef, $sindent) = line_stats("+" . $s);
1848
1849 ##print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s>\n";
1850 2015
1851 if ($check && (($sindent % 8) != 0 || 2016 ERROR("trailing statements should be on next line\n" . $herecurr . $stat_real);
1852 ($sindent <= $indent && $s ne ''))) {
1853 WARN("suspect code indent for conditional statements\n" . $herecurr);
1854 } 2017 }
1855 } 2018 }
1856 2019
@@ -1877,6 +2040,15 @@ sub process {
1877 ERROR("trailing statements should be on next line\n" . $herecurr); 2040 ERROR("trailing statements should be on next line\n" . $herecurr);
1878 } 2041 }
1879 } 2042 }
2043# case and default should not have general statements after them
2044 if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
2045 $line !~ /\G(?:
2046 (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
2047 \s*return\s+
2048 )/xg)
2049 {
2050 ERROR("trailing statements should be on next line\n" . $herecurr);
2051 }
1880 2052
1881 # Check for }<nl>else {, these must be at the same 2053 # Check for }<nl>else {, these must be at the same
1882 # indent level to be relevant to each other. 2054 # indent level to be relevant to each other.
@@ -1913,12 +2085,17 @@ sub process {
1913 2085
1914#warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line) 2086#warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line)
1915 if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 2087 if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
1916 my $checkfile = "include/linux/$1.h"; 2088 my $file = "$1.h";
1917 if (-f "$root/$checkfile" && $realfile ne $checkfile && 2089 my $checkfile = "include/linux/$file";
2090 if (-f "$root/$checkfile" &&
2091 $realfile ne $checkfile &&
1918 $1 ne 'irq') 2092 $1 ne 'irq')
1919 { 2093 {
1920 WARN("Use #include <linux/$1.h> instead of <asm/$1.h>\n" . 2094 if ($realfile =~ m{^arch/}) {
1921 $herecurr); 2095 CHK("Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
2096 } else {
2097 WARN("Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
2098 }
1922 } 2099 }
1923 } 2100 }
1924 2101
@@ -1953,8 +2130,8 @@ sub process {
1953 # Extract the remainder of the define (if any) and 2130 # Extract the remainder of the define (if any) and
1954 # rip off surrounding spaces, and trailing \'s. 2131 # rip off surrounding spaces, and trailing \'s.
1955 $rest = ''; 2132 $rest = '';
1956 while ($off != 0 || ($cnt > 0 && $rest =~ /(?:^|\\)\s*$/)) { 2133 while ($off != 0 || ($cnt > 0 && $rest =~ /\\\s*$/)) {
1957 #print "ADDING $off <" . substr($lines[$ln - 1], $off) . ">\n"; 2134 #print "ADDING cnt<$cnt> $off <" . substr($lines[$ln - 1], $off) . "> rest<$rest>\n";
1958 if ($off != 0 || $lines[$ln - 1] !~ /^-/) { 2135 if ($off != 0 || $lines[$ln - 1] !~ /^-/) {
1959 $rest .= substr($lines[$ln - 1], $off) . "\n"; 2136 $rest .= substr($lines[$ln - 1], $off) . "\n";
1960 $cnt--; 2137 $cnt--;
@@ -1978,9 +2155,10 @@ sub process {
1978 $dstat =~ s/\s*$//s; 2155 $dstat =~ s/\s*$//s;
1979 2156
1980 # Flatten any parentheses and braces 2157 # Flatten any parentheses and braces
1981 while ($dstat =~ s/\([^\(\)]*\)/1/) { 2158 while ($dstat =~ s/\([^\(\)]*\)/1/ ||
1982 } 2159 $dstat =~ s/\{[^\{\}]*\}/1/ ||
1983 while ($dstat =~ s/\{[^\{\}]*\}/1/) { 2160 $dstat =~ s/\[[^\{\}]*\]/1/)
2161 {
1984 } 2162 }
1985 2163
1986 my $exceptions = qr{ 2164 my $exceptions = qr{
@@ -2003,6 +2181,7 @@ sub process {
2003 if ($dstat ne '' && 2181 if ($dstat ne '' &&
2004 $dstat !~ /^(?:$Ident|-?$Constant)$/ && 2182 $dstat !~ /^(?:$Ident|-?$Constant)$/ &&
2005 $dstat !~ /$exceptions/ && 2183 $dstat !~ /$exceptions/ &&
2184 $dstat !~ /^\.$Ident\s*=/ &&
2006 $dstat =~ /$Operators/) 2185 $dstat =~ /$Operators/)
2007 { 2186 {
2008 ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n"); 2187 ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n");
@@ -2103,10 +2282,10 @@ sub process {
2103 } 2282 }
2104 if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 2283 if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
2105 my $herectx = $here . "\n";; 2284 my $herectx = $here . "\n";;
2106 my $end = $linenr + statement_rawlines($block) - 1; 2285 my $cnt = statement_rawlines($block);
2107 2286
2108 for (my $ln = $linenr - 1; $ln < $end; $ln++) { 2287 for (my $n = 0; $n < $cnt; $n++) {
2109 $herectx .= $rawlines[$ln] . "\n";; 2288 $herectx .= raw_line($linenr, $n) . "\n";;
2110 } 2289 }
2111 2290
2112 WARN("braces {} are not necessary for single statement blocks\n" . $herectx); 2291 WARN("braces {} are not necessary for single statement blocks\n" . $herectx);
@@ -2281,6 +2460,7 @@ sub process {
2281 my $string; 2460 my $string;
2282 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 2461 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
2283 $string = substr($rawline, $-[1], $+[1] - $-[1]); 2462 $string = substr($rawline, $-[1], $+[1] - $-[1]);
2463 $string =~ s/%%/__/g;
2284 if ($string =~ /(?<!%)%L[udi]/) { 2464 if ($string =~ /(?<!%)%L[udi]/) {
2285 WARN("\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr); 2465 WARN("\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);
2286 last; 2466 last;
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
index 3eca62566d6b..f7e8e93ff30d 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -81,7 +81,10 @@ my (@stack, $re, $dre, $x, $xs);
81 $re = qr/.*st[dw]u.*r1,-($x{1,8})\(r1\)/o; 81 $re = qr/.*st[dw]u.*r1,-($x{1,8})\(r1\)/o;
82 } elsif ($arch =~ /^s390x?$/) { 82 } elsif ($arch =~ /^s390x?$/) {
83 # 11160: a7 fb ff 60 aghi %r15,-160 83 # 11160: a7 fb ff 60 aghi %r15,-160
84 $re = qr/.*ag?hi.*\%r15,-(([0-9]{2}|[3-9])[0-9]{2})/o; 84 # or
85 # 100092: e3 f0 ff c8 ff 71 lay %r15,-56(%r15)
86 $re = qr/.*(?:lay|ag?hi).*\%r15,-(([0-9]{2}|[3-9])[0-9]{2})
87 (?:\(\%r15\))?$/ox;
85 } elsif ($arch =~ /^sh64$/) { 88 } elsif ($arch =~ /^sh64$/) {
86 #XXX: we only check for the immediate case presently, 89 #XXX: we only check for the immediate case presently,
87 # though we will want to check for the movi/sub 90 # though we will want to check for the movi/sub
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 4c9890ec2528..d4dc222a74f3 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -206,6 +206,20 @@ static void do_usb_table(void *symval, unsigned long size,
206 do_usb_entry_multi(symval + i, mod); 206 do_usb_entry_multi(symval + i, mod);
207} 207}
208 208
209/* Looks like: hid:bNvNpN */
210static int do_hid_entry(const char *filename,
211 struct hid_device_id *id, char *alias)
212{
213 id->vendor = TO_NATIVE(id->vendor);
214 id->product = TO_NATIVE(id->product);
215
216 sprintf(alias, "hid:b%04X", id->bus);
217 ADD(alias, "v", id->vendor != HID_ANY_ID, id->vendor);
218 ADD(alias, "p", id->product != HID_ANY_ID, id->product);
219
220 return 1;
221}
222
209/* Looks like: ieee1394:venNmoNspNverN */ 223/* Looks like: ieee1394:venNmoNspNverN */
210static int do_ieee1394_entry(const char *filename, 224static int do_ieee1394_entry(const char *filename,
211 struct ieee1394_device_id *id, char *alias) 225 struct ieee1394_device_id *id, char *alias)
@@ -629,6 +643,59 @@ static int do_i2c_entry(const char *filename, struct i2c_device_id *id,
629 return 1; 643 return 1;
630} 644}
631 645
646static const struct dmifield {
647 const char *prefix;
648 int field;
649} dmi_fields[] = {
650 { "bvn", DMI_BIOS_VENDOR },
651 { "bvr", DMI_BIOS_VERSION },
652 { "bd", DMI_BIOS_DATE },
653 { "svn", DMI_SYS_VENDOR },
654 { "pn", DMI_PRODUCT_NAME },
655 { "pvr", DMI_PRODUCT_VERSION },
656 { "rvn", DMI_BOARD_VENDOR },
657 { "rn", DMI_BOARD_NAME },
658 { "rvr", DMI_BOARD_VERSION },
659 { "cvn", DMI_CHASSIS_VENDOR },
660 { "ct", DMI_CHASSIS_TYPE },
661 { "cvr", DMI_CHASSIS_VERSION },
662 { NULL, DMI_NONE }
663};
664
665static void dmi_ascii_filter(char *d, const char *s)
666{
667 /* Filter out characters we don't want to see in the modalias string */
668 for (; *s; s++)
669 if (*s > ' ' && *s < 127 && *s != ':')
670 *(d++) = *s;
671
672 *d = 0;
673}
674
675
676static int do_dmi_entry(const char *filename, struct dmi_system_id *id,
677 char *alias)
678{
679 int i, j;
680
681 sprintf(alias, "dmi*");
682
683 for (i = 0; i < ARRAY_SIZE(dmi_fields); i++) {
684 for (j = 0; j < 4; j++) {
685 if (id->matches[j].slot &&
686 id->matches[j].slot == dmi_fields[i].field) {
687 sprintf(alias + strlen(alias), ":%s*",
688 dmi_fields[i].prefix);
689 dmi_ascii_filter(alias + strlen(alias),
690 id->matches[j].substr);
691 strcat(alias, "*");
692 }
693 }
694 }
695
696 strcat(alias, ":");
697 return 1;
698}
632/* Ignore any prefix, eg. some architectures prepend _ */ 699/* Ignore any prefix, eg. some architectures prepend _ */
633static inline int sym_is(const char *symbol, const char *name) 700static inline int sym_is(const char *symbol, const char *name)
634{ 701{
@@ -692,6 +759,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
692 else if (sym_is(symname, "__mod_usb_device_table")) 759 else if (sym_is(symname, "__mod_usb_device_table"))
693 /* special case to handle bcdDevice ranges */ 760 /* special case to handle bcdDevice ranges */
694 do_usb_table(symval, sym->st_size, mod); 761 do_usb_table(symval, sym->st_size, mod);
762 else if (sym_is(symname, "__mod_hid_device_table"))
763 do_table(symval, sym->st_size,
764 sizeof(struct hid_device_id), "hid",
765 do_hid_entry, mod);
695 else if (sym_is(symname, "__mod_ieee1394_device_table")) 766 else if (sym_is(symname, "__mod_ieee1394_device_table"))
696 do_table(symval, sym->st_size, 767 do_table(symval, sym->st_size,
697 sizeof(struct ieee1394_device_id), "ieee1394", 768 sizeof(struct ieee1394_device_id), "ieee1394",
@@ -760,6 +831,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
760 do_table(symval, sym->st_size, 831 do_table(symval, sym->st_size,
761 sizeof(struct i2c_device_id), "i2c", 832 sizeof(struct i2c_device_id), "i2c",
762 do_i2c_entry, mod); 833 do_i2c_entry, mod);
834 else if (sym_is(symname, "__mod_dmi_device_table"))
835 do_table(symval, sym->st_size,
836 sizeof(struct dmi_system_id), "dmi",
837 do_dmi_entry, mod);
763 free(zeros); 838 free(zeros);
764} 839}
765 840
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 8e0de6a5e18a..88921611b22e 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1726,6 +1726,14 @@ static void add_header(struct buffer *b, struct module *mod)
1726 buf_printf(b, "};\n"); 1726 buf_printf(b, "};\n");
1727} 1727}
1728 1728
1729void add_staging_flag(struct buffer *b, const char *name)
1730{
1731 static const char *staging_dir = "drivers/staging";
1732
1733 if (strncmp(staging_dir, name, strlen(staging_dir)) == 0)
1734 buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
1735}
1736
1729/** 1737/**
1730 * Record CRCs for unresolved symbols 1738 * Record CRCs for unresolved symbols
1731 **/ 1739 **/
@@ -2135,6 +2143,7 @@ int main(int argc, char **argv)
2135 buf.pos = 0; 2143 buf.pos = 0;
2136 2144
2137 add_header(&buf, mod); 2145 add_header(&buf, mod);
2146 add_staging_flag(&buf, mod->name);
2138 err |= add_versions(&buf, mod); 2147 err |= add_versions(&buf, mod);
2139 add_depends(&buf, mod, modules); 2148 add_depends(&buf, mod, modules);
2140 add_moddevtable(&buf, mod); 2149 add_moddevtable(&buf, mod);
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
new file mode 100755
index 000000000000..f56d760bd589
--- /dev/null
+++ b/scripts/recordmcount.pl
@@ -0,0 +1,395 @@
1#!/usr/bin/perl -w
2# (c) 2008, Steven Rostedt <srostedt@redhat.com>
3# Licensed under the terms of the GNU GPL License version 2
4#
5# recordmcount.pl - makes a section called __mcount_loc that holds
6# all the offsets to the calls to mcount.
7#
8#
9# What we want to end up with is a section in vmlinux called
10# __mcount_loc that contains a list of pointers to all the
11# call sites in the kernel that call mcount. Later on boot up, the kernel
12# will read this list, save the locations and turn them into nops.
13# When tracing or profiling is later enabled, these locations will then
14# be converted back to pointers to some function.
15#
16# This is no easy feat. This script is called just after the original
17# object is compiled and before it is linked.
18#
19# The references to the call sites are offsets from the section of text
20# that the call site is in. Hence, all functions in a section that
21# has a call site to mcount, will have the offset from the beginning of
22# the section and not the beginning of the function.
23#
24# The trick is to find a way to record the beginning of the section.
25# The way we do this is to look at the first function in the section
26# which will also be the location of that section after final link.
27# e.g.
28#
29# .section ".text.sched"
30# .globl my_func
31# my_func:
32# [...]
33# call mcount (offset: 0x5)
34# [...]
35# ret
36# other_func:
37# [...]
38# call mcount (offset: 0x1b)
39# [...]
40#
41# Both relocation offsets for the mcounts in the above example will be
42# offset from .text.sched. If we make another file called tmp.s with:
43#
44# .section __mcount_loc
45# .quad my_func + 0x5
46# .quad my_func + 0x1b
47#
48# We can then compile this tmp.s into tmp.o, and link it to the original
49# object.
50#
51# But this gets hard if my_func is not globl (a static function).
52# In such a case we have:
53#
54# .section ".text.sched"
55# my_func:
56# [...]
57# call mcount (offset: 0x5)
58# [...]
59# ret
60# .globl my_func
61# other_func:
62# [...]
63# call mcount (offset: 0x1b)
64# [...]
65#
66# If we make the tmp.s the same as above, when we link together with
67# the original object, we will end up with two symbols for my_func:
68# one local, one global. After final compile, we will end up with
69# an undefined reference to my_func.
70#
71# Since local objects can reference local variables, we need to find
72# a way to make tmp.o reference the local objects of the original object
73# file after it is linked together. To do this, we convert the my_func
74# into a global symbol before linking tmp.o. Then after we link tmp.o
75# we will only have a single symbol for my_func that is global.
76# We can convert my_func back into a local symbol and we are done.
77#
78# Here are the steps we take:
79#
80# 1) Record all the local symbols by using 'nm'
81# 2) Use objdump to find all the call site offsets and sections for
82# mcount.
83# 3) Compile the list into its own object.
84# 4) Do we have to deal with local functions? If not, go to step 8.
85# 5) Make an object that converts these local functions to global symbols
86# with objcopy.
87# 6) Link together this new object with the list object.
88# 7) Convert the local functions back to local symbols and rename
89# the result as the original object.
90# End.
91# 8) Link the object with the list object.
92# 9) Move the result back to the original object.
93# End.
94#
95
96use strict;
97
98my $P = $0;
99$P =~ s@.*/@@g;
100
101my $V = '0.1';
102
103if ($#ARGV < 6) {
104 print "usage: $P arch objdump objcopy cc ld nm rm mv inputfile\n";
105 print "version: $V\n";
106 exit(1);
107}
108
109my ($arch, $objdump, $objcopy, $cc, $ld, $nm, $rm, $mv, $inputfile) = @ARGV;
110
111$objdump = "objdump" if ((length $objdump) == 0);
112$objcopy = "objcopy" if ((length $objcopy) == 0);
113$cc = "gcc" if ((length $cc) == 0);
114$ld = "ld" if ((length $ld) == 0);
115$nm = "nm" if ((length $nm) == 0);
116$rm = "rm" if ((length $rm) == 0);
117$mv = "mv" if ((length $mv) == 0);
118
119#print STDERR "running: $P '$arch' '$objdump' '$objcopy' '$cc' '$ld' " .
120# "'$nm' '$rm' '$mv' '$inputfile'\n";
121
122my %locals; # List of local (static) functions
123my %weak; # List of weak functions
124my %convert; # List of local functions used that needs conversion
125
126my $type;
127my $section_regex; # Find the start of a section
128my $function_regex; # Find the name of a function
129 # (return offset and func name)
130my $mcount_regex; # Find the call site to mcount (return offset)
131
132if ($arch eq "x86_64") {
133 $section_regex = "Disassembly of section";
134 $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
135 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount([+-]0x[0-9a-zA-Z]+)?\$";
136 $type = ".quad";
137
138 # force flags for this arch
139 $ld .= " -m elf_x86_64";
140 $objdump .= " -M x86-64";
141 $objcopy .= " -O elf64-x86-64";
142 $cc .= " -m64";
143
144} elsif ($arch eq "i386") {
145 $section_regex = "Disassembly of section";
146 $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
147 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";
148 $type = ".long";
149
150 # force flags for this arch
151 $ld .= " -m elf_i386";
152 $objdump .= " -M i386";
153 $objcopy .= " -O elf32-i386";
154 $cc .= " -m32";
155
156} else {
157 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
158}
159
160my $text_found = 0;
161my $read_function = 0;
162my $opened = 0;
163my $mcount_section = "__mcount_loc";
164
165my $dirname;
166my $filename;
167my $prefix;
168my $ext;
169
170if ($inputfile =~ m,^(.*)/([^/]*)$,) {
171 $dirname = $1;
172 $filename = $2;
173} else {
174 $dirname = ".";
175 $filename = $inputfile;
176}
177
178if ($filename =~ m,^(.*)(\.\S),) {
179 $prefix = $1;
180 $ext = $2;
181} else {
182 $prefix = $filename;
183 $ext = "";
184}
185
186my $mcount_s = $dirname . "/.tmp_mc_" . $prefix . ".s";
187my $mcount_o = $dirname . "/.tmp_mc_" . $prefix . ".o";
188
189#
190# --globalize-symbols came out in 2.17, we must test the version
191# of objcopy, and if it is less than 2.17, then we can not
192# record local functions.
193my $use_locals = 01;
194my $local_warn_once = 0;
195my $found_version = 0;
196
197open (IN, "$objcopy --version |") || die "error running $objcopy";
198while (<IN>) {
199 if (/objcopy.*\s(\d+)\.(\d+)/) {
200 my $major = $1;
201 my $minor = $2;
202
203 $found_version = 1;
204 if ($major < 2 ||
205 ($major == 2 && $minor < 17)) {
206 $use_locals = 0;
207 }
208 last;
209 }
210}
211close (IN);
212
213if (!$found_version) {
214 print STDERR "WARNING: could not find objcopy version.\n" .
215 "\tDisabling local function references.\n";
216}
217
218
219#
220# Step 1: find all the local (static functions) and weak symbols.
221# 't' is local, 'w/W' is weak (we never use a weak function)
222#
223open (IN, "$nm $inputfile|") || die "error running $nm";
224while (<IN>) {
225 if (/^[0-9a-fA-F]+\s+t\s+(\S+)/) {
226 $locals{$1} = 1;
227 } elsif (/^[0-9a-fA-F]+\s+([wW])\s+(\S+)/) {
228 $weak{$2} = $1;
229 }
230}
231close(IN);
232
233my @offsets; # Array of offsets of mcount callers
234my $ref_func; # reference function to use for offsets
235my $offset = 0; # offset of ref_func to section beginning
236
237##
238# update_funcs - print out the current mcount callers
239#
240# Go through the list of offsets to callers and write them to
241# the output file in a format that can be read by an assembler.
242#
243sub update_funcs
244{
245 return if ($#offsets < 0);
246
247 defined($ref_func) || die "No function to reference";
248
249 # A section only had a weak function, to represent it.
250 # Unfortunately, a weak function may be overwritten by another
251 # function of the same name, making all these offsets incorrect.
252 # To be safe, we simply print a warning and bail.
253 if (defined $weak{$ref_func}) {
254 print STDERR
255 "$inputfile: WARNING: referencing weak function" .
256 " $ref_func for mcount\n";
257 return;
258 }
259
260 # is this function static? If so, note this fact.
261 if (defined $locals{$ref_func}) {
262
263 # only use locals if objcopy supports globalize-symbols
264 if (!$use_locals) {
265 return;
266 }
267 $convert{$ref_func} = 1;
268 }
269
270 # Loop through all the mcount caller offsets and print a reference
271 # to the caller based from the ref_func.
272 for (my $i=0; $i <= $#offsets; $i++) {
273 if (!$opened) {
274 open(FILE, ">$mcount_s") || die "can't create $mcount_s\n";
275 $opened = 1;
276 print FILE "\t.section $mcount_section,\"a\",\@progbits\n";
277 }
278 printf FILE "\t%s %s + %d\n", $type, $ref_func, $offsets[$i] - $offset;
279 }
280}
281
282#
283# Step 2: find the sections and mcount call sites
284#
285open(IN, "$objdump -dr $inputfile|") || die "error running $objdump";
286
287my $text;
288
289while (<IN>) {
290 # is it a section?
291 if (/$section_regex/) {
292 $read_function = 1;
293 # print out any recorded offsets
294 update_funcs() if ($text_found);
295
296 # reset all markers and arrays
297 $text_found = 0;
298 undef($ref_func);
299 undef(@offsets);
300
301 # section found, now is this a start of a function?
302 } elsif ($read_function && /$function_regex/) {
303 $text_found = 1;
304 $offset = hex $1;
305 $text = $2;
306
307 # if this is either a local function or a weak function
308 # keep looking for functions that are global that
309 # we can use safely.
310 if (!defined($locals{$text}) && !defined($weak{$text})) {
311 $ref_func = $text;
312 $read_function = 0;
313 } else {
314 # if we already have a function, and this is weak, skip it
315 if (!defined($ref_func) || !defined($weak{$text})) {
316 $ref_func = $text;
317 }
318 }
319 }
320
321 # is this a call site to mcount? If so, record it to print later
322 if ($text_found && /$mcount_regex/) {
323 $offsets[$#offsets + 1] = hex $1;
324 }
325}
326
327# dump out anymore offsets that may have been found
328update_funcs() if ($text_found);
329
330# If we did not find any mcount callers, we are done (do nothing).
331if (!$opened) {
332 exit(0);
333}
334
335close(FILE);
336
337#
338# Step 3: Compile the file that holds the list of call sites to mcount.
339#
340`$cc -o $mcount_o -c $mcount_s`;
341
342my @converts = keys %convert;
343
344#
345# Step 4: Do we have sections that started with local functions?
346#
347if ($#converts >= 0) {
348 my $globallist = "";
349 my $locallist = "";
350
351 foreach my $con (@converts) {
352 $globallist .= " --globalize-symbol $con";
353 $locallist .= " --localize-symbol $con";
354 }
355
356 my $globalobj = $dirname . "/.tmp_gl_" . $filename;
357 my $globalmix = $dirname . "/.tmp_mx_" . $filename;
358
359 #
360 # Step 5: set up each local function as a global
361 #
362 `$objcopy $globallist $inputfile $globalobj`;
363
364 #
365 # Step 6: Link the global version to our list.
366 #
367 `$ld -r $globalobj $mcount_o -o $globalmix`;
368
369 #
370 # Step 7: Convert the local functions back into local symbols
371 #
372 `$objcopy $locallist $globalmix $inputfile`;
373
374 # Remove the temp files
375 `$rm $globalobj $globalmix`;
376
377} else {
378
379 my $mix = $dirname . "/.tmp_mx_" . $filename;
380
381 #
382 # Step 8: Link the object with our list of call sites object.
383 #
384 `$ld -r $inputfile $mcount_o -o $mix`;
385
386 #
387 # Step 9: Move the result back to the original object.
388 #
389 `$mv $mix $inputfile`;
390}
391
392# Clean up the temp files
393`$rm $mcount_o $mcount_s`;
394
395exit(0);
diff --git a/scripts/selinux/Makefile b/scripts/selinux/Makefile
new file mode 100644
index 000000000000..ca4b1ec01822
--- /dev/null
+++ b/scripts/selinux/Makefile
@@ -0,0 +1,2 @@
1subdir-y := mdp
2subdir- += mdp
diff --git a/scripts/selinux/README b/scripts/selinux/README
new file mode 100644
index 000000000000..a936315ba2c8
--- /dev/null
+++ b/scripts/selinux/README
@@ -0,0 +1,2 @@
1Please see Documentation/SELinux.txt for information on
2installing a dummy SELinux policy.
diff --git a/scripts/selinux/install_policy.sh b/scripts/selinux/install_policy.sh
new file mode 100644
index 000000000000..7b9ccf61f8f9
--- /dev/null
+++ b/scripts/selinux/install_policy.sh
@@ -0,0 +1,69 @@
1#!/bin/sh
2if [ `id -u` -ne 0 ]; then
3 echo "$0: must be root to install the selinux policy"
4 exit 1
5fi
6SF=`which setfiles`
7if [ $? -eq 1 ]; then
8 if [ -f /sbin/setfiles ]; then
9 SF="/usr/setfiles"
10 else
11 echo "no selinux tools installed: setfiles"
12 exit 1
13 fi
14fi
15
16cd mdp
17
18CP=`which checkpolicy`
19VERS=`$CP -V | awk '{print $1}'`
20
21./mdp policy.conf file_contexts
22$CP -o policy.$VERS policy.conf
23
24mkdir -p /etc/selinux/dummy/policy
25mkdir -p /etc/selinux/dummy/contexts/files
26
27cp file_contexts /etc/selinux/dummy/contexts/files
28cp dbus_contexts /etc/selinux/dummy/contexts
29cp policy.$VERS /etc/selinux/dummy/policy
30FC_FILE=/etc/selinux/dummy/contexts/files/file_contexts
31
32if [ ! -d /etc/selinux ]; then
33 mkdir -p /etc/selinux
34fi
35if [ ! -f /etc/selinux/config ]; then
36 cat > /etc/selinux/config << EOF
37SELINUX=enforcing
38SELINUXTYPE=dummy
39EOF
40else
41 TYPE=`cat /etc/selinux/config | grep "^SELINUXTYPE" | tail -1 | awk -F= '{ print $2 '}`
42 if [ "eq$TYPE" != "eqdummy" ]; then
43 selinuxenabled
44 if [ $? -eq 0 ]; then
45 echo "SELinux already enabled with a non-dummy policy."
46 echo "Exiting. Please install policy by hand if that"
47 echo "is what you REALLY want."
48 exit 1
49 fi
50 mv /etc/selinux/config /etc/selinux/config.mdpbak
51 grep -v "^SELINUXTYPE" /etc/selinux/config.mdpbak >> /etc/selinux/config
52 echo "SELINUXTYPE=dummy" >> /etc/selinux/config
53 fi
54fi
55
56cd /etc/selinux/dummy/contexts/files
57$SF file_contexts /
58
59mounts=`cat /proc/$$/mounts | egrep "ext2|ext3|xfs|jfs|ext4|ext4dev|gfs2" | awk '{ print $2 '}`
60$SF file_contexts $mounts
61
62
63dodev=`cat /proc/$$/mounts | grep "/dev "`
64if [ "eq$dodev" != "eq" ]; then
65 mount --move /dev /mnt
66 $SF file_contexts /dev
67 mount --move /mnt /dev
68fi
69
diff --git a/scripts/selinux/mdp/.gitignore b/scripts/selinux/mdp/.gitignore
new file mode 100644
index 000000000000..654546d8dffd
--- /dev/null
+++ b/scripts/selinux/mdp/.gitignore
@@ -0,0 +1,2 @@
1# Generated file
2mdp
diff --git a/scripts/selinux/mdp/Makefile b/scripts/selinux/mdp/Makefile
new file mode 100644
index 000000000000..eb365b333441
--- /dev/null
+++ b/scripts/selinux/mdp/Makefile
@@ -0,0 +1,5 @@
1hostprogs-y := mdp
2HOST_EXTRACFLAGS += -Isecurity/selinux/include
3
4always := $(hostprogs-y)
5clean-files := $(hostprogs-y) policy.* file_contexts
diff --git a/scripts/selinux/mdp/dbus_contexts b/scripts/selinux/mdp/dbus_contexts
new file mode 100644
index 000000000000..116e684f9fc1
--- /dev/null
+++ b/scripts/selinux/mdp/dbus_contexts
@@ -0,0 +1,6 @@
1<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
2 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
3<busconfig>
4 <selinux>
5 </selinux>
6</busconfig>
diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c
new file mode 100644
index 000000000000..ca757d486187
--- /dev/null
+++ b/scripts/selinux/mdp/mdp.c
@@ -0,0 +1,242 @@
1/*
2 *
3 * mdp - make dummy policy
4 *
5 * When pointed at a kernel tree, builds a dummy policy for that kernel
6 * with exactly one type with full rights to itself.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 * Copyright (C) IBM Corporation, 2006
23 *
24 * Authors: Serge E. Hallyn <serue@us.ibm.com>
25 */
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <unistd.h>
30#include <string.h>
31
32#include "flask.h"
33
34void usage(char *name)
35{
36 printf("usage: %s [-m] policy_file context_file\n", name);
37 exit(1);
38}
39
40void find_common_name(char *cname, char *dest, int len)
41{
42 char *start, *end;
43
44 start = strchr(cname, '_')+1;
45 end = strchr(start, '_');
46 if (!start || !end || start-cname > len || end-start > len) {
47 printf("Error with commons defines\n");
48 exit(1);
49 }
50 strncpy(dest, start, end-start);
51 dest[end-start] = '\0';
52}
53
54#define S_(x) x,
55static char *classlist[] = {
56#include "class_to_string.h"
57 NULL
58};
59#undef S_
60
61#include "initial_sid_to_string.h"
62
63#define TB_(x) char *x[] = {
64#define TE_(x) NULL };
65#define S_(x) x,
66#include "common_perm_to_string.h"
67#undef TB_
68#undef TE_
69#undef S_
70
71struct common {
72 char *cname;
73 char **perms;
74};
75struct common common[] = {
76#define TB_(x) { #x, x },
77#define S_(x)
78#define TE_(x)
79#include "common_perm_to_string.h"
80#undef TB_
81#undef TE_
82#undef S_
83};
84
85#define S_(x, y, z) {x, #y},
86struct av_inherit {
87 int class;
88 char *common;
89};
90struct av_inherit av_inherit[] = {
91#include "av_inherit.h"
92};
93#undef S_
94
95#include "av_permissions.h"
96#define S_(x, y, z) {x, y, z},
97struct av_perms {
98 int class;
99 int perm_i;
100 char *perm_s;
101};
102struct av_perms av_perms[] = {
103#include "av_perm_to_string.h"
104};
105#undef S_
106
107int main(int argc, char *argv[])
108{
109 int i, j, mls = 0;
110 char **arg, *polout, *ctxout;
111 int classlist_len, initial_sid_to_string_len;
112 FILE *fout;
113
114 if (argc < 3)
115 usage(argv[0]);
116 arg = argv+1;
117 if (argc==4 && strcmp(argv[1], "-m") == 0) {
118 mls = 1;
119 arg++;
120 }
121 polout = *arg++;
122 ctxout = *arg;
123
124 fout = fopen(polout, "w");
125 if (!fout) {
126 printf("Could not open %s for writing\n", polout);
127 usage(argv[0]);
128 }
129
130 classlist_len = sizeof(classlist) / sizeof(char *);
131 /* print out the classes */
132 for (i=1; i < classlist_len; i++) {
133 if(classlist[i])
134 fprintf(fout, "class %s\n", classlist[i]);
135 else
136 fprintf(fout, "class user%d\n", i);
137 }
138 fprintf(fout, "\n");
139
140 initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *);
141 /* print out the sids */
142 for (i=1; i < initial_sid_to_string_len; i++)
143 fprintf(fout, "sid %s\n", initial_sid_to_string[i]);
144 fprintf(fout, "\n");
145
146 /* print out the commons */
147 for (i=0; i< sizeof(common)/sizeof(struct common); i++) {
148 char cname[101];
149 find_common_name(common[i].cname, cname, 100);
150 cname[100] = '\0';
151 fprintf(fout, "common %s\n{\n", cname);
152 for (j=0; common[i].perms[j]; j++)
153 fprintf(fout, "\t%s\n", common[i].perms[j]);
154 fprintf(fout, "}\n\n");
155 }
156 fprintf(fout, "\n");
157
158 /* print out the class permissions */
159 for (i=1; i < classlist_len; i++) {
160 if (classlist[i]) {
161 int firstperm = -1, numperms = 0;
162
163 fprintf(fout, "class %s\n", classlist[i]);
164 /* does it inherit from a common? */
165 for (j=0; j < sizeof(av_inherit)/sizeof(struct av_inherit); j++)
166 if (av_inherit[j].class == i)
167 fprintf(fout, "inherits %s\n", av_inherit[j].common);
168
169 for (j=0; j < sizeof(av_perms)/sizeof(struct av_perms); j++) {
170 if (av_perms[j].class == i) {
171 if (firstperm == -1)
172 firstperm = j;
173 numperms++;
174 }
175 }
176 if (!numperms) {
177 fprintf(fout, "\n");
178 continue;
179 }
180
181 fprintf(fout, "{\n");
182 /* print out the av_perms */
183 for (j=0; j < numperms; j++) {
184 fprintf(fout, "\t%s\n", av_perms[firstperm+j].perm_s);
185 }
186 fprintf(fout, "}\n\n");
187 }
188 }
189 fprintf(fout, "\n");
190
191 /* NOW PRINT OUT MLS STUFF */
192 if (mls) {
193 printf("MLS not yet implemented\n");
194 exit(1);
195 }
196
197 /* types, roles, and allows */
198 fprintf(fout, "type base_t;\n");
199 fprintf(fout, "role base_r types { base_t };\n");
200 for (i=1; i < classlist_len; i++) {
201 if (classlist[i])
202 fprintf(fout, "allow base_t base_t:%s *;\n", classlist[i]);
203 else
204 fprintf(fout, "allow base_t base_t:user%d *;\n", i);
205 }
206 fprintf(fout, "user user_u roles { base_r };\n");
207 fprintf(fout, "\n");
208
209 /* default sids */
210 for (i=1; i < initial_sid_to_string_len; i++)
211 fprintf(fout, "sid %s user_u:base_r:base_t\n", initial_sid_to_string[i]);
212 fprintf(fout, "\n");
213
214
215 fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n");
216 fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n");
217 fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n");
218 fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n");
219 fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n");
220
221 fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n");
222 fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n");
223
224 fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n");
225 fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n");
226 fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n");
227
228 fprintf(fout, "genfscon proc / user_u:base_r:base_t\n");
229
230 fclose(fout);
231
232 fout = fopen(ctxout, "w");
233 if (!fout) {
234 printf("Wrote policy, but cannot open %s for writing\n", ctxout);
235 usage(argv[0]);
236 }
237 fprintf(fout, "/ user_u:base_r:base_t\n");
238 fprintf(fout, "/.* user_u:base_r:base_t\n");
239 fclose(fout);
240
241 return 0;
242}