From 4980bdf0213c9b5f876551b2ceb8ed8ece30deaf Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 3 Dec 2014 15:55:49 +0900 Subject: kconfig: fix a misspelling in scripts/kconfig/merge_config.sh Signed-off-by: Masahiro Yamada Signed-off-by: Michal Marek --- scripts/kconfig/merge_config.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index 2ab91b9b100d..2118af84e661 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh @@ -92,7 +92,7 @@ TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) echo "Using $INITFILE as base" cat $INITFILE > $TMP_FILE -# Merge files, printing warnings on overrided values +# Merge files, printing warnings on overridden values for MERGE_FILE in $MERGE_LIST ; do echo "Merging $MERGE_FILE" CFG_LIST=$(sed -n "$SED_CONFIG_EXP" $MERGE_FILE) -- cgit v1.2.3 From 70529b1a1784503169416df19ce3d68746401340 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Tue, 27 Jan 2015 17:11:42 +0100 Subject: kconfig: Get rid of the P() macro in headers This was originally meant for dlopen()ing a potential kconfig shared library. The unused dlopen code has already been removed in commit 5a6f8d2b (kconfig: nuke LKC_DIRECT_LINK cruft), so let's remove the rest. The lkc_proto.h change was made with the following sed script: sed -r 's/^P\(([^,]*), *([^,]*), *(.*)\);/\2 \1\3;/' Plus some manual adjustments. Signed-off-by: Michal Marek --- scripts/kconfig/lkc.h | 2 -- scripts/kconfig/lkc_proto.h | 88 ++++++++++++++++++++++----------------------- 2 files changed, 43 insertions(+), 47 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index d5daa7af8b49..e418a30bbc40 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -21,9 +21,7 @@ static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c; extern "C" { #endif -#define P(name,type,arg) extern type name arg #include "lkc_proto.h" -#undef P #define SRCTREE "srctree" diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index ecdb9659b67d..ceddbcf1e5ac 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -1,57 +1,55 @@ #include /* confdata.c */ -P(conf_parse,void,(const char *name)); -P(conf_read,int,(const char *name)); -P(conf_read_simple,int,(const char *name, int)); -P(conf_write_defconfig,int,(const char *name)); -P(conf_write,int,(const char *name)); -P(conf_write_autoconf,int,(void)); -P(conf_get_changed,bool,(void)); -P(conf_set_changed_callback, void,(void (*fn)(void))); -P(conf_set_message_callback, void,(void (*fn)(const char *fmt, va_list ap))); +void conf_parse(const char *name); +int conf_read(const char *name); +int conf_read_simple(const char *name, int); +int conf_write_defconfig(const char *name); +int conf_write(const char *name); +int conf_write_autoconf(void); +bool conf_get_changed(void); +void conf_set_changed_callback(void (*fn)(void)); +void conf_set_message_callback(void (*fn)(const char *fmt, va_list ap)); /* menu.c */ -P(rootmenu,struct menu,); +extern struct menu rootmenu; -P(menu_is_empty, bool, (struct menu *menu)); -P(menu_is_visible, bool, (struct menu *menu)); -P(menu_has_prompt, bool, (struct menu *menu)); -P(menu_get_prompt,const char *,(struct menu *menu)); -P(menu_get_root_menu,struct menu *,(struct menu *menu)); -P(menu_get_parent_menu,struct menu *,(struct menu *menu)); -P(menu_has_help,bool,(struct menu *menu)); -P(menu_get_help,const char *,(struct menu *menu)); -P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct list_head - *head)); -P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct list_head - *head)); -P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help)); +bool menu_is_empty(struct menu *menu); +bool menu_is_visible(struct menu *menu); +bool menu_has_prompt(struct menu *menu); +const char * menu_get_prompt(struct menu *menu); +struct menu * menu_get_root_menu(struct menu *menu); +struct menu * menu_get_parent_menu(struct menu *menu); +bool menu_has_help(struct menu *menu); +const char * menu_get_help(struct menu *menu); +void get_symbol_str(struct gstr *r, struct symbol *sym, struct list_head *head); +struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head); +void menu_get_ext_help(struct menu *menu, struct gstr *help); /* symbol.c */ -P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); +extern struct symbol * symbol_hash[SYMBOL_HASHSIZE]; -P(sym_lookup,struct symbol *,(const char *name, int flags)); -P(sym_find,struct symbol *,(const char *name)); -P(sym_expand_string_value,const char *,(const char *in)); -P(sym_escape_string_value, const char *,(const char *in)); -P(sym_re_search,struct symbol **,(const char *pattern)); -P(sym_type_name,const char *,(enum symbol_type type)); -P(sym_calc_value,void,(struct symbol *sym)); -P(sym_get_type,enum symbol_type,(struct symbol *sym)); -P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri)); -P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri)); -P(sym_toggle_tristate_value,tristate,(struct symbol *sym)); -P(sym_string_valid,bool,(struct symbol *sym, const char *newval)); -P(sym_string_within_range,bool,(struct symbol *sym, const char *str)); -P(sym_set_string_value,bool,(struct symbol *sym, const char *newval)); -P(sym_is_changable,bool,(struct symbol *sym)); -P(sym_get_choice_prop,struct property *,(struct symbol *sym)); -P(sym_get_default_prop,struct property *,(struct symbol *sym)); -P(sym_get_string_value,const char *,(struct symbol *sym)); +struct symbol * sym_lookup(const char *name, int flags); +struct symbol * sym_find(const char *name); +const char * sym_expand_string_value(const char *in); +const char * sym_escape_string_value(const char *in); +struct symbol ** sym_re_search(const char *pattern); +const char * sym_type_name(enum symbol_type type); +void sym_calc_value(struct symbol *sym); +enum symbol_type sym_get_type(struct symbol *sym); +bool sym_tristate_within_range(struct symbol *sym,tristate tri); +bool sym_set_tristate_value(struct symbol *sym,tristate tri); +tristate sym_toggle_tristate_value(struct symbol *sym); +bool sym_string_valid(struct symbol *sym, const char *newval); +bool sym_string_within_range(struct symbol *sym, const char *str); +bool sym_set_string_value(struct symbol *sym, const char *newval); +bool sym_is_changable(struct symbol *sym); +struct property * sym_get_choice_prop(struct symbol *sym); +struct property * sym_get_default_prop(struct symbol *sym); +const char * sym_get_string_value(struct symbol *sym); -P(prop_get_type_name,const char *,(enum prop_type type)); +const char * prop_get_type_name(enum prop_type type); /* expr.c */ -P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2)); -P(expr_print,void,(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)); +int expr_compare_type(enum expr_type t1, enum expr_type t2); +void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken); -- cgit v1.2.3 From 463157444e377bf9b279101b1f16a94c4648c03a Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Tue, 24 Feb 2015 16:32:09 +0100 Subject: kconfig: Remove dead code Signed-off-by: Michal Marek --- scripts/kconfig/expr.c | 4 ---- scripts/kconfig/gconf.c | 24 ------------------------ scripts/kconfig/lkc.h | 1 - scripts/kconfig/util.c | 10 ---------- 4 files changed, 39 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index d6626521f9b9..4b4cf8e21314 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -978,9 +978,6 @@ tristate expr_calc_value(struct expr *e) int expr_compare_type(enum expr_type t1, enum expr_type t2) { -#if 0 - return 1; -#else if (t1 == t2) return 0; switch (t1) { @@ -1005,7 +1002,6 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2) } printf("[%dgt%d?]", t1, t2); return 0; -#endif } static inline struct expr * diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index d0a35b21f308..344b9e340ecb 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -169,14 +169,6 @@ void init_main_window(const gchar * glade_file) style = gtk_widget_get_style(main_wnd); widget = glade_xml_get_widget(xml, "toolbar1"); -#if 0 /* Use stock Gtk icons instead */ - replace_button_icon(xml, main_wnd->window, style, - "button1", (gchar **) xpm_back); - replace_button_icon(xml, main_wnd->window, style, - "button2", (gchar **) xpm_load); - replace_button_icon(xml, main_wnd->window, style, - "button3", (gchar **) xpm_save); -#endif replace_button_icon(xml, main_wnd->window, style, "button4", (gchar **) xpm_single_view); replace_button_icon(xml, main_wnd->window, style, @@ -184,22 +176,6 @@ void init_main_window(const gchar * glade_file) replace_button_icon(xml, main_wnd->window, style, "button6", (gchar **) xpm_tree_view); -#if 0 - switch (view_mode) { - case SINGLE_VIEW: - widget = glade_xml_get_widget(xml, "button4"); - g_signal_emit_by_name(widget, "clicked"); - break; - case SPLIT_VIEW: - widget = glade_xml_get_widget(xml, "button5"); - g_signal_emit_by_name(widget, "clicked"); - break; - case FULL_VIEW: - widget = glade_xml_get_widget(xml, "button6"); - g_signal_emit_by_name(widget, "clicked"); - break; - } -#endif txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1", "foreground", "red", diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index e418a30bbc40..9f845eab56cb 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -135,7 +135,6 @@ struct gstr { int max_width; }; struct gstr str_new(void); -struct gstr str_assign(const char *s); void str_free(struct gstr *gs); void str_append(struct gstr *gs, const char *s); void str_printf(struct gstr *gs, const char *fmt, ...); diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c index 94f9c83e324f..0e76042473cc 100644 --- a/scripts/kconfig/util.c +++ b/scripts/kconfig/util.c @@ -88,16 +88,6 @@ struct gstr str_new(void) return gs; } -/* Allocate and assign growable string */ -struct gstr str_assign(const char *s) -{ - struct gstr gs; - gs.s = strdup(s); - gs.len = strlen(s) + 1; - gs.max_width = 0; - return gs; -} - /* Free storage for growable string */ void str_free(struct gstr *gs) { -- cgit v1.2.3 From ad8d40cda3ad22ad9e8863d55a5c88f85c0173f0 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Tue, 24 Feb 2015 16:37:13 +0100 Subject: kconfig: Remove unnecessary prototypes from headers Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 5 +++++ scripts/kconfig/expr.c | 18 ++++++++++++------ scripts/kconfig/expr.h | 5 ----- scripts/kconfig/lkc.h | 11 ----------- scripts/kconfig/lkc_proto.h | 3 --- scripts/kconfig/menu.c | 4 ++-- scripts/kconfig/symbol.c | 42 +++++++++++++++++++++--------------------- 7 files changed, 40 insertions(+), 48 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 28df18dd1147..c814f57672fc 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -16,6 +16,11 @@ #include "lkc.h" +struct conf_printer { + void (*print_symbol)(FILE *, struct symbol *, const char *, void *); + void (*print_comment)(FILE *, const char *, void *); +}; + static void conf_warning(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 4b4cf8e21314..fb0a2a286dca 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -11,6 +11,12 @@ #define DEBUG_EXPR 0 +static int expr_eq(struct expr *e1, struct expr *e2); +static struct expr *expr_eliminate_yn(struct expr *e); +static struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2); +static struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2); +static void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2); + struct expr *expr_alloc_symbol(struct symbol *sym) { struct expr *e = xcalloc(1, sizeof(*e)); @@ -186,7 +192,7 @@ void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) #undef e1 #undef e2 -int expr_eq(struct expr *e1, struct expr *e2) +static int expr_eq(struct expr *e1, struct expr *e2) { int res, old_count; @@ -228,7 +234,7 @@ int expr_eq(struct expr *e1, struct expr *e2) return 0; } -struct expr *expr_eliminate_yn(struct expr *e) +static struct expr *expr_eliminate_yn(struct expr *e) { struct expr *tmp; @@ -823,7 +829,7 @@ bool expr_depends_symbol(struct expr *dep, struct symbol *sym) return false; } -struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2) +static struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2) { struct expr *tmp = NULL; expr_extract_eq(E_AND, &tmp, ep1, ep2); @@ -834,7 +840,7 @@ struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2) return tmp; } -struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2) +static struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2) { struct expr *tmp = NULL; expr_extract_eq(E_OR, &tmp, ep1, ep2); @@ -845,7 +851,7 @@ struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2) return tmp; } -void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2) +static void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2) { #define e1 (*ep1) #define e2 (*ep2) @@ -976,7 +982,7 @@ tristate expr_calc_value(struct expr *e) } } -int expr_compare_type(enum expr_type t1, enum expr_type t2) +static int expr_compare_type(enum expr_type t1, enum expr_type t2) { if (t1 == t2) return 0; diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 412ea8a2abb8..a2fc96a2bd2c 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -205,18 +205,13 @@ struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); struct expr *expr_copy(const struct expr *org); void expr_free(struct expr *e); -int expr_eq(struct expr *e1, struct expr *e2); void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); tristate expr_calc_value(struct expr *e); -struct expr *expr_eliminate_yn(struct expr *e); struct expr *expr_trans_bool(struct expr *e); struct expr *expr_eliminate_dups(struct expr *e); struct expr *expr_transform(struct expr *e); int expr_contains_symbol(struct expr *dep, struct symbol *sym); bool expr_depends_symbol(struct expr *dep, struct symbol *sym); -struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2); -struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2); -void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2); struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2); diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 9f845eab56cb..91ca126ea080 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -68,9 +68,6 @@ struct kconf_id { enum symbol_type stype; }; -extern int zconfdebug; - -int zconfparse(void); void zconfdump(FILE *out); void zconf_starthelp(void); FILE *zconf_fopen(const char *name); @@ -88,11 +85,6 @@ void sym_add_change_count(int count); bool conf_set_all_new_symbols(enum conf_def_mode mode); void set_all_choice_values(struct symbol *csym); -struct conf_printer { - void (*print_symbol)(FILE *, struct symbol *, const char *, void *); - void (*print_comment)(FILE *, const char *, void *); -}; - /* confdata.c and expr.c */ static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) { @@ -111,7 +103,6 @@ void menu_add_entry(struct symbol *sym); void menu_end_entry(void); void menu_add_dep(struct expr *dep); void menu_add_visibility(struct expr *dep); -struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep); struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); @@ -145,8 +136,6 @@ extern struct expr *sym_env_list; void sym_init(void); void sym_clear_all_valid(void); -void sym_set_all_changed(void); -void sym_set_changed(struct symbol *sym); struct symbol *sym_choice_default(struct symbol *sym); const char *sym_get_string_default(struct symbol *sym); struct symbol *sym_check_deps(struct symbol *sym); diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index ceddbcf1e5ac..d5398718ec2a 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -22,7 +22,6 @@ struct menu * menu_get_root_menu(struct menu *menu); struct menu * menu_get_parent_menu(struct menu *menu); bool menu_has_help(struct menu *menu); const char * menu_get_help(struct menu *menu); -void get_symbol_str(struct gstr *r, struct symbol *sym, struct list_head *head); struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head); void menu_get_ext_help(struct menu *menu, struct gstr *help); @@ -45,11 +44,9 @@ bool sym_string_within_range(struct symbol *sym, const char *str); bool sym_set_string_value(struct symbol *sym, const char *newval); bool sym_is_changable(struct symbol *sym); struct property * sym_get_choice_prop(struct symbol *sym); -struct property * sym_get_default_prop(struct symbol *sym); const char * sym_get_string_value(struct symbol *sym); const char * prop_get_type_name(enum prop_type type); /* expr.c */ -int expr_compare_type(enum expr_type t1, enum expr_type t2); void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken); diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 72c9dba84c5d..b05cc3d4a9be 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -125,7 +125,7 @@ void menu_set_type(int type) sym_type_name(sym->type), sym_type_name(type)); } -struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) +static struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) { struct property *prop = prop_alloc(type, current_entry->sym); @@ -615,7 +615,7 @@ static struct property *get_symbol_prop(struct symbol *sym) /* * head is optional and may be NULL */ -void get_symbol_str(struct gstr *r, struct symbol *sym, +static void get_symbol_str(struct gstr *r, struct symbol *sym, struct list_head *head) { bool hit; diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 7caabdb51c64..6731377f9bb2 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -112,7 +112,7 @@ struct property *sym_get_env_prop(struct symbol *sym) return NULL; } -struct property *sym_get_default_prop(struct symbol *sym) +static struct property *sym_get_default_prop(struct symbol *sym) { struct property *prop; @@ -186,6 +186,26 @@ static void sym_validate_range(struct symbol *sym) sym->curr.val = strdup(str); } +static void sym_set_changed(struct symbol *sym) +{ + struct property *prop; + + sym->flags |= SYMBOL_CHANGED; + for (prop = sym->prop; prop; prop = prop->next) { + if (prop->menu) + prop->menu->flags |= MENU_CHANGED; + } +} + +static void sym_set_all_changed(void) +{ + struct symbol *sym; + int i; + + for_all_symbols(i, sym) + sym_set_changed(sym); +} + static void sym_calc_visibility(struct symbol *sym) { struct property *prop; @@ -451,26 +471,6 @@ void sym_clear_all_valid(void) sym_calc_value(modules_sym); } -void sym_set_changed(struct symbol *sym) -{ - struct property *prop; - - sym->flags |= SYMBOL_CHANGED; - for (prop = sym->prop; prop; prop = prop->next) { - if (prop->menu) - prop->menu->flags |= MENU_CHANGED; - } -} - -void sym_set_all_changed(void) -{ - struct symbol *sym; - int i; - - for_all_symbols(i, sym) - sym_set_changed(sym); -} - bool sym_tristate_within_range(struct symbol *sym, tristate val) { int type = sym_get_type(sym); -- cgit v1.2.3 From 208d51154c8d7f2c3808b4401132233c5ab21572 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Wed, 25 Feb 2015 15:15:23 +0100 Subject: checkkconfigsymbols.py: filter reports for tools/ Recent changes to the build system of tools suggest to filter reports for the entire tools directory. Various C preprocessor identifiers are prefixed with CONFIG_ but are NOT defined in Kconfig but in Makefiles in the tools directory. Such identifiers are false positives for most static analysis tools (i.e., scripts/checkkconfigsymbols.py) since the CONFIG_ prefix and the _MODULE suffix is reserved for Kconfig features in CPP and Make syntax. Signed-off-by: Valentin Rothberg Signed-off-by: Greg Kroah-Hartman --- scripts/checkkconfigsymbols.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) mode change 100644 => 100755 scripts/checkkconfigsymbols.py (limited to 'scripts') diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py old mode 100644 new mode 100755 index e9cc689033fe..6445693df669 --- a/scripts/checkkconfigsymbols.py +++ b/scripts/checkkconfigsymbols.py @@ -2,7 +2,7 @@ """Find Kconfig identifiers that are referenced but not defined.""" -# (c) 2014 Valentin Rothberg +# (c) 2014-2015 Valentin Rothberg # (c) 2014 Stefan Hengelein # # Licensed under the terms of the GNU GPL License version 2 @@ -46,8 +46,9 @@ def main(): stdout = stdout[:-1] for gitfile in stdout.rsplit("\n"): - if ".git" in gitfile or "ChangeLog" in gitfile or \ - ".log" in gitfile or os.path.isdir(gitfile): + if ".git" in gitfile or "ChangeLog" in gitfile or \ + ".log" in gitfile or os.path.isdir(gitfile) or \ + gitfile.startswith("tools/"): continue if REGEX_FILE_KCONFIG.match(gitfile): kconfig_files.append(gitfile) -- cgit v1.2.3 From 9b4ade226f7468bb26f98b6cd01cb5b8a05fc96d Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Wed, 21 Jan 2015 08:49:22 +0100 Subject: xen: build infrastructure for generating hypercall depending symbols Today there are several places in the kernel which build tables containing one entry for each possible Xen hypercall. Create an infrastructure to be able to generate these tables at build time. Based-on-patch-by: Jan Beulich Signed-off-by: Juergen Gross Reviewed-by: David Vrabel Acked-by: Ingo Molnar Signed-off-by: David Vrabel --- scripts/xen-hypercalls.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 scripts/xen-hypercalls.sh (limited to 'scripts') diff --git a/scripts/xen-hypercalls.sh b/scripts/xen-hypercalls.sh new file mode 100644 index 000000000000..676d9226814f --- /dev/null +++ b/scripts/xen-hypercalls.sh @@ -0,0 +1,12 @@ +#!/bin/sh +out="$1" +shift +in="$@" + +for i in $in; do + eval $CPP $LINUXINCLUDE -dD -imacros "$i" -x c /dev/null +done | \ +awk '$1 == "#define" && $2 ~ /__HYPERVISOR_[a-z][a-z_0-9]*/ { v[$3] = $2 } + END { print "/* auto-generated by scripts/xen-hypercall.sh */" + for (i in v) if (!(v[i] in v)) + print "HYPERCALL("substr(v[i], 14)")"}' | sort -u >$out -- cgit v1.2.3 From b1a3f243485fa2643bc75fd70a23bbd7cfc74f2d Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Mon, 16 Mar 2015 12:16:14 +0100 Subject: checkkconfigsymbols.py: make it Git aware The script now supports to check a specified commit or a specified range of commits (i.e., commit1..commit2). Developers and maintainers are encouraged to use this functionality before sending or merging patches to avoid potential bugs and to keep the code, documentation, etc. clean. This patch adds the following options to the script: -c COMMIT, --commit=COMMIT Check if the specified commit (hash) introduces undefined Kconfig symbols. -d DIFF, --diff=DIFF Diff undefined symbols between two commits. The input format bases on Git log's 'commmit1..commit2'. --force Reset current Git tree even when it's dirty. Note that the first two options require to 'git reset --hard' the user's Git tree. This hard reset is necessary to keep the script fast, but it can lead to the loss of uncommitted data. Hence, the script aborts in case it is executed in a dirty tree. It won't abort if '--force' is passed. If neither -c nor -d is specified, the script defaults to check the entire local tree (i.e., the previous behavior). Signed-off-by: Valentin Rothberg Signed-off-by: Greg Kroah-Hartman --- scripts/checkkconfigsymbols.py | 138 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 132 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py index 6445693df669..ce9ca60808b8 100755 --- a/scripts/checkkconfigsymbols.py +++ b/scripts/checkkconfigsymbols.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -"""Find Kconfig identifiers that are referenced but not defined.""" +"""Find Kconfig symbols that are referenced but not defined.""" # (c) 2014-2015 Valentin Rothberg # (c) 2014 Stefan Hengelein @@ -10,7 +10,9 @@ import os import re +import sys from subprocess import Popen, PIPE, STDOUT +from optparse import OptionParser # regex expressions @@ -32,16 +34,140 @@ REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$") REGEX_FILTER_FEATURES = re.compile(r"[A-Za-z0-9]$") +def parse_options(): + """The user interface of this module.""" + usage = "%prog [options]\n\n" \ + "Run this tool to detect Kconfig symbols that are referenced but " \ + "not defined in\nKconfig. The output of this tool has the " \ + "format \'Undefined symbol\\tFile list\'\n\n" \ + "If no option is specified, %prog will default to check your\n" \ + "current tree. Please note that specifying commits will " \ + "\'git reset --hard\'\nyour current tree! You may save " \ + "uncommitted changes to avoid losing data." + + parser = OptionParser(usage=usage) + + parser.add_option('-c', '--commit', dest='commit', action='store', + default="", + help="Check if the specified commit (hash) introduces " + "undefined Kconfig symbols.") + + parser.add_option('-d', '--diff', dest='diff', action='store', + default="", + help="Diff undefined symbols between two commits. The " + "input format bases on Git log's " + "\'commmit1..commit2\'.") + + parser.add_option('', '--force', dest='force', action='store_true', + default=False, + help="Reset current Git tree even when it's dirty.") + + (opts, _) = parser.parse_args() + + if opts.commit and opts.diff: + sys.exit("Please specify only one option at once.") + + if opts.diff and not re.match(r"^[\w\-\.]+\.\.[\w\-\.]+$", opts.diff): + sys.exit("Please specify valid input in the following format: " + "\'commmit1..commit2\'") + + if opts.commit or opts.diff: + if not opts.force and tree_is_dirty(): + sys.exit("The current Git tree is dirty (see 'git status'). " + "Running this script may\ndelete important data since it " + "calls 'git reset --hard' for some performance\nreasons. " + " Please run this script in a clean Git tree or pass " + "'--force' if you\nwant to ignore this warning and " + "continue.") + + return opts + + def main(): """Main function of this module.""" + opts = parse_options() + + if opts.commit or opts.diff: + head = get_head() + + # get commit range + commit_a = None + commit_b = None + if opts.commit: + commit_a = opts.commit + "~" + commit_b = opts.commit + elif opts.diff: + split = opts.diff.split("..") + commit_a = split[0] + commit_b = split[1] + undefined_a = {} + undefined_b = {} + + # get undefined items before the commit + execute("git reset --hard %s" % commit_a) + undefined_a = check_symbols() + + # get undefined items for the commit + execute("git reset --hard %s" % commit_b) + undefined_b = check_symbols() + + # report cases that are present for the commit but not before + for feature in undefined_b: + # feature has not been undefined before + if not feature in undefined_a: + files = undefined_b.get(feature) + print "%s\t%s" % (feature, ", ".join(files)) + # check if there are new files that reference the undefined feature + else: + files = undefined_b.get(feature) - undefined_a.get(feature) + if files: + print "%s\t%s" % (feature, ", ".join(files)) + + # reset to head + execute("git reset --hard %s" % head) + + # default to check the entire tree + else: + undefined = check_symbols() + for feature in undefined: + files = undefined.get(feature) + + +def execute(cmd): + """Execute %cmd and return stdout. Exit in case of error.""" + pop = Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True) + (stdout, _) = pop.communicate() # wait until finished + if pop.returncode != 0: + sys.exit(stdout) + return stdout + + +def tree_is_dirty(): + """Return true if the current working tree is dirty (i.e., if any file has + been added, deleted, modified, renamed or copied but not committed).""" + stdout = execute("git status --porcelain") + for line in stdout: + if re.findall(r"[URMADC]{1}", line[:2]): + return True + return False + + +def get_head(): + """Return commit hash of current HEAD.""" + stdout = execute("git rev-parse HEAD") + return stdout.strip('\n') + + +def check_symbols(): + """Find undefined Kconfig symbols and return a dict with the symbol as key + and a list of referencing files as value.""" source_files = [] kconfig_files = [] defined_features = set() referenced_features = dict() # {feature: [files]} # use 'git ls-files' to get the worklist - pop = Popen("git ls-files", stdout=PIPE, stderr=STDOUT, shell=True) - (stdout, _) = pop.communicate() # wait until finished + stdout = execute("git ls-files") if len(stdout) > 0 and stdout[-1] == "\n": stdout = stdout[:-1] @@ -62,7 +188,7 @@ def main(): for kfile in kconfig_files: parse_kconfig_file(kfile, defined_features, referenced_features) - print "Undefined symbol used\tFile list" + undefined = {} # {feature: [files]} for feature in sorted(referenced_features): # filter some false positives if feature == "FOO" or feature == "BAR" or \ @@ -73,8 +199,8 @@ def main(): # avoid false positives for kernel modules if feature[:-len("_MODULE")] in defined_features: continue - files = referenced_features.get(feature) - print "%s\t%s" % (feature, ", ".join(files)) + undefined[feature] = referenced_features.get(feature) + return undefined def parse_source_file(sfile, referenced_features): -- cgit v1.2.3 From e9533ae539d5cc3d5fc501529d2df7b77e20449c Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Mon, 23 Mar 2015 18:40:49 +0100 Subject: checkkconfigsymbols.py: fix sorted output Commit b1a3f243485f ("checkkconfigsymbols.py: make it Git aware") mistakenly removed to print undefined Kconfig symbols in alphabetical order. Furthermore, the script does not print anything anymore when the entire tree is checked (i.e., when no commit is specified). This patch restores the sorted output and adds the missing print for the default case. Additionally, the file lists are now sorted as well which (a) makes it easier to read and (b) makes the output deterministic. Signed-off-by: Valentin Rothberg Signed-off-by: Greg Kroah-Hartman --- scripts/checkkconfigsymbols.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py index ce9ca60808b8..74086a583d8d 100755 --- a/scripts/checkkconfigsymbols.py +++ b/scripts/checkkconfigsymbols.py @@ -112,14 +112,15 @@ def main(): undefined_b = check_symbols() # report cases that are present for the commit but not before - for feature in undefined_b: + for feature in sorted(undefined_b): # feature has not been undefined before if not feature in undefined_a: - files = undefined_b.get(feature) + files = sorted(undefined_b.get(feature)) print "%s\t%s" % (feature, ", ".join(files)) # check if there are new files that reference the undefined feature else: - files = undefined_b.get(feature) - undefined_a.get(feature) + files = sorted(undefined_b.get(feature) - + undefined_a.get(feature)) if files: print "%s\t%s" % (feature, ", ".join(files)) @@ -129,8 +130,9 @@ def main(): # default to check the entire tree else: undefined = check_symbols() - for feature in undefined: - files = undefined.get(feature) + for feature in sorted(undefined): + files = sorted(undefined.get(feature)) + print "%s\t%s" % (feature, ", ".join(files)) def execute(cmd): -- cgit v1.2.3 From de4619937229378e81f95e99c9866acc8e207d34 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 13 Mar 2015 15:21:38 +0900 Subject: kbuild: mergeconfig: fix "jobserver unavailable" warning If "make kvmconfig" is run with "-j" option, a warning message, "jobserver unavailable: using -j1. Add `+' to parent make rule.", is displayed. $ make -s defconfig *** Default configuration is based on 'x86_64_defconfig' # # configuration written to .config # $ make -j8 kvmconfig Using ./.config as base Merging ./arch/x86/configs/kvm_guest.config [ snip ] # # merged configuration written to ./.config (needs make) # make[2]: warning: jobserver unavailable: using -j1. Add `+' to parent make rule. scripts/kconfig/conf --oldconfig Kconfig [ snip ] # # configuration written to .config # Signed-off-by: Masahiro Yamada Reviewed-by: Josh Triplett Reviewed-by: Darren Hart Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 9645c0739386..fc34f46cb025 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -110,7 +110,7 @@ define mergeconfig $(if $(wildcard $(objtree)/.config),, $(error You need an existing .config for this target)) $(if $(call configfiles,$(1)),, $(error No configuration exists for this target on this architecture)) $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config $(call configfiles,$(1)) -$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig ++$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig endef PHONY += kvmconfig -- cgit v1.2.3 From b9fe99c5b994c6ddc57780993966b18899526c0b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 13 Mar 2015 15:21:39 +0900 Subject: kbuild: mergeconfig: move an error check to merge_config.sh Currently, "make tinyconfig" does not work with "-j" option. $ make mrproper $ make -j8 tinyconfig HOSTCC scripts/basic/fixdep HOSTCC scripts/kconfig/conf.o SHIPPED scripts/kconfig/zconf.tab.c SHIPPED scripts/kconfig/zconf.lex.c SHIPPED scripts/kconfig/zconf.hash.c HOSTCC scripts/kconfig/zconf.tab.o HOSTLD scripts/kconfig/conf scripts/kconfig/conf --allnoconfig Kconfig # # configuration written to .config # scripts/kconfig/Makefile:122: *** You need an existing .config for this target. Stop. make: *** [tinyconfig] Error 2 As shown above, "allnoconfig" has created the .config file before mergeconfig is called, but Make still raises a false alarm because of some sort of race condition. We can fix this issue by moving the error check to the shell script. Anyway, scripts/kconfig/merge_config.sh always requires an existing .config as a base file. It is reasonable to check its existence in the shell script. Signed-off-by: Masahiro Yamada Reviewed-by: Josh Triplett Reviewed-by: Darren Hart Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 1 - scripts/kconfig/merge_config.sh | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index fc34f46cb025..be0fad44ddd8 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -107,7 +107,6 @@ endif configfiles=$(wildcard $(srctree)/kernel/configs/$(1).config $(srctree)/arch/$(SRCARCH)/configs/$(1).config) define mergeconfig -$(if $(wildcard $(objtree)/.config),, $(error You need an existing .config for this target)) $(if $(call configfiles,$(1)),, $(error No configuration exists for this target on this architecture)) $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config $(call configfiles,$(1)) +$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index 2118af84e661..88d89b2986db 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh @@ -85,6 +85,11 @@ fi INITFILE=$1 shift; +if [ ! -r "$INITFILE" ]; then + echo "The base file '$INITFILE' does not exist. Exit." >&2 + exit 1 +fi + MERGE_LIST=$* SED_CONFIG_EXP="s/^\(# \)\{0,1\}\(CONFIG_[a-zA-Z0-9_]*\)[= ].*/\2/p" TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) -- cgit v1.2.3 From 371cfd4ff0611d8bc5d18bbb9cc6a2bc3d56cd3d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 13 Mar 2015 15:21:40 +0900 Subject: kbuild: mergeconfig: remove redundant $(objtree) Kbuild always runs in $(objtree). Actually, $(objtree) is always set to "." by the top-level Makefile. We can omit "-O $(objtree)" and "$(objtree)/". Signed-off-by: Masahiro Yamada Reviewed-by: Josh Triplett Reviewed-by: Darren Hart Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index be0fad44ddd8..b0e4be28204d 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -108,7 +108,7 @@ configfiles=$(wildcard $(srctree)/kernel/configs/$(1).config $(srctree)/arch/$(S define mergeconfig $(if $(call configfiles,$(1)),, $(error No configuration exists for this target on this architecture)) -$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config $(call configfiles,$(1)) +$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m .config $(call configfiles,$(1)) +$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig endef -- cgit v1.2.3 From 3a975b8cfcbe026b535f83bde9a3c009bae214f9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 13 Mar 2015 15:21:41 +0900 Subject: merge_config.sh: improve indentation It is true that we do not want to move the code too far to the right, but something like below is not preferred: if [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then echo Value of $CFG is redefined by fragment $MERGE_FILE: echo Previous value: $PREV_VAL echo New value: $NEW_VAL echo elif [ "$WARNREDUN" = "true" ]; then echo Value of $CFG is redundant by fragment $MERGE_FILE: fi To fix this, call "continue" if the "grep" command fails to find the given CONFIG. Signed-off-by: Masahiro Yamada Reviewed-by: Josh Triplett Reviewed-by: Darren Hart Signed-off-by: Michal Marek --- scripts/kconfig/merge_config.sh | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index 88d89b2986db..56584b107bf8 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh @@ -103,20 +103,18 @@ for MERGE_FILE in $MERGE_LIST ; do CFG_LIST=$(sed -n "$SED_CONFIG_EXP" $MERGE_FILE) for CFG in $CFG_LIST ; do - grep -q -w $CFG $TMP_FILE - if [ $? -eq 0 ] ; then - PREV_VAL=$(grep -w $CFG $TMP_FILE) - NEW_VAL=$(grep -w $CFG $MERGE_FILE) - if [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then + grep -q -w $CFG $TMP_FILE || continue + PREV_VAL=$(grep -w $CFG $TMP_FILE) + NEW_VAL=$(grep -w $CFG $MERGE_FILE) + if [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then echo Value of $CFG is redefined by fragment $MERGE_FILE: echo Previous value: $PREV_VAL echo New value: $NEW_VAL echo - elif [ "$WARNREDUN" = "true" ]; then + elif [ "$WARNREDUN" = "true" ]; then echo Value of $CFG is redundant by fragment $MERGE_FILE: - fi - sed -i "/$CFG[ =]/d" $TMP_FILE fi + sed -i "/$CFG[ =]/d" $TMP_FILE done cat $MERGE_FILE >> $TMP_FILE done -- cgit v1.2.3 From bc8f8f5fc47cd02c2c5f3580dac2fe6695af1edd Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 13 Mar 2015 15:21:42 +0900 Subject: merge_config.sh: rename MAKE to RUNMAKE The variable "MAKE" is used to store the command name that has invoked the Makefile. (Actually, it is already set to "make" if you run this script from a Makefile.) In this script, however, it is used to determine if Make should be run or not. It is not what we usually expect. Signed-off-by: Masahiro Yamada Reviewed-by: Josh Triplett Reviewed-by: Darren Hart Signed-off-by: Michal Marek --- scripts/kconfig/merge_config.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index 56584b107bf8..ec8e20350a64 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh @@ -35,7 +35,7 @@ usage() { echo " -O dir to put generated output files" } -MAKE=true +RUNMAKE=true ALLTARGET=alldefconfig WARNREDUN=false OUTPUT=. @@ -48,7 +48,7 @@ while true; do continue ;; "-m") - MAKE=false + RUNMAKE=false shift continue ;; @@ -119,7 +119,7 @@ for MERGE_FILE in $MERGE_LIST ; do cat $MERGE_FILE >> $TMP_FILE done -if [ "$MAKE" = "false" ]; then +if [ "$RUNMAKE" = "false" ]; then cp $TMP_FILE $OUTPUT/.config echo "#" echo "# merged configuration written to $OUTPUT/.config (needs make)" -- cgit v1.2.3 From 63a91033d52e64a22e571fe84924c0b7f21c280d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 13 Mar 2015 15:21:43 +0900 Subject: kbuild: add generic mergeconfig target, %.config "scripts/kconfig/merge_config.sh && make oldconfig" works well enough for merging local config fragments, but Kbuild currently has the entry points only for "kvmconfig" and "tinyconfig". This commit provides the generic target for mergeconfig, so we can manage our own config fragments easily: put "foo.config" in arch/$(SRCARCH)/configs/ or kernel/configs/, and then run "make foo.config". Now "make kvmconfig" is just a shorthand of "make kvm_guest.config". Likewise, "make tinyconfig" is equivalent to "make allnoconfig tiny.config". Signed-off-by: Masahiro Yamada Reviewed-by: Josh Triplett Reviewed-by: Darren Hart Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index b0e4be28204d..cb2cf548c45c 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -104,21 +104,20 @@ endif %_defconfig: $(obj)/conf $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) -configfiles=$(wildcard $(srctree)/kernel/configs/$(1).config $(srctree)/arch/$(SRCARCH)/configs/$(1).config) +configfiles=$(wildcard $(srctree)/kernel/configs/$@ $(srctree)/arch/$(SRCARCH)/configs/$@) -define mergeconfig -$(if $(call configfiles,$(1)),, $(error No configuration exists for this target on this architecture)) -$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m .config $(call configfiles,$(1)) -+$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig -endef +%.config: $(obj)/conf + $(if $(call configfiles),, $(error No configuration exists for this target on this architecture)) + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m .config $(configfiles) + +$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig PHONY += kvmconfig -kvmconfig: - $(call mergeconfig,kvm_guest) +kvmconfig: kvm_guest.config + @: PHONY += tinyconfig -tinyconfig: allnoconfig - $(call mergeconfig,tiny) +tinyconfig: + $(Q)$(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config # Help text used by make help help: -- cgit v1.2.3 From 2c2b913d19e149bf7c4ae5f62634fc3b46a06306 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Wed, 4 Mar 2015 09:32:32 +0100 Subject: irqf_oneshot.cocci: add check of devm_request_threaded_irq() Since commit 1c6c69525b40eb76de8adf039409722015927dc3 ("genirq: Reject bogus threaded irq requests") threaded IRQs without a primary handler need to be requested with IRQF_ONESHOT, otherwise the request will fail. Until now, this coccinelle script only checked request_threaded_irq(). However, the counterpart devm function (see kernel/irq/devres.c) is also affected by the missing flag which can be detected with this patch. Signed-off-by: Valentin Rothberg Signed-off-by: Peter Senna Tschudin Acked-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/misc/irqf_oneshot.cocci | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'scripts') diff --git a/scripts/coccinelle/misc/irqf_oneshot.cocci b/scripts/coccinelle/misc/irqf_oneshot.cocci index 6cfde94be0ef..a24a754ae1d7 100644 --- a/scripts/coccinelle/misc/irqf_oneshot.cocci +++ b/scripts/coccinelle/misc/irqf_oneshot.cocci @@ -12,11 +12,13 @@ virtual org virtual report @r1@ +expression dev; expression irq; expression thread_fn; expression flags; position p; @@ +( request_threaded_irq@p(irq, NULL, thread_fn, ( flags | IRQF_ONESHOT @@ -24,13 +26,24 @@ flags | IRQF_ONESHOT IRQF_ONESHOT ) , ...) +| +devm_request_threaded_irq@p(dev, irq, NULL, thread_fn, +( +flags | IRQF_ONESHOT +| +IRQF_ONESHOT +) +, ...) +) @depends on patch@ +expression dev; expression irq; expression thread_fn; expression flags; position p != r1.p; @@ +( request_threaded_irq@p(irq, NULL, thread_fn, ( -0 @@ -40,6 +53,17 @@ request_threaded_irq@p(irq, NULL, thread_fn, +flags | IRQF_ONESHOT ) , ...) +| +devm_request_threaded_irq@p(dev, irq, NULL, thread_fn, +( +-0 ++IRQF_ONESHOT +| +-flags ++flags | IRQF_ONESHOT +) +, ...) +) @depends on context@ position p != r1.p; -- cgit v1.2.3 From 8286ae03308c6f97f346f9f8cb9174b04969add5 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Wed, 25 Mar 2015 15:39:50 +0000 Subject: MIPS: Add CDMM bus support Add MIPS Common Device Memory Map (CDMM) support in the form of a bus in the standard Linux device model. Each device attached via CDMM is discoverable via an 8-bit type identifier and may contain a number of blocks of memory mapped registers in the CDMM region. IRQs are expected to be handled separately. Due to the per-cpu (per-VPE for MT cores) nature of the CDMM devices, all the driver callbacks take place from workqueues which are run on the right CPU for the device in question, so that the driver doesn't need to be as concerned about which CPU it is running on. Callbacks also exist for when CPUs are taken offline, so that any per-CPU resources used by the driver can be disabled so they don't get forcefully migrated. CDMM devices are created as children of the CPU device they are attached to. Any existing CDMM configuration by the bootloader will be inherited, however platforms wishing to enable CDMM should implement the weak mips_cdmm_phys_base() function (see asm/cdmm.h) so that the bus driver knows where it should put the CDMM region in the physical address space if the bootloader hasn't already enabled it. A mips_cdmm_early_probe() function is also provided to allow early boot or particularly low level code to set up the CDMM region and probe for a specific device type, for example early console or KGDB IO drivers for the EJTAG Fast Debug Channel (FDC) CDMM device. Signed-off-by: James Hogan Cc: Greg Kroah-Hartman Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/9599/ Signed-off-by: Ralf Baechle --- scripts/mod/devicetable-offsets.c | 3 +++ scripts/mod/file2alias.c | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index f282516acc7b..fce36d0f6898 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c @@ -168,6 +168,9 @@ int main(void) DEVID_FIELD(amba_id, id); DEVID_FIELD(amba_id, mask); + DEVID(mips_cdmm_device_id); + DEVID_FIELD(mips_cdmm_device_id, type); + DEVID(x86_cpu_id); DEVID_FIELD(x86_cpu_id, feature); DEVID_FIELD(x86_cpu_id, family); diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index e614ef689eee..78691d51a479 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1109,6 +1109,22 @@ static int do_amba_entry(const char *filename, } ADD_TO_DEVTABLE("amba", amba_id, do_amba_entry); +/* + * looks like: "mipscdmm:tN" + * + * N is exactly 2 digits, where each is an upper-case hex digit, or + * a ? or [] pattern matching exactly one digit. + */ +static int do_mips_cdmm_entry(const char *filename, + void *symval, char *alias) +{ + DEF_FIELD(symval, mips_cdmm_device_id, type); + + sprintf(alias, "mipscdmm:t%02X*", type); + return 1; +} +ADD_TO_DEVTABLE("mipscdmm", mips_cdmm_device_id, do_mips_cdmm_entry); + /* LOOKS like cpu:type:x86,venVVVVfamFFFFmodMMMM:feature:*,FEAT,* * All fields are numbers. It would be nicer to use strings for vendor * and feature, but getting those out of the build system here is too -- cgit v1.2.3 From 7aacad53aeb57b7ff52399f56eb6d7d4010e72e9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 27 Mar 2015 20:43:35 +0900 Subject: kbuild: use relative path to include Makefile The "MAKEFLAGS += --include-dir=$(srctree)" line in the top Makefile allows us to do this. Signed-off-by: Masahiro Yamada Signed-off-by: Michal Marek --- scripts/Makefile.dtbinst | 2 +- scripts/Makefile.fwinst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst index 909ed7a2ac61..7cbff167341f 100644 --- a/scripts/Makefile.dtbinst +++ b/scripts/Makefile.dtbinst @@ -18,7 +18,7 @@ export dtbinst-root ?= $(obj) include include/config/auto.conf include scripts/Kbuild.include -include $(srctree)/$(obj)/Makefile +include $(obj)/Makefile PHONY += __dtbs_install_prep __dtbs_install_prep: diff --git a/scripts/Makefile.fwinst b/scripts/Makefile.fwinst index 5b698add4f31..baf5eaedb278 100644 --- a/scripts/Makefile.fwinst +++ b/scripts/Makefile.fwinst @@ -13,7 +13,7 @@ src := $(obj) -include $(objtree)/.config include scripts/Kbuild.include -include $(srctree)/$(obj)/Makefile +include $(obj)/Makefile include scripts/Makefile.host -- cgit v1.2.3 From 5f655c7a4c9fcf7152b8a34e987d936f7b5255b8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 27 Mar 2015 20:43:37 +0900 Subject: kbuild: include $(src)/Makefile rather than $(obj)/Makefile This commit actually has no impact because $(src) and $(obj) point to the same path, but $(src)/Makefile looks better when we include source files. Signed-off-by: Masahiro Yamada Signed-off-by: Michal Marek --- scripts/Makefile.dtbinst | 2 +- scripts/Makefile.fwinst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst index 7cbff167341f..1c15717e0d56 100644 --- a/scripts/Makefile.dtbinst +++ b/scripts/Makefile.dtbinst @@ -18,7 +18,7 @@ export dtbinst-root ?= $(obj) include include/config/auto.conf include scripts/Kbuild.include -include $(obj)/Makefile +include $(src)/Makefile PHONY += __dtbs_install_prep __dtbs_install_prep: diff --git a/scripts/Makefile.fwinst b/scripts/Makefile.fwinst index baf5eaedb278..b27290035253 100644 --- a/scripts/Makefile.fwinst +++ b/scripts/Makefile.fwinst @@ -13,7 +13,7 @@ src := $(obj) -include $(objtree)/.config include scripts/Kbuild.include -include $(obj)/Makefile +include $(src)/Makefile include scripts/Makefile.host -- cgit v1.2.3 From 77479b38e2f58890eb221a0418357502a5b41cd6 Mon Sep 17 00:00:00 2001 From: Nathan Rossi Date: Mon, 30 Mar 2015 14:39:08 +0200 Subject: kbuild: Create directory for target DTB When building specific DTBs out of the kernel tree the vendor subdirs (boot/dts/) are not created, ensure that they are before building the DTB. Signed-off-by: Nathan Rossi Signed-off-by: Michal Simek Acked-by: Will Deacon Signed-off-by: Olof Johansson --- scripts/Makefile.lib | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 044eb4f89a91..79e86613712f 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -282,7 +282,8 @@ $(obj)/%.dtb.S: $(obj)/%.dtb $(call cmd,dt_S_dtb) quiet_cmd_dtc = DTC $@ -cmd_dtc = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ +cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ + $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \ -i $(dir $<) $(DTC_FLAGS) \ -d $(depfile).dtc.tmp $(dtc-tmp) ; \ -- cgit v1.2.3 From bd8b22d2888e75063c9012b95341d6cb36456434 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 30 Mar 2015 15:20:31 +0200 Subject: Kbuild: kallsyms: ignore veneers emitted by the ARM linker When linking large kernels on ARM, the linker will insert veneers (i.e., PLT like stubs) when function symbols are out of reach for the ordinary relative branch/branch-and-link instructions. However, due to the fact that the kallsyms region sits in .rodata, which is between .text and .init.text, additional veneers may be emitted in the second pass due to the fact that the size of the kallsyms region itself has pushed the .init.text section further apart, requiring even more veneers. So ignore the veneers when generating the symbol table. Veneers have no corresponding source code, and they will not turn up in backtraces anyway. This patch also lightly refactors the symbol_valid() function to use a local 'sym_name' rather than the obfuscated 'sym + 1' and 'sym + offset' Signed-off-by: Ard Biesheuvel Signed-off-by: Michal Marek --- scripts/kallsyms.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index c6d33bd15b04..f4b016782f0d 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -212,15 +212,23 @@ static int symbol_valid(struct sym_entry *s) "_SDA_BASE_", /* ppc */ "_SDA2_BASE_", /* ppc */ NULL }; + + static char *special_suffixes[] = { + "_compiled.", /* gcc < 3.0: "gcc[0-9]_compiled." */ + "_veneer", /* arm */ + NULL }; + int i; - int offset = 1; + char *sym_name = (char *)s->sym + 1; + if (s->addr < kernel_start_addr) return 0; /* skip prefix char */ - if (symbol_prefix_char && *(s->sym + 1) == symbol_prefix_char) - offset++; + if (symbol_prefix_char && *sym_name == symbol_prefix_char) + sym_name++; + /* if --all-symbols is not specified, then symbols outside the text * and inittext sections are discarded */ @@ -235,22 +243,26 @@ static int symbol_valid(struct sym_entry *s) * rules. */ if ((s->addr == text_range_text->end && - strcmp((char *)s->sym + offset, + strcmp(sym_name, text_range_text->end_sym)) || (s->addr == text_range_inittext->end && - strcmp((char *)s->sym + offset, + strcmp(sym_name, text_range_inittext->end_sym))) return 0; } /* Exclude symbols which vary between passes. */ - if (strstr((char *)s->sym + offset, "_compiled.")) - return 0; - for (i = 0; special_symbols[i]; i++) - if( strcmp((char *)s->sym + offset, special_symbols[i]) == 0 ) + if (strcmp(sym_name, special_symbols[i]) == 0) return 0; + for (i = 0; special_suffixes[i]; i++) { + int l = strlen(sym_name) - strlen(special_suffixes[i]); + + if (l >= 0 && strcmp(sym_name + l, special_suffixes[i]) == 0) + return 0; + } + return 1; } -- cgit v1.2.3 From 41b585b2ed793db6f02ec87d0026d73382e8180a Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 30 Mar 2015 15:20:32 +0200 Subject: Kbuild: kallsyms: drop special handling of pre-3.0 GCC symbols Since we have required at least GCC v3.2 for some time now, we can drop the special handling of the 'gcc[0-9]_compiled.' label which is not emitted anymore since GCC v3.0. Signed-off-by: Ard Biesheuvel Signed-off-by: Michal Marek --- scripts/kallsyms.c | 1 - 1 file changed, 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index f4b016782f0d..8fa81e84e295 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -214,7 +214,6 @@ static int symbol_valid(struct sym_entry *s) NULL }; static char *special_suffixes[] = { - "_compiled.", /* gcc < 3.0: "gcc[0-9]_compiled." */ "_veneer", /* arm */ NULL }; -- cgit v1.2.3 From 1cba0c305758c3c1786ecaceb03e142c95a4edc9 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Wed, 8 Apr 2015 11:11:57 +0200 Subject: kconfig: Simplify Makefile Use a single rule for targets handled directly by the conf program. Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index cb2cf548c45c..1f5e45355731 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -2,7 +2,7 @@ # Kernel configuration targets # These targets are used from top-level makefile -PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config \ +PHONY += xconfig gconfig menuconfig config silentoldconfig update-po-config \ localmodconfig localyesconfig ifdef KBUILD_KCONFIG @@ -29,9 +29,6 @@ config: $(obj)/conf nconfig: $(obj)/nconf $< $(Kconfig) -oldconfig: $(obj)/conf - $< --$@ $(Kconfig) - silentoldconfig: $(obj)/conf $(Q)mkdir -p include/config include/generated $< --$@ $(Kconfig) @@ -74,21 +71,20 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h --output $(obj)/linux.pot $(Q)rm -f $(obj)/config.pot -PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig +# These targets map 1:1 to the commandline options of 'conf' +simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \ + alldefconfig randconfig listnewconfig olddefconfig +PHONY += $(simple-targets) -allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf +$(simple-targets): $(obj)/conf $< --$@ $(Kconfig) -PHONY += listnewconfig olddefconfig oldnoconfig savedefconfig defconfig - -listnewconfig olddefconfig: $(obj)/conf - $< --$@ $(Kconfig) +PHONY += oldnoconfig savedefconfig defconfig # oldnoconfig is an alias of olddefconfig, because people already are dependent # on its behavior(sets new symbols to their default value but not 'n') with the # counter-intuitive name. -oldnoconfig: $(obj)/conf - $< --olddefconfig $(Kconfig) +oldnoconfig: olddefconfig savedefconfig: $(obj)/conf $< --$@=defconfig $(Kconfig) -- cgit v1.2.3 From 0a1f00a1c86421cc07cec87011c7cf4df68ee54b Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Wed, 8 Apr 2015 13:30:42 +0200 Subject: kconfig: Do not print status messages in make -s mode Add an -s option to the various frontends and pass it when make -s is used. Also, use $(kecho) instead of @echo in the Makefile. Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 40 ++++++++++++++++++++++------------------ scripts/kconfig/conf.c | 8 ++++++-- scripts/kconfig/gconf.c | 5 ++++- scripts/kconfig/mconf.c | 31 +++++++++++++++++++++---------- scripts/kconfig/nconf.c | 5 +++++ scripts/kconfig/qconf.cc | 5 ++++- 6 files changed, 62 insertions(+), 32 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 1f5e45355731..d9b1fef0c67e 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -11,27 +11,31 @@ else Kconfig := Kconfig endif +ifeq ($(quiet),silent_) +silent := -s +endif + # We need this, in case the user has it in its environment unexport CONFIG_ xconfig: $(obj)/qconf - $< $(Kconfig) + $< $(silent) $(Kconfig) gconfig: $(obj)/gconf - $< $(Kconfig) + $< $(silent) $(Kconfig) menuconfig: $(obj)/mconf - $< $(Kconfig) + $< $(silent) $(Kconfig) config: $(obj)/conf - $< --oldaskconfig $(Kconfig) + $< $(silent) --oldaskconfig $(Kconfig) nconfig: $(obj)/nconf - $< $(Kconfig) + $< $(silent) $(Kconfig) silentoldconfig: $(obj)/conf $(Q)mkdir -p include/config include/generated - $< --$@ $(Kconfig) + $< $(silent) --$@ $(Kconfig) localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf $(Q)mkdir -p include/config include/generated @@ -40,18 +44,18 @@ localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf cmp -s .tmp.config .config || \ (mv -f .config .config.old.1; \ mv -f .tmp.config .config; \ - $(obj)/conf --silentoldconfig $(Kconfig); \ + $(obj)/conf $(silent) --silentoldconfig $(Kconfig); \ mv -f .config.old.1 .config.old) \ else \ mv -f .tmp.config .config; \ - $(obj)/conf --silentoldconfig $(Kconfig); \ + $(obj)/conf $(silent) --silentoldconfig $(Kconfig); \ fi $(Q)rm -f .tmp.config # Create new linux.pot file # Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h - $(Q)echo " GEN config.pot" + $(Q)$(kecho) " GEN config.pot" $(Q)xgettext --default-domain=linux \ --add-comments --keyword=_ --keyword=N_ \ --from-code=UTF-8 \ @@ -62,11 +66,11 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h $(Q)(for i in `ls $(srctree)/arch/*/Kconfig \ $(srctree)/arch/*/um/Kconfig`; \ do \ - echo " GEN $$i"; \ + $(kecho) " GEN $$i"; \ $(obj)/kxgettext $$i \ >> $(obj)/config.pot; \ done ) - $(Q)echo " GEN linux.pot" + $(Q)$(kecho) " GEN linux.pot" $(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \ --output $(obj)/linux.pot $(Q)rm -f $(obj)/config.pot @@ -77,7 +81,7 @@ simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \ PHONY += $(simple-targets) $(simple-targets): $(obj)/conf - $< --$@ $(Kconfig) + $< $(silent) --$@ $(Kconfig) PHONY += oldnoconfig savedefconfig defconfig @@ -87,18 +91,18 @@ PHONY += oldnoconfig savedefconfig defconfig oldnoconfig: olddefconfig savedefconfig: $(obj)/conf - $< --$@=defconfig $(Kconfig) + $< $(silent) --$@=defconfig $(Kconfig) defconfig: $(obj)/conf ifeq ($(KBUILD_DEFCONFIG),) - $< --defconfig $(Kconfig) + $< $(silent) --defconfig $(Kconfig) else - @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" - $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) + @$(kecho) "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" + $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) endif %_defconfig: $(obj)/conf - $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) + $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) configfiles=$(wildcard $(srctree)/kernel/configs/$@ $(srctree)/arch/$(SRCARCH)/configs/$@) @@ -215,7 +219,7 @@ $(obj)/.tmp_qtcheck: $(src)/Makefile # QT needs some extra effort... $(obj)/.tmp_qtcheck: - @set -e; echo " CHECK qt"; dir=""; pkg=""; \ + @set -e; $(kecho) " CHECK qt"; dir=""; pkg=""; \ if ! pkg-config --exists QtCore 2> /dev/null; then \ echo "* Unable to find the QT4 tool qmake. Trying to use QT3"; \ pkg-config --exists qt 2> /dev/null && pkg=qt; \ diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index fef75fc756f4..6c204318bc94 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -471,7 +471,7 @@ static struct option long_opts[] = { static void conf_usage(const char *progname) { - printf("Usage: %s [option] \n", progname); + printf("Usage: %s [-s] [option] \n", progname); printf("[option] is _one_ of the following:\n"); printf(" --listnewconfig List new options\n"); printf(" --oldaskconfig Start a new configuration using a line-oriented program\n"); @@ -501,7 +501,11 @@ int main(int ac, char **av) tty_stdio = isatty(0) && isatty(1) && isatty(2); - while ((opt = getopt_long(ac, av, "", long_opts, NULL)) != -1) { + while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) { + if (opt == 's') { + conf_set_message_callback(NULL); + continue; + } input_mode = (enum input_mode)opt; switch (opt) { case silentoldconfig: diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 344b9e340ecb..26d208b435a0 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -1474,9 +1474,12 @@ int main(int ac, char *av[]) case 'a': //showAll = 1; break; + case 's': + conf_set_message_callback(NULL); + break; case 'h': case '?': - printf("%s \n", av[0]); + printf("%s [-s] \n", av[0]); exit(0); } name = av[2]; diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 4dd37552abc2..315ce2c7cb9d 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -279,6 +279,7 @@ static int child_count; static int single_menu_mode; static int show_all_options; static int save_and_exit; +static int silent; static void conf(struct menu *menu, struct menu *active_menu); static void conf_choice(struct menu *menu); @@ -777,10 +778,12 @@ static void conf_message_callback(const char *fmt, va_list ap) char buf[PATH_MAX+1]; vsnprintf(buf, sizeof(buf), fmt, ap); - if (save_and_exit) - printf("%s", buf); - else + if (save_and_exit) { + if (!silent) + printf("%s", buf); + } else { show_textbox(NULL, buf, 6, 60); + } } static void show_help(struct menu *menu) @@ -977,16 +980,18 @@ static int handle_exit(void) } /* fall through */ case -1: - printf(_("\n\n" - "*** End of the configuration.\n" - "*** Execute 'make' to start the build or try 'make help'." - "\n\n")); + if (!silent) + printf(_("\n\n" + "*** End of the configuration.\n" + "*** Execute 'make' to start the build or try 'make help'." + "\n\n")); res = 0; break; default: - fprintf(stderr, _("\n\n" - "Your configuration changes were NOT saved." - "\n\n")); + if (!silent) + fprintf(stderr, _("\n\n" + "Your configuration changes were NOT saved." + "\n\n")); if (res != KEY_ESC) res = 0; } @@ -1010,6 +1015,12 @@ int main(int ac, char **av) signal(SIGINT, sig_handler); + if (ac > 1 && strcmp(av[1], "-s") == 0) { + silent = 1; + /* Silence conf_read() until the real callback is set up */ + conf_set_message_callback(NULL); + av++; + } conf_parse(av[1]); conf_read(NULL); diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 984489ef2b46..d42d534a66cd 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -1482,6 +1482,11 @@ int main(int ac, char **av) bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); + if (ac > 1 && strcmp(av[1], "-s") == 0) { + /* Silence conf_read() until the real callback is set up */ + conf_set_message_callback(NULL); + av++; + } conf_parse(av[1]); conf_read(NULL); diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 9d3b04b0769c..c3bb7fe8dfa6 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1746,7 +1746,7 @@ static const char *progname; static void usage(void) { - printf(_("%s \n"), progname); + printf(_("%s [-s] \n"), progname); exit(0); } @@ -1762,6 +1762,9 @@ int main(int ac, char** av) configApp = new QApplication(ac, av); if (ac > 1 && av[1][0] == '-') { switch (av[1][1]) { + case 's': + conf_set_message_callback(NULL); + break; case 'h': case '?': usage(); -- cgit v1.2.3 From 050e57fd5936eb175cbb7a788252aa6867201120 Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Mon, 13 Apr 2015 20:41:04 +0930 Subject: modpost: add strict white-listing when referencing sections. Prints a warning when a section references a section outside a strict white-list. This will be useful to print a warning if __ex_table references a non-executable section. Signed-off-by: Quentin Casasnovas Signed-off-by: Rusty Russell --- scripts/mod/modpost.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index d439856f8176..7094a57273b9 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -925,7 +925,8 @@ enum mismatch { struct sectioncheck { const char *fromsec[20]; - const char *tosec[20]; + const char *bad_tosec[20]; + const char *good_tosec[20]; enum mismatch mismatch; const char *symbol_white_list[20]; }; @@ -936,19 +937,19 @@ static const struct sectioncheck sectioncheck[] = { */ { .fromsec = { TEXT_SECTIONS, NULL }, - .tosec = { ALL_INIT_SECTIONS, NULL }, + .bad_tosec = { ALL_INIT_SECTIONS, NULL }, .mismatch = TEXT_TO_ANY_INIT, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, { .fromsec = { DATA_SECTIONS, NULL }, - .tosec = { ALL_XXXINIT_SECTIONS, NULL }, + .bad_tosec = { ALL_XXXINIT_SECTIONS, NULL }, .mismatch = DATA_TO_ANY_INIT, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, { .fromsec = { DATA_SECTIONS, NULL }, - .tosec = { INIT_SECTIONS, NULL }, + .bad_tosec = { INIT_SECTIONS, NULL }, .mismatch = DATA_TO_ANY_INIT, .symbol_white_list = { "*_template", "*_timer", "*_sht", "*_ops", @@ -957,54 +958,54 @@ static const struct sectioncheck sectioncheck[] = { }, { .fromsec = { TEXT_SECTIONS, NULL }, - .tosec = { ALL_EXIT_SECTIONS, NULL }, + .bad_tosec = { ALL_EXIT_SECTIONS, NULL }, .mismatch = TEXT_TO_ANY_EXIT, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, { .fromsec = { DATA_SECTIONS, NULL }, - .tosec = { ALL_EXIT_SECTIONS, NULL }, + .bad_tosec = { ALL_EXIT_SECTIONS, NULL }, .mismatch = DATA_TO_ANY_EXIT, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, /* Do not reference init code/data from meminit code/data */ { .fromsec = { ALL_XXXINIT_SECTIONS, NULL }, - .tosec = { INIT_SECTIONS, NULL }, + .bad_tosec = { INIT_SECTIONS, NULL }, .mismatch = XXXINIT_TO_SOME_INIT, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, /* Do not reference exit code/data from memexit code/data */ { .fromsec = { ALL_XXXEXIT_SECTIONS, NULL }, - .tosec = { EXIT_SECTIONS, NULL }, + .bad_tosec = { EXIT_SECTIONS, NULL }, .mismatch = XXXEXIT_TO_SOME_EXIT, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, /* Do not use exit code/data from init code */ { .fromsec = { ALL_INIT_SECTIONS, NULL }, - .tosec = { ALL_EXIT_SECTIONS, NULL }, + .bad_tosec = { ALL_EXIT_SECTIONS, NULL }, .mismatch = ANY_INIT_TO_ANY_EXIT, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, /* Do not use init code/data from exit code */ { .fromsec = { ALL_EXIT_SECTIONS, NULL }, - .tosec = { ALL_INIT_SECTIONS, NULL }, + .bad_tosec = { ALL_INIT_SECTIONS, NULL }, .mismatch = ANY_EXIT_TO_ANY_INIT, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, { .fromsec = { ALL_PCI_INIT_SECTIONS, NULL }, - .tosec = { INIT_SECTIONS, NULL }, + .bad_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 }, - .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL }, + .bad_tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL }, .mismatch = EXPORT_TO_INIT_EXIT, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, } @@ -1018,9 +1019,12 @@ static const struct sectioncheck *section_mismatch( const struct sectioncheck *check = §ioncheck[0]; for (i = 0; i < elems; i++) { - if (match(fromsec, check->fromsec) && - match(tosec, check->tosec)) - return check; + if (match(fromsec, check->fromsec)) { + if (check->bad_tosec[0] && match(tosec, check->bad_tosec)) + return check; + if (check->good_tosec[0] && !match(tosec, check->good_tosec)) + return check; + } check++; } return NULL; -- cgit v1.2.3 From 157d1972d079207332d31a761cdfb81598455e0a Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Mon, 13 Apr 2015 20:42:52 +0930 Subject: modpost: add .sched.text and .kprobes.text to the TEXT_SECTIONS list. sched.text and .kprobes.text should behave exactly like .text with regards to how we should warn about referencing sections which might get discarded at runtime. Signed-off-by: Quentin Casasnovas Signed-off-by: Rusty Russell --- scripts/mod/modpost.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 7094a57273b9..8cef46b18dc6 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -873,7 +873,8 @@ static void check_section(const char *modname, struct elf_info *elf, #define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS #define DATA_SECTIONS ".data", ".data.rel" -#define TEXT_SECTIONS ".text", ".text.unlikely" +#define TEXT_SECTIONS ".text", ".text.unlikely", ".sched.text", \ + ".kprobes.text" #define INIT_SECTIONS ".init.*" #define MEM_INIT_SECTIONS ".meminit.*" -- cgit v1.2.3 From 644e8f14cb3bca5c66f6ddd944d9d26074eec46e Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Mon, 13 Apr 2015 20:43:17 +0930 Subject: modpost: add handler function pointer to sectioncheck. This will be useful when we want to have special handlers which need to go through more hops to print useful information to the user. Signed-off-by: Quentin Casasnovas Signed-off-by: Rusty Russell --- scripts/mod/modpost.c | 68 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 26 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 8cef46b18dc6..0f48f8b97b17 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -930,6 +930,10 @@ struct sectioncheck { const char *good_tosec[20]; enum mismatch mismatch; const char *symbol_white_list[20]; + void (*handler)(const char *modname, struct elf_info *elf, + const struct sectioncheck* const mismatch, + Elf_Rela *r, Elf_Sym *sym, const char *fromsec); + }; static const struct sectioncheck sectioncheck[] = { @@ -1417,37 +1421,49 @@ static void report_sec_mismatch(const char *modname, fprintf(stderr, "\n"); } -static void check_section_mismatch(const char *modname, struct elf_info *elf, - Elf_Rela *r, Elf_Sym *sym, const char *fromsec) +static void default_mismatch_handler(const char *modname, struct elf_info *elf, + const struct sectioncheck* const mismatch, + Elf_Rela *r, Elf_Sym *sym, const char *fromsec) { const char *tosec; - const struct sectioncheck *mismatch; + Elf_Sym *to; + Elf_Sym *from; + const char *tosym; + const char *fromsym; tosec = sec_name(elf, get_secindex(elf, sym)); - mismatch = section_mismatch(fromsec, tosec); + from = find_elf_symbol2(elf, r->r_offset, fromsec); + fromsym = sym_name(elf, from); + to = find_elf_symbol(elf, r->r_addend, sym); + tosym = sym_name(elf, to); + + if (!strncmp(fromsym, "reference___initcall", + sizeof("reference___initcall")-1)) + return; + + /* check whitelist - we may ignore it */ + if (secref_whitelist(mismatch, + fromsec, fromsym, tosec, tosym)) { + report_sec_mismatch(modname, mismatch, + fromsec, r->r_offset, fromsym, + is_function(from), tosec, tosym, + is_function(to)); + } +} + +static void check_section_mismatch(const char *modname, struct elf_info *elf, + Elf_Rela *r, Elf_Sym *sym, const char *fromsec) +{ + const char *tosec = sec_name(elf, get_secindex(elf, sym));; + const struct sectioncheck *mismatch = section_mismatch(fromsec, tosec); + if (mismatch) { - Elf_Sym *to; - Elf_Sym *from; - const char *tosym; - const char *fromsym; - - from = find_elf_symbol2(elf, r->r_offset, fromsec); - fromsym = sym_name(elf, from); - to = find_elf_symbol(elf, r->r_addend, sym); - tosym = sym_name(elf, to); - - if (!strncmp(fromsym, "reference___initcall", - sizeof("reference___initcall")-1)) - return; - - /* check whitelist - we may ignore it */ - if (secref_whitelist(mismatch, - fromsec, fromsym, tosec, tosym)) { - report_sec_mismatch(modname, mismatch, - fromsec, r->r_offset, fromsym, - is_function(from), tosec, tosym, - is_function(to)); - } + if (mismatch->handler) + mismatch->handler(modname, elf, mismatch, + r, sym, fromsec); + else + default_mismatch_handler(modname, elf, mismatch, + r, sym, fromsec); } } -- cgit v1.2.3 From 356ad538128ed9221f7d01199a3a7d080f158a5d Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Mon, 13 Apr 2015 20:43:34 +0930 Subject: modpost: factorize symbol pretty print in get_pretty_name(). Signed-off-by: Quentin Casasnovas Signed-off-by: Rusty Russell --- scripts/mod/modpost.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 0f48f8b97b17..c69681e815b2 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1270,6 +1270,15 @@ static void print_section_list(const char * const list[20]) fprintf(stderr, "\n"); } +static inline void get_pretty_name(int is_func, const char** name, const char** name_p) +{ + switch (is_func) { + case 0: *name = "variable"; *name_p = ""; break; + case 1: *name = "function"; *name_p = "()"; break; + default: *name = "(unknown reference)"; *name_p = ""; break; + } +} + /* * Print a warning about a section mismatch. * Try to find symbols near it so user can find it. @@ -1289,21 +1298,13 @@ static void report_sec_mismatch(const char *modname, char *prl_from; char *prl_to; - switch (from_is_func) { - case 0: from = "variable"; from_p = ""; break; - case 1: from = "function"; from_p = "()"; break; - default: from = "(unknown reference)"; from_p = ""; break; - } - switch (to_is_func) { - case 0: to = "variable"; to_p = ""; break; - case 1: to = "function"; to_p = "()"; break; - default: to = "(unknown reference)"; to_p = ""; break; - } - sec_mismatch_count++; if (!sec_mismatch_verbose) return; + get_pretty_name(from_is_func, &from, &from_p); + get_pretty_name(to_is_func, &to, &to_p); + warn("%s(%s+0x%llx): Section mismatch in reference from the %s %s%s " "to the %s %s:%s%s\n", modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec, -- cgit v1.2.3 From c7a65e0645b2d1f8382ce27f4edaf1b4f2e09549 Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Mon, 13 Apr 2015 20:43:45 +0930 Subject: modpost: mismatch_handler: retrieve tosym information only when needed. Signed-off-by: Quentin Casasnovas Signed-off-by: Rusty Russell --- scripts/mod/modpost.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c69681e815b2..bf0cf8173beb 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1432,16 +1432,17 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, const char *tosym; const char *fromsym; - tosec = sec_name(elf, get_secindex(elf, sym)); from = find_elf_symbol2(elf, r->r_offset, fromsec); fromsym = sym_name(elf, from); - to = find_elf_symbol(elf, r->r_addend, sym); - tosym = sym_name(elf, to); if (!strncmp(fromsym, "reference___initcall", sizeof("reference___initcall")-1)) return; + tosec = sec_name(elf, get_secindex(elf, sym)); + to = find_elf_symbol(elf, r->r_addend, sym); + tosym = sym_name(elf, to); + /* check whitelist - we may ignore it */ if (secref_whitelist(mismatch, fromsec, fromsym, tosec, tosym)) { -- cgit v1.2.3 From c31e4b832f124dccdb5d80ba3c1cd4f9081f7fb2 Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Mon, 13 Apr 2015 20:44:04 +0930 Subject: scripts: add check_extable.sh script. This shell script can be used to sanity check the __ex_table section on an object file, making sure the relocations in there are pointing to valid executable sections. If it finds some suspicious relocations, it'll use addr2line to try and dump where this is coming from. This works best with CONFIG_DEBUG_INFO. Signed-off-by: Quentin Casasnovas Signed-off-by: Rusty Russell --- scripts/check_extable.sh | 146 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100755 scripts/check_extable.sh (limited to 'scripts') diff --git a/scripts/check_extable.sh b/scripts/check_extable.sh new file mode 100755 index 000000000000..0fb6b1c97c27 --- /dev/null +++ b/scripts/check_extable.sh @@ -0,0 +1,146 @@ +#! /bin/bash +# (c) 2015, Quentin Casasnovas + +obj=$1 + +file ${obj} | grep -q ELF || (echo "${obj} is not and ELF file." 1>&2 ; exit 0) + +# Bail out early if there isn't an __ex_table section in this object file. +objdump -hj __ex_table ${obj} 2> /dev/null > /dev/null +[ $? -ne 0 ] && exit 0 + +white_list=.text,.fixup + +suspicious_relocs=$(objdump -rj __ex_table ${obj} | tail -n +6 | + grep -v $(eval echo -e{${white_list}}) | awk '{print $3}') + +# No suspicious relocs in __ex_table, jobs a good'un +[ -z "${suspicious_relocs}" ] && exit 0 + + +# After this point, something is seriously wrong since we just found out we +# have some relocations in __ex_table which point to sections which aren't +# white listed. If you're adding a new section in the Linux kernel, and +# you're expecting this section to contain code which can fault (i.e. the +# __ex_table relocation to your new section is expected), simply add your +# new section to the white_list variable above. If not, you're probably +# doing something wrong and the rest of this code is just trying to print +# you more information about it. + +function find_section_offset_from_symbol() +{ + eval $(objdump -t ${obj} | grep ${1} | sed 's/\([0-9a-f]\+\) .\{7\} \([^ \t]\+\).*/section="\2"; section_offset="0x\1" /') + + # addr2line takes addresses in hexadecimal... + section_offset=$(printf "0x%016x" $(( ${section_offset} + $2 )) ) +} + +function find_symbol_and_offset_from_reloc() +{ + # Extract symbol and offset from the objdump output + eval $(echo $reloc | sed 's/\([^+]\+\)+\?\(0x[0-9a-f]\+\)\?/symbol="\1"; symbol_offset="\2"/') + + # When the relocation points to the begining of a symbol or section, it + # won't print the offset since it is zero. + if [ -z "${symbol_offset}" ]; then + symbol_offset=0x0 + fi +} + +function find_alt_replacement_target() +{ + # The target of the .altinstr_replacement is the relocation just before + # the .altinstr_replacement one. + eval $(objdump -rj .altinstructions ${obj} | grep -B1 "${section}+${section_offset}" | head -n1 | awk '{print $3}' | + sed 's/\([^+]\+\)+\(0x[0-9a-f]\+\)/alt_target_section="\1"; alt_target_offset="\2"/') +} + +function handle_alt_replacement_reloc() +{ + # This will define alt_target_section and alt_target_section_offset + find_alt_replacement_target ${section} ${section_offset} + + echo "Error: found a reference to .altinstr_replacement in __ex_table:" + addr2line -fip -j ${alt_target_section} -e ${obj} ${alt_target_offset} | awk '{print "\t" $0}' + + error=true +} + +function is_executable_section() +{ + objdump -hwj ${section} ${obj} | grep -q CODE + return $? +} + +function handle_suspicious_generic_reloc() +{ + if is_executable_section ${section}; then + # We've got a relocation to a non white listed _executable_ + # section, print a warning so the developper adds the section to + # the white list or fix his code. We try to pretty-print the file + # and line number where that relocation was added. + echo "Warning: found a reference to section \"${section}\" in __ex_table:" + addr2line -fip -j ${section} -e ${obj} ${section_offset} | awk '{print "\t" $0}' + else + # Something is definitively wrong here since we've got a relocation + # to a non-executable section, there's no way this would ever be + # running in the kernel. + echo "Error: found a reference to non-executable section \"${section}\" in __ex_table at offset ${section_offset}" + error=true + fi +} + +function handle_suspicious_reloc() +{ + case "${section}" in + ".altinstr_replacement") + handle_alt_replacement_reloc ${section} ${section_offset} + ;; + *) + handle_suspicious_generic_reloc ${section} ${section_offset} + ;; + esac +} + +function diagnose() +{ + + for reloc in ${suspicious_relocs}; do + # Let's find out where the target of the relocation in __ex_table + # is, this will define ${symbol} and ${symbol_offset} + find_symbol_and_offset_from_reloc ${reloc} + + # When there's a global symbol at the place of the relocation, + # objdump will use it instead of giving us a section+offset, so + # let's find out which section is this symbol in and the total + # offset withing that section. + find_section_offset_from_symbol ${symbol} ${symbol_offset} + + # In this case objdump was presenting us with a reloc to a symbol + # rather than a section. Now that we've got the actual section, + # we can skip it if it's in the white_list. + if [ -z "$( echo $section | grep -v $(eval echo -e{${white_list}}))" ]; then + continue; + fi + + # Will either print a warning if the relocation happens to be in a + # section we do not know but has executable bit set, or error out. + handle_suspicious_reloc + done +} + +function check_debug_info() { + objdump -hj .debug_info ${obj} 2> /dev/null > /dev/null || + echo -e "${obj} does not contain debug information, the addr2line output will be limited.\n" \ + "Recompile ${obj} with CONFIG_DEBUG_INFO to get a more useful output." +} + +check_debug_info + +diagnose + +if [ "${error}" ]; then + exit 1 +fi + +exit 0 -- cgit v1.2.3 From 52dc0595d540155436d91811f929bdc8afd6a2a1 Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Mon, 13 Apr 2015 20:52:53 +0930 Subject: modpost: handle relocations mismatch in __ex_table. __ex_table is a simple table section where each entry is a pair of addresses - the first address is an address which can fault in kernel space, and the second address points to where the kernel should jump to when handling that fault. This is how copy_from_user() does not crash the kernel if userspace gives a borked pointer for example. If one of these addresses point to a non-executable section, something is seriously wrong since it either means the kernel will never fault from there or it will not be able to jump to there. As both cases are serious enough, we simply error out in these cases so the build fails and the developper has to fix the issue. In case the section is executable, but it isn't referenced in our list of authorized sections to point to from __ex_table, we just dump a warning giving more information about it. We do this in case the new section is executable but isn't supposed to be executed by the kernel. This happened with .altinstr_replacement, which is executable but is only used to copy instructions from - we should never have our instruction pointer pointing in .altinstr_replacement. Admitedly, a proper fix in that case would be to just set .altinstr_replacement NX, but we need to warn about future cases like this. Signed-off-by: Quentin Casasnovas Signed-off-by: Rusty Russell (added long casts) --- scripts/mod/modpost.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index bf0cf8173beb..e95aa28ce0f7 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -875,6 +875,8 @@ static void check_section(const char *modname, struct elf_info *elf, #define DATA_SECTIONS ".data", ".data.rel" #define TEXT_SECTIONS ".text", ".text.unlikely", ".sched.text", \ ".kprobes.text" +#define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \ + ".fixup", ".entry.text" #define INIT_SECTIONS ".init.*" #define MEM_INIT_SECTIONS ".meminit.*" @@ -882,6 +884,9 @@ static void check_section(const char *modname, struct elf_info *elf, #define EXIT_SECTIONS ".exit.*" #define MEM_EXIT_SECTIONS ".memexit.*" +#define ALL_TEXT_SECTIONS ALL_INIT_TEXT_SECTIONS, ALL_EXIT_TEXT_SECTIONS, \ + TEXT_SECTIONS, OTHER_TEXT_SECTIONS + /* init data sections */ static const char *const init_data_sections[] = { ALL_INIT_DATA_SECTIONS, NULL }; @@ -922,6 +927,7 @@ enum mismatch { ANY_INIT_TO_ANY_EXIT, ANY_EXIT_TO_ANY_INIT, EXPORT_TO_INIT_EXIT, + EXTABLE_TO_NON_TEXT, }; struct sectioncheck { @@ -936,6 +942,11 @@ struct sectioncheck { }; +static void extable_mismatch_handler(const char *modname, struct elf_info *elf, + const struct sectioncheck* const mismatch, + Elf_Rela *r, Elf_Sym *sym, + const char *fromsec); + static const struct sectioncheck sectioncheck[] = { /* Do not reference init/exit code/data from * normal code and data @@ -1013,6 +1024,16 @@ static const struct sectioncheck sectioncheck[] = { .bad_tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL }, .mismatch = EXPORT_TO_INIT_EXIT, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, +}, +{ + .fromsec = { "__ex_table", NULL }, + /* If you're adding any new black-listed sections in here, consider + * adding a special 'printer' for them in scripts/check_extable. + */ + .bad_tosec = { ".altinstr_replacement", NULL }, + .good_tosec = {ALL_TEXT_SECTIONS , NULL}, + .mismatch = EXTABLE_TO_NON_TEXT, + .handler = extable_mismatch_handler, } }; @@ -1418,6 +1439,10 @@ static void report_sec_mismatch(const char *modname, tosym, prl_to, prl_to, tosym); free(prl_to); break; + case EXTABLE_TO_NON_TEXT: + fatal("There's a special handler for this mismatch type, " + "we should never get here."); + break; } fprintf(stderr, "\n"); } @@ -1453,6 +1478,120 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, } } +static int is_executable_section(struct elf_info* elf, unsigned int section_index) +{ + if (section_index > elf->num_sections) + fatal("section_index is outside elf->num_sections!\n"); + + return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR); +} + +/* + * We rely on a gross hack in section_rel[a]() calling find_extable_entry_size() + * to know the sizeof(struct exception_table_entry) for the target architecture. + */ +static unsigned int extable_entry_size = 0; +static void find_extable_entry_size(const char* const sec, const Elf_Rela* r, + const void* start, const void* cur) +{ + /* + * If we're currently checking the second relocation within __ex_table, + * that relocation offset tells us the offsetof(struct + * exception_table_entry, fixup) which is equal to sizeof(struct + * exception_table_entry) divided by two. We use that to our advantage + * since there's no portable way to get that size as every architecture + * seems to go with different sized types. Not pretty but better than + * hard-coding the size for every architecture.. + */ + if (!extable_entry_size && cur == start + 1 && + strcmp("__ex_table", sec) == 0) + extable_entry_size = r->r_offset * 2; +} +static inline bool is_extable_fault_address(Elf_Rela *r) +{ + if (!extable_entry_size == 0) + fatal("extable_entry size hasn't been discovered!\n"); + + return ((r->r_offset == 0) || + (r->r_offset % extable_entry_size == 0)); +} + +static void report_extable_warnings(const char* modname, struct elf_info* elf, + const struct sectioncheck* const mismatch, + Elf_Rela* r, Elf_Sym* sym, + const char* fromsec, const char* tosec) +{ + Elf_Sym* fromsym = find_elf_symbol2(elf, r->r_offset, fromsec); + const char* fromsym_name = sym_name(elf, fromsym); + Elf_Sym* tosym = find_elf_symbol(elf, r->r_addend, sym); + const char* tosym_name = sym_name(elf, tosym); + const char* from_pretty_name; + const char* from_pretty_name_p; + const char* to_pretty_name; + const char* to_pretty_name_p; + + get_pretty_name(is_function(fromsym), + &from_pretty_name, &from_pretty_name_p); + get_pretty_name(is_function(tosym), + &to_pretty_name, &to_pretty_name_p); + + warn("%s(%s+0x%lx): Section mismatch in reference" + " from the %s %s%s to the %s %s:%s%s\n", + modname, fromsec, (long)r->r_offset, from_pretty_name, + fromsym_name, from_pretty_name_p, + to_pretty_name, tosec, tosym_name, to_pretty_name_p); + + if (!match(tosec, mismatch->bad_tosec) && + is_executable_section(elf, get_secindex(elf, sym))) + fprintf(stderr, + "The relocation at %s+0x%lx references\n" + "section \"%s\" which is not in the list of\n" + "authorized sections. If you're adding a new section\n" + "and/or if this reference is valid, add \"%s\" to the\n" + "list of authorized sections to jump to on fault.\n" + "This can be achieved by adding \"%s\" to \n" + "OTHER_TEXT_SECTIONS in scripts/mod/modpost.c.\n", + fromsec, (long)r->r_offset, tosec, tosec, tosec); +} + +static void extable_mismatch_handler(const char* modname, struct elf_info *elf, + const struct sectioncheck* const mismatch, + Elf_Rela* r, Elf_Sym* sym, + const char *fromsec) +{ + const char* tosec = sec_name(elf, get_secindex(elf, sym)); + + sec_mismatch_count++; + + if (sec_mismatch_verbose) + report_extable_warnings(modname, elf, mismatch, r, sym, + fromsec, tosec); + + if (match(tosec, mismatch->bad_tosec)) + fatal("The relocation at %s+0x%lx references\n" + "section \"%s\" which is black-listed.\n" + "Something is seriously wrong and should be fixed.\n" + "You might get more information about where this is\n" + "coming from by using scripts/check_extable.sh %s\n", + fromsec, (long)r->r_offset, tosec, modname); + else if (!is_executable_section(elf, get_secindex(elf, sym))) { + if (is_extable_fault_address(r)) + fatal("The relocation at %s+0x%lx references\n" + "section \"%s\" which is not executable, IOW\n" + "it is not possible for the kernel to fault\n" + "at that address. Something is seriously wrong\n" + "and should be fixed.\n", + fromsec, (long)r->r_offset, tosec); + else + fatal("The relocation at %s+0x%lx references\n" + "section \"%s\" which is not executable, IOW\n" + "the kernel will fault if it ever tries to\n" + "jump to it. Something is seriously wrong\n" + "and should be fixed.\n", + fromsec, (long)r->r_offset, tosec); + } +} + static void check_section_mismatch(const char *modname, struct elf_info *elf, Elf_Rela *r, Elf_Sym *sym, const char *fromsec) { @@ -1605,6 +1744,7 @@ static void section_rela(const char *modname, struct elf_info *elf, /* Skip special sections */ if (is_shndx_special(sym->st_shndx)) continue; + find_extable_entry_size(fromsec, &r, start, rela); check_section_mismatch(modname, elf, &r, sym, fromsec); } } @@ -1663,6 +1803,7 @@ static void section_rel(const char *modname, struct elf_info *elf, /* Skip special sections */ if (is_shndx_special(sym->st_shndx)) continue; + find_extable_entry_size(fromsec, &r, start, rel); check_section_mismatch(modname, elf, &r, sym, fromsec); } } -- cgit v1.2.3 From e5d8f59a5cfa76ab5ebe47622d0c569eddd42fbe Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Mon, 13 Apr 2015 20:55:15 +0930 Subject: modpost: document the use of struct section_check. struct section_check is used as a generic way of describing what relocations are authorized/forbidden when running modpost. This commit tries to describe how each field is used. Signed-off-by: Quentin Casasnovas Signed-off-by: Rusty Russell (Fixed "mist"ake) --- scripts/mod/modpost.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index e95aa28ce0f7..cbd53e08769d 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -930,6 +930,26 @@ enum mismatch { EXTABLE_TO_NON_TEXT, }; +/** + * Describe how to match sections on different criterias: + * + * @fromsec: Array of sections to be matched. + * + * @bad_tosec: Relocations applied to a section in @fromsec to a section in + * this array is forbidden (black-list). Can be empty. + * + * @good_tosec: Relocations applied to a section in @fromsec must be + * targetting sections in this array (white-list). Can be empty. + * + * @mismatch: Type of mismatch. + * + * @symbol_white_list: Do not match a relocation to a symbol in this list + * even if it is targetting a section in @bad_to_sec. + * + * @handler: Specific handler to call when a match is found. If NULL, + * default_mismatch_handler() will be called. + * + */ struct sectioncheck { const char *fromsec[20]; const char *bad_tosec[20]; -- cgit v1.2.3 From 5017335d6d8c1fc3bbc04f80785440885f305879 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Tue, 14 Apr 2015 15:42:34 -0700 Subject: scripts/coccinelle/misc/bugon.cocci: update bug_on conversion warning if()/BUG conversion to BUG_ON must be avoided when there's side effect in condition. The reason being BUG_ON won't execute the condition when CONFIG_BUG is not defined. With inspiration from Bruce Fields. Signed-off-by: Fabian Frederick Suggested-by: Julia Lawall Acked-by: Julia Lawall Cc: J. Bruce Fields Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/coccinelle/misc/bugon.cocci | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/coccinelle/misc/bugon.cocci b/scripts/coccinelle/misc/bugon.cocci index 3b7eec24fb5a..27c97f1f2767 100644 --- a/scripts/coccinelle/misc/bugon.cocci +++ b/scripts/coccinelle/misc/bugon.cocci @@ -57,6 +57,6 @@ coccilib.org.print_todo(p[0], "WARNING use BUG_ON") p << r.p; @@ -msg="WARNING: Use BUG_ON" +msg="WARNING: Use BUG_ON instead of if condition followed by BUG.\nPlease make sure the condition has no side effects (see conditional BUG_ON definition in include/asm-generic/bug.h)" coccilib.report.print_report(p[0], msg) -- cgit v1.2.3 From 99b2cdde83726a89daadbfd1264fb9a3b91eed0b Mon Sep 17 00:00:00 2001 From: Alex Pilon Date: Tue, 14 Apr 2015 00:38:33 -0400 Subject: scripts/extract-ikconfig: Support LZ4-compressed images. Support for kernel image LZ4 compression was added around 3.11, but not the corresponding kernel .config extraction. This makes possible extracting the kernel config for LZ4-compressed kernels you're not running, or the current LZ4-compressed kernel if compiled without /proc/config.gz support. Signed-off-by: Alex Pilon Signed-off-by: Michal Marek --- scripts/extract-ikconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/extract-ikconfig b/scripts/extract-ikconfig index e1862429ccda..3b42f255e2ba 100755 --- a/scripts/extract-ikconfig +++ b/scripts/extract-ikconfig @@ -61,6 +61,7 @@ try_decompress '\3757zXZ\000' abcde unxz try_decompress 'BZh' xy bunzip2 try_decompress '\135\0\0\0' xxx unlzma try_decompress '\211\114\132' xy 'lzop -d' +try_decompress '\002\041\114\030' xyy 'lz4 -d -l' # Bail out: echo "$me: Cannot find kernel config." >&2 -- cgit v1.2.3 From 33236415ece63d5689411f3ddb676eeb93af2698 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Thu, 9 Apr 2015 22:58:04 +0200 Subject: scripts/coccinelle/misc/bugon.cocci: update bug_on conversion warning if()/BUG conversion to BUG_ON must be avoided when there's side effect in condition. The reason being BUG_ON won't execute the condition when CONFIG_BUG is not defined. Inspired-by: J. Bruce Fields Suggested-by: Julia Lawall Acked-by: Julia Lawall Signed-off-by: Fabian Frederick Signed-off-by: Michal Marek --- scripts/coccinelle/misc/bugon.cocci | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/coccinelle/misc/bugon.cocci b/scripts/coccinelle/misc/bugon.cocci index 3b7eec24fb5a..27c97f1f2767 100644 --- a/scripts/coccinelle/misc/bugon.cocci +++ b/scripts/coccinelle/misc/bugon.cocci @@ -57,6 +57,6 @@ coccilib.org.print_todo(p[0], "WARNING use BUG_ON") p << r.p; @@ -msg="WARNING: Use BUG_ON" +msg="WARNING: Use BUG_ON instead of if condition followed by BUG.\nPlease make sure the condition has no side effects (see conditional BUG_ON definition in include/asm-generic/bug.h)" coccilib.report.print_report(p[0], msg) -- cgit v1.2.3 From 6ab3a9701e00c2a085bac6a7a9bdcf8fc5eca6c5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 16 Apr 2015 12:44:05 -0700 Subject: checkpatch: improve "no space is necessary after a cast" test The "no space is necessary after a cast" sizeof exclusion doesn't work properly. The test reports a false positive for code like: BUILD_BUG_ON(sizeof(struct batadv_bla_claim_dst) != 6); Make it work, simplify the exclusions, and add some comments. Signed-off-by: Joe Perches Reported-by: Marek Lindner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index d12435992dea..421bbb47844f 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2552,8 +2552,15 @@ sub process { } } - if ($line =~ /^\+.*(\w+\s*)?\(\s*$Type\s*\)[ \t]+(?!$Assignment|$Arithmetic|[,;:\?\(\{\}\[\<\>]|&&|\|\||\\$)/ && - (!defined($1) || $1 !~ /sizeof\s*/)) { +# check for space after cast like "(int) foo" or "(struct foo) bar" +# avoid checking a few false positives: +# "sizeof()" or "__alignof__()" +# function pointer declarations like "(*foo)(int) = bar;" +# structure definitions like "(struct foo) { 0 };" +# multiline macros that define functions +# known attributes or the __attribute__ keyword + if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && + (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { if (CHK("SPACING", "No space is necessary after a cast\n" . $herecurr) && $fix) { -- cgit v1.2.3 From 66d7a382cb5d2d40b468e68b665bbf6f9bc3400e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 16 Apr 2015 12:44:08 -0700 Subject: checkpatch: add spell checking of email subject line Only commit log and patch additions are checked for typos and spelling errors currently. Add a check of the email subject line too. Signed-off-by: Joe Perches Suggested-by: Jani Nikula Tested-by: Jani Nikula Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 421bbb47844f..c061a63afa20 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2303,7 +2303,8 @@ sub process { } # Check for various typo / spelling mistakes - if (defined($misspellings) && ($in_commit_log || $line =~ /^\+/)) { + if (defined($misspellings) && + ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:$|[^a-z@])/gi) { my $typo = $1; my $typo_fix = $spelling_fix{lc($typo)}; -- cgit v1.2.3 From b3e9a677fc0875c7cc26d4edf6742a1436e86c52 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 16 Apr 2015 12:44:11 -0700 Subject: checkpatch: spell check reudce References: http://mid.gmane.org/1424977312-24902-1-git-send-email-ville.syrjala@linux.intel.com Signed-off-by: Jani Nikula Cc: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/spelling.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/spelling.txt b/scripts/spelling.txt index fc7fd52b5e03..bb8e4d0a1911 100644 --- a/scripts/spelling.txt +++ b/scripts/spelling.txt @@ -825,6 +825,7 @@ retreived||retrieved retreive||retrieve retrive||retrieve retuned||returned +reudce||reduce reuest||request reuqest||request reutnred||returned -- cgit v1.2.3 From ebfd7d62375316ff532b6b9bae9d88a29f434ba7 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 16 Apr 2015 12:44:14 -0700 Subject: checkpatch: add optional --codespell dictionary to find more typos If a codespell dictionary exists, use it if desired. default is off, maybe it could be turned on later. codespell's dictionary format allows multiple possible corrections, ignore that for now and only use the first suggestion. Also add \b to spelling test so that consecutive misspelled words are found properly. Signed-off-by: Joe Perches Cc: Andy Whitcroft Cc: Kees Cook Cc: Masanari Iida Cc: Lucas De Marchi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index c061a63afa20..6b79beb2751d 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -47,6 +47,8 @@ my $ignore_perl_version = 0; my $minimum_perl_version = 5.10.0; my $min_conf_desc_length = 4; my $spelling_file = "$D/spelling.txt"; +my $codespell = 0; +my $codespellfile = "/usr/local/share/codespell/dictionary.txt"; sub help { my ($exitcode) = @_; @@ -88,6 +90,9 @@ Options: file. It's your fault if there's no backup or git --ignore-perl-version override checking of perl version. expect runtime errors. + --codespell Use the codespell dictionary for spelling/typos + (default:/usr/local/share/codespell/dictionary.txt) + --codespellfile Use this codespell dictionary -h, --help, --version display this help and exit When FILE is - read standard input. @@ -146,6 +151,8 @@ GetOptions( 'ignore-perl-version!' => \$ignore_perl_version, 'debug=s' => \%debug, 'test-only=s' => \$tst_only, + 'codespell!' => \$codespell, + 'codespellfile=s' => \$codespellfile, 'h|help' => \$help, 'version' => \$help ) or help(1); @@ -449,7 +456,6 @@ my $misspellings; my %spelling_fix; if (open(my $spelling, '<', $spelling_file)) { - my @spelling_list; while (<$spelling>) { my $line = $_; @@ -461,15 +467,39 @@ if (open(my $spelling, '<', $spelling_file)) { my ($suspect, $fix) = split(/\|\|/, $line); - push(@spelling_list, $suspect); $spelling_fix{$suspect} = $fix; } close($spelling); - $misspellings = join("|", @spelling_list); } else { warn "No typos will be found - file '$spelling_file': $!\n"; } +if ($codespell) { + if (open(my $spelling, '<', $codespellfile)) { + while (<$spelling>) { + my $line = $_; + + $line =~ s/\s*\n?$//g; + $line =~ s/^\s*//g; + + next if ($line =~ m/^\s*#/); + next if ($line =~ m/^\s*$/); + next if ($line =~ m/, disabled/i); + + $line =~ s/,.*$//; + + my ($suspect, $fix) = split(/->/, $line); + + $spelling_fix{$suspect} = $fix; + } + close($spelling); + } else { + warn "No codespell typos will be found - file '$codespellfile': $!\n"; + } +} + +$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; + sub build_types { my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)"; my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)"; @@ -2305,7 +2335,7 @@ sub process { # Check for various typo / spelling mistakes if (defined($misspellings) && ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { - while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:$|[^a-z@])/gi) { + while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) { my $typo = $1; my $typo_fix = $spelling_fix{lc($typo)}; $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); -- cgit v1.2.3 From b392c64f59d7b088aefb4e86d208cd6d3b93eefb Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 16 Apr 2015 12:44:16 -0700 Subject: checkpatch: match more world writable permissions Currently checkpatch will fuss if one uses world writable settings in debugfs files and DEVICE_ATTR uses by testing S_IWUGO but not testing S_IWOTH, S_IRWXUGO or S_IALLUGO. Extend the check to catch all cases exporting world writable permissions including octal values. [akpm@linux-foundation.org: remove stray $] Signed-off-by: Joe Perches Original-patch-by: Nicholas Mc Guire Cc: Guenter Roeck Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 6b79beb2751d..5748c35d0342 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -443,6 +443,14 @@ foreach my $entry (@mode_permission_funcs) { $mode_perms_search .= $entry->[0]; } +our $mode_perms_world_writable = qr{ + S_IWUGO | + S_IWOTH | + S_IRWXUGO | + S_IALLUGO | + 0[0-7][0-7][2367] +}x; + our $allowed_asm_includes = qr{(?x: irq| memory| @@ -5356,8 +5364,8 @@ sub process { } } - if ($line =~ /debugfs_create_file.*S_IWUGO/ || - $line =~ /DEVICE_ATTR.*S_IWUGO/ ) { + if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || + $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { WARN("EXPORTED_WORLD_WRITABLE", "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); } -- cgit v1.2.3 From f34e4a4f979c0d39f741bc809127fcf2167a7389 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 16 Apr 2015 12:44:19 -0700 Subject: checkpatch: improve return negative errno check Add a few conditions to the test to find return (ERRNO); Make the output message a bit less cryptic too. Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 5748c35d0342..45babf2243f3 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -4009,12 +4009,12 @@ sub process { } } -# Return of what appears to be an errno should normally be -'ve - if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) { +# Return of what appears to be an errno should normally be negative + if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { my $name = $1; if ($name ne 'EOF' && $name ne 'ERROR') { WARN("USE_NEGATIVE_ERRNO", - "return of an errno should typically be -ve (return -$1)\n" . $herecurr); + "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); } } -- cgit v1.2.3 From ab7e23f3448e55f4808f443a7b98ded6707701bb Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 16 Apr 2015 12:44:22 -0700 Subject: checkpatch: add test for repeated const uses Using 'const const *' is generally meant to be written 'const * const'. Add a test for the miswritten form. Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 45babf2243f3..d54a814a4bc8 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -323,6 +323,7 @@ our $Operators = qr{ our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; +our $BasicType; our $NonptrType; our $NonptrTypeMisordered; our $NonptrTypeWithAttr; @@ -514,6 +515,11 @@ sub build_types { my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; + $BasicType = qr{ + (?:$typeOtherOSTypedefs\b)| + (?:$typeTypedefs\b)| + (?:${all}\b) + }x; $NonptrType = qr{ (?:$Modifier\s+|const\s+)* (?: @@ -3192,6 +3198,18 @@ sub process { $herecurr); } +# check for const const where is not a pointer or array type + if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { + my $found = $1; + if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { + WARN("CONST_CONST", + "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); + } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { + WARN("CONST_CONST", + "'const $found const' should probably be 'const $found'\n" . $herecurr); + } + } + # check for non-global char *foo[] = {"bar", ...} declarations. if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { WARN("STATIC_CONST_CHAR_ARRAY", -- cgit v1.2.3 From 0e212e0a720601fabda102f7998d27625f9e144a Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Thu, 16 Apr 2015 12:44:25 -0700 Subject: checkpatch: don't ask for asm/file.h to linux/file.h unconditionally Currently checkpatch warns when asm/file.h is included and linux/file.h exists. That conversion can be made when linux/file.h includes asm/file.h which is not always the case.(See signal.h) Signed-off-by: Fabian Frederick Cc: Andy Whitcroft Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index d54a814a4bc8..c72e7ee1000b 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -4242,7 +4242,8 @@ sub process { } } -#warn if is #included and is available (uses RAW line) +# warn if is #included and is available and includes +# itself (uses RAW line) if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\}) { my $file = "$1.h"; my $checkfile = "include/linux/$file"; @@ -4250,12 +4251,15 @@ sub process { $realfile ne $checkfile && $1 !~ /$allowed_asm_includes/) { - if ($realfile =~ m{^arch/}) { - CHK("ARCH_INCLUDE_LINUX", - "Consider using #include instead of \n" . $herecurr); - } else { - WARN("INCLUDE_LINUX", - "Use #include instead of \n" . $herecurr); + my $asminclude = `grep -Ec "#include\\s+" $root/$checkfile`; + if ($asminclude > 0) { + if ($realfile =~ m{^arch/}) { + CHK("ARCH_INCLUDE_LINUX", + "Consider using #include instead of \n" . $herecurr); + } else { + WARN("INCLUDE_LINUX", + "Use #include instead of \n" . $herecurr); + } } } } -- cgit v1.2.3 From 2a076f40d8c9be95bee7bcf18436655e1140447f Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 16 Apr 2015 12:44:28 -0700 Subject: checkpatch, SubmittingPatches: suggest line wrapping commit messages at 75 columns Commit messages lines are sometimes overly long. Suggest line wrapping at 75 columns so the default git commit log indentation of 4 plus the commit message text still fits on an 80 column screen. Add a checkpatch test for long commit messages lines too. Signed-off-by: Joe Perches Cc: David Miller Cc: Jonathan Corbet Cc: Ian Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index c72e7ee1000b..9a8b2bd14dc2 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1898,6 +1898,7 @@ sub process { my $in_header_lines = $file ? 0 : 1; my $in_commit_log = 0; #Scanning lines before patch + my $commit_log_long_line = 0; my $reported_maintainer_file = 0; my $non_utf8_charset = 0; @@ -2233,6 +2234,14 @@ sub process { "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr); } +# Check for line lengths > 75 in commit log, warn once + if ($in_commit_log && !$commit_log_long_line && + length($line) > 75) { + WARN("COMMIT_LOG_LONG_LINE", + "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); + $commit_log_long_line = 1; + } + # Check for git id commit length and improperly formed commit descriptions if ($in_commit_log && $line =~ /\b(c)ommit\s+([0-9a-f]{5,})/i) { my $init_char = $1; -- cgit v1.2.3 From 29a3c46673a5e3ee22feaba7020a280486c78f0a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 16 Apr 2015 12:44:30 -0700 Subject: checkpatch: add #define foo "string" long line exception There are #defines with long string constants like: #define foo "some really long string > 80 columns" Add a long line exception for them. Miscellanea: Use the $String variable for slightly better readability Signed-off-by: Joe Perches Reported-by: Madalin-Cristian Bucur Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 9a8b2bd14dc2..36d7e704af8f 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2513,8 +2513,9 @@ sub process { #line length limit if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && $rawline !~ /^.\s*\*\s*\@$Ident\s/ && - !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ || - $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) && + !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?$String\s*(?:|,|\)\s*;)\s*$/ || + $line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || + $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) && $length > $max_line_length) { WARN("LONG_LINE", -- cgit v1.2.3 From 6d07d01b62b2d81500803058f736b46677ec873a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 16 Apr 2015 12:44:33 -0700 Subject: checkpatch: add uart_ops to normally const structs Add another struct to the list of normally const struct types Signed-off-by: Joe Perches Cc: Andy Whitcroft Cc: Maxime Coquelin Cc: Greg Kroah-Hartman Cc: Jiri Slaby Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 36d7e704af8f..ea628ebfa20e 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -5339,6 +5339,7 @@ sub process { stacktrace_ops| sysfs_ops| tty_operations| + uart_ops| usb_mon_operations| wd_ops}x; if ($line !~ /\bconst\b/ && -- cgit v1.2.3 From b598b67060f14eb8c34d0cef1db4727dab56ef91 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 16 Apr 2015 12:44:36 -0700 Subject: checkpatch: add 'Prefer ARRAY_SIZE" test Add a test for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo). Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index ea628ebfa20e..6c11cb61e9f4 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3227,6 +3227,19 @@ sub process { $herecurr); } +# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) + if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { + my $array = $1; + if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) { + my $array_div = $1; + if (WARN("ARRAY_SIZE", + "Prefer ARRAY_SIZE($array)\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; + } + } + } + # check for function declarations without arguments like "int foo()" if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) { if (ERROR("FUNCTION_WITHOUT_ARGS", -- cgit v1.2.3 From d7fe8065ad891a2ad38b73ff10b97d08f0fb3b0b Mon Sep 17 00:00:00 2001 From: Sam Bobroff Date: Thu, 16 Apr 2015 12:44:39 -0700 Subject: checkpatch: improve operator spacing check Code such as: x = timercmp(&now, &end, <); Will currently trigger a checkpatch error. e.g. ERROR: spaces required around that '<' This is because the "Ignore operators passed as parameters" check looks only for a comma following the operator. Improve the check by also looking for a close parenthesis. Signed-off-by: Sam Bobroff Cc: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 6c11cb61e9f4..78a951f80706 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3652,7 +3652,7 @@ sub process { # Ignore operators passed as parameters. if ($op_type ne 'V' && - $ca =~ /\s$/ && $cc =~ /^\s*,/) { + $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { # # Ignore comments # } elsif ($op =~ /^$;+$/) { -- cgit v1.2.3 From c17893c7407fbe988f5901596c3e5e75c0dc0f67 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 16 Apr 2015 12:44:42 -0700 Subject: checkpatch: add a test for const with __read_mostly uses const objects shouldn't be __read_mostly. They are read-only. Marking these objects as __read_mostly causes section conflicts with LTO linking. So add a test to try to avoid this issue. Signed-off-by: Joe Perches Cc: Andy Whitcroft Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 78a951f80706..28516587baba 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -4791,6 +4791,16 @@ sub process { } } +# check for __read_mostly with const non-pointer (should just be const) + if ($line =~ /\b__read_mostly\b/ && + $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { + if (ERROR("CONST_READ_MOSTLY", + "Invalid use of __read_mostly with const type\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; + } + } + # don't use __constant_ functions outside of include/uapi/ if ($realfile !~ m@^include/uapi/@ && $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { -- cgit v1.2.3 From 91c9afaf97ee554d2cd3042a5ad01ad21c99e8c4 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 16 Apr 2015 12:44:44 -0700 Subject: checkpatch.pl: new instances of ENOSYS are errors ENOSYS means that a nonexistent system call was called. We have a bad habit of using it for things like invalid operations on otherwise valid syscalls. We should avoid this in new code. Pervasive incorrect usage of ENOSYS came up at the kernel summit ABI review discussion. Let's see if checkpatch can help. I'll submit a separate patch for include/uapi/asm-generic/errno.h. Signed-off-by: Andy Lutomirski Cc: Pavel Machek Cc: Michael Kerrisk Cc: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 28516587baba..561f41ef531f 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3396,6 +3396,14 @@ sub process { "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); } +# ENOSYS means "bad syscall nr" and nothing else. This will have a small +# number of false positives, but assembly files are not checked, so at +# least the arch entry code will not trigger this warning. + if ($line =~ /\bENOSYS\b/) { + WARN("ENOSYS", + "ENOSYS means 'invalid syscall nr' and nothing else\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 -- cgit v1.2.3 From 323b267faff4db5f2424b6c09ab78a272393b69e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 16 Apr 2015 12:44:50 -0700 Subject: checkpatch: fix --fix use with a patch of multiple files If a patch touches multiple files, the --fix and --fix-inplace option doesn't keep the proper line count and makes the new patch file not able to be applied via bad offset line numbers when lines are added or deleted by the --fix option. Dunno how that extra backslash snuck in there. Signed-off-by: Joe Perches Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 561f41ef531f..35aecb3b013c 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1690,7 +1690,7 @@ sub fix_inserted_deleted_lines { foreach my $old_line (@{$linesRef}) { my $save_line = 1; my $line = $old_line; #don't modify the array - if ($line =~ /^(?:\+\+\+\|\-\-\-)\s+\S+/) { #new filename + if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename $delta_offset = 0; } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk $range_last_linenr = $new_linenr; -- cgit v1.2.3 From e0df7e1faebad9a7ac0931d03f86fcd5c0d1896e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 16 Apr 2015 12:44:53 -0700 Subject: checkpatch: avoid "spaces required around that ':'" false positive Since commit 1f65f947a6a8 ("checkpatch: add checks for question mark and colon spacing") back in 2008, checkpatch has reported false positive for asm volatile uses of "::" checkpatch thinks colons should always have spaces around it. Add an exception for colons with colons on either side for this valid asm volatile (and c++) use. Signed-off-by: Joe Perches Reported-by: Yehuda Yitschak Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 35aecb3b013c..89b1df4e72ab 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3845,6 +3845,14 @@ sub process { $ok = 1; } + # for asm volatile statements + # ignore a colon with another + # colon immediately before or after + if (($op eq ':') && + ($ca =~ /:$/ || $cc =~ /^:/)) { + $ok = 1; + } + # messages are ERROR, but ?: are CHK if ($ok == 0) { my $msg_type = \&ERROR; -- cgit v1.2.3 From 6e54abac1b8e0b7febffdbad37b605daef1cfcff Mon Sep 17 00:00:00 2001 From: Andrey Ryabinin Date: Thu, 16 Apr 2015 12:44:58 -0700 Subject: kasan: Makefile: shut up warnings if CONFIG_COMPILE_TEST=y It might be annoying to constantly see this: scripts/Makefile.kasan:16: Cannot use CONFIG_KASAN: -fsanitize=kernel-address is not supported by compiler while performing allmodconfig/allyesconfig build tests. Disable this warning if CONFIG_COMPILE_TEST=y. Signed-off-by: Andrey Ryabinin Cc: Michal Marek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/Makefile.kasan | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan index 631619b2b118..3f874d24234f 100644 --- a/scripts/Makefile.kasan +++ b/scripts/Makefile.kasan @@ -13,12 +13,16 @@ CFLAGS_KASAN := $(call cc-option, -fsanitize=kernel-address \ --param asan-instrumentation-with-call-threshold=$(call_threshold)) ifeq ($(call cc-option, $(CFLAGS_KASAN_MINIMAL) -Werror),) + ifneq ($(CONFIG_COMPILE_TEST),y) $(warning Cannot use CONFIG_KASAN: \ -fsanitize=kernel-address is not supported by compiler) + endif else ifeq ($(CFLAGS_KASAN),) - $(warning CONFIG_KASAN: compiler does not support all options.\ - Trying minimal configuration) + ifneq ($(CONFIG_COMPILE_TEST),y) + $(warning CONFIG_KASAN: compiler does not support all options.\ + Trying minimal configuration) + endif CFLAGS_KASAN := $(CFLAGS_KASAN_MINIMAL) endif endif -- cgit v1.2.3 From d7e0abcf4c6d9fc4ebb948c9bbc880b2483434b4 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 15 Apr 2015 13:23:48 +0930 Subject: modpost: Whitelist .text.fixup and .exception.text 32-bit and 64-bit ARM use these sections to store executable code, so they must be whitelisted in modpost's table of valid text sections. Signed-off-by: Thierry Reding Signed-off-by: Rusty Russell --- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index cbd53e08769d..6a925f200b25 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -876,7 +876,7 @@ static void check_section(const char *modname, struct elf_info *elf, #define TEXT_SECTIONS ".text", ".text.unlikely", ".sched.text", \ ".kprobes.text" #define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \ - ".fixup", ".entry.text" + ".fixup", ".entry.text", ".text.fixup", ".exception.text" #define INIT_SECTIONS ".init.*" #define MEM_INIT_SECTIONS ".meminit.*" -- cgit v1.2.3 From 6c730bfc894f5d4989c2c1493512d3330402be94 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 15 Apr 2015 13:28:08 +0930 Subject: modpost: handle -ffunction-sections 52dc0595d540 introduced OTHER_TEXT_SECTIONS for identifying what sections could validly have __ex_table entries. Unfortunately, it wasn't tested with -ffunction-sections, which some architectures use. Reported-by: kbuild test robot Cc: Quentin Casasnovas Signed-off-by: Rusty Russell --- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 6a925f200b25..22dbc604cdb9 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -876,7 +876,7 @@ static void check_section(const char *modname, struct elf_info *elf, #define TEXT_SECTIONS ".text", ".text.unlikely", ".sched.text", \ ".kprobes.text" #define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \ - ".fixup", ".entry.text", ".text.fixup", ".exception.text" + ".fixup", ".entry.text", ".exception.text", ".text.*" #define INIT_SECTIONS ".init.*" #define MEM_INIT_SECTIONS ".meminit.*" -- cgit v1.2.3 From d3df4de7eb095cc4334759a5e65bf3bfb4be04f1 Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Thu, 16 Apr 2015 13:03:32 +0930 Subject: modpost: fix inverted logic in is_extable_fault_address(). As Guenter pointed out, we want to assert that extable_entry_size has been discovered and not the other way around. Moreover, this sanity check is only valid when we're not dealing with the first relocation in __ex_table, since we have not discovered the extable entry size at that point. This was leading to a divide-by-zero on some architectures and make the build fail. Signed-off-by: Quentin Casasnovas Reported-by: Guenter Roeck CC: Rusty Russell Signed-off-by: Rusty Russell --- scripts/mod/modpost.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 22dbc604cdb9..93bb87d0e17d 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1529,7 +1529,12 @@ static void find_extable_entry_size(const char* const sec, const Elf_Rela* r, } static inline bool is_extable_fault_address(Elf_Rela *r) { - if (!extable_entry_size == 0) + /* + * extable_entry_size is only discovered after we've handled the + * _second_ relocation in __ex_table, so only abort when we're not + * handling the first reloc and extable_entry_size is zero. + */ + if (r->r_offset && extable_entry_size == 0) fatal("extable_entry size hasn't been discovered!\n"); return ((r->r_offset == 0) || -- cgit v1.2.3 From e84048aa173f2403fa468cb189f101b57fece539 Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Thu, 16 Apr 2015 13:05:36 +0930 Subject: modpost: fix extable entry size calculation. As Guenter pointed out, we were never really calculating the extable entry size because the pointer arithmetic was simply wrong. We want to check we're handling the second relocation in __ex_table to infer an entry size, but we were using (void*) pointers instead of Elf_Rel[a]* ones. This fixes the problem by moving that check in the caller (since we can deal with different types of relocations) and add is_second_extable_reloc() to make the whole thing more readable. Signed-off-by: Quentin Casasnovas Reported-by: Guenter Roeck CC: Rusty Russell Signed-off-by: Rusty Russell --- scripts/mod/modpost.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 93bb87d0e17d..fd949770da0c 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1511,8 +1511,7 @@ static int is_executable_section(struct elf_info* elf, unsigned int section_inde * to know the sizeof(struct exception_table_entry) for the target architecture. */ static unsigned int extable_entry_size = 0; -static void find_extable_entry_size(const char* const sec, const Elf_Rela* r, - const void* start, const void* cur) +static void find_extable_entry_size(const char* const sec, const Elf_Rela* r) { /* * If we're currently checking the second relocation within __ex_table, @@ -1523,10 +1522,10 @@ static void find_extable_entry_size(const char* const sec, const Elf_Rela* r, * seems to go with different sized types. Not pretty but better than * hard-coding the size for every architecture.. */ - if (!extable_entry_size && cur == start + 1 && - strcmp("__ex_table", sec) == 0) + if (!extable_entry_size) extable_entry_size = r->r_offset * 2; } + static inline bool is_extable_fault_address(Elf_Rela *r) { /* @@ -1541,6 +1540,9 @@ static inline bool is_extable_fault_address(Elf_Rela *r) (r->r_offset % extable_entry_size == 0)); } +#define is_second_extable_reloc(Start, Cur, Sec) \ + (((Cur) == (Start) + 1) && (strcmp("__ex_table", (Sec)) == 0)) + static void report_extable_warnings(const char* modname, struct elf_info* elf, const struct sectioncheck* const mismatch, Elf_Rela* r, Elf_Sym* sym, @@ -1769,7 +1771,8 @@ static void section_rela(const char *modname, struct elf_info *elf, /* Skip special sections */ if (is_shndx_special(sym->st_shndx)) continue; - find_extable_entry_size(fromsec, &r, start, rela); + if (is_second_extable_reloc(start, rela, fromsec)) + find_extable_entry_size(fromsec, &r); check_section_mismatch(modname, elf, &r, sym, fromsec); } } @@ -1828,7 +1831,8 @@ static void section_rel(const char *modname, struct elf_info *elf, /* Skip special sections */ if (is_shndx_special(sym->st_shndx)) continue; - find_extable_entry_size(fromsec, &r, start, rel); + if (is_second_extable_reloc(start, rel, fromsec)) + find_extable_entry_size(fromsec, &r); check_section_mismatch(modname, elf, &r, sym, fromsec); } } -- cgit v1.2.3 From c5c3439af0f9c08e253d2a703a7eb3deba7d8591 Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Thu, 16 Apr 2015 13:16:41 +0930 Subject: modpost: do not try to match the SHT_NUL section. Trying to match the SHT_NUL section isn't useful and causes build failures on parisc and mn10300 since the addition of section strict white-listing and __ex_table sanitizing. Signed-off-by: Quentin Casasnovas Reported-by: Guenter Roeck Fixes: 050e57fd5936 ("modpost: add strict white-listing when referencing....") Fixes: 52dc0595d540 ("modpost: handle relocations mismatch in __ex_table.") Tested-by: Guenter Roeck Signed-off-by: Rusty Russell --- scripts/mod/modpost.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index fd949770da0c..45e4027d3193 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1064,6 +1064,15 @@ static const struct sectioncheck *section_mismatch( int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck); const struct sectioncheck *check = §ioncheck[0]; + /* + * The target section could be the SHT_NUL section when we're + * handling relocations to un-resolved symbols, trying to match it + * doesn't make much sense and causes build failures on parisc and + * mn10300 architectures. + */ + if (*tosec == '\0') + return NULL; + for (i = 0; i < elems; i++) { if (match(fromsec, check->fromsec)) { if (check->bad_tosec[0] && match(tosec, check->bad_tosec)) -- cgit v1.2.3 From 09c20c032b0f753969ae778d9783d946f054d7fe Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Mon, 20 Apr 2015 10:20:26 +0930 Subject: modpost: expand pattern matching to support substring matches Currently the match() function supports a leading * to match any prefix and a trailing * to match any suffix. However there currently is not a combination of both that can be used to target matches of whole families of functions that share a common substring. Here we expand the *foo and foo* match to also support *foo* with the goal of targeting compiler generated symbol names that contain strings like ".constprop." and ".isra." Signed-off-by: Paul Gortmaker Signed-off-by: Rusty Russell --- scripts/mod/modpost.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 45e4027d3193..1c2101bf63d2 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -776,6 +776,7 @@ static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr) * "foo" will match an exact string equal to "foo" * "*foo" will match a string that ends with "foo" * "foo*" will match a string that begins with "foo" + * "*foo*" will match a string that contains "foo" */ static int match(const char *sym, const char * const pat[]) { @@ -784,8 +785,17 @@ static int match(const char *sym, const char * const pat[]) p = *pat++; const char *endp = p + strlen(p) - 1; + /* "*foo*" */ + if (*p == '*' && *endp == '*') { + char *here, *bare = strndup(p + 1, strlen(p) - 2); + + here = strstr(sym, bare); + free(bare); + if (here != NULL) + return 1; + } /* "*foo" */ - if (*p == '*') { + else if (*p == '*') { if (strrcmp(sym, p + 1) == 0) return 1; } -- cgit v1.2.3 From 4a3893d069b788f3570c19c12d9e986e8e15870f Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Mon, 20 Apr 2015 10:20:40 +0930 Subject: modpost: don't emit section mismatch warnings for compiler optimizations Currently an allyesconfig build [gcc-4.9.1] can generate the following: WARNING: vmlinux.o(.text.unlikely+0x3864): Section mismatch in reference from the function cpumask_empty.constprop.3() to the variable .init.data:nmi_ipi_mask which comes from the cpumask_empty usage in arch/x86/kernel/nmi_selftest.c. Normally we would not see a symbol entry for cpumask_empty since it is: static inline bool cpumask_empty(const struct cpumask *srcp) however in this case, the variant of the symbol gets emitted when GCC does constant propagation optimization. Fix things up so that any locally optimized constprop variants don't warn when accessing variables that live in the __init sections. Signed-off-by: Paul Gortmaker Signed-off-by: Rusty Russell --- scripts/mod/modpost.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 1c2101bf63d2..91ee1b2e0f9a 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -908,6 +908,9 @@ static const char *const init_sections[] = { ALL_INIT_SECTIONS, NULL }; static const char *const init_exit_sections[] = {ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL }; +/* all text sections */ +static const char *const text_sections[] = { ALL_TEXT_SECTIONS, NULL }; + /* data section */ static const char *const data_sections[] = { DATA_SECTIONS, NULL }; @@ -926,6 +929,7 @@ static const char *const data_sections[] = { DATA_SECTIONS, NULL }; static const char *const head_sections[] = { ".head.text*", NULL }; static const char *const linker_symbols[] = { "__init_begin", "_sinittext", "_einittext", NULL }; +static const char *const optim_symbols[] = { "*.constprop.*", NULL }; enum mismatch { TEXT_TO_ANY_INIT, @@ -1136,6 +1140,17 @@ static const struct sectioncheck *section_mismatch( * This pattern is identified by * refsymname = __init_begin, _sinittext, _einittext * + * Pattern 5: + * GCC may optimize static inlines when fed constant arg(s) resulting + * in functions like cpumask_empty() -- generating an associated symbol + * cpumask_empty.constprop.3 that appears in the audit. If the const that + * is passed in comes from __init, like say nmi_ipi_mask, we get a + * meaningless section warning. May need to add isra symbols too... + * This pattern is identified by + * tosec = init section + * fromsec = text section + * refsymname = *.constprop.* + * **/ static int secref_whitelist(const struct sectioncheck *mismatch, const char *fromsec, const char *fromsym, @@ -1168,6 +1183,12 @@ static int secref_whitelist(const struct sectioncheck *mismatch, if (match(tosym, linker_symbols)) return 0; + /* Check for pattern 5 */ + if (match(fromsec, text_sections) && + match(tosec, init_sections) && + match(fromsym, optim_symbols)) + return 0; + return 1; } -- cgit v1.2.3