diff options
author | Michal Marek <mmarek@suse.cz> | 2011-06-07 13:37:51 (GMT) |
---|---|---|
committer | Michal Marek <mmarek@suse.cz> | 2011-06-07 13:37:51 (GMT) |
commit | 2e483528cebad089d0bb3f9aebb0ada22d968ffa (patch) | |
tree | d701405826b271e819a9a8500838cebd37b1364a /scripts | |
parent | 163d3fe6a2357aba7b18b938d6ae6ce9570324e4 (diff) | |
parent | 55922c9d1b84b89cb946c777fddccb3247e7df2c (diff) | |
download | linux-2e483528cebad089d0bb3f9aebb0ada22d968ffa.tar.xz |
Merge commit 'v3.0-rc1' into kbuild/kbuild
Diffstat (limited to 'scripts')
33 files changed, 471 insertions, 230 deletions
diff --git a/scripts/Makefile.build b/scripts/Makefile.build index f133641..a0fd502 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -260,14 +260,19 @@ endif ifdef CONFIG_FTRACE_MCOUNT_RECORD ifdef BUILD_C_RECORDMCOUNT +ifeq ("$(origin RECORDMCOUNT_WARN)", "command line") + RECORDMCOUNT_FLAGS = -w +endif # Due to recursion, we must skip empty.o. # The empty.o file is created in the make process in order to determine # the target endianness and word size. It is made before all other C # files, including recordmcount. sub_cmd_record_mcount = \ if [ $(@) != "scripts/mod/empty.o" ]; then \ - $(objtree)/scripts/recordmcount "$(@)"; \ + $(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)"; \ fi; +recordmcount_source := $(srctree)/scripts/recordmcount.c \ + $(srctree)/scripts/recordmcount.h else sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \ @@ -275,6 +280,7 @@ sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH "$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CFLAGS)" \ "$(LD)" "$(NM)" "$(RM)" "$(MV)" \ "$(if $(part-of-module),1,0)" "$(@)"; +recordmcount_source := $(srctree)/scripts/recordmcount.pl endif cmd_record_mcount = \ if [ "$(findstring -pg,$(_c_flags))" = "-pg" ]; then \ @@ -295,13 +301,13 @@ define rule_cc_o_c endef # Built-in and composite module parts -$(obj)/%.o: $(src)/%.c FORCE +$(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE $(call cmd,force_checksrc) $(call if_changed_rule,cc_o_c) # Single-part modules are special since we need to mark them in $(MODVERDIR) -$(single-used-m): $(obj)/%.o: $(src)/%.c FORCE +$(single-used-m): $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE $(call cmd,force_checksrc) $(call if_changed_rule,cc_o_c) @{ echo $(@:.o=.ko); echo $@; } > $(MODVERDIR)/$(@F:.o=.mod) diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 6ba4332..08dce14 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -35,14 +35,14 @@ # KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined # symbols in the final module linking stage # KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules. -# This is solely usefull to speed up test compiles +# This is solely useful to speed up test compiles PHONY := _modpost _modpost: __modpost include include/config/auto.conf include scripts/Kbuild.include -# When building external modules load the Kbuild file to retreive EXTRA_SYMBOLS info +# When building external modules load the Kbuild file to retrieve EXTRA_SYMBOLS info ifneq ($(KBUILD_EXTMOD),) # set src + obj - they may be used when building the .mod.c file diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 8f9e394..8657f99 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -210,10 +210,10 @@ our $typeTypedefs = qr{(?x: our $logFunctions = qr{(?x: printk| - pr_(debug|dbg|vdbg|devel|info|warning|err|notice|alert|crit|emerg|cont)| - (dev|netdev|netif)_(printk|dbg|vdbg|info|warn|err|notice|alert|crit|emerg|WARN)| + [a-z]+_(emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)| WARN| - panic + panic| + MODULE_[A-Z_]+ )}; our @typeList = ( @@ -1462,7 +1462,7 @@ sub process { #80 column limit if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && $rawline !~ /^.\s*\*\s*\@$Ident\s/ && - !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ || + !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ || $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) && $length > 80) { @@ -1946,13 +1946,13 @@ sub process { # printk should use KERN_* levels. Note that follow on printk's on the # same line do not need a level, so we use the current block context # to try and find and validate the current printk. In summary the current -# printk includes all preceeding printk's which have no newline on the end. +# printk includes all preceding printk's which have no newline on the end. # we assume the first bad printk is the one to report. if ($line =~ /\bprintk\((?!KERN_)\s*"/) { my $ok = 0; for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { #print "CHECK<$lines[$ln - 1]\n"; - # we have a preceeding printk if it ends + # we have a preceding printk if it ends # with "\n" ignore it, else it is to blame if ($lines[$ln - 1] =~ m{\bprintk\(}) { if ($rawlines[$ln - 1] !~ m{\\n"}) { @@ -2044,7 +2044,7 @@ sub process { for (my $n = 0; $n < $#elements; $n += 2) { $off += length($elements[$n]); - # Pick up the preceeding and succeeding characters. + # Pick up the preceding and succeeding characters. my $ca = substr($opline, 0, $off); my $cc = ''; if (length($opline) >= ($off + length($elements[$n + 1]))) { @@ -2748,6 +2748,11 @@ sub process { WARN("sizeof(& should be avoided\n" . $herecurr); } +# check for line continuations in quoted strings with odd counts of " + if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { + WARN("Avoid line continuations in quoted strings\n" . $herecurr); + } + # 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/checkstack.pl b/scripts/checkstack.pl index 1afff66..17e3843 100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl @@ -12,7 +12,7 @@ # sh64 port by Paul Mundt # Random bits by Matt Mackall <mpm@selenic.com> # M68k port by Geert Uytterhoeven and Andreas Schwab -# AVR32 port by Haavard Skinnemoen <hskinnemoen@atmel.com> +# AVR32 port by Haavard Skinnemoen (Atmel) # PARISC port by Kyle McMartin <kyle@parisc-linux.org> # sparc port by Martin Habets <errandir_news@mph.eclipse.co.uk> # diff --git a/scripts/checkversion.pl b/scripts/checkversion.pl index b444e89..5e490a8 100755 --- a/scripts/checkversion.pl +++ b/scripts/checkversion.pl @@ -12,6 +12,7 @@ $| = 1; my $debugging; foreach my $file (@ARGV) { + next if $file =~ "include/linux/version\.h"; # Open this file. open( my $f, '<', $file ) or die "Can't open $file: $!\n"; diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h index ce80e4f..ff6246f 100644 --- a/scripts/dtc/libfdt/libfdt.h +++ b/scripts/dtc/libfdt/libfdt.h @@ -61,7 +61,7 @@ #define FDT_ERR_NOTFOUND 1 /* FDT_ERR_NOTFOUND: The requested node or property does not exist */ #define FDT_ERR_EXISTS 2 - /* FDT_ERR_EXISTS: Attemped to create a node or property which + /* FDT_ERR_EXISTS: Attempted to create a node or property which * already exists */ #define FDT_ERR_NOSPACE 3 /* FDT_ERR_NOSPACE: Operation needed to expand the device diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c index c9209d5..26d0e1e 100644 --- a/scripts/dtc/livetree.c +++ b/scripts/dtc/livetree.c @@ -155,7 +155,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node) } } - /* if no collision occured, add child to the old node. */ + /* if no collision occurred, add child to the old node. */ if (new_child) add_child(old_node, new_child); } diff --git a/scripts/export_report.pl b/scripts/export_report.pl index 04dce7c..8f79b70 100644 --- a/scripts/export_report.pl +++ b/scripts/export_report.pl @@ -25,11 +25,12 @@ sub alphabetically { sub print_depends_on { my ($href) = @_; print "\n"; - while (my ($mod, $list) = each %$href) { + for my $mod (sort keys %$href) { + my $list = $href->{$mod}; print "\t$mod:\n"; foreach my $sym (sort numerically @{$list}) { my ($symbol, $no) = split /\s+/, $sym; - printf("\t\t%-25s\t%-25d\n", $symbol, $no); + printf("\t\t%-25s\n", $symbol); } print "\n"; } @@ -49,8 +50,14 @@ sub usage { } sub collectcfiles { - my @file - = `cat .tmp_versions/*.mod | grep '.*\.ko\$' | sed s/\.ko$/.mod.c/`; + my @file; + while (<.tmp_versions/*.mod>) { + open my $fh, '<', $_ or die "cannot open $_: $!\n"; + push (@file, + grep s/\.ko/.mod.c/, # change the suffix + grep m/.+\.ko/, # find the .ko path + <$fh>); # lines in opened file + } chomp @file; return @file; } @@ -95,6 +102,8 @@ close($module_symvers); # # collect the usage count of each symbol. # +my $modversion_warnings = 0; + foreach my $thismod (@allcfiles) { my $module; @@ -125,7 +134,8 @@ foreach my $thismod (@allcfiles) { } } if ($state != 2) { - print "WARNING:$thismod is not built with CONFIG_MODVERSION enabled\n"; + warn "WARNING:$thismod is not built with CONFIG_MODVERSIONS enabled\n"; + $modversion_warnings++; } close($module); } @@ -159,8 +169,12 @@ printf("SECTION 2:\n\tThis section reports export-symbol-usage of in-kernel modules. Each module lists the modules, and the symbols from that module that it uses. Each listed symbol reports the number of modules using it\n"); +print "\nNOTE: Got $modversion_warnings CONFIG_MODVERSIONS warnings\n\n" + if $modversion_warnings; + print "~"x80 , "\n"; -while (my ($thismod, $list) = each %MODULE) { +for my $thismod (sort keys %MODULE) { + my $list = $MODULE{$thismod}; my %depends; $thismod =~ s/\.mod\.c/.ko/; print "\t\t\t$thismod\n"; diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh index 8da7890..b482f16 100644 --- a/scripts/gen_initramfs_list.sh +++ b/scripts/gen_initramfs_list.sh @@ -284,7 +284,7 @@ while [ $# -gt 0 ]; do done # If output_file is set we will generate cpio archive and compress it -# we are carefull to delete tmp files +# we are careful to delete tmp files if [ ! -z ${output_file} ]; then if [ -z ${cpio_file} ]; then timestamp= diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 368ae30..faa9a47 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -77,14 +77,15 @@ localyesconfig: $(obj)/streamline_config.pl $(obj)/conf # The symlink is used to repair a deficiency in arch/um update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h $(Q)echo " GEN config" - $(Q)xgettext --default-domain=linux \ - --add-comments --keyword=_ --keyword=N_ \ - --from-code=UTF-8 \ - --files-from=scripts/kconfig/POTFILES.in \ + $(Q)xgettext --default-domain=linux \ + --add-comments --keyword=_ --keyword=N_ \ + --from-code=UTF-8 \ + --files-from=$(srctree)/scripts/kconfig/POTFILES.in \ + --directory=$(srctree) --directory=$(objtree) \ --output $(obj)/config.pot $(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot - $(Q)ln -fs Kconfig.i386 arch/um/Kconfig.arch - $(Q)(for i in `ls arch/*/Kconfig`; \ + $(Q)ln -fs Kconfig.x86 arch/um/Kconfig + $(Q)(for i in `ls $(srctree)/arch/*/Kconfig`; \ do \ echo " GEN $$i"; \ $(obj)/kxgettext $$i \ @@ -92,7 +93,7 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h done ) $(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \ --output $(obj)/linux.pot - $(Q)rm -f arch/um/Kconfig.arch + $(Q)rm -f $(srctree)/arch/um/Kconfig $(Q)rm -f $(obj)/config.pot PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig @@ -168,8 +169,11 @@ conf-objs := conf.o zconf.tab.o mconf-objs := mconf.o zconf.tab.o $(lxdialog) nconf-objs := nconf.o zconf.tab.o nconf.gui.o kxgettext-objs := kxgettext.o zconf.tab.o +qconf-cxxobjs := qconf.o +qconf-objs := kconfig_load.o zconf.tab.o +gconf-objs := gconf.o kconfig_load.o zconf.tab.o -hostprogs-y := conf qconf gconf kxgettext +hostprogs-y := conf ifeq ($(MAKECMDGOALS),nconfig) hostprogs-y += nconf @@ -179,6 +183,10 @@ ifeq ($(MAKECMDGOALS),menuconfig) hostprogs-y += mconf endif +ifeq ($(MAKECMDGOALS),update-po-config) + hostprogs-y += kxgettext +endif + ifeq ($(MAKECMDGOALS),xconfig) qconf-target := 1 endif @@ -188,16 +196,15 @@ endif ifeq ($(qconf-target),1) -qconf-cxxobjs := qconf.o -qconf-objs := kconfig_load.o zconf.tab.o + hostprogs-y += qconf endif ifeq ($(gconf-target),1) -gconf-objs := gconf.o kconfig_load.o zconf.tab.o + hostprogs-y += gconf endif -clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \ - .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h +clean-files := lkc_defs.h qconf.moc .tmp_qtcheck .tmp_gtkcheck +clean-files += zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h clean-files += mconf qconf gconf nconf clean-files += config.pot linux.pot @@ -321,11 +328,12 @@ $(obj)/%.moc: $(src)/%.h $(KC_QT_MOC) -i $< -o $@ $(obj)/lkc_defs.h: $(src)/lkc_proto.h - sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' + $(Q)sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' # Extract gconf menu items for I18N support $(obj)/gconf.glade.h: $(obj)/gconf.glade - intltool-extract --type=gettext/glade $(obj)/gconf.glade + $(Q)intltool-extract --type=gettext/glade --srcdir=$(srctree) \ + $(obj)/gconf.glade ### # The following requires flex/bison/gperf diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 659326c..006ad81 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -332,7 +332,7 @@ static int conf_choice(struct menu *menu) } if (!child) continue; - if (line[strlen(line) - 1] == '?') { + if (line[0] && line[strlen(line) - 1] == '?') { print_help(child); continue; } diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 61c35bf..2bafd9a 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -560,8 +560,6 @@ int conf_write(const char *name) const char *basename; const char *str; char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1]; - time_t now; - int use_timestamp = 1; char *env; dirname[0] = 0; @@ -598,19 +596,11 @@ int conf_write(const char *name) if (!out) return 1; - time(&now); - env = getenv("KCONFIG_NOTIMESTAMP"); - if (env && *env) - use_timestamp = 0; - fprintf(out, _("#\n" "# Automatically generated make config: don't edit\n" "# %s\n" - "%s%s" "#\n"), - rootmenu.prompt->text, - use_timestamp ? "# " : "", - use_timestamp ? ctime(&now) : ""); + rootmenu.prompt->text); if (!conf_get_changed()) sym_clear_all_valid(); @@ -784,7 +774,6 @@ int conf_write_autoconf(void) const char *str; const char *name; FILE *out, *tristate, *out_h; - time_t now; int i; sym_clear_all_valid(); @@ -811,22 +800,19 @@ int conf_write_autoconf(void) return 1; } - time(&now); fprintf(out, "#\n" "# Automatically generated make config: don't edit\n" "# %s\n" - "# %s" "#\n", - rootmenu.prompt->text, ctime(&now)); + rootmenu.prompt->text); fprintf(tristate, "#\n" "# Automatically generated - do not edit\n" "\n"); fprintf(out_h, "/*\n" " * Automatically generated C config: don't edit\n" " * %s\n" - " * %s" " */\n", - rootmenu.prompt->text, ctime(&now)); + rootmenu.prompt->text); for_all_symbols(i, sym) { sym_calc_value(sym); diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 3d238db..16bfae2 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -20,12 +20,8 @@ struct file { struct file *parent; const char *name; int lineno; - int flags; }; -#define FILE_BUSY 0x0001 -#define FILE_SCANNED 0x0002 - typedef enum tristate { no, mod, yes } tristate; diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 45589616..a11d5f7 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -253,7 +253,7 @@ void init_left_tree(void) gtk_tree_view_set_model(view, model1); gtk_tree_view_set_headers_visible(view, TRUE); - gtk_tree_view_set_rules_hint(view, FALSE); + gtk_tree_view_set_rules_hint(view, TRUE); column = gtk_tree_view_column_new(); gtk_tree_view_append_column(view, column); @@ -298,7 +298,7 @@ void init_right_tree(void) gtk_tree_view_set_model(view, model2); gtk_tree_view_set_headers_visible(view, TRUE); - gtk_tree_view_set_rules_hint(view, FALSE); + gtk_tree_view_set_rules_hint(view, TRUE); column = gtk_tree_view_column_new(); gtk_tree_view_append_column(view, column); @@ -756,7 +756,6 @@ void on_load_clicked(GtkButton * button, gpointer user_data) void on_single_clicked(GtkButton * button, gpointer user_data) { view_mode = SINGLE_VIEW; - gtk_paned_set_position(GTK_PANED(hpaned), 0); gtk_widget_hide(tree1_w); current = &rootmenu; display_tree_part(); @@ -782,7 +781,6 @@ void on_split_clicked(GtkButton * button, gpointer user_data) void on_full_clicked(GtkButton * button, gpointer user_data) { view_mode = FULL_VIEW; - gtk_paned_set_position(GTK_PANED(hpaned), 0); gtk_widget_hide(tree1_w); if (tree2) gtk_tree_store_clear(tree2); @@ -1444,6 +1442,12 @@ static void display_tree(struct menu *menu) if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) || (view_mode == FULL_VIEW) || (view_mode == SPLIT_VIEW))*/ + + /* Change paned position if the view is not in 'split mode' */ + if (view_mode == SINGLE_VIEW || view_mode == FULL_VIEW) { + gtk_paned_set_position(GTK_PANED(hpaned), 0); + } + if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT)) || (view_mode == FULL_VIEW) || (view_mode == SPLIT_VIEW)) { diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped index 6eb0397..d918291 100644 --- a/scripts/kconfig/lex.zconf.c_shipped +++ b/scripts/kconfig/lex.zconf.c_shipped @@ -2363,11 +2363,11 @@ void zconf_initscan(const char *name) current_file = file_lookup(name); current_file->lineno = 1; - current_file->flags = FILE_BUSY; } void zconf_nextfile(const char *name) { + struct file *iter; struct file *file = file_lookup(name); struct buffer *buf = malloc(sizeof(*buf)); memset(buf, 0, sizeof(*buf)); @@ -2383,18 +2383,25 @@ void zconf_nextfile(const char *name) buf->parent = current_buf; current_buf = buf; - if (file->flags & FILE_BUSY) { - printf("%s:%d: do not source '%s' from itself\n", - zconf_curname(), zconf_lineno(), name); - exit(1); - } - if (file->flags & FILE_SCANNED) { - printf("%s:%d: file '%s' is already sourced from '%s'\n", - zconf_curname(), zconf_lineno(), name, - file->parent->name); - exit(1); + for (iter = current_file->parent; iter; iter = iter->parent ) { + if (!strcmp(current_file->name,iter->name) ) { + printf("%s:%d: recursive inclusion detected. " + "Inclusion path:\n current file : '%s'\n", + zconf_curname(), zconf_lineno(), + zconf_curname()); + iter = current_file->parent; + while (iter && \ + strcmp(iter->name,current_file->name)) { + printf(" included from: '%s:%d'\n", + iter->name, iter->lineno-1); + iter = iter->parent; + } + if (iter) + printf(" included from: '%s:%d'\n", + iter->name, iter->lineno+1); + exit(1); + } } - file->flags |= FILE_BUSY; file->lineno = 1; file->parent = current_file; current_file = file; @@ -2404,8 +2411,6 @@ static void zconf_endfile(void) { struct buffer *parent; - current_file->flags |= FILE_SCANNED; - current_file->flags &= ~FILE_BUSY; current_file = current_file->parent; parent = current_buf->parent; diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index db56377..488dd74 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -373,18 +373,18 @@ static void print_function_line(void) const int skip = 1; for (i = 0; i < function_keys_num; i++) { - wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]); + (void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]); mvwprintw(main_window, LINES-3, offset, "%s", function_keys[i].key_str); - wattrset(main_window, attributes[FUNCTION_TEXT]); + (void) wattrset(main_window, attributes[FUNCTION_TEXT]); offset += strlen(function_keys[i].key_str); mvwprintw(main_window, LINES-3, offset, "%s", function_keys[i].func); offset += strlen(function_keys[i].func) + skip; } - wattrset(main_window, attributes[NORMAL]); + (void) wattrset(main_window, attributes[NORMAL]); } /* help */ @@ -953,16 +953,16 @@ static void show_menu(const char *prompt, const char *instructions, current_instructions = instructions; clear(); - wattrset(main_window, attributes[NORMAL]); + (void) wattrset(main_window, attributes[NORMAL]); print_in_middle(stdscr, 1, 0, COLS, menu_backtitle, attributes[MAIN_HEADING]); - wattrset(main_window, attributes[MAIN_MENU_BOX]); + (void) wattrset(main_window, attributes[MAIN_MENU_BOX]); box(main_window, 0, 0); - wattrset(main_window, attributes[MAIN_MENU_HEADING]); + (void) wattrset(main_window, attributes[MAIN_MENU_HEADING]); mvwprintw(main_window, 0, 3, " %s ", prompt); - wattrset(main_window, attributes[NORMAL]); + (void) wattrset(main_window, attributes[NORMAL]); set_menu_items(curses_menu, curses_menu_items); diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 06dd2e3..c2796b8 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1489,8 +1489,7 @@ void ConfigMainWindow::saveConfigAs(void) QString s = Q3FileDialog::getSaveFileName(conf_get_configname(), NULL, this); if (s.isNull()) return; - if (conf_write(QFile::encodeName(s))) - QMessageBox::information(this, "qconf", _("Unable to save configuration!")); + saveConfig(); } void ConfigMainWindow::searchConfig(void) @@ -1643,7 +1642,7 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e) mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit")); switch (mb.exec()) { case QMessageBox::Yes: - conf_write(NULL); + saveConfig(); case QMessageBox::No: e->accept(); break; diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l index 3dbaec1..b22f884 100644 --- a/scripts/kconfig/zconf.l +++ b/scripts/kconfig/zconf.l @@ -294,11 +294,11 @@ void zconf_initscan(const char *name) current_file = file_lookup(name); current_file->lineno = 1; - current_file->flags = FILE_BUSY; } void zconf_nextfile(const char *name) { + struct file *iter; struct file *file = file_lookup(name); struct buffer *buf = malloc(sizeof(*buf)); memset(buf, 0, sizeof(*buf)); @@ -314,18 +314,25 @@ void zconf_nextfile(const char *name) buf->parent = current_buf; current_buf = buf; - if (file->flags & FILE_BUSY) { - printf("%s:%d: do not source '%s' from itself\n", - zconf_curname(), zconf_lineno(), name); - exit(1); - } - if (file->flags & FILE_SCANNED) { - printf("%s:%d: file '%s' is already sourced from '%s'\n", - zconf_curname(), zconf_lineno(), name, - file->parent->name); - exit(1); + for (iter = current_file->parent; iter; iter = iter->parent ) { + if (!strcmp(current_file->name,iter->name) ) { + printf("%s:%d: recursive inclusion detected. " + "Inclusion path:\n current file : '%s'\n", + zconf_curname(), zconf_lineno(), + zconf_curname()); + iter = current_file->parent; + while (iter && \ + strcmp(iter->name,current_file->name)) { + printf(" included from: '%s:%d'\n", + iter->name, iter->lineno-1); + iter = iter->parent; + } + if (iter) + printf(" included from: '%s:%d'\n", + iter->name, iter->lineno+1); + exit(1); + } } - file->flags |= FILE_BUSY; file->lineno = 1; file->parent = current_file; current_file = file; @@ -335,8 +342,6 @@ static void zconf_endfile(void) { struct buffer *parent; - current_file->flags |= FILE_SCANNED; - current_file->flags &= ~FILE_BUSY; current_file = current_file->parent; parent = current_buf->parent; diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 9f85012..d793001 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1705,7 +1705,7 @@ sub push_parameter($$$) { $param = xml_escape($param); - # strip spaces from $param so that it is one continous string + # strip spaces from $param so that it is one continuous string # on @parameterlist; # this fixes a problem where check_sections() cannot find # a parameter like "addr[6 + 2]" because it actually appears diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 88f3f07..e26e2fb 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -702,6 +702,24 @@ static int do_ssb_entry(const char *filename, return 1; } +/* Looks like: bcma:mNidNrevNclN. */ +static int do_bcma_entry(const char *filename, + struct bcma_device_id *id, char *alias) +{ + id->manuf = TO_NATIVE(id->manuf); + id->id = TO_NATIVE(id->id); + id->rev = TO_NATIVE(id->rev); + id->class = TO_NATIVE(id->class); + + strcpy(alias, "bcma:"); + ADD(alias, "m", id->manuf != BCMA_ANY_MANUF, id->manuf); + ADD(alias, "id", id->id != BCMA_ANY_ID, id->id); + ADD(alias, "rev", id->rev != BCMA_ANY_REV, id->rev); + ADD(alias, "cl", id->class != BCMA_ANY_CLASS, id->class); + add_wildcard(alias); + return 1; +} + /* Looks like: virtio:dNvN */ static int do_virtio_entry(const char *filename, struct virtio_device_id *id, char *alias) @@ -968,6 +986,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, do_table(symval, sym->st_size, sizeof(struct ssb_device_id), "ssb", do_ssb_entry, mod); + else if (sym_is(symname, "__mod_bcma_device_table")) + do_table(symval, sym->st_size, + sizeof(struct bcma_device_id), "bcma", + do_bcma_entry, mod); else if (sym_is(symname, "__mod_virtio_device_table")) do_table(symval, sym->st_size, sizeof(struct virtio_device_id), "virtio", diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index cd104af..413c536 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -420,11 +420,10 @@ static int parse_elf(struct elf_info *info, const char *filename) return 0; } - if (hdr->e_shnum == 0) { + if (hdr->e_shnum == SHN_UNDEF) { /* * There are more than 64k sections, * read count from .sh_size. - * note: it doesn't need shndx2secindex() */ info->num_sections = TO_NATIVE(sechdrs[0].sh_size); } @@ -432,8 +431,7 @@ static int parse_elf(struct elf_info *info, const char *filename) info->num_sections = hdr->e_shnum; } if (hdr->e_shstrndx == SHN_XINDEX) { - info->secindex_strings = - shndx2secindex(TO_NATIVE(sechdrs[0].sh_link)); + info->secindex_strings = TO_NATIVE(sechdrs[0].sh_link); } else { info->secindex_strings = hdr->e_shstrndx; @@ -489,7 +487,7 @@ static int parse_elf(struct elf_info *info, const char *filename) sechdrs[i].sh_offset; info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset + sechdrs[i].sh_size; - sh_link_idx = shndx2secindex(sechdrs[i].sh_link); + sh_link_idx = sechdrs[i].sh_link; info->strtab = (void *)hdr + sechdrs[sh_link_idx].sh_offset; } @@ -516,11 +514,9 @@ static int parse_elf(struct elf_info *info, const char *filename) if (symtab_shndx_idx != ~0U) { Elf32_Word *p; - if (symtab_idx != - shndx2secindex(sechdrs[symtab_shndx_idx].sh_link)) + if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link) fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n", - filename, - shndx2secindex(sechdrs[symtab_shndx_idx].sh_link), + filename, sechdrs[symtab_shndx_idx].sh_link, symtab_idx); /* Fix endianness */ for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop; @@ -1446,7 +1442,7 @@ static unsigned int *reloc_location(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) { Elf_Shdr *sechdrs = elf->sechdrs; - int section = shndx2secindex(sechdr->sh_info); + int section = sechdr->sh_info; return (void *)elf->hdr + sechdrs[section].sh_offset + r->r_offset; diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 0388cfcc..2031119 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -145,33 +145,22 @@ static inline int is_shndx_special(unsigned int i) return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE; } -/* shndx is in [0..SHN_LORESERVE) U (SHN_HIRESERVE, 0xfffffff], thus: - * shndx == 0 <=> sechdrs[0] - * ...... - * shndx == SHN_LORESERVE-1 <=> sechdrs[SHN_LORESERVE-1] - * shndx == SHN_HIRESERVE+1 <=> sechdrs[SHN_LORESERVE] - * shndx == SHN_HIRESERVE+2 <=> sechdrs[SHN_LORESERVE+1] - * ...... - * fyi: sym->st_shndx is uint16, SHN_LORESERVE = ff00, SHN_HIRESERVE = ffff, - * so basically we map 0000..feff -> 0000..feff - * ff00..ffff -> (you are a bad boy, dont do it) - * 10000..xxxx -> ff00..(xxxx-0x100) +/* + * Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of + * the way to -256..-1, to avoid conflicting with real section + * indices. */ -static inline unsigned int shndx2secindex(unsigned int i) -{ - if (i <= SHN_HIRESERVE) - return i; - return i - (SHN_HIRESERVE + 1 - SHN_LORESERVE); -} +#define SPECIAL(i) ((i) - (SHN_HIRESERVE + 1)) /* Accessor for sym->st_shndx, hides ugliness of "64k sections" */ static inline unsigned int get_secindex(const struct elf_info *info, const Elf_Sym *sym) { + if (is_shndx_special(sym->st_shndx)) + return SPECIAL(sym->st_shndx); if (sym->st_shndx != SHN_XINDEX) return sym->st_shndx; - return shndx2secindex(info->symtab_shndx_start[sym - - info->symtab_start]); + return info->symtab_shndx_start[sym - info->symtab_start]; } /* file2alias.c */ diff --git a/scripts/module-common.lds b/scripts/module-common.lds index 47a1f9a..0865b3e 100644 --- a/scripts/module-common.lds +++ b/scripts/module-common.lds @@ -5,4 +5,15 @@ */ SECTIONS { /DISCARD/ : { *(.discard) } + + __ksymtab : { *(SORT(___ksymtab+*)) } + __ksymtab_gpl : { *(SORT(___ksymtab_gpl+*)) } + __ksymtab_unused : { *(SORT(___ksymtab_unused+*)) } + __ksymtab_unused_gpl : { *(SORT(___ksymtab_unused_gpl+*)) } + __ksymtab_gpl_future : { *(SORT(___ksymtab_gpl_future+*)) } + __kcrctab : { *(SORT(___kcrctab+*)) } + __kcrctab_gpl : { *(SORT(___kcrctab_gpl+*)) } + __kcrctab_unused : { *(SORT(___kcrctab_unused+*)) } + __kcrctab_unused_gpl : { *(SORT(___kcrctab_unused_gpl+*)) } + __kcrctab_gpl_future : { *(SORT(___kcrctab_gpl_future+*)) } } diff --git a/scripts/package/Makefile b/scripts/package/Makefile index a834b93..006960e 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -26,9 +26,9 @@ RPM := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \ else echo rpm; fi) # Remove hyphens since they have special meaning in RPM filenames -KERNELPATH := kernel-$(subst -,,$(KERNELRELEASE)) +KERNELPATH := kernel-$(subst -,_,$(KERNELRELEASE)) MKSPEC := $(srctree)/scripts/package/mkspec -PREV := set -e; cd ..; +PREV := set -e; cd -P ..; # rpm-pkg # --------------------------------------------------------------------------- diff --git a/scripts/package/buildtar b/scripts/package/buildtar index 83c9c04..8a7b155 100644 --- a/scripts/package/buildtar +++ b/scripts/package/buildtar @@ -92,7 +92,7 @@ case "${ARCH}" in echo "" >&2 echo '** ** ** WARNING ** ** **' >&2 echo "" >&2 - echo "Your architecture did not define any architecture-dependant files" >&2 + echo "Your architecture did not define any architecture-dependent files" >&2 echo "to be placed into the tarball. Please add those to ${0} ..." >&2 echo "" >&2 sleep 5 diff --git a/scripts/package/mkspec b/scripts/package/mkspec index e1c1d5b..4bf17dd 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -22,7 +22,7 @@ if [ "`grep CONFIG_DRM=y .config | cut -f2 -d\=`" = "y" ]; then fi PROVIDES="$PROVIDES kernel-$KERNELRELEASE" -__KERNELRELEASE=`echo $KERNELRELEASE | sed -e "s/-//g"` +__KERNELRELEASE=`echo $KERNELRELEASE | sed -e "s/-/_/g"` echo "Name: kernel" echo "Summary: The Linux Kernel" @@ -47,6 +47,18 @@ echo "" echo "%description" echo "The Linux Kernel, the operating system core itself" echo "" +echo "%package headers" +echo "Summary: Header files for the Linux kernel for use by glibc" +echo "Group: Development/System" +echo "Obsoletes: kernel-headers" +echo "Provides: kernel-headers = %{version}" +echo "%description headers" +echo "Kernel-headers includes the C header files that specify the interface" +echo "between the Linux kernel and userspace libraries and programs. The" +echo "header files define structures and constants that are needed for" +echo "building most standard programs and are also needed for rebuilding the" +echo "glibc package." +echo "" if ! $PREBUILT; then echo "%prep" @@ -83,6 +95,7 @@ echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/vmlinuz-$KERNELRELEASE" echo "%endif" echo "%endif" +echo 'make %{?_smp_mflags} INSTALL_HDR_PATH=$RPM_BUILD_ROOT/usr headers_install' echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$KERNELRELEASE" echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$KERNELRELEASE" @@ -105,3 +118,7 @@ echo "/lib/modules/$KERNELRELEASE" echo "/lib/firmware" echo "/boot/*" echo "" +echo "%files headers" +echo '%defattr (-, root, root)' +echo "/usr/include" +echo "" diff --git a/scripts/patch-kernel b/scripts/patch-kernel index 46a59ca..20fb25c 100755 --- a/scripts/patch-kernel +++ b/scripts/patch-kernel @@ -250,7 +250,7 @@ while : # incrementing SUBLEVEL (s in v.p.s) do CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" EXTRAVER= - if [ $STOPFULLVERSION = $CURRENTFULLVERSION ]; then + if [ x$STOPFULLVERSION = x$CURRENTFULLVERSION ]; then echo "Stopping at $CURRENTFULLVERSION base as requested." break fi diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index f9f6f52..ee52cb8 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -24,6 +24,7 @@ #include <sys/types.h> #include <sys/mman.h> #include <sys/stat.h> +#include <getopt.h> #include <elf.h> #include <fcntl.h> #include <setjmp.h> @@ -39,6 +40,7 @@ static char gpfx; /* prefix for global symbol name (sometimes '_') */ static struct stat sb; /* Remember .st_size, etc. */ static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */ static const char *altmcount; /* alternate mcount symbol name */ +static int warn_on_notrace_sect; /* warn when section has mcount not being recorded */ /* setjmp() return values */ enum { @@ -78,7 +80,7 @@ static off_t ulseek(int const fd, off_t const offset, int const whence) { off_t const w = lseek(fd, offset, whence); - if ((off_t)-1 == w) { + if (w == (off_t)-1) { perror("lseek"); fail_file(); } @@ -111,13 +113,41 @@ static void * umalloc(size_t size) { void *const addr = malloc(size); - if (0 == addr) { + if (addr == 0) { fprintf(stderr, "malloc failed: %zu bytes\n", size); fail_file(); } return addr; } +static unsigned char ideal_nop5_x86_64[5] = { 0x0f, 0x1f, 0x44, 0x00, 0x00 }; +static unsigned char ideal_nop5_x86_32[5] = { 0x3e, 0x8d, 0x74, 0x26, 0x00 }; +static unsigned char *ideal_nop; + +static char rel_type_nop; + +static int (*make_nop)(void *map, size_t const offset); + +static int make_nop_x86(void *map, size_t const offset) +{ + uint32_t *ptr; + unsigned char *op; + + /* Confirm we have 0xe8 0x0 0x0 0x0 0x0 */ + ptr = map + offset; + if (*ptr != 0) + return -1; + + op = map + offset - 1; + if (*op != 0xe8) + return -1; + + /* convert to nop */ + ulseek(fd_map, offset - 1, SEEK_SET); + uwrite(fd_map, ideal_nop, 5); + return 0; +} + /* * Get the whole file as a programming convenience in order to avoid * malloc+lseek+read+free of many pieces. If successful, then mmap @@ -136,7 +166,7 @@ static void *mmap_file(char const *fname) void *addr; fd_map = open(fname, O_RDWR); - if (0 > fd_map || 0 > fstat(fd_map, &sb)) { + if (fd_map < 0 || fstat(fd_map, &sb) < 0) { perror(fname); fail_file(); } @@ -147,7 +177,7 @@ static void *mmap_file(char const *fname) addr = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd_map, 0); mmap_failed = 0; - if (MAP_FAILED == addr) { + if (addr == MAP_FAILED) { mmap_failed = 1; addr = umalloc(sb.st_size); uread(fd_map, addr, sb.st_size); @@ -206,12 +236,13 @@ static uint32_t (*w2)(uint16_t); static int is_mcounted_section_name(char const *const txtname) { - return 0 == strcmp(".text", txtname) || - 0 == strcmp(".ref.text", txtname) || - 0 == strcmp(".sched.text", txtname) || - 0 == strcmp(".spinlock.text", txtname) || - 0 == strcmp(".irqentry.text", txtname) || - 0 == strcmp(".text.unlikely", txtname); + return strcmp(".text", txtname) == 0 || + strcmp(".ref.text", txtname) == 0 || + strcmp(".sched.text", txtname) == 0 || + strcmp(".spinlock.text", txtname) == 0 || + strcmp(".irqentry.text", txtname) == 0 || + strcmp(".kprobes.text", txtname) == 0 || + strcmp(".text.unlikely", txtname) == 0; } /* 32 bit and 64 bit are very similar */ @@ -264,43 +295,48 @@ do_file(char const *const fname) w8 = w8nat; switch (ehdr->e_ident[EI_DATA]) { static unsigned int const endian = 1; - default: { + default: fprintf(stderr, "unrecognized ELF data encoding %d: %s\n", ehdr->e_ident[EI_DATA], fname); fail_file(); - } break; - case ELFDATA2LSB: { - if (1 != *(unsigned char const *)&endian) { + break; + case ELFDATA2LSB: + if (*(unsigned char const *)&endian != 1) { /* main() is big endian, file.o is little endian. */ w = w4rev; w2 = w2rev; w8 = w8rev; } - } break; - case ELFDATA2MSB: { - if (0 != *(unsigned char const *)&endian) { + break; + case ELFDATA2MSB: + if (*(unsigned char const *)&endian != 0) { /* main() is little endian, file.o is big endian. */ w = w4rev; w2 = w2rev; w8 = w8rev; } - } break; + break; } /* end switch */ - if (0 != memcmp(ELFMAG, ehdr->e_ident, SELFMAG) - || ET_REL != w2(ehdr->e_type) - || EV_CURRENT != ehdr->e_ident[EI_VERSION]) { + if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0 + || w2(ehdr->e_type) != ET_REL + || ehdr->e_ident[EI_VERSION] != EV_CURRENT) { fprintf(stderr, "unrecognized ET_REL file %s\n", fname); fail_file(); } gpfx = 0; switch (w2(ehdr->e_machine)) { - default: { + default: fprintf(stderr, "unrecognized e_machine %d %s\n", w2(ehdr->e_machine), fname); fail_file(); - } break; - case EM_386: reltype = R_386_32; break; + break; + case EM_386: + reltype = R_386_32; + make_nop = make_nop_x86; + ideal_nop = ideal_nop5_x86_32; + mcount_adjust_32 = -1; + break; case EM_ARM: reltype = R_ARM_ABS32; altmcount = "__gnu_mcount_nc"; break; @@ -311,67 +347,91 @@ do_file(char const *const fname) case EM_S390: /* reltype: e_class */ gpfx = '_'; break; case EM_SH: reltype = R_SH_DIR32; break; case EM_SPARCV9: reltype = R_SPARC_64; gpfx = '_'; break; - case EM_X86_64: reltype = R_X86_64_64; break; + case EM_X86_64: + make_nop = make_nop_x86; + ideal_nop = ideal_nop5_x86_64; + reltype = R_X86_64_64; + mcount_adjust_64 = -1; + break; } /* end switch */ switch (ehdr->e_ident[EI_CLASS]) { - default: { + default: fprintf(stderr, "unrecognized ELF class %d %s\n", ehdr->e_ident[EI_CLASS], fname); fail_file(); - } break; - case ELFCLASS32: { - if (sizeof(Elf32_Ehdr) != w2(ehdr->e_ehsize) - || sizeof(Elf32_Shdr) != w2(ehdr->e_shentsize)) { + break; + case ELFCLASS32: + if (w2(ehdr->e_ehsize) != sizeof(Elf32_Ehdr) + || w2(ehdr->e_shentsize) != sizeof(Elf32_Shdr)) { fprintf(stderr, "unrecognized ET_REL file: %s\n", fname); fail_file(); } - if (EM_S390 == w2(ehdr->e_machine)) + if (w2(ehdr->e_machine) == EM_S390) { reltype = R_390_32; - if (EM_MIPS == w2(ehdr->e_machine)) { + mcount_adjust_32 = -4; + } + if (w2(ehdr->e_machine) == EM_MIPS) { reltype = R_MIPS_32; is_fake_mcount32 = MIPS32_is_fake_mcount; } do32(ehdr, fname, reltype); - } break; + break; case ELFCLASS64: { Elf64_Ehdr *const ghdr = (Elf64_Ehdr *)ehdr; - if (sizeof(Elf64_Ehdr) != w2(ghdr->e_ehsize) - || sizeof(Elf64_Shdr) != w2(ghdr->e_shentsize)) { + if (w2(ghdr->e_ehsize) != sizeof(Elf64_Ehdr) + || w2(ghdr->e_shentsize) != sizeof(Elf64_Shdr)) { fprintf(stderr, "unrecognized ET_REL file: %s\n", fname); fail_file(); } - if (EM_S390 == w2(ghdr->e_machine)) + if (w2(ghdr->e_machine) == EM_S390) { reltype = R_390_64; - if (EM_MIPS == w2(ghdr->e_machine)) { + mcount_adjust_64 = -8; + } + if (w2(ghdr->e_machine) == EM_MIPS) { reltype = R_MIPS_64; Elf64_r_sym = MIPS64_r_sym; Elf64_r_info = MIPS64_r_info; is_fake_mcount64 = MIPS64_is_fake_mcount; } do64(ghdr, fname, reltype); - } break; + break; + } } /* end switch */ cleanup(); } int -main(int argc, char const *argv[]) +main(int argc, char *argv[]) { const char ftrace[] = "/ftrace.o"; int ftrace_size = sizeof(ftrace) - 1; int n_error = 0; /* gcc-4.3.0 false positive complaint */ + int c; + int i; + + while ((c = getopt(argc, argv, "w")) >= 0) { + switch (c) { + case 'w': + warn_on_notrace_sect = 1; + break; + default: + fprintf(stderr, "usage: recordmcount [-w] file.o...\n"); + return 0; + } + } - if (argc <= 1) { - fprintf(stderr, "usage: recordmcount file.o...\n"); + if ((argc - optind) < 1) { + fprintf(stderr, "usage: recordmcount [-w] file.o...\n"); return 0; } /* Process each file in turn, allowing deep failure. */ - for (--argc, ++argv; 0 < argc; --argc, ++argv) { + for (i = optind; i < argc; i++) { + char *file = argv[i]; int const sjval = setjmp(jmpenv); int len; @@ -380,29 +440,29 @@ main(int argc, char const *argv[]) * function but does not call it. Since ftrace.o should * not be traced anyway, we just skip it. */ - len = strlen(argv[0]); + len = strlen(file); if (len >= ftrace_size && - strcmp(argv[0] + (len - ftrace_size), ftrace) == 0) + strcmp(file + (len - ftrace_size), ftrace) == 0) continue; switch (sjval) { - default: { - fprintf(stderr, "internal error: %s\n", argv[0]); + default: + fprintf(stderr, "internal error: %s\n", file); exit(1); - } break; - case SJ_SETJMP: { /* normal sequence */ + break; + case SJ_SETJMP: /* normal sequence */ /* Avoid problems if early cleanup() */ fd_map = -1; ehdr_curr = NULL; mmap_failed = 1; - do_file(argv[0]); - } break; - case SJ_FAIL: { /* error in do_file or below */ + do_file(file); + break; + case SJ_FAIL: /* error in do_file or below */ ++n_error; - } break; - case SJ_SUCCEED: { /* premature success */ + break; + case SJ_SUCCEED: /* premature success */ /* do nothing */ - } break; + break; } /* end switch */ } return !!n_error; diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index baf187b..f40a6af6 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h @@ -22,11 +22,15 @@ #undef is_fake_mcount #undef fn_is_fake_mcount #undef MIPS_is_fake_mcount +#undef mcount_adjust #undef sift_rel_mcount +#undef nop_mcount #undef find_secsym_ndx #undef __has_rel_mcount #undef has_rel_mcount #undef tot_relsize +#undef get_mcountsym +#undef get_sym_str_and_relp #undef do_func #undef Elf_Addr #undef Elf_Ehdr @@ -39,6 +43,7 @@ #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 @@ -49,14 +54,18 @@ #ifdef RECORD_MCOUNT_64 # define append_func append64 # define sift_rel_mcount sift64_rel_mcount +# define nop_mcount nop_mcount_64 # define find_secsym_ndx find64_secsym_ndx # define __has_rel_mcount __has64_rel_mcount # define has_rel_mcount has64_rel_mcount # define tot_relsize tot64_relsize +# define get_sym_str_and_relp get_sym_str_and_relp_64 # define do_func do64 +# define get_mcountsym get_mcountsym_64 # define is_fake_mcount is_fake_mcount64 # define fn_is_fake_mcount fn_is_fake_mcount64 # define MIPS_is_fake_mcount MIPS64_is_fake_mcount +# define mcount_adjust mcount_adjust_64 # define Elf_Addr Elf64_Addr # define Elf_Ehdr Elf64_Ehdr # define Elf_Shdr Elf64_Shdr @@ -68,6 +77,7 @@ # 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 @@ -77,14 +87,18 @@ #else # define append_func append32 # define sift_rel_mcount sift32_rel_mcount +# define nop_mcount nop_mcount_32 # define find_secsym_ndx find32_secsym_ndx # define __has_rel_mcount __has32_rel_mcount # define has_rel_mcount has32_rel_mcount # define tot_relsize tot32_relsize +# define get_sym_str_and_relp get_sym_str_and_relp_32 # define do_func do32 +# define get_mcountsym get_mcountsym_32 # define is_fake_mcount is_fake_mcount32 # define fn_is_fake_mcount fn_is_fake_mcount32 # define MIPS_is_fake_mcount MIPS32_is_fake_mcount +# define mcount_adjust mcount_adjust_32 # define Elf_Addr Elf32_Addr # define Elf_Ehdr Elf32_Ehdr # define Elf_Shdr Elf32_Shdr @@ -96,6 +110,7 @@ # 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 @@ -123,6 +138,8 @@ static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type) } static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO; +static int mcount_adjust = 0; + /* * MIPS mcount long call has 2 _mcount symbols, only the position of the 1st * _mcount symbol is needed for dynamic function tracer, with it, to disable @@ -234,6 +251,49 @@ static void append_func(Elf_Ehdr *const ehdr, uwrite(fd_map, ehdr, sizeof(*ehdr)); } +static unsigned get_mcountsym(Elf_Sym const *const sym0, + Elf_Rel const *relp, + char const *const str0) +{ + unsigned mcountsym = 0; + + Elf_Sym const *const symp = + &sym0[Elf_r_sym(relp)]; + char const *symname = &str0[w(symp->st_name)]; + char const *mcount = gpfx == '_' ? "_mcount" : "mcount"; + + if (symname[0] == '.') + ++symname; /* ppc64 hack */ + if (strcmp(mcount, symname) == 0 || + (altmcount && strcmp(altmcount, symname) == 0)) + mcountsym = Elf_r_sym(relp); + + return mcountsym; +} + +static void get_sym_str_and_relp(Elf_Shdr const *const relhdr, + Elf_Ehdr const *const ehdr, + Elf_Sym const **sym0, + char const **str0, + Elf_Rel const **relp) +{ + Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff) + + (void *)ehdr); + unsigned const symsec_sh_link = w(relhdr->sh_link); + Elf_Shdr const *const symsec = &shdr0[symsec_sh_link]; + Elf_Shdr const *const strsec = &shdr0[w(symsec->sh_link)]; + Elf_Rel const *const rel0 = (Elf_Rel const *)(_w(relhdr->sh_offset) + + (void *)ehdr); + + *sym0 = (Elf_Sym const *)(_w(symsec->sh_offset) + + (void *)ehdr); + + *str0 = (char const *)(_w(strsec->sh_offset) + + (void *)ehdr); + + *relp = rel0; +} + /* * Look at the relocations in order to find the calls to mcount. * Accumulate the section offsets that are found, and their relocation info, @@ -250,47 +310,27 @@ static uint_t *sift_rel_mcount(uint_t *mlocp, { uint_t *const mloc0 = mlocp; Elf_Rel *mrelp = *mrelpp; - Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff) - + (void *)ehdr); - unsigned const symsec_sh_link = w(relhdr->sh_link); - Elf_Shdr const *const symsec = &shdr0[symsec_sh_link]; - Elf_Sym const *const sym0 = (Elf_Sym const *)(_w(symsec->sh_offset) - + (void *)ehdr); - - Elf_Shdr const *const strsec = &shdr0[w(symsec->sh_link)]; - char const *const str0 = (char const *)(_w(strsec->sh_offset) - + (void *)ehdr); - - Elf_Rel const *const rel0 = (Elf_Rel const *)(_w(relhdr->sh_offset) - + (void *)ehdr); + Elf_Sym const *sym0; + char const *str0; + Elf_Rel const *relp; unsigned rel_entsize = _w(relhdr->sh_entsize); unsigned const nrel = _w(relhdr->sh_size) / rel_entsize; - Elf_Rel const *relp = rel0; - unsigned mcountsym = 0; unsigned t; + get_sym_str_and_relp(relhdr, ehdr, &sym0, &str0, &relp); + for (t = nrel; t; --t) { - if (!mcountsym) { - Elf_Sym const *const symp = - &sym0[Elf_r_sym(relp)]; - char const *symname = &str0[w(symp->st_name)]; - char const *mcount = '_' == gpfx ? "_mcount" : "mcount"; - - if ('.' == symname[0]) - ++symname; /* ppc64 hack */ - if (0 == strcmp(mcount, symname) || - (altmcount && 0 == strcmp(altmcount, symname))) - mcountsym = Elf_r_sym(relp); - } + if (!mcountsym) + mcountsym = get_mcountsym(sym0, relp, str0); if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) { - uint_t const addend = _w(_w(relp->r_offset) - recval); - + uint_t const addend = + _w(_w(relp->r_offset) - recval + mcount_adjust); mrelp->r_offset = _w(offbase + ((void *)mlocp - (void *)mloc0)); Elf_r_info(mrelp, recsym, reltype); - if (sizeof(Elf_Rela) == rel_entsize) { + if (rel_entsize == sizeof(Elf_Rela)) { ((Elf_Rela *)mrelp)->r_addend = addend; *mlocp++ = 0; } else @@ -304,6 +344,63 @@ static uint_t *sift_rel_mcount(uint_t *mlocp, return mlocp; } +/* + * Read the relocation table again, but this time its called on sections + * that are not going to be traced. The mcount calls here will be converted + * into nops. + */ +static void nop_mcount(Elf_Shdr const *const relhdr, + Elf_Ehdr const *const ehdr, + const char *const txtname) +{ + Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff) + + (void *)ehdr); + Elf_Sym const *sym0; + char const *str0; + Elf_Rel const *relp; + Elf_Shdr const *const shdr = &shdr0[w(relhdr->sh_info)]; + unsigned rel_entsize = _w(relhdr->sh_entsize); + unsigned const nrel = _w(relhdr->sh_size) / rel_entsize; + unsigned mcountsym = 0; + unsigned t; + int once = 0; + + get_sym_str_and_relp(relhdr, ehdr, &sym0, &str0, &relp); + + for (t = nrel; t; --t) { + int ret = -1; + + if (!mcountsym) + mcountsym = get_mcountsym(sym0, relp, str0); + + if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) { + if (make_nop) + ret = make_nop((void *)ehdr, shdr->sh_offset + relp->r_offset); + if (warn_on_notrace_sect && !once) { + printf("Section %s has mcount callers being ignored\n", + txtname); + once = 1; + /* just warn? */ + if (!make_nop) + return; + } + } + + /* + * If we successfully removed the mcount, mark the relocation + * as a nop (don't do anything with it). + */ + if (!ret) { + Elf_Rel rel; + rel = *(Elf_Rel *)relp; + Elf_r_info(&rel, Elf_r_sym(relp), rel_type_nop); + ulseek(fd_map, (void *)relp - (void *)ehdr, SEEK_SET); + uwrite(fd_map, &rel, sizeof(rel)); + } + relp = (Elf_Rel const *)(rel_entsize + (void *)relp); + } +} + /* * Find a symbol in the given section, to be used as the base for relocating @@ -333,6 +430,11 @@ static unsigned find_secsym_ndx(unsigned const txtndx, if (txtndx == w2(symp->st_shndx) /* avoid STB_WEAK */ && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) { + /* function symbols on ARM have quirks, avoid them */ + if (w2(ehdr->e_machine) == EM_ARM + && ELF_ST_TYPE(symp->st_info) == STT_FUNC) + continue; + *recvalp = _w(symp->st_value); return symp - sym0; } @@ -354,13 +456,13 @@ __has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */ Elf_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)]; char const *const txtname = &shstrtab[w(txthdr->sh_name)]; - if (0 == strcmp("__mcount_loc", txtname)) { + if (strcmp("__mcount_loc", txtname) == 0) { fprintf(stderr, "warning: __mcount_loc already exists: %s\n", fname); succeed_file(); } - if (SHT_PROGBITS != w(txthdr->sh_type) || - !is_mcounted_section_name(txtname)) + if (w(txthdr->sh_type) != SHT_PROGBITS || + !(w(txthdr->sh_flags) & SHF_EXECINSTR)) return NULL; return txtname; } @@ -370,7 +472,7 @@ static char const *has_rel_mcount(Elf_Shdr const *const relhdr, char const *const shstrtab, char const *const fname) { - if (SHT_REL != w(relhdr->sh_type) && SHT_RELA != w(relhdr->sh_type)) + if (w(relhdr->sh_type) != SHT_REL && w(relhdr->sh_type) != SHT_RELA) return NULL; return __has_rel_mcount(relhdr, shdr0, shstrtab, fname); } @@ -383,9 +485,11 @@ static unsigned tot_relsize(Elf_Shdr const *const shdr0, { unsigned totrelsz = 0; Elf_Shdr const *shdrp = shdr0; + char const *txtname; for (; nhdr; --nhdr, ++shdrp) { - if (has_rel_mcount(shdrp, shdr0, shstrtab, fname)) + txtname = has_rel_mcount(shdrp, shdr0, shstrtab, fname); + if (txtname && is_mcounted_section_name(txtname)) totrelsz += _w(shdrp->sh_size); } return totrelsz; @@ -421,7 +525,7 @@ do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype) for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) { char const *const txtname = has_rel_mcount(relhdr, shdr0, shstrtab, fname); - if (txtname) { + if (txtname && is_mcounted_section_name(txtname)) { uint_t recval = 0; unsigned const recsym = find_secsym_ndx( w(relhdr->sh_info), txtname, &recval, @@ -432,6 +536,12 @@ do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype) mlocp = sift_rel_mcount(mlocp, (void *)mlocp - (void *)mloc0, &mrelp, relhdr, ehdr, recsym, recval, reltype); + } else if (txtname && (warn_on_notrace_sect || make_nop)) { + /* + * This section is ignored by ftrace, but still + * has mcount calls. Convert them to nops now. + */ + nop_mcount(relhdr, ehdr, txtname); } } if (mloc0 != mlocp) { diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 4be0dee..858966a 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -134,6 +134,7 @@ my %text_sections = ( ".sched.text" => 1, ".spinlock.text" => 1, ".irqentry.text" => 1, + ".kprobes.text" => 1, ".text.unlikely" => 1, ); @@ -222,6 +223,7 @@ if ($arch eq "x86_64") { $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount([+-]0x[0-9a-zA-Z]+)?\$"; $type = ".quad"; $alignment = 8; + $mcount_adjust = -1; # force flags for this arch $ld .= " -m elf_x86_64"; @@ -231,6 +233,7 @@ if ($arch eq "x86_64") { } elsif ($arch eq "i386") { $alignment = 4; + $mcount_adjust = -1; # force flags for this arch $ld .= " -m elf_i386"; @@ -240,12 +243,14 @@ if ($arch eq "x86_64") { } elsif ($arch eq "s390" && $bits == 32) { $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_390_32\\s+_mcount\$"; + $mcount_adjust = -4; $alignment = 4; $ld .= " -m elf_s390"; $cc .= " -m31"; } elsif ($arch eq "s390" && $bits == 64) { $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_390_(PC|PLT)32DBL\\s+_mcount\\+0x2\$"; + $mcount_adjust = -8; $alignment = 8; $type = ".quad"; $ld .= " -m elf64_s390"; diff --git a/scripts/rt-tester/rt-tester.py b/scripts/rt-tester/rt-tester.py index 8c81d76..34186ca 100644 --- a/scripts/rt-tester/rt-tester.py +++ b/scripts/rt-tester/rt-tester.py @@ -180,7 +180,7 @@ while 1: for s in stat: s = s.strip() if s.startswith(testop[0]): - # Seperate status value + # Separate status value val = s[2:].strip() query = analyse(val, testop, dat) break diff --git a/scripts/selinux/README b/scripts/selinux/README index a936315..4d020ec 100644 --- a/scripts/selinux/README +++ b/scripts/selinux/README @@ -1,2 +1,2 @@ -Please see Documentation/SELinux.txt for information on +Please see Documentation/security/SELinux.txt for information on installing a dummy SELinux policy. diff --git a/scripts/tags.sh b/scripts/tags.sh index bd6185d..75c5d24 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -132,7 +132,7 @@ exuberant() --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ - --regex-c++='/^DEFINE_EVENT\(([^,)]*).*/trace_\1/' + --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/' all_kconfigs | xargs $1 -a \ --langdef=kconfig --language-force=kconfig \ @@ -152,7 +152,9 @@ emacs() { all_sources | xargs $1 -a \ --regex='/^ENTRY(\([^)]*\)).*/\1/' \ - --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' + --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \ + --regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \ + --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/' all_kconfigs | xargs $1 -a \ --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' |