diff options
| author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-03 22:41:33 -0300 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-03 22:41:33 -0300 |
| commit | f9cd49033b349b8be3bb1f01b39eed837853d880 (patch) | |
| tree | 7f10a70e420f83cce2709e67ff993270276f0277 /scripts | |
| parent | 2f2da1e2995c9362babd7da3cc9d340be184ea73 (diff) | |
| parent | 0d7614f09c1ebdbaa1599a5aba7593f147bf96ee (diff) | |
Merge tag 'v3.6-rc1' into staging/for_v3.6
Linux 3.6-rc1
* tag 'v3.6-rc1': (18733 commits)
Linux 3.6-rc1
mm: remove node_start_pfn checking in new WARN_ON for now
ARM: mmp: add missing irqs.h
arm: mvebu: fix typo in .dtsi comment for Armada XP SoCs
ARM: PRIMA2: delete redundant codes to restore LATCHED when timer resumes
libceph: fix crypto key null deref, memory leak
ceph: simplify+fix atomic_open
sh: explicitly include sh_dma.h in setup-sh7722.c
um: Add arch/x86/um to MAINTAINERS
um: pass siginfo to guest process
um: fix ubd_file_size for read-only files
md/dm-raid: DM_RAID should select MD_RAID10
md/raid1: submit IO from originating thread instead of md thread.
raid5: raid5d handle stripe in batch way
raid5: make_request use batch stripe release
um: pull interrupt_end() into userspace()
um: split syscall_trace(), pass pt_regs to it
um: switch UPT_SET_RETURN_VALUE and regs_return_value to pt_regs
MIPS: Loongson 2: Sort out clock managment.
locks: remove unused lm_release_private
...
Diffstat (limited to 'scripts')
28 files changed, 1510 insertions, 98 deletions
diff --git a/scripts/.gitignore b/scripts/.gitignore index 105b21f08185..65f362d931b5 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -9,3 +9,4 @@ unifdef ihex2fw recordmcount docproc +sortextable diff --git a/scripts/Makefile b/scripts/Makefile index df7678febf27..a55b0067758a 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -8,11 +8,16 @@ # conmakehash: Create arrays for initializing the kernel console tables # docproc: Used in Documentation/DocBook +HOST_EXTRACFLAGS += -I$(srctree)/tools/include + hostprogs-$(CONFIG_KALLSYMS) += kallsyms hostprogs-$(CONFIG_LOGO) += pnmtologo hostprogs-$(CONFIG_VT) += conmakehash hostprogs-$(CONFIG_IKCONFIG) += bin2c hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount +hostprogs-$(CONFIG_BUILDTIME_EXTABLE_SORT) += sortextable + +HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include always := $(hostprogs-y) $(hostprogs-m) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index faea0ec612bf..913d6bdfdda3 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1600,13 +1600,17 @@ sub process { # Check signature styles if (!$in_header_lines && - $line =~ /^(\s*)($signature_tags)(\s*)(.*)/) { + $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { my $space_before = $1; my $sign_off = $2; my $space_after = $3; my $email = $4; my $ucfirst_sign_off = ucfirst(lc($sign_off)); + if ($sign_off !~ /$signature_tags/) { + WARN("BAD_SIGN_OFF", + "Non-standard signature: $sign_off\n" . $herecurr); + } if (defined $space_before && $space_before ne "") { WARN("BAD_SIGN_OFF", "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr); @@ -1848,8 +1852,8 @@ sub process { my $pos = pos_last_openparen($rest); if ($pos >= 0) { - $line =~ /^\+([ \t]*)/; - my $newindent = $1; + $line =~ /^(\+| )([ \t]*)/; + my $newindent = $2; my $goodtabindent = $oldindent . "\t" x ($pos / 8) . @@ -2382,6 +2386,19 @@ sub process { } } + if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { + my $orig = $1; + my $level = lc($orig); + $level = "warn" if ($level eq "warning"); + WARN("PREFER_PR_LEVEL", + "Prefer pr_$level(... to printk(KERN_$1, ...\n" . $herecurr); + } + + if ($line =~ /\bpr_warning\s*\(/) { + WARN("PREFER_PR_LEVEL", + "Prefer pr_warn(... to pr_warning(...\n" . $herecurr); + } + # function brace can't be on same line, except for #defines of do while, # or if closed on same line if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and @@ -2448,6 +2465,13 @@ sub process { "space prohibited between function name and open parenthesis '('\n" . $herecurr); } } + +# check for whitespace before a non-naked semicolon + if ($line =~ /^\+.*\S\s+;/) { + CHK("SPACING", + "space prohibited before semicolon\n" . $herecurr); + } + # Check operator spacing. if (!($line=~/\#\s*include/)) { my $ops = qr{ @@ -2964,6 +2988,45 @@ sub process { } } +# do {} while (0) macro tests: +# single-statement macros do not need to be enclosed in do while (0) loop, +# macro should not end with a semicolon + if ($^V && $^V ge 5.10.0 && + $realfile !~ m@/vmlinux.lds.h$@ && + $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { + my $ln = $linenr; + my $cnt = $realcnt; + my ($off, $dstat, $dcond, $rest); + my $ctx = ''; + ($dstat, $dcond, $ln, $cnt, $off) = + ctx_statement_block($linenr, $realcnt, 0); + $ctx = $dstat; + + $dstat =~ s/\\\n.//g; + + if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { + my $stmts = $2; + my $semis = $3; + + $ctx =~ s/\n*$//; + my $cnt = statement_rawlines($ctx); + my $herectx = $here . "\n"; + + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + + if (($stmts =~ tr/;/;/) == 1) { + WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", + "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); + } + if (defined $semis && $semis ne "") { + WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", + "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); + } + } + } + # make sure symbols are always wrapped with VMLINUX_SYMBOL() ... # all assignments may have only one of the following with an assignment: # . @@ -3241,6 +3304,12 @@ sub process { "sizeof(& should be avoided\n" . $herecurr); } +# check for sizeof without parenthesis + if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { + WARN("SIZEOF_PARENTHESIS", + "sizeof $1 should be sizeof($1)\n" . $herecurr); + } + # check for line continuations in quoted strings with odd counts of " if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { WARN("LINE_CONTINUATIONS", @@ -3289,6 +3358,22 @@ sub process { } } +# check usleep_range arguments + if ($^V && $^V ge 5.10.0 && + defined $stat && + $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { + my $min = $1; + my $max = $7; + if ($min eq $max) { + WARN("USLEEP_RANGE", + "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); + } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && + $min > $max) { + WARN("USLEEP_RANGE", + "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); + } + } + # check for new externs in .c files. if ($realfile =~ /\.c$/ && defined $stat && $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) diff --git a/scripts/coccinelle/iterators/use_after_iter.cocci b/scripts/coccinelle/iterators/use_after_iter.cocci new file mode 100644 index 000000000000..06284c57a951 --- /dev/null +++ b/scripts/coccinelle/iterators/use_after_iter.cocci @@ -0,0 +1,147 @@ +/// If list_for_each_entry, etc complete a traversal of the list, the iterator +/// variable ends up pointing to an address at an offset from the list head, +/// and not a meaningful structure. Thus this value should not be used after +/// the end of the iterator. +//#False positives arise when there is a goto in the iterator and the +//#reported reference is at the label of this goto. Some flag tests +//#may also cause a report to be a false positive. +/// +// Confidence: Moderate +// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2012 Gilles Muller, INRIA/LIP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual context +virtual org +virtual report + +@r exists@ +identifier c,member; +expression E,x; +iterator name list_for_each_entry; +iterator name list_for_each_entry_reverse; +iterator name list_for_each_entry_continue; +iterator name list_for_each_entry_continue_reverse; +iterator name list_for_each_entry_from; +iterator name list_for_each_entry_safe; +iterator name list_for_each_entry_safe_continue; +iterator name list_for_each_entry_safe_from; +iterator name list_for_each_entry_safe_reverse; +iterator name hlist_for_each_entry; +iterator name hlist_for_each_entry_continue; +iterator name hlist_for_each_entry_from; +iterator name hlist_for_each_entry_safe; +statement S; +position p1,p2; +@@ + +( +list_for_each_entry@p1(c,...,member) { ... when != break; + when forall + when strict +} +| +list_for_each_entry_reverse@p1(c,...,member) { ... when != break; + when forall + when strict +} +| +list_for_each_entry_continue@p1(c,...,member) { ... when != break; + when forall + when strict +} +| +list_for_each_entry_continue_reverse@p1(c,...,member) { ... when != break; + when forall + when strict +} +| +list_for_each_entry_from@p1(c,...,member) { ... when != break; + when forall + when strict +} +| +list_for_each_entry_safe@p1(c,...,member) { ... when != break; + when forall + when strict +} +| +list_for_each_entry_safe_continue@p1(c,...,member) { ... when != break; + when forall + when strict +} +| +list_for_each_entry_safe_from@p1(c,...,member) { ... when != break; + when forall + when strict +} +| +list_for_each_entry_safe_reverse@p1(c,...,member) { ... when != break; + when forall + when strict +} +) +... +( +list_for_each_entry(c,...) S +| +list_for_each_entry_reverse(c,...) S +| +list_for_each_entry_continue(c,...) S +| +list_for_each_entry_continue_reverse(c,...) S +| +list_for_each_entry_from(c,...) S +| +list_for_each_entry_safe(c,...) S +| +list_for_each_entry_safe(x,c,...) S +| +list_for_each_entry_safe_continue(c,...) S +| +list_for_each_entry_safe_continue(x,c,...) S +| +list_for_each_entry_safe_from(c,...) S +| +list_for_each_entry_safe_from(x,c,...) S +| +list_for_each_entry_safe_reverse(c,...) S +| +list_for_each_entry_safe_reverse(x,c,...) S +| +hlist_for_each_entry(c,...) S +| +hlist_for_each_entry_continue(c,...) S +| +hlist_for_each_entry_from(c,...) S +| +hlist_for_each_entry_safe(c,...) S +| +list_remove_head(x,c,...) +| +sizeof(<+...c...+>) +| +&c->member +| +c = E +| +*c@p2 +) + +@script:python depends on org@ +p1 << r.p1; +p2 << r.p2; +@@ + +cocci.print_main("invalid iterator index reference",p2) +cocci.print_secs("iterator",p1) + +@script:python depends on report@ +p1 << r.p1; +p2 << r.p2; +@@ + +msg = "ERROR: invalid reference to the index variable of the iterator on line %s" % (p1[0].line) +coccilib.report.print_report(p2[0], msg) diff --git a/scripts/coccinelle/misc/ifaddr.cocci b/scripts/coccinelle/misc/ifaddr.cocci new file mode 100644 index 000000000000..3e4089a77000 --- /dev/null +++ b/scripts/coccinelle/misc/ifaddr.cocci @@ -0,0 +1,35 @@ +/// the address of a variable or field is non-zero is likely always to bo +/// non-zero +/// +// Confidence: High +// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual org +virtual report +virtual context + +@r@ +expression x; +statement S1,S2; +position p; +@@ + +*if@p (&x) + S1 else S2 + +@script:python depends on org@ +p << r.p; +@@ + +cocci.print_main("test of a variable/field address",p) + +@script:python depends on report@ +p << r.p; +@@ + +msg = "ERROR: test of a variable/field address" +coccilib.report.print_report(p[0],msg) diff --git a/scripts/coccinelle/misc/irqf_oneshot.cocci b/scripts/coccinelle/misc/irqf_oneshot.cocci new file mode 100644 index 000000000000..6cfde94be0ef --- /dev/null +++ b/scripts/coccinelle/misc/irqf_oneshot.cocci @@ -0,0 +1,65 @@ +/// Make sure threaded IRQs without a primary handler are always request with +/// IRQF_ONESHOT +/// +// +// Confidence: Good +// Comments: +// Options: --no-includes + +virtual patch +virtual context +virtual org +virtual report + +@r1@ +expression irq; +expression thread_fn; +expression flags; +position p; +@@ +request_threaded_irq@p(irq, NULL, thread_fn, +( +flags | IRQF_ONESHOT +| +IRQF_ONESHOT +) +, ...) + +@depends on patch@ +expression irq; +expression thread_fn; +expression flags; +position p != r1.p; +@@ +request_threaded_irq@p(irq, NULL, thread_fn, +( +-0 ++IRQF_ONESHOT +| +-flags ++flags | IRQF_ONESHOT +) +, ...) + +@depends on context@ +position p != r1.p; +@@ +*request_threaded_irq@p(...) + +@match depends on report || org@ +expression irq; +position p != r1.p; +@@ +request_threaded_irq@p(irq, NULL, ...) + +@script:python depends on org@ +p << match.p; +@@ +msg = "ERROR: Threaded IRQ with no primary handler requested without IRQF_ONESHOT" +coccilib.org.print_todo(p[0],msg) + +@script:python depends on report@ +p << match.p; +@@ +msg = "ERROR: Threaded IRQ with no primary handler requested without IRQF_ONESHOT" +coccilib.report.print_report(p[0],msg) diff --git a/scripts/coccinelle/misc/noderef.cocci b/scripts/coccinelle/misc/noderef.cocci new file mode 100644 index 000000000000..c1707214e602 --- /dev/null +++ b/scripts/coccinelle/misc/noderef.cocci @@ -0,0 +1,65 @@ +/// sizeof when applied to a pointer typed expression gives the size of +/// the pointer +/// +// Confidence: High +// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual org +virtual report +virtual context +virtual patch + +@depends on patch@ +expression *x; +expression f; +type T; +@@ + +( +x = <+... sizeof( +- x ++ *x + ) ...+> +| +f(...,(T)(x),...,sizeof( +- x ++ *x + ),...) +| +f(...,sizeof(x),...,(T)( +- x ++ *x + ),...) +) + +@r depends on !patch@ +expression *x; +expression f; +position p; +type T; +@@ + +( +*x = <+... sizeof@p(x) ...+> +| +*f(...,(T)(x),...,sizeof@p(x),...) +| +*f(...,sizeof@p(x),...,(T)(x),...) +) + +@script:python depends on org@ +p << r.p; +@@ + +cocci.print_main("application of sizeof to pointer",p) + +@script:python depends on report@ +p << r.p; +@@ + +msg = "ERROR: application of sizeof to pointer" +coccilib.report.print_report(p[0],msg) diff --git a/scripts/config b/scripts/config index a7c7c4b8e957..ee355394f4ef 100755 --- a/scripts/config +++ b/scripts/config @@ -1,6 +1,9 @@ #!/bin/bash # Manipulate options in a .config file from the command line +# If no prefix forced, use the default CONFIG_ +CONFIG_="${CONFIG_-CONFIG_}" + usage() { cat >&2 <<EOL Manipulate options in a .config file from the command line. @@ -14,6 +17,7 @@ commands: Set option to "string" --set-val option value Set option to value + --undefine|-u option Undefine option --state|-s option Print state of option (n,y,m,undef) --enable-after|-E beforeopt option @@ -26,10 +30,17 @@ commands: commands can be repeated multiple times options: - --file .config file to change (default .config) + --file config-file .config file to change (default .config) + --keep-case|-k Keep next symbols' case (dont' upper-case it) config doesn't check the validity of the .config file. This is done at next - make time. +make time. + +By default, config will upper-case the given symbol. Use --keep-case to keep +the case of all following symbols unchanged. + +config uses 'CONFIG_' as the default symbol prefix. Set the environment +variable CONFIG_ to the prefix to use. Eg.: CONFIG_="FOO_" config ... EOL exit 1 } @@ -40,11 +51,13 @@ checkarg() { usage fi case "$ARG" in - CONFIG_*) - ARG="${ARG/CONFIG_/}" + ${CONFIG_}*) + ARG="${ARG/${CONFIG_}/}" ;; esac - ARG="`echo $ARG | tr a-z A-Z`" + if [ "$MUNGE_CASE" = "yes" ] ; then + ARG="`echo $ARG | tr a-z A-Z`" + fi } set_var() { @@ -61,6 +74,12 @@ set_var() { fi } +undef_var() { + local name=$1 + + sed -ri "/^($name=|# $name is not set)/d" "$FN" +} + if [ "$1" = "--file" ]; then FN="$2" if [ "$FN" = "" ] ; then @@ -75,10 +94,16 @@ if [ "$1" = "" ] ; then usage fi +MUNGE_CASE=yes while [ "$1" != "" ] ; do CMD="$1" shift case "$CMD" in + --keep-case|-k) + MUNGE_CASE=no + shift + continue + ;; --refresh) ;; --*-after) @@ -95,52 +120,58 @@ while [ "$1" != "" ] ; do esac case "$CMD" in --enable|-e) - set_var "CONFIG_$ARG" "CONFIG_$ARG=y" + set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=y" ;; --disable|-d) - set_var "CONFIG_$ARG" "# CONFIG_$ARG is not set" + set_var "${CONFIG_}$ARG" "# ${CONFIG_}$ARG is not set" ;; --module|-m) - set_var "CONFIG_$ARG" "CONFIG_$ARG=m" + set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=m" ;; --set-str) - set_var "CONFIG_$ARG" "CONFIG_$ARG=\"$1\"" + # sed swallows one level of escaping, so we need double-escaping + set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=\"${1//\"/\\\\\"}\"" shift ;; --set-val) - set_var "CONFIG_$ARG" "CONFIG_$ARG=$1" + set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=$1" shift ;; + --undefine|-u) + undef_var "${CONFIG_}$ARG" + ;; --state|-s) - if grep -q "# CONFIG_$ARG is not set" $FN ; then + if grep -q "# ${CONFIG_}$ARG is not set" $FN ; then echo n else - V="$(grep "^CONFIG_$ARG=" $FN)" + V="$(grep "^${CONFIG_}$ARG=" $FN)" if [ $? != 0 ] ; then echo undef else - V="${V/CONFIG_$ARG=/}" - V="${V/\"/}" - echo "$V" + V="${V/#${CONFIG_}$ARG=/}" + V="${V/#\"/}" + V="${V/%\"/}" + V="${V//\\\"/\"}" + echo "${V}" fi fi ;; --enable-after|-E) - set_var "CONFIG_$B" "CONFIG_$B=y" "CONFIG_$A" + set_var "${CONFIG_}$B" "${CONFIG_}$B=y" "${CONFIG_}$A" ;; --disable-after|-D) - set_var "CONFIG_$B" "# CONFIG_$B is not set" "CONFIG_$A" + set_var "${CONFIG_}$B" "# ${CONFIG_}$B is not set" "${CONFIG_}$A" ;; --module-after|-M) - set_var "CONFIG_$B" "CONFIG_$B=m" "CONFIG_$A" + set_var "${CONFIG_}$B" "${CONFIG_}$B=m" "${CONFIG_}$A" ;; # undocumented because it ignores --file (fixme) diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 0948c6b5a321..8b673dd4627f 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -83,6 +83,8 @@ push(@signature_tags, "Signed-off-by:"); push(@signature_tags, "Reviewed-by:"); push(@signature_tags, "Acked-by:"); +my $signature_pattern = "\(" . join("|", @signature_tags) . "\)"; + # rfc822 email address - preloaded methods go here. my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])"; my $rfc822_char = '[\\000-\\377]'; @@ -473,7 +475,6 @@ my @subsystem = (); my @status = (); my %deduplicate_name_hash = (); my %deduplicate_address_hash = (); -my $signature_pattern; my @maintainers = get_maintainers(); diff --git a/scripts/gfp-translate b/scripts/gfp-translate index c9230e158a8f..c9230e158a8f 100644..100755 --- a/scripts/gfp-translate +++ b/scripts/gfp-translate diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore index ee120d441565..be603c4fef62 100644 --- a/scripts/kconfig/.gitignore +++ b/scripts/kconfig/.gitignore @@ -7,7 +7,6 @@ config* *.tab.h zconf.hash.c *.moc -lkc_defs.h gconf.glade.h *.pot *.mo diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 79662658fb91..77d53999ffb9 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -114,7 +114,7 @@ help: @echo ' alldefconfig - New config with all symbols set to default' @echo ' randconfig - New config with random answer to all options' @echo ' listnewconfig - List new options' - @echo ' oldnoconfig - Same as silentoldconfig but set new symbols to n (unset)' + @echo ' oldnoconfig - Same as silentoldconfig but sets new symbols to their default value' # lxdialog stuff check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh @@ -234,12 +234,12 @@ $(obj)/.tmp_qtcheck: if [ -f $$d/include/qconfig.h ]; then dir=$$d; break; fi; \ done; \ if [ -z "$$dir" ]; then \ - echo "*"; \ - echo "* Unable to find any QT installation. Please make sure that"; \ - echo "* the QT4 or QT3 development package is correctly installed and"; \ - echo "* either qmake can be found or install pkg-config or set"; \ - echo "* the QTDIR environment variable to the correct location."; \ - echo "*"; \ + echo >&2 "*"; \ + echo >&2 "* Unable to find any QT installation. Please make sure that"; \ + echo >&2 "* the QT4 or QT3 development package is correctly installed and"; \ + echo >&2 "* either qmake can be found or install pkg-config or set"; \ + echo >&2 "* the QTDIR environment variable to the correct location."; \ + echo >&2 "*"; \ false; \ fi; \ libpath=$$dir/lib; lib=qt; osdir=""; \ @@ -260,8 +260,8 @@ $(obj)/.tmp_qtcheck: else \ cflags="\$$(shell pkg-config QtCore QtGui Qt3Support --cflags)"; \ libs="\$$(shell pkg-config QtCore QtGui Qt3Support --libs)"; \ - binpath="\$$(shell pkg-config QtCore --variable=prefix)"; \ - moc="$$binpath/bin/moc"; \ + moc="\$$(shell pkg-config QtCore --variable=moc_location)"; \ + [ -n "$$moc" ] || moc="\$$(shell pkg-config QtCore --variable=prefix)/bin/moc"; \ fi; \ echo "KC_QT_CFLAGS=$$cflags" > $@; \ echo "KC_QT_LIBS=$$libs" >> $@; \ @@ -279,17 +279,17 @@ $(obj)/.tmp_gtkcheck: if `pkg-config --atleast-version=2.0.0 gtk+-2.0`; then \ touch $@; \ else \ - echo "*"; \ - echo "* GTK+ is present but version >= 2.0.0 is required."; \ - echo "*"; \ + echo >&2 "*"; \ + echo >&2 "* GTK+ is present but version >= 2.0.0 is required."; \ + echo >&2 "*"; \ false; \ fi \ else \ - echo "*"; \ - echo "* Unable to find the GTK+ installation. Please make sure that"; \ - echo "* the GTK+ 2.0 development package is correctly installed..."; \ - echo "* You need gtk+-2.0, glib-2.0 and libglade-2.0."; \ - echo "*"; \ + echo >&2 "*"; \ + echo >&2 "* Unable to find the GTK+ installation. Please make sure that"; \ + echo >&2 "* the GTK+ 2.0 development package is correctly installed..."; \ + echo >&2 "* You need gtk+-2.0, glib-2.0 and libglade-2.0."; \ + echo >&2 "*"; \ false; \ fi endif @@ -298,8 +298,11 @@ $(obj)/zconf.tab.o: $(obj)/zconf.lex.c $(obj)/zconf.hash.c $(obj)/qconf.o: $(obj)/qconf.moc -$(obj)/%.moc: $(src)/%.h - $(KC_QT_MOC) -i $< -o $@ +quiet_cmd_moc = MOC $@ + cmd_moc = $(KC_QT_MOC) -i $< -o $@ + +$(obj)/%.moc: $(src)/%.h $(obj)/.tmp_qtcheck + $(call cmd,moc) # Extract gconf menu items for I18N support $(obj)/gconf.glade.h: $(obj)/gconf.glade diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index f208f900ed3a..0dc4a2c779b1 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -574,8 +574,15 @@ int main(int ac, char **av) case alldefconfig: case randconfig: name = getenv("KCONFIG_ALLCONFIG"); - if (name && !stat(name, &tmpstat)) { - conf_read_simple(name, S_DEF_USER); + if (!name) + break; + if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) { + if (conf_read_simple(name, S_DEF_USER)) { + fprintf(stderr, + _("*** Can't read seed configuration \"%s\"!\n"), + name); + exit(1); + } break; } switch (input_mode) { @@ -586,10 +593,13 @@ int main(int ac, char **av) case randconfig: name = "allrandom.config"; break; default: break; } - if (!stat(name, &tmpstat)) - conf_read_simple(name, S_DEF_USER); - else if (!stat("all.config", &tmpstat)) - conf_read_simple("all.config", S_DEF_USER); + if (conf_read_simple(name, S_DEF_USER) && + conf_read_simple("all.config", S_DEF_USER)) { + fprintf(stderr, + _("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"), + name); + exit(1); + } break; default: break; diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 52577f052bc1..13ddf1126c2a 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -182,10 +182,66 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) return 0; } +#define LINE_GROWTH 16 +static int add_byte(int c, char **lineptr, size_t slen, size_t *n) +{ + char *nline; + size_t new_size = slen + 1; + if (new_size > *n) { + new_size += LINE_GROWTH - 1; + new_size *= 2; + nline = realloc(*lineptr, new_size); + if (!nline) + return -1; + + *lineptr = nline; + *n = new_size; + } + + (*lineptr)[slen] = c; + + return 0; +} + +static ssize_t compat_getline(char **lineptr, size_t *n, FILE *stream) +{ + char *line = *lineptr; + size_t slen = 0; + + for (;;) { + int c = getc(stream); + + switch (c) { + case '\n': + if (add_byte(c, &line, slen, n) < 0) + goto e_out; + slen++; + /* fall through */ + case EOF: + if (add_byte('\0', &line, slen, n) < 0) + goto e_out; + *lineptr = line; + if (slen == 0) + return -1; + return slen; + default: + if (add_byte(c, &line, slen, n) < 0) + goto e_out; + slen++; + } + } + +e_out: + line[slen-1] = '\0'; + *lineptr = line; + return -1; +} + int conf_read_simple(const char *name, int def) { FILE *in = NULL; - char line[1024]; + char *line = NULL; + size_t line_asize = 0; char *p, *p2; struct symbol *sym; int i, def_flags; @@ -247,7 +303,7 @@ load: } } - while (fgets(line, sizeof(line), in)) { + while (compat_getline(&line, &line_asize, in) != -1) { conf_lineno++; sym = NULL; if (line[0] == '#') { @@ -335,6 +391,7 @@ setsym: cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri); } } + free(line); fclose(in); if (modules_sym) diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index 82cc3a85e7f8..e3b12c010417 100644 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -4,7 +4,7 @@ # What library to link ldflags() { - for ext in so a dylib ; do + for ext in so a dll.a dylib ; do for lib in ncursesw ncurses curses ; do $cc -print-file-name=lib${lib}.${ext} | grep -q / if [ $? -eq 0 ]; then @@ -19,12 +19,12 @@ ldflags() # Where is ncurses.h? ccflags() { - if [ -f /usr/include/ncurses/ncurses.h ]; then + if [ -f /usr/include/ncursesw/curses.h ]; then + echo '-I/usr/include/ncursesw -DCURSES_LOC="<ncursesw/curses.h>"' + elif [ -f /usr/include/ncurses/ncurses.h ]; then echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"' elif [ -f /usr/include/ncurses/curses.h ]; then echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"' - elif [ -f /usr/include/ncursesw/curses.h ]; then - echo '-I/usr/include/ncursesw -DCURSES_LOC="<ncursesw/curses.h>"' elif [ -f /usr/include/ncurses.h ]; then echo '-DCURSES_LOC="<ncurses.h>"' else diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c index 154c2dd245b7..4e5de60a0c0d 100644 --- a/scripts/kconfig/lxdialog/textbox.c +++ b/scripts/kconfig/lxdialog/textbox.c @@ -129,6 +129,7 @@ do_resize: case 'e': case 'X': case 'x': + case 'q': delwin(box); delwin(dialog); return 0; @@ -190,6 +191,7 @@ do_resize: break; case 'B': /* Previous page */ case 'b': + case 'u': case KEY_PPAGE: if (begin_reached) break; @@ -214,6 +216,7 @@ do_resize: break; case KEY_NPAGE: /* Next page */ case ' ': + case 'd': if (end_reached) break; diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 2c6286c0bc1a..f584a281bb4c 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -105,10 +105,10 @@ static const char mconf_readme[] = N_( "Text Box (Help Window)\n" "--------\n" "o Use the cursor keys to scroll up/down/left/right. The VI editor\n" -" keys h,j,k,l function here as do <SPACE BAR> and <B> for those\n" -" who are familiar with less and lynx.\n" +" keys h,j,k,l function here as do <u>, <d>, <SPACE BAR> and <B> for \n" +" those who are familiar with less and lynx.\n" "\n" -"o Press <E>, <X>, <Enter> or <Esc><Esc> to exit.\n" +"o Press <E>, <X>, <q>, <Enter> or <Esc><Esc> to exit.\n" "\n" "\n" "Alternate Configuration Files\n" @@ -240,7 +240,7 @@ search_help[] = N_( "Defined at drivers/pci/Kconfig:47\n" "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" "Location:\n" - " -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n" + " -> Bus options (PCI, PCMCIA, EISA, ISA)\n" " -> PCI support (PCI [=y])\n" " -> PCI access mode (<choice> [=y])\n" "Selects: LIBCRC32\n" diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 73070cb0b6de..1704a8562a5d 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -83,10 +83,10 @@ static const char nconf_readme[] = N_( "Text Box (Help Window)\n" "--------\n" "o Use the cursor keys to scroll up/down/left/right. The VI editor\n" -" keys h,j,k,l function here as do <SPACE BAR> for those\n" -" who are familiar with less and lynx.\n" +" keys h,j,k,l function here as do <u>, <d> and <SPACE BAR> for\n" +" those who are familiar with less and lynx.\n" "\n" -"o Press <Enter>, <F1>, <F5>, <F7> or <Esc> to exit.\n" +"o Press <Enter>, <F1>, <F5>, <F9>, <q> or <Esc> to exit.\n" "\n" "\n" "Alternate Configuration Files\n" @@ -223,7 +223,7 @@ search_help[] = N_( "Defined at drivers/pci/Kconfig:47\n" "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" "Location:\n" -" -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n" +" -> Bus options (PCI, PCMCIA, EISA, ISA)\n" " -> PCI support (PCI [ = y])\n" " -> PCI access mode (<choice> [ = y])\n" "Selects: LIBCRC32\n" @@ -1503,7 +1503,11 @@ int main(int ac, char **av) } notimeout(stdscr, FALSE); +#if NCURSES_REENTRANT + set_escdelay(1); +#else ESCDELAY = 1; +#endif /* set btns menu */ curses_menu = new_menu(curses_menu_items); diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index 3b18dd839668..379003c7a2b4 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -604,9 +604,11 @@ void show_scroll_win(WINDOW *main_window, switch (res) { case KEY_NPAGE: case ' ': + case 'd': start_y += text_lines-2; break; case KEY_PPAGE: + case 'u': start_y -= text_lines+2; break; case KEY_HOME: @@ -632,10 +634,10 @@ void show_scroll_win(WINDOW *main_window, start_x++; break; } - if (res == 10 || res == 27 || res == 'q' - || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) { + if (res == 10 || res == 27 || res == 'q' || + res == KEY_F(F_HELP) || res == KEY_F(F_BACK) || + res == KEY_F(F_EXIT)) break; - } if (start_y < 0) start_y = 0; if (start_y >= total_lines-text_lines) diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index bccf07ddd0b6..2fbbbc1ddea0 100644 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -45,6 +45,16 @@ use strict; use Getopt::Long; +# set the environment variable LOCALMODCONFIG_DEBUG to get +# debug output. +my $debugprint = 0; +$debugprint = 1 if (defined($ENV{LOCALMODCONFIG_DEBUG})); + +sub dprint { + return if (!$debugprint); + print STDERR @_; +} + my $config = ".config"; my $uname = `uname -r`; @@ -113,6 +123,10 @@ sub find_config { find_config; +# Read in the entire config file into config_file +my @config_file = <CIN>; +close CIN; + # Parse options my $localmodconfig = 0; my $localyesconfig = 0; @@ -186,6 +200,7 @@ sub read_kconfig { $state = "NEW"; $config = $2; + # Add depends for 'if' nesting for (my $i = 0; $i < $iflevel; $i++) { if ($i) { $depends{$config} .= " " . $ifdeps[$i]; @@ -204,10 +219,11 @@ sub read_kconfig { # Get the configs that select this config } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) { - if (defined($selects{$1})) { - $selects{$1} .= " " . $config; + my $conf = $1; + if (defined($selects{$conf})) { + $selects{$conf} .= " " . $config; } else { - $selects{$1} = $config; + $selects{$conf} = $config; } # configs without prompts must be selected @@ -250,6 +266,7 @@ if ($kconfig) { read_kconfig($kconfig); } +# Makefiles can use variables to define their dependencies sub convert_vars { my ($line, %vars) = @_; @@ -293,6 +310,7 @@ foreach my $makefile (@makefiles) { my $objs; + # Convert variables in a line (could define configs) $_ = convert_vars($_, %make_vars); # collect objects after obj-$(CONFIG_FOO_BAR) @@ -373,13 +391,15 @@ while (<LIN>) { close (LIN); # add to the configs hash all configs that are needed to enable -# a loaded module. +# a loaded module. This is a direct obj-${CONFIG_FOO} += bar.o +# where we know we need bar.o so we add FOO to the list. my %configs; foreach my $module (keys(%modules)) { if (defined($objects{$module})) { my @arr = @{$objects{$module}}; foreach my $conf (@arr) { $configs{$conf} = $module; + dprint "$conf added by direct ($module)\n"; } } else { # Most likely, someone has a custom (binary?) module loaded. @@ -387,9 +407,24 @@ foreach my $module (keys(%modules)) { } } +# Read the current config, and see what is enabled. We want to +# ignore configs that we would not enable anyway. + +my %orig_configs; my $valid = "A-Za-z_0-9"; + +foreach my $line (@config_file) { + $_ = $line; + + if (/(CONFIG_[$valid]*)=(m|y)/) { + $orig_configs{$1} = $2; + } +} + my $repeat = 1; +my $depconfig; + # # Note, we do not care about operands (like: &&, ||, !) we want to add any # config that is in the depend list of another config. This script does @@ -398,7 +433,7 @@ my $repeat = 1; # to keep on. If A was on in the original config, B would not have been # and B would not be turned on by this script. # -sub parse_config_dep_select +sub parse_config_depends { my ($p) = @_; @@ -409,10 +444,16 @@ sub parse_config_dep_select $p =~ s/^[^$valid]*[$valid]+//; + # We only need to process if the depend config is a module + if (!defined($orig_configs{$conf}) || !$orig_configs{conf} eq "m") { + next; + } + if (!defined($configs{$conf})) { # We must make sure that this config has its # dependencies met. $repeat = 1; # do again + dprint "$conf selected by depend $depconfig\n"; $configs{$conf} = 1; } } else { @@ -421,31 +462,132 @@ sub parse_config_dep_select } } -while ($repeat) { - $repeat = 0; +# Select is treated a bit differently than depends. We call this +# when a config has no prompt and requires another config to be +# selected. We use to just select all configs that selected this +# config, but found that that can balloon into enabling hundreds +# of configs that we do not care about. +# +# The idea is we look at all the configs that select it. If one +# is already in our list of configs to enable, then there's nothing +# else to do. If there isn't, we pick the first config that was +# enabled in the orignal config and use that. +sub parse_config_selects +{ + my ($config, $p) = @_; - foreach my $config (keys %configs) { - $config =~ s/^CONFIG_//; + my $next_config; + + while ($p =~ /[$valid]/) { - if (defined($depends{$config})) { - # This config has dependencies. Make sure they are also included - parse_config_dep_select $depends{$config}; + if ($p =~ /^[^$valid]*([$valid]+)/) { + my $conf = "CONFIG_" . $1; + + $p =~ s/^[^$valid]*[$valid]+//; + + # Make sure that this config exists in the current .config file + if (!defined($orig_configs{$conf})) { + dprint "$conf not set for $config select\n"; + next; + } + + # Check if something other than a module selects this config + if (defined($orig_configs{$conf}) && $orig_configs{$conf} ne "m") { + dprint "$conf (non module) selects config, we are good\n"; + # we are good with this + return; + } + if (defined($configs{$conf})) { + dprint "$conf selects $config so we are good\n"; + # A set config selects this config, we are good + return; + } + # Set this config to be selected + if (!defined($next_config)) { + $next_config = $conf; + } + } else { + die "this should never happen"; } + } - if (defined($prompts{$config}) || !defined($selects{$config})) { - next; + # If no possible config selected this, then something happened. + if (!defined($next_config)) { + print STDERR "WARNING: $config is required, but nothing in the\n"; + print STDERR " current config selects it.\n"; + return; + } + + # If we are here, then we found no config that is set and + # selects this config. Repeat. + $repeat = 1; + # Make this config need to be selected + $configs{$next_config} = 1; + dprint "$next_config selected by select $config\n"; +} + +my %process_selects; + +# loop through all configs, select their dependencies. +sub loop_depend { + $repeat = 1; + + while ($repeat) { + $repeat = 0; + + forloop: + foreach my $config (keys %configs) { + + # If this config is not a module, we do not need to process it + if (defined($orig_configs{$config}) && $orig_configs{$config} ne "m") { + next forloop; + } + + $config =~ s/^CONFIG_//; + $depconfig = $config; + + if (defined($depends{$config})) { + # This config has dependencies. Make sure they are also included + parse_config_depends $depends{$config}; + } + + # If the config has no prompt, then we need to check if a config + # that is enabled selected it. Or if we need to enable one. + if (!defined($prompts{$config}) && defined($selects{$config})) { + $process_selects{$config} = 1; + } } + } +} + +sub loop_select { + + foreach my $config (keys %process_selects) { + $config =~ s/^CONFIG_//; + + dprint "Process select $config\n"; # config has no prompt and must be selected. - parse_config_dep_select $selects{$config}; + parse_config_selects $config, $selects{$config}; } } +while ($repeat) { + # Get the first set of configs and their dependencies. + loop_depend; + + $repeat = 0; + + # Now we need to see if we have to check selects; + loop_select; +} + my %setconfigs; # Finally, read the .config file and turn off any module enabled that # we could not find a reason to keep enabled. -while(<CIN>) { +foreach my $line (@config_file) { + $_ = $line; if (/CONFIG_IKCONFIG/) { if (/# CONFIG_IKCONFIG is not set/) { @@ -473,7 +615,6 @@ while(<CIN>) { } print; } -close(CIN); # Integrity check, make sure all modules that we want enabled do # indeed have their configs set. diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh new file mode 100644 index 000000000000..4629038c9e5a --- /dev/null +++ b/scripts/link-vmlinux.sh @@ -0,0 +1,221 @@ +#!/bin/sh +# +# 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. +# +# vmlinux +# ^ +# | +# +-< $(KBUILD_VMLINUX_INIT) +# | +--< init/version.o + more +# | +# +--< $(KBUILD_VMLINUX_MAIN) +# | +--< drivers/built-in.o mm/built-in.o + more +# | +# +-< ${kallsymso} (see description in KALLSYMS section) +# +# vmlinux version (uname -v) cannot be updated during normal +# descending-into-subdirs phase since we do not yet know if we need to +# update vmlinux. +# Therefore this step is delayed until just before final link of vmlinux. +# +# System.map is generated to document addresses of all kernel symbols + +# Error out on error +set -e + +# Nice output in kbuild format +# Will be supressed by "make -s" +info() +{ + if [ "${quiet}" != "silent_" ]; then + printf " %-7s %s\n" ${1} ${2} + fi +} + +# Link of vmlinux.o used for section mismatch analysis +# ${1} output file +modpost_link() +{ + ${LD} ${LDFLAGS} -r -o ${1} ${KBUILD_VMLINUX_INIT} \ + --start-group ${KBUILD_VMLINUX_MAIN} --end-group +} + +# Link of vmlinux +# ${1} - optional extra .o files +# ${2} - output file +vmlinux_link() +{ + local lds="${objtree}/${KBUILD_LDS}" + + if [ "${SRCARCH}" != "um" ]; then + ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \ + -T ${lds} ${KBUILD_VMLINUX_INIT} \ + --start-group ${KBUILD_VMLINUX_MAIN} --end-group ${1} + else + ${CC} ${CFLAGS_vmlinux} -o ${2} \ + -Wl,-T,${lds} ${KBUILD_VMLINUX_INIT} \ + -Wl,--start-group \ + ${KBUILD_VMLINUX_MAIN} \ + -Wl,--end-group \ + -lutil ${1} + rm -f linux + fi +} + + +# Create ${2} .o file with all symbols from the ${1} object file +kallsyms() +{ + info KSYM ${2} + local kallsymopt; + + if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then + kallsymopt=--all-symbols + fi + + local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ + ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}" + + ${NM} -n ${1} | \ + scripts/kallsyms ${kallsymopt} | \ + ${CC} ${aflags} -c -o ${2} -x assembler-with-cpp - +} + +# Create map file with all symbols from ${1} +# See mksymap for additional details +mksysmap() +{ + ${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2} +} + +sortextable() +{ + ${objtree}/scripts/sortextable ${1} +} + +# Delete output files in case of error +trap cleanup SIGHUP SIGINT SIGQUIT SIGTERM ERR +cleanup() +{ + rm -f .old_version + rm -f .tmp_System.map + rm -f .tmp_kallsyms* + rm -f .tmp_version + rm -f .tmp_vmlinux* + rm -f System.map + rm -f vmlinux + rm -f vmlinux.o +} + +# +# +# Use "make V=1" to debug this script +case "${KBUILD_VERBOSE}" in +*1*) + set -x + ;; +esac + +if [ "$1" = "clean" ]; then + cleanup + exit 0 +fi + +# We need access to CONFIG_ symbols +. ./.config + +#link vmlinux.o +info LD vmlinux.o +modpost_link vmlinux.o + +# modpost vmlinux.o to check for section mismatches +${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o + +# Update version +info GEN .version +if [ ! -r .version ]; then + rm -f .version; + echo 1 >.version; +else + mv .version .old_version; + expr 0$(cat .old_version) + 1 >.version; +fi; + +# final build of init/ +${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init + +kallsymso="" +kallsyms_vmlinux="" +if [ -n "${CONFIG_KALLSYMS}" ]; then + + # kallsyms support + # Generate section listing all symbols and add it into vmlinux + # It's a three step process: + # 1) Link .tmp_vmlinux1 so it has all symbols and sections, + # but __kallsyms is empty. + # Running kallsyms on that gives us .tmp_kallsyms1.o with + # the right size + # 2) Link .tmp_vmlinux2 so it now has a __kallsyms section of + # the right size, but due to the added section, some + # addresses have shifted. + # From here, we generate a correct .tmp_kallsyms2.o + # 2a) We may use an extra pass as this has been necessary to + # woraround some alignment related bugs. + # KALLSYMS_EXTRA_PASS=1 is used to trigger this. + # 3) The correct ${kallsymso} is linked into the final vmlinux. + # + # a) Verify that the System.map from vmlinux matches the map from + # ${kallsymso}. + + kallsymso=.tmp_kallsyms2.o + kallsyms_vmlinux=.tmp_vmlinux2 + + # step 1 + vmlinux_link "" .tmp_vmlinux1 + kallsyms .tmp_vmlinux1 .tmp_kallsyms1.o + + # step 2 + vmlinux_link .tmp_kallsyms1.o .tmp_vmlinux2 + kallsyms .tmp_vmlinux2 .tmp_kallsyms2.o + + # step 2a + if [ -n "${KALLSYMS_EXTRA_PASS}" ]; then + kallsymso=.tmp_kallsyms3.o + kallsyms_vmlinux=.tmp_vmlinux3 + + vmlinux_link .tmp_kallsyms2.o .tmp_vmlinux3 + + kallsyms .tmp_vmlinux3 .tmp_kallsyms3.o + fi +fi + +info LD vmlinux +vmlinux_link "${kallsymso}" vmlinux + +if [ -n "${CONFIG_BUILDTIME_EXTABLE_SORT}" ]; then + info SORTEX vmlinux + sortextable vmlinux +fi + +info SYSMAP System.map +mksysmap vmlinux System.map + +# step a (see comment above) +if [ -n "${CONFIG_KALLSYMS}" ]; then + mksysmap ${kallsyms_vmlinux} .tmp_System.map + + if ! cmp -s System.map .tmp_System.map; then + echo >&2 Inconsistent kallsyms data + echo >&2 echo Try "make KALLSYMS_EXTRA_PASS=1" as a workaround + cleanup + exit 1 + fi +fi + +# We made a new kernel - delete old version file +rm -f .old_version diff --git a/scripts/mksysmap b/scripts/mksysmap index 6e133a0bae7a..c1b6191ef879 100644 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -16,7 +16,7 @@ # The second row specify the type of the symbol: # A = Absolute # B = Uninitialised data (.bss) -# C = Comon symbol +# C = Common symbol # D = Initialised data # G = Initialised data for small objects # I = Indirect reference to another symbol diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 44ddaa542db6..7ed6864ef65b 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -156,7 +156,7 @@ static void device_id_check(const char *modname, const char *device_id, } /* USB is special because the bcdDevice can be matched against a numeric range */ -/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipN" */ +/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipNinN" */ static void do_usb_entry(struct usb_device_id *id, unsigned int bcdDevice_initial, int bcdDevice_initial_digits, unsigned char range_lo, unsigned char range_hi, @@ -210,6 +210,9 @@ static void do_usb_entry(struct usb_device_id *id, ADD(alias, "ip", id->match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL, id->bInterfaceProtocol); + ADD(alias, "in", + id->match_flags&USB_DEVICE_ID_MATCH_INT_NUMBER, + id->bInterfaceNumber); add_wildcard(alias); buf_printf(&mod->dev_table_buf, @@ -336,10 +339,13 @@ static int do_hid_entry(const char *filename, struct hid_device_id *id, char *alias) { id->bus = TO_NATIVE(id->bus); + id->group = TO_NATIVE(id->group); id->vendor = TO_NATIVE(id->vendor); id->product = TO_NATIVE(id->product); - sprintf(alias, "hid:b%04X", id->bus); + sprintf(alias, "hid:"); + ADD(alias, "b", id->bus != HID_BUS_ANY, id->bus); + ADD(alias, "g", id->group != HID_GROUP_ANY, id->group); ADD(alias, "v", id->vendor != HID_ANY_ID, id->vendor); ADD(alias, "p", id->product != HID_ANY_ID, id->product); diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c4e7d1510f9d..68e9f5ed0a6f 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -337,17 +337,20 @@ static void sym_update_crc(const char *name, struct module *mod, void *grab_file(const char *filename, unsigned long *size) { struct stat st; - void *map; + void *map = MAP_FAILED; int fd; fd = open(filename, O_RDONLY); - if (fd < 0 || fstat(fd, &st) != 0) + if (fd < 0) return NULL; + if (fstat(fd, &st)) + goto failed; *size = st.st_size; map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); - close(fd); +failed: + close(fd); if (map == MAP_FAILED) return NULL; return map; @@ -862,6 +865,11 @@ static void check_section(const char *modname, struct elf_info *elf, #define ALL_EXIT_TEXT_SECTIONS \ ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$" +#define ALL_PCI_INIT_SECTIONS \ + ".pci_fixup_early$", ".pci_fixup_header$", ".pci_fixup_final$", \ + ".pci_fixup_enable$", ".pci_fixup_resume$", \ + ".pci_fixup_resume_early$", ".pci_fixup_suspend$" + #define ALL_XXXINIT_SECTIONS DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, \ MEM_INIT_SECTIONS #define ALL_XXXEXIT_SECTIONS DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, \ @@ -1024,6 +1032,12 @@ const struct sectioncheck sectioncheck[] = { .mismatch = ANY_EXIT_TO_ANY_INIT, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, +{ + .fromsec = { ALL_PCI_INIT_SECTIONS, NULL }, + .tosec = { INIT_SECTIONS, NULL }, + .mismatch = ANY_INIT_TO_ANY_EXIT, + .symbol_white_list = { NULL }, +}, /* Do not export init/exit functions or data */ { .fromsec = { "__ksymtab*", NULL }, @@ -1850,14 +1864,14 @@ static void add_header(struct buffer *b, struct module *mod) buf_printf(b, "\n"); buf_printf(b, "struct module __this_module\n"); buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n"); - buf_printf(b, " .name = KBUILD_MODNAME,\n"); + buf_printf(b, "\t.name = KBUILD_MODNAME,\n"); if (mod->has_init) - buf_printf(b, " .init = init_module,\n"); + buf_printf(b, "\t.init = init_module,\n"); if (mod->has_cleanup) buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n" - " .exit = cleanup_module,\n" + "\t.exit = cleanup_module,\n" "#endif\n"); - buf_printf(b, " .arch = MODULE_ARCH_INIT,\n"); + buf_printf(b, "\t.arch = MODULE_ARCH_INIT,\n"); buf_printf(b, "};\n"); } diff --git a/scripts/package/builddeb b/scripts/package/builddeb index eee5f8ed2493..acb86507828a 100644 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -92,7 +92,7 @@ rm -rf "$tmpdir" "$fwdir" "$kernel_headers_dir" "$libc_headers_dir" mkdir -m 755 -p "$tmpdir/DEBIAN" mkdir -p "$tmpdir/lib" "$tmpdir/boot" "$tmpdir/usr/share/doc/$packagename" mkdir -m 755 -p "$fwdir/DEBIAN" -mkdir -p "$fwdir/lib" "$fwdir/usr/share/doc/$fwpackagename" +mkdir -p "$fwdir/lib/firmware/$version/" "$fwdir/usr/share/doc/$fwpackagename" mkdir -m 755 -p "$libc_headers_dir/DEBIAN" mkdir -p "$libc_headers_dir/usr/share/doc/$libc_headers_packagename" mkdir -m 755 -p "$kernel_headers_dir/DEBIAN" @@ -243,9 +243,9 @@ EOF fi # Build header package -(cd $srctree; find . -name Makefile -o -name Kconfig\* -o -name \*.pl > "$objtree/debian/hdrsrcfiles") +(cd $srctree; find . -name Makefile\* -o -name Kconfig\* -o -name \*.pl > "$objtree/debian/hdrsrcfiles") (cd $srctree; find arch/$SRCARCH/include include scripts -type f >> "$objtree/debian/hdrsrcfiles") -(cd $objtree; find .config Module.symvers include scripts -type f >> "$objtree/debian/hdrobjfiles") +(cd $objtree; find arch/$SRCARCH/include .config Module.symvers include scripts -type f >> "$objtree/debian/hdrobjfiles") destdir=$kernel_headers_dir/usr/src/linux-headers-$version mkdir -p "$destdir" (cd $srctree; tar -c -f - -T "$objtree/debian/hdrsrcfiles") | (cd $destdir; tar -xf -) @@ -267,7 +267,8 @@ EOF # Do we have firmware? Move it out of the way and build it into a package. if [ -e "$tmpdir/lib/firmware" ]; then - mv "$tmpdir/lib/firmware" "$fwdir/lib/" + mv "$tmpdir/lib/firmware"/* "$fwdir/lib/firmware/$version/" + rmdir "$tmpdir/lib/firmware" cat <<EOF >> debian/control diff --git a/scripts/sortextable.c b/scripts/sortextable.c new file mode 100644 index 000000000000..6acf83449105 --- /dev/null +++ b/scripts/sortextable.c @@ -0,0 +1,323 @@ +/* + * sortextable.c: Sort the kernel's exception table + * + * Copyright 2011 - 2012 Cavium, Inc. + * + * Based on code taken from recortmcount.c which is: + * + * Copyright 2009 John F. Reiser <jreiser@BitWagon.com>. All rights reserved. + * Licensed under the GNU General Public License, version 2 (GPLv2). + * + * Restructured to fit Linux format, as well as other updates: + * Copyright 2010 Steven Rostedt <srostedt@redhat.com>, Red Hat Inc. + */ + +/* + * Strategy: alter the vmlinux file in-place. + */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <getopt.h> +#include <elf.h> +#include <fcntl.h> +#include <setjmp.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <tools/be_byteshift.h> +#include <tools/le_byteshift.h> + +static int fd_map; /* File descriptor for file being modified. */ +static int mmap_failed; /* Boolean flag. */ +static void *ehdr_curr; /* current ElfXX_Ehdr * for resource cleanup */ +static struct stat sb; /* Remember .st_size, etc. */ +static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */ + +/* setjmp() return values */ +enum { + SJ_SETJMP = 0, /* hardwired first return */ + SJ_FAIL, + SJ_SUCCEED +}; + +/* Per-file resource cleanup when multiple files. */ +static void +cleanup(void) +{ + if (!mmap_failed) + munmap(ehdr_curr, sb.st_size); + close(fd_map); +} + +static void __attribute__((noreturn)) +fail_file(void) +{ + cleanup(); + longjmp(jmpenv, SJ_FAIL); +} + +static void __attribute__((noreturn)) +succeed_file(void) +{ + cleanup(); + longjmp(jmpenv, SJ_SUCCEED); +} + + +/* + * Get the whole file as a programming convenience in order to avoid + * malloc+lseek+read+free of many pieces. If successful, then mmap + * avoids copying unused pieces; else just read the whole file. + * Open for both read and write. + */ +static void *mmap_file(char const *fname) +{ + void *addr; + + fd_map = open(fname, O_RDWR); + if (fd_map < 0 || fstat(fd_map, &sb) < 0) { + perror(fname); + fail_file(); + } + if (!S_ISREG(sb.st_mode)) { + fprintf(stderr, "not a regular file: %s\n", fname); + fail_file(); + } + addr = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, + fd_map, 0); + if (addr == MAP_FAILED) { + mmap_failed = 1; + fprintf(stderr, "Could not mmap file: %s\n", fname); + fail_file(); + } + return addr; +} + +static uint64_t r8be(const uint64_t *x) +{ + return get_unaligned_be64(x); +} +static uint32_t rbe(const uint32_t *x) +{ + return get_unaligned_be32(x); +} +static uint16_t r2be(const uint16_t *x) +{ + return get_unaligned_be16(x); +} +static uint64_t r8le(const uint64_t *x) +{ + return get_unaligned_le64(x); +} +static uint32_t rle(const uint32_t *x) +{ + return get_unaligned_le32(x); +} +static uint16_t r2le(const uint16_t *x) +{ + return get_unaligned_le16(x); +} + +static void w8be(uint64_t val, uint64_t *x) +{ + put_unaligned_be64(val, x); +} +static void wbe(uint32_t val, uint32_t *x) +{ + put_unaligned_be32(val, x); +} +static void w2be(uint16_t val, uint16_t *x) +{ + put_unaligned_be16(val, x); +} +static void w8le(uint64_t val, uint64_t *x) +{ + put_unaligned_le64(val, x); +} +static void wle(uint32_t val, uint32_t *x) +{ + put_unaligned_le32(val, x); +} +static void w2le(uint16_t val, uint16_t *x) +{ + put_unaligned_le16(val, x); +} + +static uint64_t (*r8)(const uint64_t *); +static uint32_t (*r)(const uint32_t *); +static uint16_t (*r2)(const uint16_t *); +static void (*w8)(uint64_t, uint64_t *); +static void (*w)(uint32_t, uint32_t *); +static void (*w2)(uint16_t, uint16_t *); + +typedef void (*table_sort_t)(char *, int); + +/* 32 bit and 64 bit are very similar */ +#include "sortextable.h" +#define SORTEXTABLE_64 +#include "sortextable.h" + +static int compare_x86_table(const void *a, const void *b) +{ + int32_t av = (int32_t)r(a); + int32_t bv = (int32_t)r(b); + + if (av < bv) + return -1; + if (av > bv) + return 1; + return 0; +} + +static void sort_x86_table(char *extab_image, int image_size) +{ + int i; + + /* + * Do the same thing the runtime sort does, first normalize to + * being relative to the start of the section. + */ + i = 0; + while (i < image_size) { + uint32_t *loc = (uint32_t *)(extab_image + i); + w(r(loc) + i, loc); + i += 4; + } + + qsort(extab_image, image_size / 8, 8, compare_x86_table); + + /* Now denormalize. */ + i = 0; + while (i < image_size) { + uint32_t *loc = (uint32_t *)(extab_image + i); + w(r(loc) - i, loc); + i += 4; + } +} + +static void +do_file(char const *const fname) +{ + table_sort_t custom_sort; + Elf32_Ehdr *ehdr = mmap_file(fname); + + ehdr_curr = ehdr; + switch (ehdr->e_ident[EI_DATA]) { + default: + fprintf(stderr, "unrecognized ELF data encoding %d: %s\n", + ehdr->e_ident[EI_DATA], fname); + fail_file(); + break; + case ELFDATA2LSB: + r = rle; + r2 = r2le; + r8 = r8le; + w = wle; + w2 = w2le; + w8 = w8le; + break; + case ELFDATA2MSB: + r = rbe; + r2 = r2be; + r8 = r8be; + w = wbe; + w2 = w2be; + w8 = w8be; + break; + } /* end switch */ + if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0 + || r2(&ehdr->e_type) != ET_EXEC + || ehdr->e_ident[EI_VERSION] != EV_CURRENT) { + fprintf(stderr, "unrecognized ET_EXEC file %s\n", fname); + fail_file(); + } + + custom_sort = NULL; + switch (r2(&ehdr->e_machine)) { + default: + fprintf(stderr, "unrecognized e_machine %d %s\n", + r2(&ehdr->e_machine), fname); + fail_file(); + break; + case EM_386: + case EM_X86_64: + custom_sort = sort_x86_table; + break; + case EM_S390: + case EM_MIPS: + break; + } /* end switch */ + + switch (ehdr->e_ident[EI_CLASS]) { + default: + fprintf(stderr, "unrecognized ELF class %d %s\n", + ehdr->e_ident[EI_CLASS], fname); + fail_file(); + break; + case ELFCLASS32: + if (r2(&ehdr->e_ehsize) != sizeof(Elf32_Ehdr) + || r2(&ehdr->e_shentsize) != sizeof(Elf32_Shdr)) { + fprintf(stderr, + "unrecognized ET_EXEC file: %s\n", fname); + fail_file(); + } + do32(ehdr, fname, custom_sort); + break; + case ELFCLASS64: { + Elf64_Ehdr *const ghdr = (Elf64_Ehdr *)ehdr; + if (r2(&ghdr->e_ehsize) != sizeof(Elf64_Ehdr) + || r2(&ghdr->e_shentsize) != sizeof(Elf64_Shdr)) { + fprintf(stderr, + "unrecognized ET_EXEC file: %s\n", fname); + fail_file(); + } + do64(ghdr, fname, custom_sort); + break; + } + } /* end switch */ + + cleanup(); +} + +int +main(int argc, char *argv[]) +{ + int n_error = 0; /* gcc-4.3.0 false positive complaint */ + int i; + + if (argc < 2) { + fprintf(stderr, "usage: sortextable vmlinux...\n"); + return 0; + } + + /* Process each file in turn, allowing deep failure. */ + for (i = 1; i < argc; i++) { + char *file = argv[i]; + int const sjval = setjmp(jmpenv); + + switch (sjval) { + default: + fprintf(stderr, "internal error: %s\n", file); + exit(1); + break; + case SJ_SETJMP: /* normal sequence */ + /* Avoid problems if early cleanup() */ + fd_map = -1; + ehdr_curr = NULL; + mmap_failed = 1; + do_file(file); + break; + case SJ_FAIL: /* error in do_file or below */ + ++n_error; + break; + case SJ_SUCCEED: /* premature success */ + /* do nothing */ + break; + } /* end switch */ + } + return !!n_error; +} diff --git a/scripts/sortextable.h b/scripts/sortextable.h new file mode 100644 index 000000000000..e4fd45b7e456 --- /dev/null +++ b/scripts/sortextable.h @@ -0,0 +1,191 @@ +/* + * sortextable.h + * + * Copyright 2011 - 2012 Cavium, Inc. + * + * Some of this code was taken out of recordmcount.h written by: + * + * Copyright 2009 John F. Reiser <jreiser@BitWagon.com>. All rights reserved. + * Copyright 2010 Steven Rostedt <srostedt@redhat.com>, Red Hat Inc. + * + * + * Licensed under the GNU General Public License, version 2 (GPLv2). + */ + +#undef extable_ent_size +#undef compare_extable +#undef do_func +#undef Elf_Addr +#undef Elf_Ehdr +#undef Elf_Shdr +#undef Elf_Rel +#undef Elf_Rela +#undef Elf_Sym +#undef ELF_R_SYM +#undef Elf_r_sym +#undef ELF_R_INFO +#undef Elf_r_info +#undef ELF_ST_BIND +#undef ELF_ST_TYPE +#undef fn_ELF_R_SYM +#undef fn_ELF_R_INFO +#undef uint_t +#undef _r +#undef _w + +#ifdef SORTEXTABLE_64 +# define extable_ent_size 16 +# define compare_extable compare_extable_64 +# define do_func do64 +# define Elf_Addr Elf64_Addr +# define Elf_Ehdr Elf64_Ehdr +# define Elf_Shdr Elf64_Shdr +# define Elf_Rel Elf64_Rel +# define Elf_Rela Elf64_Rela +# define Elf_Sym Elf64_Sym +# define ELF_R_SYM ELF64_R_SYM +# define Elf_r_sym Elf64_r_sym +# define ELF_R_INFO ELF64_R_INFO +# define Elf_r_info Elf64_r_info +# define ELF_ST_BIND ELF64_ST_BIND +# define ELF_ST_TYPE ELF64_ST_TYPE +# define fn_ELF_R_SYM fn_ELF64_R_SYM +# define fn_ELF_R_INFO fn_ELF64_R_INFO +# define uint_t uint64_t +# define _r r8 +# define _w w8 +#else +# define extable_ent_size 8 +# define compare_extable compare_extable_32 +# define do_func do32 +# define Elf_Addr Elf32_Addr +# define Elf_Ehdr Elf32_Ehdr +# define Elf_Shdr Elf32_Shdr +# define Elf_Rel Elf32_Rel +# define Elf_Rela Elf32_Rela +# define Elf_Sym Elf32_Sym +# define ELF_R_SYM ELF32_R_SYM +# define Elf_r_sym Elf32_r_sym +# define ELF_R_INFO ELF32_R_INFO +# define Elf_r_info Elf32_r_info +# define ELF_ST_BIND ELF32_ST_BIND +# define ELF_ST_TYPE ELF32_ST_TYPE +# define fn_ELF_R_SYM fn_ELF32_R_SYM +# define fn_ELF_R_INFO fn_ELF32_R_INFO +# define uint_t uint32_t +# define _r r +# define _w w +#endif + +static int compare_extable(const void *a, const void *b) +{ + Elf_Addr av = _r(a); + Elf_Addr bv = _r(b); + + if (av < bv) + return -1; + if (av > bv) + return 1; + return 0; +} + +static void +do_func(Elf_Ehdr *ehdr, char const *const fname, table_sort_t custom_sort) +{ + Elf_Shdr *shdr; + Elf_Shdr *shstrtab_sec; + Elf_Shdr *strtab_sec = NULL; + Elf_Shdr *symtab_sec = NULL; + Elf_Shdr *extab_sec = NULL; + Elf_Sym *sym; + Elf_Sym *sort_needed_sym; + Elf_Shdr *sort_needed_sec; + Elf_Rel *relocs = NULL; + int relocs_size; + uint32_t *sort_done_location; + const char *secstrtab; + const char *strtab; + char *extab_image; + int extab_index = 0; + int i; + int idx; + + shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->e_shoff)); + shstrtab_sec = shdr + r2(&ehdr->e_shstrndx); + secstrtab = (const char *)ehdr + _r(&shstrtab_sec->sh_offset); + for (i = 0; i < r2(&ehdr->e_shnum); i++) { + idx = r(&shdr[i].sh_name); + if (strcmp(secstrtab + idx, "__ex_table") == 0) { + extab_sec = shdr + i; + extab_index = i; + } + if ((r(&shdr[i].sh_type) == SHT_REL || + r(&shdr[i].sh_type) == SHT_RELA) && + r(&shdr[i].sh_info) == extab_index) { + relocs = (void *)ehdr + _r(&shdr[i].sh_offset); + relocs_size = _r(&shdr[i].sh_size); + } + if (strcmp(secstrtab + idx, ".symtab") == 0) + symtab_sec = shdr + i; + if (strcmp(secstrtab + idx, ".strtab") == 0) + strtab_sec = shdr + i; + } + if (strtab_sec == NULL) { + fprintf(stderr, "no .strtab in file: %s\n", fname); + fail_file(); + } + if (symtab_sec == NULL) { + fprintf(stderr, "no .symtab in file: %s\n", fname); + fail_file(); + } + if (extab_sec == NULL) { + fprintf(stderr, "no __ex_table in file: %s\n", fname); + fail_file(); + } + strtab = (const char *)ehdr + _r(&strtab_sec->sh_offset); + + extab_image = (void *)ehdr + _r(&extab_sec->sh_offset); + + if (custom_sort) { + custom_sort(extab_image, _r(&extab_sec->sh_size)); + } else { + int num_entries = _r(&extab_sec->sh_size) / extable_ent_size; + qsort(extab_image, num_entries, + extable_ent_size, compare_extable); + } + /* If there were relocations, we no longer need them. */ + if (relocs) + memset(relocs, 0, relocs_size); + + /* find main_extable_sort_needed */ + sort_needed_sym = NULL; + for (i = 0; i < _r(&symtab_sec->sh_size) / sizeof(Elf_Sym); i++) { + sym = (void *)ehdr + _r(&symtab_sec->sh_offset); + sym += i; + if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) + continue; + idx = r(&sym->st_name); + if (strcmp(strtab + idx, "main_extable_sort_needed") == 0) { + sort_needed_sym = sym; + break; + } + } + if (sort_needed_sym == NULL) { + fprintf(stderr, + "no main_extable_sort_needed symbol in file: %s\n", + fname); + fail_file(); + } + sort_needed_sec = &shdr[r2(&sort_needed_sym->st_shndx)]; + sort_done_location = (void *)ehdr + + _r(&sort_needed_sec->sh_offset) + + _r(&sort_needed_sym->st_value) - + _r(&sort_needed_sec->sh_addr); + +#if 1 + printf("sort done marker at %lx\n", + (unsigned long)((char *)sort_done_location - (char *)ehdr)); +#endif + /* We sorted it, clear the flag. */ + w(0, sort_done_location); +} diff --git a/scripts/tags.sh b/scripts/tags.sh index cf7b12fee573..cff8faad73d1 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -153,7 +153,8 @@ exuberant() --regex-c++='/CLEARPAGEFLAG_NOOP\(([^,)]*).*/ClearPage\1/' \ --regex-c++='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \ --regex-c++='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \ - --regex-c++='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' + --regex-c++='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' \ + --regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/' all_kconfigs | xargs $1 -a \ --langdef=kconfig --language-force=kconfig \ @@ -195,7 +196,8 @@ emacs() --regex='/CLEARPAGEFLAG_NOOP\(([^,)]*).*/ClearPage\1/' \ --regex='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \ --regex='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \ - --regex='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' + --regex='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' \ + --regex='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/' all_kconfigs | xargs $1 -a \ --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' |
