From 6c5e9059692567740a4ee51530dffe51a4b9584d Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Fri, 21 Oct 2016 08:58:50 -0700 Subject: timers: Fix usleep_range() in the context of wake_up_process() Users of usleep_range() expect that it will _never_ return in less time than the minimum passed parameter. However, nothing in the code ensures this, when the sleeping task is woken by wake_up_process() or any other mechanism which can wake a task from uninterruptible state. Neither usleep_range() nor schedule_hrtimeout_range*() have any protection against wakeups. schedule_hrtimeout_range*() is designed this way despite the fact that the API documentation does not mention it. msleep() already has code to handle this case since it will loop as long as there was still time left. usleep_range() has no such loop, add it. Presumably this problem was not detected before because usleep_range() is only used in a few places and the function is mostly used in contexts which are not exposed to wakeups of any form. An effort was made to look for users relying on the old behavior by looking for usleep_range() in the same file as wake_up_process(). No problems were found by this search, though it is conceivable that someone could have put the sleep and wakeup in two different files. An effort was made to ask several upstream maintainers if they were aware of people relying on wake_up_process() to wake up usleep_range(). No maintainers were aware of that but they were aware of many people relying on usleep_range() never returning before the minimum. Reported-by: Tao Huang Signed-off-by: Douglas Anderson Cc: heiko@sntech.de Cc: broonie@kernel.org Cc: briannorris@chromium.org Cc: Andreas Mohr Cc: linux-rockchip@lists.infradead.org Cc: tony.xie@rock-chips.com Cc: John Stultz Cc: djkurtz@chromium.org Cc: linux@roeck-us.net Cc: tskd08@gmail.com Link: http://lkml.kernel.org/r/1477065531-30342-1-git-send-email-dianders@chromium.org Signed-off-by: Thomas Gleixner --- kernel/time/timer.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 2d47980a1bc4..12681c9a7683 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1896,16 +1896,6 @@ unsigned long msleep_interruptible(unsigned int msecs) EXPORT_SYMBOL(msleep_interruptible); -static void __sched do_usleep_range(unsigned long min, unsigned long max) -{ - ktime_t kmin; - u64 delta; - - kmin = ktime_set(0, min * NSEC_PER_USEC); - delta = (u64)(max - min) * NSEC_PER_USEC; - schedule_hrtimeout_range(&kmin, delta, HRTIMER_MODE_REL); -} - /** * usleep_range - Sleep for an approximate time * @min: Minimum time in usecs to sleep @@ -1919,7 +1909,14 @@ static void __sched do_usleep_range(unsigned long min, unsigned long max) */ void __sched usleep_range(unsigned long min, unsigned long max) { - __set_current_state(TASK_UNINTERRUPTIBLE); - do_usleep_range(min, max); + ktime_t exp = ktime_add_us(ktime_get(), min); + u64 delta = (u64)(max - min) * NSEC_PER_USEC; + + for (;;) { + __set_current_state(TASK_UNINTERRUPTIBLE); + /* Do not return before the requested sleep time has elapsed */ + if (!schedule_hrtimeout_range(&exp, delta, HRTIMER_MODE_ABS)) + break; + } } EXPORT_SYMBOL(usleep_range); -- cgit v1.2.3 From 4b7e9cf9c84b09adc428e0433cd376b91f9c52a7 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Fri, 21 Oct 2016 08:58:51 -0700 Subject: timers: Fix documentation for schedule_timeout() and similar The documentation for schedule_timeout(), schedule_hrtimeout(), and schedule_hrtimeout_range() all claim that the routines couldn't possibly return early if the task state was TASK_UNINTERRUPTIBLE. This is simply not true since wake_up_process() will cause those routines to exit early. We cannot make schedule_[hr]timeout() loop until the timeout expires if the task state is uninterruptible because we have users which rely on the existing and designed behaviour. Make the documentation match the (correct) implementation. schedule_hrtimeout() returns -EINTR even when a uninterruptible task was woken up. This might look strange, but making the return code depend on the state is too much of an effort as it would affect all the call sites. There is no value in doing so, but we spell it out clearly in the documentation. Suggested-by: Daniel Kurtz Signed-off-by: Douglas Anderson Cc: huangtao@rock-chips.com Cc: heiko@sntech.de Cc: broonie@kernel.org Cc: briannorris@chromium.org Cc: Andreas Mohr Cc: linux-rockchip@lists.infradead.org Cc: tony.xie@rock-chips.com Cc: John Stultz Cc: linux@roeck-us.net Cc: tskd08@gmail.com Link: http://lkml.kernel.org/r/1477065531-30342-2-git-send-email-dianders@chromium.org Signed-off-by: Thomas Gleixner --- kernel/time/hrtimer.c | 20 ++++++++++++++------ kernel/time/timer.c | 11 +++++++---- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index bb5ec425dfe0..08be5c99d26b 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -1742,15 +1742,19 @@ schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta, * You can set the task state as follows - * * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to - * pass before the routine returns. + * pass before the routine returns unless the current task is explicitly + * woken up, (e.g. by wake_up_process()). * * %TASK_INTERRUPTIBLE - the routine may return early if a signal is - * delivered to the current task. + * delivered to the current task or the current task is explicitly woken + * up. * * The current task state is guaranteed to be TASK_RUNNING when this * routine returns. * - * Returns 0 when the timer has expired otherwise -EINTR + * Returns 0 when the timer has expired. If the task was woken before the + * timer expired by a signal (only possible in state TASK_INTERRUPTIBLE) or + * by an explicit wakeup, it returns -EINTR. */ int __sched schedule_hrtimeout_range(ktime_t *expires, u64 delta, const enum hrtimer_mode mode) @@ -1772,15 +1776,19 @@ EXPORT_SYMBOL_GPL(schedule_hrtimeout_range); * You can set the task state as follows - * * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to - * pass before the routine returns. + * pass before the routine returns unless the current task is explicitly + * woken up, (e.g. by wake_up_process()). * * %TASK_INTERRUPTIBLE - the routine may return early if a signal is - * delivered to the current task. + * delivered to the current task or the current task is explicitly woken + * up. * * The current task state is guaranteed to be TASK_RUNNING when this * routine returns. * - * Returns 0 when the timer has expired otherwise -EINTR + * Returns 0 when the timer has expired. If the task was woken before the + * timer expired by a signal (only possible in state TASK_INTERRUPTIBLE) or + * by an explicit wakeup, it returns -EINTR. */ int __sched schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode) diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 12681c9a7683..88aab86a4594 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1691,11 +1691,12 @@ static void process_timeout(unsigned long __data) * You can set the task state as follows - * * %TASK_UNINTERRUPTIBLE - at least @timeout jiffies are guaranteed to - * pass before the routine returns. The routine will return 0 + * pass before the routine returns unless the current task is explicitly + * woken up, (e.g. by wake_up_process())". * * %TASK_INTERRUPTIBLE - the routine may return early if a signal is - * delivered to the current task. In this case the remaining time - * in jiffies will be returned, or 0 if the timer expired in time + * delivered to the current task or the current task is explicitly woken + * up. * * The current task state is guaranteed to be TASK_RUNNING when this * routine returns. @@ -1704,7 +1705,9 @@ static void process_timeout(unsigned long __data) * the CPU away without a bound on the timeout. In this case the return * value will be %MAX_SCHEDULE_TIMEOUT. * - * In all cases the return value is guaranteed to be non-negative. + * Returns 0 when the timer has expired otherwise the remaining time in + * jiffies will be returned. In all cases the return value is guaranteed + * to be non-negative. */ signed long __sched schedule_timeout(signed long timeout) { -- cgit v1.2.3 From 237e3ad0f195d8fd34f1299e45f04793832a16fc Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 11 Nov 2016 00:10:05 -0500 Subject: Kconfig: Introduce the "imply" keyword The "imply" keyword is a weak version of "select" where the target config symbol can still be turned off, avoiding those pitfalls that come with the "select" keyword. This is useful e.g. with multiple drivers that want to indicate their ability to hook into a secondary subsystem while allowing the user to configure that subsystem out without also having to unset these drivers. Currently, the same effect can almost be achieved with: config DRIVER_A tristate config DRIVER_B tristate config DRIVER_C tristate config DRIVER_D tristate [...] config SUBSYSTEM_X tristate default DRIVER_A || DRIVER_B || DRIVER_C || DRIVER_D || [...] This is unwieldy to maintain especially with a large number of drivers. Furthermore, there is no easy way to restrict the choice for SUBSYSTEM_X to y or n, excluding m, when some drivers are built-in. The "select" keyword allows for excluding m, but it excludes n as well. Hence this "imply" keyword. The above becomes: config DRIVER_A tristate imply SUBSYSTEM_X config DRIVER_B tristate imply SUBSYSTEM_X [...] config SUBSYSTEM_X tristate This is much cleaner, and way more flexible than "select". SUBSYSTEM_X can still be configured out, and it can be set as a module when none of the drivers are configured in or all of them are modular. Signed-off-by: Nicolas Pitre Acked-by: Richard Cochran Acked-by: Thomas Gleixner Acked-by: John Stultz Reviewed-by: Josh Triplett Cc: Paul Bolle Cc: linux-kbuild@vger.kernel.org Cc: netdev@vger.kernel.org Cc: Michal Marek Cc: Edward Cree Link: http://lkml.kernel.org/r/1478841010-28605-2-git-send-email-nicolas.pitre@linaro.org Signed-off-by: Thomas Gleixner --- Documentation/kbuild/kconfig-language.txt | 29 ++++++++++++++++ scripts/kconfig/expr.h | 2 ++ scripts/kconfig/menu.c | 55 ++++++++++++++++++++++--------- scripts/kconfig/symbol.c | 24 +++++++++++++- scripts/kconfig/zconf.gperf | 1 + scripts/kconfig/zconf.y | 16 +++++++-- 6 files changed, 108 insertions(+), 19 deletions(-) diff --git a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt index 069fcb3eef6e..262722d8867b 100644 --- a/Documentation/kbuild/kconfig-language.txt +++ b/Documentation/kbuild/kconfig-language.txt @@ -113,6 +113,34 @@ applicable everywhere (see syntax). That will limit the usefulness but on the other hand avoid the illegal configurations all over. +- weak reverse dependencies: "imply" ["if" ] + This is similar to "select" as it enforces a lower limit on another + symbol except that the "implied" symbol's value may still be set to n + from a direct dependency or with a visible prompt. + + Given the following example: + + config FOO + tristate + imply BAZ + + config BAZ + tristate + depends on BAR + + The following values are possible: + + FOO BAR BAZ's default choice for BAZ + --- --- ------------- -------------- + n y n N/m/y + m y m M/y/n + y y y Y/n + y n * N + + This is useful e.g. with multiple drivers that want to indicate their + ability to hook into a secondary subsystem while allowing the user to + configure that subsystem out without also having to unset these drivers. + - limiting menu display: "visible if" This attribute is only applicable to menu blocks, if the condition is false, the menu block is not displayed to the user (the symbols @@ -481,6 +509,7 @@ historical issues resolved through these different solutions. b) Match dependency semantics: b1) Swap all "select FOO" to "depends on FOO" or, b2) Swap all "depends on FOO" to "select FOO" + c) Consider the use of "imply" instead of "select" The resolution to a) can be tested with the sample Kconfig file Documentation/kbuild/Kconfig.recursion-issue-01 through the removal diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 973b6f733368..a73f762c48d6 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -85,6 +85,7 @@ struct symbol { struct property *prop; struct expr_value dir_dep; struct expr_value rev_dep; + struct expr_value implied; }; #define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) @@ -136,6 +137,7 @@ enum prop_type { P_DEFAULT, /* default y */ P_CHOICE, /* choice value */ P_SELECT, /* select BAR */ + P_IMPLY, /* imply BAR */ P_RANGE, /* range 7..100 (for a symbol) */ P_ENV, /* value from environment variable */ P_SYMBOL, /* where a symbol is defined */ diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index aed678e8a777..e9357931b47d 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -233,6 +233,8 @@ static void sym_check_prop(struct symbol *sym) { struct property *prop; struct symbol *sym2; + char *use; + for (prop = sym->prop; prop; prop = prop->next) { switch (prop->type) { case P_DEFAULT: @@ -252,18 +254,20 @@ static void sym_check_prop(struct symbol *sym) } break; case P_SELECT: + case P_IMPLY: + use = prop->type == P_SELECT ? "select" : "imply"; sym2 = prop_get_symbol(prop); if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE) prop_warn(prop, - "config symbol '%s' uses select, but is " - "not boolean or tristate", sym->name); + "config symbol '%s' uses %s, but is " + "not boolean or tristate", sym->name, use); else if (sym2->type != S_UNKNOWN && sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE) prop_warn(prop, - "'%s' has wrong type. 'select' only " + "'%s' has wrong type. '%s' only " "accept arguments of boolean and " - "tristate type", sym2->name); + "tristate type", sym2->name, use); break; case P_RANGE: if (sym->type != S_INT && sym->type != S_HEX) @@ -333,6 +337,10 @@ void menu_finalize(struct menu *parent) struct symbol *es = prop_get_symbol(prop); es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr, expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); + } else if (prop->type == P_IMPLY) { + struct symbol *es = prop_get_symbol(prop); + es->implied.expr = expr_alloc_or(es->implied.expr, + expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); } } } @@ -612,13 +620,30 @@ static struct property *get_symbol_prop(struct symbol *sym) return prop; } +static void get_symbol_props_str(struct gstr *r, struct symbol *sym, + enum prop_type tok, const char *prefix) +{ + bool hit = false; + struct property *prop; + + for_all_properties(sym, prop, tok) { + if (!hit) { + str_append(r, prefix); + hit = true; + } else + str_printf(r, " && "); + expr_gstr_print(prop->expr, r); + } + if (hit) + str_append(r, "\n"); +} + /* * head is optional and may be NULL */ static void get_symbol_str(struct gstr *r, struct symbol *sym, struct list_head *head) { - bool hit; struct property *prop; if (sym && sym->name) { @@ -648,22 +673,20 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym, } } - hit = false; - for_all_properties(sym, prop, P_SELECT) { - if (!hit) { - str_append(r, " Selects: "); - hit = true; - } else - str_printf(r, " && "); - expr_gstr_print(prop->expr, r); - } - if (hit) - str_append(r, "\n"); + get_symbol_props_str(r, sym, P_SELECT, _(" Selects: ")); if (sym->rev_dep.expr) { str_append(r, _(" Selected by: ")); expr_gstr_print(sym->rev_dep.expr, r); str_append(r, "\n"); } + + get_symbol_props_str(r, sym, P_IMPLY, _(" Implies: ")); + if (sym->implied.expr) { + str_append(r, _(" Implied by: ")); + expr_gstr_print(sym->implied.expr, r); + str_append(r, "\n"); + } + str_append(r, "\n\n"); } diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 2432298487fb..20136ffefb23 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -258,6 +258,15 @@ static void sym_calc_visibility(struct symbol *sym) sym->rev_dep.tri = tri; sym_set_changed(sym); } + tri = no; + if (sym->implied.expr && sym->dir_dep.tri != no) + tri = expr_calc_value(sym->implied.expr); + if (tri == mod && sym_get_type(sym) == S_BOOLEAN) + tri = yes; + if (sym->implied.tri != tri) { + sym->implied.tri = tri; + sym_set_changed(sym); + } } /* @@ -397,6 +406,10 @@ void sym_calc_value(struct symbol *sym) newval.tri = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri); } + if (sym->implied.tri != no) { + sym->flags |= SYMBOL_WRITE; + newval.tri = EXPR_OR(newval.tri, sym->implied.tri); + } } calc_newval: if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { @@ -413,7 +426,8 @@ void sym_calc_value(struct symbol *sym) } newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); } - if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) + if (newval.tri == mod && + (sym_get_type(sym) == S_BOOLEAN || sym->implied.tri == yes)) newval.tri = yes; break; case S_STRING: @@ -498,6 +512,8 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val) return false; if (sym->visible <= sym->rev_dep.tri) return false; + if (sym->implied.tri == yes && val == mod) + return false; if (sym_is_choice_value(sym) && sym->visible == yes) return val == yes; return val >= sym->rev_dep.tri && val <= sym->visible; @@ -750,6 +766,10 @@ const char *sym_get_string_default(struct symbol *sym) if (sym->type == S_BOOLEAN && val == mod) val = yes; + /* adjust the default value if this symbol is implied by another */ + if (val < sym->implied.tri) + val = sym->implied.tri; + switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: @@ -1352,6 +1372,8 @@ const char *prop_get_type_name(enum prop_type type) return "choice"; case P_SELECT: return "select"; + case P_IMPLY: + return "imply"; case P_RANGE: return "range"; case P_SYMBOL: diff --git a/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf index ac498f01b449..ead02edec936 100644 --- a/scripts/kconfig/zconf.gperf +++ b/scripts/kconfig/zconf.gperf @@ -38,6 +38,7 @@ int, T_TYPE, TF_COMMAND, S_INT hex, T_TYPE, TF_COMMAND, S_HEX string, T_TYPE, TF_COMMAND, S_STRING select, T_SELECT, TF_COMMAND +imply, T_IMPLY, TF_COMMAND range, T_RANGE, TF_COMMAND visible, T_VISIBLE, TF_COMMAND option, T_OPTION, TF_COMMAND diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y index 71bf8bff696a..001305fa080b 100644 --- a/scripts/kconfig/zconf.y +++ b/scripts/kconfig/zconf.y @@ -31,7 +31,7 @@ struct symbol *symbol_hash[SYMBOL_HASHSIZE]; static struct menu *current_menu, *current_entry; %} -%expect 30 +%expect 32 %union { @@ -62,6 +62,7 @@ static struct menu *current_menu, *current_entry; %token T_TYPE %token T_DEFAULT %token T_SELECT +%token T_IMPLY %token T_RANGE %token T_VISIBLE %token T_OPTION @@ -124,7 +125,7 @@ stmt_list: ; option_name: - T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE + T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_IMPLY | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE ; common_stmt: @@ -216,6 +217,12 @@ config_option: T_SELECT T_WORD if_expr T_EOL printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); }; +config_option: T_IMPLY T_WORD if_expr T_EOL +{ + menu_add_symbol(P_IMPLY, sym_lookup($2, 0), $3); + printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno()); +}; + config_option: T_RANGE symbol symbol if_expr T_EOL { menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4); @@ -664,6 +671,11 @@ static void print_symbol(FILE *out, struct menu *menu) expr_fprint(prop->expr, out); fputc('\n', out); break; + case P_IMPLY: + fputs( " imply ", out); + expr_fprint(prop->expr, out); + fputc('\n', out); + break; case P_RANGE: fputs( " range ", out); expr_fprint(prop->expr, out); -- cgit v1.2.3 From 32ce5ac867bf4ba8350a751216d087f574a38133 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 11 Nov 2016 00:10:06 -0500 Subject: Kconfig: Regenerate *.c_shipped files after previous changes Signed-off-by: Nicolas Pitre Cc: Paul Bolle Cc: linux-kbuild@vger.kernel.org Cc: netdev@vger.kernel.org Cc: Richard Cochran Cc: Josh Triplett Cc: Michal Marek Cc: John Stultz Cc: Edward Cree Link: http://lkml.kernel.org/r/1478841010-28605-3-git-send-email-nicolas.pitre@linaro.org Signed-off-by: Thomas Gleixner --- scripts/kconfig/zconf.hash.c_shipped | 30 +- scripts/kconfig/zconf.tab.c_shipped | 1581 ++++++++++++++++------------------ 2 files changed, 753 insertions(+), 858 deletions(-) diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped index 360a62df2b5e..d51b15de074a 100644 --- a/scripts/kconfig/zconf.hash.c_shipped +++ b/scripts/kconfig/zconf.hash.c_shipped @@ -55,10 +55,10 @@ kconf_id_hash (register const char *str, register unsigned int len) 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 5, 25, 25, + 73, 73, 73, 73, 73, 73, 73, 10, 25, 25, 0, 0, 0, 5, 0, 0, 73, 73, 5, 0, 10, 5, 45, 73, 20, 20, 0, 15, 15, 73, - 20, 5, 73, 73, 73, 73, 73, 73, 73, 73, + 20, 0, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, @@ -120,6 +120,7 @@ struct kconf_id_strings_t char kconf_id_strings_str43[sizeof("hex")]; char kconf_id_strings_str46[sizeof("config")]; char kconf_id_strings_str47[sizeof("boolean")]; + char kconf_id_strings_str50[sizeof("imply")]; char kconf_id_strings_str51[sizeof("string")]; char kconf_id_strings_str54[sizeof("help")]; char kconf_id_strings_str56[sizeof("prompt")]; @@ -157,6 +158,7 @@ static const struct kconf_id_strings_t kconf_id_strings_contents = "hex", "config", "boolean", + "imply", "string", "help", "prompt", @@ -174,7 +176,7 @@ kconf_id_lookup (register const char *str, register unsigned int len) { enum { - TOTAL_KEYWORDS = 34, + TOTAL_KEYWORDS = 35, MIN_WORD_LENGTH = 2, MAX_WORD_LENGTH = 14, MIN_HASH_VALUE = 2, @@ -205,15 +207,15 @@ kconf_id_lookup (register const char *str, register unsigned int len) {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_TRISTATE}, #line 36 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN}, -#line 46 "scripts/kconfig/zconf.gperf" +#line 47 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_OPT_DEFCONFIG_LIST,TF_OPTION}, {-1}, {-1}, -#line 44 "scripts/kconfig/zconf.gperf" +#line 45 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_ON, TF_PARAM}, #line 29 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_OPTIONAL, TF_COMMAND}, {-1}, {-1}, -#line 43 "scripts/kconfig/zconf.gperf" +#line 44 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_OPTION, TF_COMMAND}, #line 17 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ENDMENU, TF_COMMAND}, @@ -223,9 +225,9 @@ kconf_id_lookup (register const char *str, register unsigned int len) #line 23 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str25, T_MENUCONFIG, TF_COMMAND}, {-1}, -#line 45 "scripts/kconfig/zconf.gperf" +#line 46 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION}, -#line 48 "scripts/kconfig/zconf.gperf" +#line 49 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_OPT_ALLNOCONFIG_Y,TF_OPTION}, #line 16 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND}, @@ -234,10 +236,10 @@ kconf_id_lookup (register const char *str, register unsigned int len) {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SELECT, TF_COMMAND}, #line 21 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND}, -#line 47 "scripts/kconfig/zconf.gperf" +#line 48 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_OPT_ENV, TF_OPTION}, {-1}, -#line 41 "scripts/kconfig/zconf.gperf" +#line 42 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_RANGE, TF_COMMAND}, #line 19 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_CHOICE, TF_COMMAND}, @@ -247,7 +249,7 @@ kconf_id_lookup (register const char *str, register unsigned int len) {-1}, #line 18 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_SOURCE, TF_COMMAND}, -#line 42 "scripts/kconfig/zconf.gperf" +#line 43 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42, T_VISIBLE, TF_COMMAND}, #line 38 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str43, T_TYPE, TF_COMMAND, S_HEX}, @@ -256,7 +258,9 @@ kconf_id_lookup (register const char *str, register unsigned int len) {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_CONFIG, TF_COMMAND}, #line 35 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str47, T_TYPE, TF_COMMAND, S_BOOLEAN}, - {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 41 "scripts/kconfig/zconf.gperf" + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str50, T_IMPLY, TF_COMMAND}, #line 39 "scripts/kconfig/zconf.gperf" {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str51, T_TYPE, TF_COMMAND, S_STRING}, {-1}, {-1}, @@ -289,5 +293,5 @@ kconf_id_lookup (register const char *str, register unsigned int len) } return 0; } -#line 49 "scripts/kconfig/zconf.gperf" +#line 50 "scripts/kconfig/zconf.gperf" diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped index 7a4d658c2066..65b7515a577c 100644 --- a/scripts/kconfig/zconf.tab.c_shipped +++ b/scripts/kconfig/zconf.tab.c_shipped @@ -1,19 +1,19 @@ -/* A Bison parser, made by GNU Bison 2.5.1. */ +/* A Bison parser, made by GNU Bison 3.0.4. */ /* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. - + + Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -26,7 +26,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -44,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.5.1" +#define YYBISON_VERSION "3.0.4" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -58,18 +58,16 @@ /* Pull parsers. */ #define YYPULL 1 -/* Using locations. */ -#define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse zconfparse #define yylex zconflex #define yyerror zconferror -#define yylval zconflval -#define yychar zconfchar #define yydebug zconfdebug #define yynerrs zconfnerrs +#define yylval zconflval +#define yychar zconfchar /* Copy the first part of user declarations. */ @@ -108,19 +106,14 @@ static struct menu *current_menu, *current_entry; -# ifndef YY_NULL +# ifndef YY_NULLPTR # if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULL nullptr +# define YY_NULLPTR nullptr # else -# define YY_NULL 0 +# define YY_NULLPTR 0 # endif # endif -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 1 -#endif - /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE @@ -129,62 +122,65 @@ static struct menu *current_menu, *current_entry; # define YYERROR_VERBOSE 0 #endif -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 1 +#endif +#if YYDEBUG +extern int zconfdebug; +#endif -/* Tokens. */ +/* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - T_MAINMENU = 258, - T_MENU = 259, - T_ENDMENU = 260, - T_SOURCE = 261, - T_CHOICE = 262, - T_ENDCHOICE = 263, - T_COMMENT = 264, - T_CONFIG = 265, - T_MENUCONFIG = 266, - T_HELP = 267, - T_HELPTEXT = 268, - T_IF = 269, - T_ENDIF = 270, - T_DEPENDS = 271, - T_OPTIONAL = 272, - T_PROMPT = 273, - T_TYPE = 274, - T_DEFAULT = 275, - T_SELECT = 276, - T_RANGE = 277, - T_VISIBLE = 278, - T_OPTION = 279, - T_ON = 280, - T_WORD = 281, - T_WORD_QUOTE = 282, - T_UNEQUAL = 283, - T_LESS = 284, - T_LESS_EQUAL = 285, - T_GREATER = 286, - T_GREATER_EQUAL = 287, - T_CLOSE_PAREN = 288, - T_OPEN_PAREN = 289, - T_EOL = 290, - T_OR = 291, - T_AND = 292, - T_EQUAL = 293, - T_NOT = 294 - }; + enum yytokentype + { + T_MAINMENU = 258, + T_MENU = 259, + T_ENDMENU = 260, + T_SOURCE = 261, + T_CHOICE = 262, + T_ENDCHOICE = 263, + T_COMMENT = 264, + T_CONFIG = 265, + T_MENUCONFIG = 266, + T_HELP = 267, + T_HELPTEXT = 268, + T_IF = 269, + T_ENDIF = 270, + T_DEPENDS = 271, + T_OPTIONAL = 272, + T_PROMPT = 273, + T_TYPE = 274, + T_DEFAULT = 275, + T_SELECT = 276, + T_IMPLY = 277, + T_RANGE = 278, + T_VISIBLE = 279, + T_OPTION = 280, + T_ON = 281, + T_WORD = 282, + T_WORD_QUOTE = 283, + T_UNEQUAL = 284, + T_LESS = 285, + T_LESS_EQUAL = 286, + T_GREATER = 287, + T_GREATER_EQUAL = 288, + T_CLOSE_PAREN = 289, + T_OPEN_PAREN = 290, + T_EOL = 291, + T_OR = 292, + T_AND = 293, + T_EQUAL = 294, + T_NOT = 295 + }; #endif - - +/* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE + +union YYSTYPE { @@ -196,14 +192,20 @@ typedef union YYSTYPE const struct kconf_id *id; +}; -} YYSTYPE; +typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 #endif +extern YYSTYPE zconflval; + +int zconfparse (void); + + + /* Copy the second part of user declarations. */ @@ -224,11 +226,8 @@ typedef unsigned char yytype_uint8; #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; #else -typedef short int yytype_int8; +typedef signed char yytype_int8; #endif #ifdef YYTYPE_UINT16 @@ -248,8 +247,7 @@ typedef short int yytype_int16; # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) +# elif ! defined YYSIZE_T # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else @@ -263,38 +261,67 @@ typedef short int yytype_int16; # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ -# define YY_(msgid) msgid +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef YY_ATTRIBUTE +# if (defined __GNUC__ \ + && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ + || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +# define YY_ATTRIBUTE(Spec) /* empty */ +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + +#if !defined _Noreturn \ + && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) +# if defined _MSC_VER && 1200 <= _MSC_VER +# define _Noreturn __declspec (noreturn) +# else +# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) +# define YYUSE(E) ((void) (E)) #else -# define YYUSE(e) /* empty */ +# define YYUSE(E) /* empty */ #endif -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) +#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") #else -static int -YYID (yyi) - int yyi; +# define YY_INITIAL_VALUE(Value) Value #endif -{ - return yyi; -} +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END #endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + #if ! defined yyoverflow || YYERROR_VERBOSE @@ -313,8 +340,7 @@ YYID (yyi) # define alloca _alloca # else # define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS @@ -326,8 +352,8 @@ YYID (yyi) # endif # ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely @@ -343,7 +369,7 @@ YYID (yyi) # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) + && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 @@ -351,15 +377,13 @@ YYID (yyi) # endif # ifndef YYMALLOC # define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) +# if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) +# if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif @@ -369,7 +393,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc @@ -394,16 +418,16 @@ union yyalloc elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) #endif @@ -422,7 +446,7 @@ union yyalloc for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ - while (YYID (0)) + while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ @@ -430,25 +454,27 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 11 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 298 +#define YYLAST 301 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 40 +#define YYNTOKENS 41 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 50 /* YYNRULES -- Number of rules. */ -#define YYNRULES 122 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 199 +#define YYNRULES 124 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 204 -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned + by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 294 +#define YYMAXUTOK 295 -#define YYTRANSLATE(YYX) \ +#define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, without out-of-bounds checking. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -480,90 +506,30 @@ static const yytype_uint8 yytranslate[] = 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39 + 35, 36, 37, 38, 39, 40 }; #if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint16 yyprhs[] = -{ - 0, 0, 3, 6, 8, 11, 13, 14, 17, 20, - 23, 26, 31, 36, 40, 42, 44, 46, 48, 50, - 52, 54, 56, 58, 60, 62, 64, 66, 68, 72, - 75, 79, 82, 86, 89, 90, 93, 96, 99, 102, - 105, 108, 112, 117, 122, 127, 133, 137, 138, 142, - 143, 146, 150, 153, 155, 159, 160, 163, 166, 169, - 172, 175, 180, 184, 187, 192, 193, 196, 200, 202, - 206, 207, 210, 213, 216, 220, 224, 228, 230, 234, - 235, 238, 241, 244, 248, 252, 255, 258, 261, 262, - 265, 268, 271, 276, 277, 280, 283, 286, 287, 290, - 292, 294, 297, 300, 303, 305, 308, 309, 312, 314, - 318, 322, 326, 330, 334, 338, 342, 345, 349, 353, - 355, 357, 358 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 41, 0, -1, 85, 42, -1, 42, -1, 67, 43, - -1, 43, -1, -1, 43, 45, -1, 43, 59, -1, - 43, 71, -1, 43, 84, -1, 43, 26, 1, 35, - -1, 43, 44, 1, 35, -1, 43, 1, 35, -1, - 16, -1, 18, -1, 19, -1, 21, -1, 17, -1, - 22, -1, 20, -1, 23, -1, 35, -1, 65, -1, - 75, -1, 48, -1, 50, -1, 73, -1, 26, 1, - 35, -1, 1, 35, -1, 10, 26, 35, -1, 47, - 51, -1, 11, 26, 35, -1, 49, 51, -1, -1, - 51, 52, -1, 51, 53, -1, 51, 79, -1, 51, - 77, -1, 51, 46, -1, 51, 35, -1, 19, 82, - 35, -1, 18, 83, 86, 35, -1, 20, 87, 86, - 35, -1, 21, 26, 86, 35, -1, 22, 88, 88, - 86, 35, -1, 24, 54, 35, -1, -1, 54, 26, - 55, -1, -1, 38, 83, -1, 7, 89, 35, -1, - 56, 60, -1, 84, -1, 57, 62, 58, -1, -1, - 60, 61, -1, 60, 79, -1, 60, 77, -1, 60, - 35, -1, 60, 46, -1, 18, 83, 86, 35, -1, - 19, 82, 35, -1, 17, 35, -1, 20, 26, 86, - 35, -1, -1, 62, 45, -1, 14, 87, 85, -1, - 84, -1, 63, 66, 64, -1, -1, 66, 45, -1, - 66, 71, -1, 66, 59, -1, 3, 83, 85, -1, - 4, 83, 35, -1, 68, 80, 78, -1, 84, -1, - 69, 72, 70, -1, -1, 72, 45, -1, 72, 71, - -1, 72, 59, -1, 6, 83, 35, -1, 9, 83, - 35, -1, 74, 78, -1, 12, 35, -1, 76, 13, - -1, -1, 78, 79, -1, 78, 35, -1, 78, 46, - -1, 16, 25, 87, 35, -1, -1, 80, 81, -1, - 80, 35, -1, 23, 86, -1, -1, 83, 86, -1, - 26, -1, 27, -1, 5, 35, -1, 8, 35, -1, - 15, 35, -1, 35, -1, 85, 35, -1, -1, 14, - 87, -1, 88, -1, 88, 29, 88, -1, 88, 30, - 88, -1, 88, 31, 88, -1, 88, 32, 88, -1, - 88, 38, 88, -1, 88, 28, 88, -1, 34, 87, - 33, -1, 39, 87, -1, 87, 36, 87, -1, 87, - 37, 87, -1, 26, -1, 27, -1, -1, 26, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 108, 108, 108, 110, 110, 112, 114, 115, 116, - 117, 118, 119, 123, 127, 127, 127, 127, 127, 127, - 127, 127, 131, 132, 133, 134, 135, 136, 140, 141, - 147, 155, 161, 169, 179, 181, 182, 183, 184, 185, - 186, 189, 197, 203, 213, 219, 225, 228, 230, 241, - 242, 247, 256, 261, 269, 272, 274, 275, 276, 277, - 278, 281, 287, 298, 304, 314, 316, 321, 329, 337, - 340, 342, 343, 344, 349, 356, 363, 368, 376, 379, - 381, 382, 383, 386, 394, 401, 408, 414, 421, 423, - 424, 425, 428, 436, 438, 439, 442, 449, 451, 456, - 457, 460, 461, 462, 466, 467, 470, 471, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 483, 484, 487, - 488, 491, 492 + 0, 109, 109, 109, 111, 111, 113, 115, 116, 117, + 118, 119, 120, 124, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 132, 133, 134, 135, 136, 137, 141, + 142, 148, 156, 162, 170, 180, 182, 183, 184, 185, + 186, 187, 190, 198, 204, 214, 220, 226, 232, 235, + 237, 248, 249, 254, 263, 268, 276, 279, 281, 282, + 283, 284, 285, 288, 294, 305, 311, 321, 323, 328, + 336, 344, 347, 349, 350, 351, 356, 363, 370, 375, + 383, 386, 388, 389, 390, 393, 401, 408, 415, 421, + 428, 430, 431, 432, 435, 443, 445, 446, 449, 456, + 458, 463, 464, 467, 468, 469, 473, 474, 477, 478, + 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, + 491, 494, 495, 498, 499 }; #endif -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +#if YYDEBUG || YYERROR_VERBOSE || 0 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = @@ -571,9 +537,9 @@ static const char *const yytname[] = "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU", "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG", "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS", - "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_RANGE", - "T_VISIBLE", "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", - "T_LESS", "T_LESS_EQUAL", "T_GREATER", "T_GREATER_EQUAL", + "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_IMPLY", + "T_RANGE", "T_VISIBLE", "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", + "T_UNEQUAL", "T_LESS", "T_LESS_EQUAL", "T_GREATER", "T_GREATER_EQUAL", "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL", "T_NOT", "$accept", "input", "start", "stmt_list", "option_name", "common_stmt", "option_error", "config_entry_start", "config_stmt", @@ -585,260 +551,254 @@ static const char *const yytname[] = "menu_entry", "menu_end", "menu_stmt", "menu_block", "source_stmt", "comment", "comment_stmt", "help_start", "help", "depends_list", "depends", "visibility_list", "visible", "prompt_stmt_opt", "prompt", - "end", "nl", "if_expr", "expr", "symbol", "word_opt", YY_NULL + "end", "nl", "if_expr", "expr", "symbol", "word_opt", YY_NULLPTR }; #endif # ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294 + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295 }; # endif -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = +#define YYPACT_NINF -92 + +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-92))) + +#define YYTABLE_NINF -88 + +#define yytable_value_is_error(Yytable_value) \ + 0 + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int16 yypact[] = { - 0, 40, 41, 41, 42, 42, 43, 43, 43, 43, - 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, - 44, 44, 45, 45, 45, 45, 45, 45, 46, 46, - 47, 48, 49, 50, 51, 51, 51, 51, 51, 51, - 51, 52, 52, 52, 52, 52, 53, 54, 54, 55, - 55, 56, 57, 58, 59, 60, 60, 60, 60, 60, - 60, 61, 61, 61, 61, 62, 62, 63, 64, 65, - 66, 66, 66, 66, 67, 68, 69, 70, 71, 72, - 72, 72, 72, 73, 74, 75, 76, 77, 78, 78, - 78, 78, 79, 80, 80, 80, 81, 82, 82, 83, - 83, 84, 84, 84, 85, 85, 86, 86, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, - 88, 89, 89 + 17, 41, -92, 15, -92, 150, -92, 19, -92, -92, + -13, -92, 28, 41, 38, 41, 50, 47, 41, 79, + 82, 44, 76, -92, -92, -92, -92, -92, -92, -92, + -92, -92, 118, -92, 129, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, 184, -92, -92, 107, -92, 111, -92, 113, + -92, 116, -92, 139, 140, 151, -92, -92, 44, 44, + 142, 256, -92, 160, 173, 27, 117, 80, 51, 255, + -15, 255, 217, -92, -92, -92, -92, -92, -92, -8, + -92, 44, 44, 107, 87, 87, 87, 87, 87, 87, + -92, -92, 174, 176, 187, 41, 41, 44, 188, 189, + 87, -92, 213, -92, -92, -92, -92, 206, -92, -92, + 193, 41, 41, 203, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, 229, -92, 241, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + 216, -92, -92, -92, -92, -92, -92, -92, -92, -92, + 44, 229, 222, 229, 64, 229, 229, 87, 31, 231, + -92, -92, 229, 236, 229, 44, -92, 145, 242, -92, + -92, 243, 244, 245, 229, 251, -92, -92, 247, -92, + 257, 125, -92, -92, -92, -92, -92, 260, 41, -92, + -92, -92, -92, -92 }; -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = { - 0, 2, 2, 1, 2, 1, 0, 2, 2, 2, - 2, 4, 4, 3, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, - 3, 2, 3, 2, 0, 2, 2, 2, 2, 2, - 2, 3, 4, 4, 4, 5, 3, 0, 3, 0, - 2, 3, 2, 1, 3, 0, 2, 2, 2, 2, - 2, 4, 3, 2, 4, 0, 2, 3, 1, 3, - 0, 2, 2, 2, 3, 3, 3, 1, 3, 0, - 2, 2, 2, 3, 3, 2, 2, 2, 0, 2, - 2, 2, 4, 0, 2, 2, 2, 0, 2, 1, - 1, 2, 2, 2, 1, 2, 0, 2, 1, 3, - 3, 3, 3, 3, 3, 3, 2, 3, 3, 1, - 1, 0, 1 + 6, 0, 106, 0, 3, 0, 6, 6, 101, 102, + 0, 1, 0, 0, 0, 0, 123, 0, 0, 0, + 0, 0, 0, 14, 19, 15, 16, 21, 17, 18, + 20, 22, 0, 23, 0, 7, 35, 26, 35, 27, + 57, 67, 8, 72, 24, 95, 81, 9, 28, 90, + 25, 10, 0, 107, 2, 76, 13, 0, 103, 0, + 124, 0, 104, 0, 0, 0, 121, 122, 0, 0, + 0, 110, 105, 0, 0, 0, 0, 0, 0, 0, + 90, 0, 0, 77, 85, 53, 86, 31, 33, 0, + 118, 0, 0, 69, 0, 0, 0, 0, 0, 0, + 11, 12, 0, 0, 0, 0, 99, 0, 0, 0, + 0, 49, 0, 41, 40, 36, 37, 0, 39, 38, + 0, 0, 99, 0, 61, 62, 58, 60, 59, 68, + 56, 55, 73, 75, 71, 74, 70, 108, 97, 0, + 96, 82, 84, 80, 83, 79, 92, 93, 91, 117, + 119, 120, 116, 111, 112, 113, 114, 115, 30, 88, + 0, 108, 0, 108, 108, 108, 108, 0, 0, 0, + 89, 65, 108, 0, 108, 0, 98, 0, 0, 42, + 100, 0, 0, 0, 108, 51, 48, 29, 0, 64, + 0, 109, 94, 43, 44, 45, 46, 0, 0, 50, + 63, 66, 47, 52 }; -/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = + /* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = { - 6, 0, 104, 0, 3, 0, 6, 6, 99, 100, - 0, 1, 0, 0, 0, 0, 121, 0, 0, 0, - 0, 0, 0, 14, 18, 15, 16, 20, 17, 19, - 21, 0, 22, 0, 7, 34, 25, 34, 26, 55, - 65, 8, 70, 23, 93, 79, 9, 27, 88, 24, - 10, 0, 105, 2, 74, 13, 0, 101, 0, 122, - 0, 102, 0, 0, 0, 119, 120, 0, 0, 0, - 108, 103, 0, 0, 0, 0, 0, 0, 0, 88, - 0, 0, 75, 83, 51, 84, 30, 32, 0, 116, - 0, 0, 67, 0, 0, 0, 0, 0, 0, 11, - 12, 0, 0, 0, 0, 97, 0, 0, 0, 47, - 0, 40, 39, 35, 36, 0, 38, 37, 0, 0, - 97, 0, 59, 60, 56, 58, 57, 66, 54, 53, - 71, 73, 69, 72, 68, 106, 95, 0, 94, 80, - 82, 78, 81, 77, 90, 91, 89, 115, 117, 118, - 114, 109, 110, 111, 112, 113, 29, 86, 0, 106, - 0, 106, 106, 106, 0, 0, 0, 87, 63, 106, - 0, 106, 0, 96, 0, 0, 41, 98, 0, 0, - 106, 49, 46, 28, 0, 62, 0, 107, 92, 42, - 43, 44, 0, 0, 48, 61, 64, 45, 50 + -92, -92, 285, 291, -92, 32, -66, -92, -92, -92, + -92, 261, -92, -92, -92, -92, -92, -92, -92, 1, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, 24, -92, -92, -92, -92, -92, 221, 220, -64, + -92, -92, 179, -1, 67, 0, 110, -67, -91, -92 }; -/* YYDEFGOTO[NTERM-NUM]. */ + /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 3, 4, 5, 33, 34, 112, 35, 36, 37, - 38, 74, 113, 114, 165, 194, 39, 40, 128, 41, - 76, 124, 77, 42, 132, 43, 78, 6, 44, 45, - 141, 46, 80, 47, 48, 49, 115, 116, 81, 117, - 79, 138, 160, 161, 50, 7, 173, 69, 70, 60 + -1, 3, 4, 5, 34, 35, 114, 36, 37, 38, + 39, 75, 115, 116, 168, 199, 40, 41, 130, 42, + 77, 126, 78, 43, 134, 44, 79, 6, 45, 46, + 143, 47, 81, 48, 49, 50, 117, 118, 82, 119, + 80, 140, 162, 163, 51, 7, 176, 70, 71, 61 }; -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -91 -static const yytype_int16 yypact[] = + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_int16 yytable[] = { - 19, 37, -91, 13, -91, 79, -91, 20, -91, -91, - -16, -91, 21, 37, 25, 37, 41, 36, 37, 78, - 83, 31, 56, -91, -91, -91, -91, -91, -91, -91, - -91, 116, -91, 127, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, 147, -91, -91, 105, -91, 109, -91, 111, -91, - 114, -91, 136, 137, 142, -91, -91, 31, 31, 76, - 254, -91, 143, 146, 27, 115, 207, 258, 243, -14, - 243, 179, -91, -91, -91, -91, -91, -91, -7, -91, - 31, 31, 105, 51, 51, 51, 51, 51, 51, -91, - -91, 156, 168, 181, 37, 37, 31, 178, 51, -91, - 206, -91, -91, -91, -91, 196, -91, -91, 175, 37, - 37, 185, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, 214, -91, 230, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, 183, -91, - -91, -91, -91, -91, -91, -91, -91, -91, 31, 214, - 194, 214, 45, 214, 51, 26, 195, -91, -91, 214, - 197, 214, 31, -91, 139, 208, -91, -91, 220, 224, - 214, 222, -91, -91, 226, -91, 227, 123, -91, -91, - -91, -91, 235, 37, -91, -91, -91, -91, -91 + 10, 89, 90, 152, 153, 154, 155, 156, 157, 137, + 55, 125, 57, 128, 59, 11, 147, 63, 148, 167, + 1, 138, 1, 2, 150, 151, 149, -32, 102, 91, + 92, -32, -32, -32, -32, -32, -32, -32, -32, 103, + 164, -32, -32, 104, -32, 105, 106, 107, 108, 109, + 110, -32, 111, 2, 112, 53, 14, 15, 185, 17, + 18, 19, 20, 113, 56, 21, 22, 186, 8, 9, + 93, 66, 67, 147, 58, 148, 184, 60, 175, 68, + 133, 102, 142, 62, 69, -54, -54, 33, -54, -54, + -54, -54, 103, 177, -54, -54, 104, 120, 121, 122, + 123, 91, 92, 135, 161, 144, 64, 112, 191, 65, + 129, 132, 72, 141, 66, 67, 124, -34, 102, 73, + 172, -34, -34, -34, -34, -34, -34, -34, -34, 103, + 74, -34, -34, 104, -34, 105, 106, 107, 108, 109, + 110, -34, 111, 53, 112, 131, 136, 83, 145, 84, + -5, 12, 85, 113, 13, 14, 15, 16, 17, 18, + 19, 20, 91, 92, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 86, 87, 32, 2, 91, + 92, 192, 91, 92, -4, 12, 33, 88, 13, 14, + 15, 16, 17, 18, 19, 20, 100, 203, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 101, + 158, 32, 159, 160, 169, 165, 166, -87, 102, 170, + 33, -87, -87, -87, -87, -87, -87, -87, -87, 171, + 174, -87, -87, 104, -87, -87, -87, -87, -87, -87, + -87, -87, 102, 175, 112, -78, -78, -78, -78, -78, + -78, -78, -78, 146, 92, -78, -78, 104, 179, 13, + 14, 15, 16, 17, 18, 19, 20, 187, 112, 21, + 22, 178, 189, 180, 181, 182, 183, 146, 193, 194, + 195, 196, 188, 200, 190, 94, 95, 96, 97, 98, + 198, 33, 54, 201, 197, 99, 202, 52, 127, 76, + 139, 173 }; -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = +static const yytype_uint8 yycheck[] = { - -91, -91, 264, 268, -91, 30, -65, -91, -91, -91, - -91, 238, -91, -91, -91, -91, -91, -91, -91, -12, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -5, -91, -91, -91, -91, -91, 200, 209, -61, - -91, -91, 170, -1, 65, 0, 118, -66, -90, -91 + 1, 68, 69, 94, 95, 96, 97, 98, 99, 24, + 10, 77, 13, 77, 15, 0, 82, 18, 82, 110, + 3, 36, 3, 36, 91, 92, 34, 0, 1, 37, + 38, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 107, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 36, 27, 36, 5, 6, 27, 8, + 9, 10, 11, 36, 36, 14, 15, 36, 27, 28, + 70, 27, 28, 139, 36, 139, 167, 27, 14, 35, + 79, 1, 81, 36, 40, 5, 6, 36, 8, 9, + 10, 11, 12, 160, 14, 15, 16, 17, 18, 19, + 20, 37, 38, 79, 105, 81, 27, 27, 175, 27, + 78, 79, 36, 81, 27, 28, 36, 0, 1, 1, + 121, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 1, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 36, 27, 78, 79, 36, 81, 36, + 0, 1, 36, 36, 4, 5, 6, 7, 8, 9, + 10, 11, 37, 38, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 36, 36, 27, 36, 37, + 38, 36, 37, 38, 0, 1, 36, 36, 4, 5, + 6, 7, 8, 9, 10, 11, 36, 198, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 36, + 36, 27, 36, 26, 1, 27, 27, 0, 1, 13, + 36, 4, 5, 6, 7, 8, 9, 10, 11, 36, + 27, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 1, 14, 27, 4, 5, 6, 7, 8, + 9, 10, 11, 36, 38, 14, 15, 16, 36, 4, + 5, 6, 7, 8, 9, 10, 11, 36, 27, 14, + 15, 161, 36, 163, 164, 165, 166, 36, 36, 36, + 36, 36, 172, 36, 174, 29, 30, 31, 32, 33, + 39, 36, 7, 36, 184, 39, 36, 6, 77, 38, + 80, 122 }; -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -86 -static const yytype_int16 yytable[] = + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = { - 10, 88, 89, 150, 151, 152, 153, 154, 155, 135, - 54, 123, 56, 11, 58, 126, 145, 62, 164, 2, - 146, 136, 1, 1, 148, 149, 147, -31, 101, 90, - 91, -31, -31, -31, -31, -31, -31, -31, -31, 102, - 162, -31, -31, 103, -31, 104, 105, 106, 107, 108, - -31, 109, 181, 110, 2, 52, 55, 65, 66, 172, - 57, 182, 111, 8, 9, 67, 131, 59, 140, 92, - 68, 61, 145, 133, 180, 142, 146, 65, 66, -5, - 12, 90, 91, 13, 14, 15, 16, 17, 18, 19, - 20, 71, 174, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 159, 63, 31, 187, 127, 130, 64, - 139, 2, 90, 91, 32, -33, 101, 72, 169, -33, - -33, -33, -33, -33, -33, -33, -33, 102, 73, -33, - -33, 103, -33, 104, 105, 106, 107, 108, -33, 109, - 52, 110, 129, 134, 82, 143, 83, -4, 12, 84, - 111, 13, 14, 15, 16, 17, 18, 19, 20, 90, - 91, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 85, 86, 31, 188, 90, 91, 87, 99, -85, - 101, 100, 32, -85, -85, -85, -85, -85, -85, -85, - -85, 156, 198, -85, -85, 103, -85, -85, -85, -85, - -85, -85, -85, 157, 163, 110, 158, 166, 101, 167, - 168, 171, -52, -52, 144, -52, -52, -52, -52, 102, - 91, -52, -52, 103, 118, 119, 120, 121, 172, 176, - 183, 101, 185, 110, -76, -76, -76, -76, -76, -76, - -76, -76, 122, 189, -76, -76, 103, 13, 14, 15, - 16, 17, 18, 19, 20, 190, 110, 21, 22, 191, - 193, 195, 196, 14, 15, 144, 17, 18, 19, 20, - 197, 53, 21, 22, 51, 75, 125, 175, 32, 177, - 178, 179, 93, 94, 95, 96, 97, 184, 137, 186, - 170, 0, 98, 32, 0, 0, 0, 0, 192 + 0, 3, 36, 42, 43, 44, 68, 86, 27, 28, + 84, 0, 1, 4, 5, 6, 7, 8, 9, 10, + 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 27, 36, 45, 46, 48, 49, 50, 51, + 57, 58, 60, 64, 66, 69, 70, 72, 74, 75, + 76, 85, 44, 36, 43, 86, 36, 84, 36, 84, + 27, 90, 36, 84, 27, 27, 27, 28, 35, 40, + 88, 89, 36, 1, 1, 52, 52, 61, 63, 67, + 81, 73, 79, 36, 36, 36, 36, 36, 36, 88, + 88, 37, 38, 86, 29, 30, 31, 32, 33, 39, + 36, 36, 1, 12, 16, 18, 19, 20, 21, 22, + 23, 25, 27, 36, 47, 53, 54, 77, 78, 80, + 17, 18, 19, 20, 36, 47, 62, 78, 80, 46, + 59, 85, 46, 60, 65, 72, 85, 24, 36, 79, + 82, 46, 60, 71, 72, 85, 36, 47, 80, 34, + 88, 88, 89, 89, 89, 89, 89, 89, 36, 36, + 26, 84, 83, 84, 88, 27, 27, 89, 55, 1, + 13, 36, 84, 83, 27, 14, 87, 88, 87, 36, + 87, 87, 87, 87, 89, 27, 36, 36, 87, 36, + 87, 88, 36, 36, 36, 36, 36, 87, 39, 56, + 36, 36, 36, 84 }; -#define yypact_value_is_default(yystate) \ - ((yystate) == (-91)) - -#define yytable_value_is_error(yytable_value) \ - YYID (0) - -static const yytype_int16 yycheck[] = + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = { - 1, 67, 68, 93, 94, 95, 96, 97, 98, 23, - 10, 76, 13, 0, 15, 76, 81, 18, 108, 35, - 81, 35, 3, 3, 90, 91, 33, 0, 1, 36, - 37, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 106, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 26, 26, 35, 35, 35, 26, 27, 14, - 35, 35, 35, 26, 27, 34, 78, 26, 80, 69, - 39, 35, 137, 78, 164, 80, 137, 26, 27, 0, - 1, 36, 37, 4, 5, 6, 7, 8, 9, 10, - 11, 35, 158, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 104, 26, 26, 172, 77, 78, 26, - 80, 35, 36, 37, 35, 0, 1, 1, 119, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 1, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 35, 26, 77, 78, 35, 80, 35, 0, 1, 35, - 35, 4, 5, 6, 7, 8, 9, 10, 11, 36, - 37, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 35, 35, 26, 35, 36, 37, 35, 35, 0, - 1, 35, 35, 4, 5, 6, 7, 8, 9, 10, - 11, 35, 193, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 35, 26, 26, 25, 1, 1, 13, - 35, 26, 5, 6, 35, 8, 9, 10, 11, 12, - 37, 14, 15, 16, 17, 18, 19, 20, 14, 35, - 35, 1, 35, 26, 4, 5, 6, 7, 8, 9, - 10, 11, 35, 35, 14, 15, 16, 4, 5, 6, - 7, 8, 9, 10, 11, 35, 26, 14, 15, 35, - 38, 35, 35, 5, 6, 35, 8, 9, 10, 11, - 35, 7, 14, 15, 6, 37, 76, 159, 35, 161, - 162, 163, 28, 29, 30, 31, 32, 169, 79, 171, - 120, -1, 38, 35, -1, -1, -1, -1, 180 + 0, 41, 42, 42, 43, 43, 44, 44, 44, 44, + 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 46, 46, 46, 46, 46, 46, 47, + 47, 48, 49, 50, 51, 52, 52, 52, 52, 52, + 52, 52, 53, 53, 53, 53, 53, 53, 54, 55, + 55, 56, 56, 57, 58, 59, 60, 61, 61, 61, + 61, 61, 61, 62, 62, 62, 62, 63, 63, 64, + 65, 66, 67, 67, 67, 67, 68, 69, 70, 71, + 72, 73, 73, 73, 73, 74, 75, 76, 77, 78, + 79, 79, 79, 79, 80, 81, 81, 81, 82, 83, + 83, 84, 84, 85, 85, 85, 86, 86, 87, 87, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 89, 89, 90, 90 }; -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = { - 0, 3, 35, 41, 42, 43, 67, 85, 26, 27, - 83, 0, 1, 4, 5, 6, 7, 8, 9, 10, - 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 26, 35, 44, 45, 47, 48, 49, 50, 56, - 57, 59, 63, 65, 68, 69, 71, 73, 74, 75, - 84, 43, 35, 42, 85, 35, 83, 35, 83, 26, - 89, 35, 83, 26, 26, 26, 27, 34, 39, 87, - 88, 35, 1, 1, 51, 51, 60, 62, 66, 80, - 72, 78, 35, 35, 35, 35, 35, 35, 87, 87, - 36, 37, 85, 28, 29, 30, 31, 32, 38, 35, - 35, 1, 12, 16, 18, 19, 20, 21, 22, 24, - 26, 35, 46, 52, 53, 76, 77, 79, 17, 18, - 19, 20, 35, 46, 61, 77, 79, 45, 58, 84, - 45, 59, 64, 71, 84, 23, 35, 78, 81, 45, - 59, 70, 71, 84, 35, 46, 79, 33, 87, 87, - 88, 88, 88, 88, 88, 88, 35, 35, 25, 83, - 82, 83, 87, 26, 88, 54, 1, 13, 35, 83, - 82, 26, 14, 86, 87, 86, 35, 86, 86, 86, - 88, 26, 35, 35, 86, 35, 86, 87, 35, 35, - 35, 35, 86, 38, 55, 35, 35, 35, 83 + 0, 2, 2, 1, 2, 1, 0, 2, 2, 2, + 2, 4, 4, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, + 2, 3, 2, 3, 2, 0, 2, 2, 2, 2, + 2, 2, 3, 4, 4, 4, 4, 5, 3, 0, + 3, 0, 2, 3, 2, 1, 3, 0, 2, 2, + 2, 2, 2, 4, 3, 2, 4, 0, 2, 3, + 1, 3, 0, 2, 2, 2, 3, 3, 3, 1, + 3, 0, 2, 2, 2, 3, 3, 2, 2, 2, + 0, 2, 2, 2, 4, 0, 2, 2, 2, 0, + 2, 1, 1, 2, 2, 2, 1, 2, 0, 2, + 1, 3, 3, 3, 3, 3, 3, 3, 2, 3, + 3, 1, 1, 0, 1 }; -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. However, - YYFAIL appears to be in use. Nevertheless, it is formally deprecated - in Bison 2.4.2's NEWS entry, where a plan to phase it out is - discussed. */ - -#define YYFAIL goto yyerrlab -#if defined YYFAIL - /* This is here to suppress warnings from the GCC cpp's - -Wunused-macros. Normally we don't worry about that warning, but - some users do, and we want to make it easy for users to remove - YYFAIL uses, which will produce warnings from Bison 2.5. */ -#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + #define YYRECOVERING() (!!yyerrstatus) @@ -855,55 +815,15 @@ do \ else \ { \ yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* This macro is provided for backward compatibility. */ - -#ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -#endif + YYERROR; \ + } \ +while (0) +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 -/* YYLEX -- calling `yylex' with the right arguments. */ -#ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) -#else -# define YYLEX yylex () -#endif /* Enable debugging if requested. */ #if YYDEBUG @@ -913,40 +833,36 @@ while (YYID (0)) # define YYFPRINTF fprintf # endif -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ +/*----------------------------------------. +| Print this symbol's value on YYOUTPUT. | +`----------------------------------------*/ -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif { FILE *yyo = yyoutput; YYUSE (yyo); @@ -955,14 +871,8 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep) # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); # endif - switch (yytype) - { - default: - break; - } + YYUSE (yytype); } @@ -970,22 +880,11 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep) | Print this symbol on YYOUTPUT. | `--------------------------------*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif { - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + YYFPRINTF (yyoutput, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep); YYFPRINTF (yyoutput, ")"); @@ -996,16 +895,8 @@ yy_symbol_print (yyoutput, yytype, yyvaluep) | TOP (included). | `------------------------------------------------------------------*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) @@ -1016,49 +907,42 @@ yy_stack_print (yybottom, yytop) YYFPRINTF (stderr, "\n"); } -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule) -#else -static void -yy_reduce_print (yyvsp, yyrule) - YYSTYPE *yyvsp; - int yyrule; -#endif +yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) { + unsigned long int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; - unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); + yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - ); + yy_symbol_print (stderr, + yystos[yyssp[yyi + 1 - yynrhs]], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); YYFPRINTF (stderr, "\n"); } } -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, Rule); \ -} while (YYID (0)) +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ @@ -1072,7 +956,7 @@ int yydebug; /* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH +#ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif @@ -1095,15 +979,8 @@ int yydebug; # define yystrlen strlen # else /* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) @@ -1119,16 +996,8 @@ yystrlen (yystr) # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif { char *yyd = yydest; const char *yys = yysrc; @@ -1158,27 +1027,27 @@ yytnamerr (char *yyres, const char *yystr) char const *yyp = yystr; for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } do_not_strip_quotes: ; } @@ -1201,12 +1070,11 @@ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { - YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); + YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ - const char *yyformat = YY_NULL; + const char *yyformat = YY_NULLPTR; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per @@ -1214,10 +1082,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, int yycount = 0; /* There are many possibilities here to consider: - - Assume YYFAIL is not used. It's too flawed to consider. See - - for details. YYERROR is fine as it does not invoke this - function. - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected @@ -1266,11 +1130,13 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, break; } yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } } } } @@ -1290,10 +1156,12 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, # undef YYCASE_ } - yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } if (*yymsg_alloc < yysize) { @@ -1330,78 +1198,58 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, | Release the memory associated to this symbol. | `-----------------------------------------------*/ -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yymsg, yytype, yyvaluep) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; -#endif { YYUSE (yyvaluep); - if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN switch (yytype) { - case 57: /* "choice_entry" */ + case 58: /* choice_entry */ - { + { fprintf(stderr, "%s:%d: missing end statement for this entry\n", - (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); - if (current_menu == (yyvaluep->menu)) + ((*yyvaluep).menu)->file->name, ((*yyvaluep).menu)->lineno); + if (current_menu == ((*yyvaluep).menu)) menu_end_menu(); -}; +} + + break; - break; - case 63: /* "if_entry" */ + case 64: /* if_entry */ - { + { fprintf(stderr, "%s:%d: missing end statement for this entry\n", - (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); - if (current_menu == (yyvaluep->menu)) + ((*yyvaluep).menu)->file->name, ((*yyvaluep).menu)->lineno); + if (current_menu == ((*yyvaluep).menu)) menu_end_menu(); -}; +} - break; - case 69: /* "menu_entry" */ + break; - { + case 70: /* menu_entry */ + + { fprintf(stderr, "%s:%d: missing end statement for this entry\n", - (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); - if (current_menu == (yyvaluep->menu)) + ((*yyvaluep).menu)->file->name, ((*yyvaluep).menu)->lineno); + if (current_menu == ((*yyvaluep).menu)) menu_end_menu(); -}; +} + + break; - break; default: - break; + break; } + YY_IGNORE_MAYBE_UNINITIALIZED_END } -/* Prevent warnings from -Wmissing-prototypes. */ -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ /* The lookahead symbol. */ @@ -1409,7 +1257,6 @@ int yychar; /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; - /* Number of syntax errors so far. */ int yynerrs; @@ -1418,35 +1265,16 @@ int yynerrs; | yyparse. | `----------*/ -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) int yyparse (void) -#else -int -yyparse () - -#endif -#endif { int yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. + 'yyss': related to states. + 'yyvs': related to semantic values. Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ @@ -1466,7 +1294,7 @@ yyparse () int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ - int yytoken; + int yytoken = 0; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; @@ -1484,9 +1312,8 @@ yyparse () Keep to zero when no symbol should be popped. */ int yylen = 0; - yytoken = 0; - yyss = yyssa; - yyvs = yyvsa; + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); @@ -1495,14 +1322,6 @@ yyparse () yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - yyssp = yyss; - yyvsp = yyvs; - goto yysetstate; /*------------------------------------------------------------. @@ -1523,23 +1342,23 @@ yyparse () #ifdef yyoverflow { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE @@ -1547,22 +1366,22 @@ yyparse () # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; + goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; + yystacksize = YYMAXDEPTH; { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ @@ -1571,10 +1390,10 @@ yyparse () yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) - YYABORT; + YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); @@ -1603,7 +1422,7 @@ yybackup: if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; + yychar = yylex (); } if (yychar <= YYEOF) @@ -1643,7 +1462,9 @@ yybackup: yychar = YYEMPTY; yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END goto yynewstate; @@ -1666,7 +1487,7 @@ yyreduce: yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. + '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison @@ -1682,64 +1503,73 @@ yyreduce: case 10: { zconf_error("unexpected end statement"); } + break; case 11: - { zconf_error("unknown statement \"%s\"", (yyvsp[(2) - (4)].string)); } + { zconf_error("unknown statement \"%s\"", (yyvsp[-2].string)); } + break; case 12: { - zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[(2) - (4)].id)->name); + zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[-2].id)->name); } + break; case 13: { zconf_error("invalid statement"); } + break; - case 28: + case 29: + + { zconf_error("unknown option \"%s\"", (yyvsp[-2].string)); } - { zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); } break; - case 29: + case 30: { zconf_error("invalid option"); } + break; - case 30: + case 31: { - struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0); + struct symbol *sym = sym_lookup((yyvsp[-1].string), 0); sym->flags |= SYMBOL_OPTIONAL; menu_add_entry(sym); - printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); + printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string)); } + break; - case 31: + case 32: { menu_end_entry(); printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); } + break; - case 32: + case 33: { - struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0); + struct symbol *sym = sym_lookup((yyvsp[-1].string), 0); sym->flags |= SYMBOL_OPTIONAL; menu_add_entry(sym); - printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); + printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string)); } + break; - case 33: + case 34: { if (current_entry->prompt) @@ -1749,352 +1579,410 @@ yyreduce: menu_end_entry(); printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); } + break; - case 41: + case 42: { - menu_set_type((yyvsp[(1) - (3)].id)->stype); + menu_set_type((yyvsp[-2].id)->stype); printd(DEBUG_PARSE, "%s:%d:type(%u)\n", zconf_curname(), zconf_lineno(), - (yyvsp[(1) - (3)].id)->stype); + (yyvsp[-2].id)->stype); } + break; - case 42: + case 43: { - menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr)); + menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr)); printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); } + break; - case 43: + case 44: { - menu_add_expr(P_DEFAULT, (yyvsp[(2) - (4)].expr), (yyvsp[(3) - (4)].expr)); - if ((yyvsp[(1) - (4)].id)->stype != S_UNKNOWN) - menu_set_type((yyvsp[(1) - (4)].id)->stype); + menu_add_expr(P_DEFAULT, (yyvsp[-2].expr), (yyvsp[-1].expr)); + if ((yyvsp[-3].id)->stype != S_UNKNOWN) + menu_set_type((yyvsp[-3].id)->stype); printd(DEBUG_PARSE, "%s:%d:default(%u)\n", zconf_curname(), zconf_lineno(), - (yyvsp[(1) - (4)].id)->stype); + (yyvsp[-3].id)->stype); } + break; - case 44: + case 45: { - menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr)); + menu_add_symbol(P_SELECT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr)); printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); } + break; - case 45: + case 46: { - menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[(2) - (5)].symbol), (yyvsp[(3) - (5)].symbol)), (yyvsp[(4) - (5)].expr)); + menu_add_symbol(P_IMPLY, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr)); + printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno()); +} + + break; + + case 47: + + { + menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[-3].symbol), (yyvsp[-2].symbol)), (yyvsp[-1].expr)); printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); } + break; - case 48: + case 50: { - const struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string))); + const struct kconf_id *id = kconf_id_lookup((yyvsp[-1].string), strlen((yyvsp[-1].string))); if (id && id->flags & TF_OPTION) - menu_add_option(id->token, (yyvsp[(3) - (3)].string)); + menu_add_option(id->token, (yyvsp[0].string)); else - zconfprint("warning: ignoring unknown option %s", (yyvsp[(2) - (3)].string)); - free((yyvsp[(2) - (3)].string)); + zconfprint("warning: ignoring unknown option %s", (yyvsp[-1].string)); + free((yyvsp[-1].string)); } + break; - case 49: + case 51: { (yyval.string) = NULL; } + break; - case 50: + case 52: + + { (yyval.string) = (yyvsp[0].string); } - { (yyval.string) = (yyvsp[(2) - (2)].string); } break; - case 51: + case 53: { - struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), SYMBOL_CHOICE); + struct symbol *sym = sym_lookup((yyvsp[-1].string), SYMBOL_CHOICE); sym->flags |= SYMBOL_AUTO; menu_add_entry(sym); menu_add_expr(P_CHOICE, NULL, NULL); printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); } + break; - case 52: + case 54: { (yyval.menu) = menu_add_menu(); } + break; - case 53: + case 55: { - if (zconf_endtoken((yyvsp[(1) - (1)].id), T_CHOICE, T_ENDCHOICE)) { + if (zconf_endtoken((yyvsp[0].id), T_CHOICE, T_ENDCHOICE)) { menu_end_menu(); printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); } } + break; - case 61: + case 63: { - menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr)); + menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr)); printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); } + break; - case 62: + case 64: { - if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) { - menu_set_type((yyvsp[(1) - (3)].id)->stype); + if ((yyvsp[-2].id)->stype == S_BOOLEAN || (yyvsp[-2].id)->stype == S_TRISTATE) { + menu_set_type((yyvsp[-2].id)->stype); printd(DEBUG_PARSE, "%s:%d:type(%u)\n", zconf_curname(), zconf_lineno(), - (yyvsp[(1) - (3)].id)->stype); + (yyvsp[-2].id)->stype); } else YYERROR; } + break; - case 63: + case 65: { current_entry->sym->flags |= SYMBOL_OPTIONAL; printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); } + break; - case 64: + case 66: { - if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) { - menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr)); + if ((yyvsp[-3].id)->stype == S_UNKNOWN) { + menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr)); printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); } else YYERROR; } + break; - case 67: + case 69: { printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); menu_add_entry(NULL); - menu_add_dep((yyvsp[(2) - (3)].expr)); + menu_add_dep((yyvsp[-1].expr)); (yyval.menu) = menu_add_menu(); } + break; - case 68: + case 70: { - if (zconf_endtoken((yyvsp[(1) - (1)].id), T_IF, T_ENDIF)) { + if (zconf_endtoken((yyvsp[0].id), T_IF, T_ENDIF)) { menu_end_menu(); printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); } } + break; - case 74: + case 76: { - menu_add_prompt(P_MENU, (yyvsp[(2) - (3)].string), NULL); + menu_add_prompt(P_MENU, (yyvsp[-1].string), NULL); } + break; - case 75: + case 77: { menu_add_entry(NULL); - menu_add_prompt(P_MENU, (yyvsp[(2) - (3)].string), NULL); + menu_add_prompt(P_MENU, (yyvsp[-1].string), NULL); printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); } + break; - case 76: + case 78: { (yyval.menu) = menu_add_menu(); } + break; - case 77: + case 79: { - if (zconf_endtoken((yyvsp[(1) - (1)].id), T_MENU, T_ENDMENU)) { + if (zconf_endtoken((yyvsp[0].id), T_MENU, T_ENDMENU)) { menu_end_menu(); printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); } } + break; - case 83: + case 85: { - printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); - zconf_nextfile((yyvsp[(2) - (3)].string)); + printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string)); + zconf_nextfile((yyvsp[-1].string)); } + break; - case 84: + case 86: { menu_add_entry(NULL); - menu_add_prompt(P_COMMENT, (yyvsp[(2) - (3)].string), NULL); + menu_add_prompt(P_COMMENT, (yyvsp[-1].string), NULL); printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); } + break; - case 85: + case 87: { menu_end_entry(); } + break; - case 86: + case 88: { printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); zconf_starthelp(); } + break; - case 87: + case 89: { - current_entry->help = (yyvsp[(2) - (2)].string); + current_entry->help = (yyvsp[0].string); } + break; - case 92: + case 94: { - menu_add_dep((yyvsp[(3) - (4)].expr)); + menu_add_dep((yyvsp[-1].expr)); printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); } - break; - - case 96: - { - menu_add_visibility((yyvsp[(2) - (2)].expr)); -} break; case 98: { - menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr)); + menu_add_visibility((yyvsp[0].expr)); } - break; - case 101: - - { (yyval.id) = (yyvsp[(1) - (2)].id); } break; - case 102: + case 100: + + { + menu_add_prompt(P_PROMPT, (yyvsp[-1].string), (yyvsp[0].expr)); +} - { (yyval.id) = (yyvsp[(1) - (2)].id); } break; case 103: - { (yyval.id) = (yyvsp[(1) - (2)].id); } + { (yyval.id) = (yyvsp[-1].id); } + break; - case 106: + case 104: + + { (yyval.id) = (yyvsp[-1].id); } - { (yyval.expr) = NULL; } break; - case 107: + case 105: + + { (yyval.id) = (yyvsp[-1].id); } - { (yyval.expr) = (yyvsp[(2) - (2)].expr); } break; case 108: - { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); } + { (yyval.expr) = NULL; } + break; case 109: - { (yyval.expr) = expr_alloc_comp(E_LTH, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); } + { (yyval.expr) = (yyvsp[0].expr); } + break; case 110: - { (yyval.expr) = expr_alloc_comp(E_LEQ, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); } + { (yyval.expr) = expr_alloc_symbol((yyvsp[0].symbol)); } + break; case 111: - { (yyval.expr) = expr_alloc_comp(E_GTH, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); } + { (yyval.expr) = expr_alloc_comp(E_LTH, (yyvsp[-2].symbol), (yyvsp[0].symbol)); } + break; case 112: - { (yyval.expr) = expr_alloc_comp(E_GEQ, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); } + { (yyval.expr) = expr_alloc_comp(E_LEQ, (yyvsp[-2].symbol), (yyvsp[0].symbol)); } + break; case 113: - { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); } + { (yyval.expr) = expr_alloc_comp(E_GTH, (yyvsp[-2].symbol), (yyvsp[0].symbol)); } + break; case 114: - { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); } + { (yyval.expr) = expr_alloc_comp(E_GEQ, (yyvsp[-2].symbol), (yyvsp[0].symbol)); } + break; case 115: - { (yyval.expr) = (yyvsp[(2) - (3)].expr); } + { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); } + break; case 116: - { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); } + { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); } + break; case 117: - { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } + { (yyval.expr) = (yyvsp[-1].expr); } + break; case 118: - { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); } + { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[0].expr)); } + break; case 119: - { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); } + { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[-2].expr), (yyvsp[0].expr)); } + break; case 120: - { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); } + { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); } + break; case 121: + { (yyval.symbol) = sym_lookup((yyvsp[0].string), 0); free((yyvsp[0].string)); } + + break; + + case 122: + + { (yyval.symbol) = sym_lookup((yyvsp[0].string), SYMBOL_CONST); free((yyvsp[0].string)); } + + break; + + case 123: + { (yyval.string) = NULL; } + break; @@ -2120,7 +2008,7 @@ yyreduce: *++yyvsp = yyval; - /* Now `shift' the result of the reduction. Determine what state + /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ @@ -2135,9 +2023,9 @@ yyreduce: goto yynewstate; -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ @@ -2188,20 +2076,20 @@ yyerrlab: if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an - error, discard it. */ + error, discard it. */ if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } } /* Else will try to reuse lookahead token after shifting the error @@ -2220,7 +2108,7 @@ yyerrorlab: if (/*CONSTCOND*/ 0) goto yyerrorlab; - /* Do not reclaim the symbols of the rule which action triggered + /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; @@ -2233,35 +2121,37 @@ yyerrorlab: | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ + yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) - YYABORT; + YYABORT; yydestruct ("Error: popping", - yystos[yystate], yyvsp); + yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ @@ -2304,14 +2194,14 @@ yyreturn: yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); } - /* Do not reclaim the symbols of the rule which action triggered + /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); + yystos[*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow @@ -2322,14 +2212,11 @@ yyreturn: if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif - /* Make sure YYID is used. */ - return YYID (yyresult); + return yyresult; } - - void conf_parse(const char *name) { struct symbol *sym; @@ -2501,6 +2388,11 @@ static void print_symbol(FILE *out, struct menu *menu) expr_fprint(prop->expr, out); fputc('\n', out); break; + case P_IMPLY: + fputs( " imply ", out); + expr_fprint(prop->expr, out); + fputc('\n', out); + break; case P_RANGE: fputs( " range ", out); expr_fprint(prop->expr, out); @@ -2577,4 +2469,3 @@ void zconfdump(FILE *out) #include "expr.c" #include "symbol.c" #include "menu.c" - -- cgit v1.2.3 From d1cbfd771ce8297fa11e89f315392de6056a2181 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 11 Nov 2016 00:10:07 -0500 Subject: ptp_clock: Allow for it to be optional In order to break the hard dependency between the PTP clock subsystem and ethernet drivers capable of being clock providers, this patch provides simple PTP stub functions to allow linkage of those drivers into the kernel even when the PTP subsystem is configured out. Drivers must be ready to accept NULL from ptp_clock_register() in that case. And to make it possible for PTP to be configured out, the select statement in those driver's Kconfig menu entries is converted to the new "imply" statement. This way the PTP subsystem may have Kconfig dependencies of its own, such as POSIX_TIMERS, without having to make those ethernet drivers unavailable if POSIX timers are cconfigured out. And when support for POSIX timers is selected again then the default config option for PTP clock support will automatically be adjusted accordingly. The pch_gbe driver is a bit special as it relies on extra code in drivers/ptp/ptp_pch.c. Therefore we let the make process descend into drivers/ptp/ even if PTP_1588_CLOCK is unselected. Signed-off-by: Nicolas Pitre Acked-by: Richard Cochran Acked-by: Edward Cree Acked-by: Thomas Gleixner Acked-by: John Stultz Reviewed-by: Josh Triplett Cc: Paul Bolle Cc: linux-kbuild@vger.kernel.org Cc: netdev@vger.kernel.org Cc: Michal Marek Link: http://lkml.kernel.org/r/1478841010-28605-4-git-send-email-nicolas.pitre@linaro.org Signed-off-by: Thomas Gleixner --- drivers/Makefile | 2 +- drivers/net/ethernet/adi/Kconfig | 2 +- drivers/net/ethernet/amd/Kconfig | 2 +- drivers/net/ethernet/amd/xgbe/xgbe-main.c | 6 ++- drivers/net/ethernet/broadcom/Kconfig | 4 +- drivers/net/ethernet/cavium/Kconfig | 2 +- drivers/net/ethernet/freescale/Kconfig | 2 +- drivers/net/ethernet/intel/Kconfig | 10 ++-- drivers/net/ethernet/mellanox/mlx4/Kconfig | 2 +- drivers/net/ethernet/mellanox/mlx5/core/Kconfig | 2 +- drivers/net/ethernet/renesas/Kconfig | 2 +- drivers/net/ethernet/samsung/Kconfig | 2 +- drivers/net/ethernet/sfc/Kconfig | 2 +- drivers/net/ethernet/stmicro/stmmac/Kconfig | 2 +- drivers/net/ethernet/ti/Kconfig | 2 +- drivers/net/ethernet/tile/Kconfig | 2 +- drivers/ptp/Kconfig | 8 +-- include/linux/ptp_clock_kernel.h | 65 ++++++++++++++++--------- 18 files changed, 69 insertions(+), 50 deletions(-) diff --git a/drivers/Makefile b/drivers/Makefile index 194d20bee7dc..060026a02f59 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -107,7 +107,7 @@ obj-$(CONFIG_INPUT) += input/ obj-$(CONFIG_RTC_LIB) += rtc/ obj-y += i2c/ media/ obj-$(CONFIG_PPS) += pps/ -obj-$(CONFIG_PTP_1588_CLOCK) += ptp/ +obj-y += ptp/ obj-$(CONFIG_W1) += w1/ obj-y += power/ obj-$(CONFIG_HWMON) += hwmon/ diff --git a/drivers/net/ethernet/adi/Kconfig b/drivers/net/ethernet/adi/Kconfig index 6b94ba610399..98cc8f535021 100644 --- a/drivers/net/ethernet/adi/Kconfig +++ b/drivers/net/ethernet/adi/Kconfig @@ -58,7 +58,7 @@ config BFIN_RX_DESC_NUM config BFIN_MAC_USE_HWSTAMP bool "Use IEEE 1588 hwstamp" depends on BFIN_MAC && BF518 - select PTP_1588_CLOCK + imply PTP_1588_CLOCK default y ---help--- To support the IEEE 1588 Precision Time Protocol (PTP), select y here diff --git a/drivers/net/ethernet/amd/Kconfig b/drivers/net/ethernet/amd/Kconfig index 0038709fd317..713ea7ad22c3 100644 --- a/drivers/net/ethernet/amd/Kconfig +++ b/drivers/net/ethernet/amd/Kconfig @@ -177,7 +177,7 @@ config AMD_XGBE depends on ARM64 || COMPILE_TEST select BITREVERSE select CRC32 - select PTP_1588_CLOCK + imply PTP_1588_CLOCK ---help--- This driver supports the AMD 10GbE Ethernet device found on an AMD SoC. diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c index 9de078819aa6..e10e569c0d5f 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c @@ -773,7 +773,8 @@ static int xgbe_probe(struct platform_device *pdev) goto err_wq; } - xgbe_ptp_register(pdata); + if (IS_REACHABLE(CONFIG_PTP_1588_CLOCK)) + xgbe_ptp_register(pdata); xgbe_debugfs_init(pdata); @@ -812,7 +813,8 @@ static int xgbe_remove(struct platform_device *pdev) xgbe_debugfs_exit(pdata); - xgbe_ptp_unregister(pdata); + if (IS_REACHABLE(CONFIG_PTP_1588_CLOCK)) + xgbe_ptp_unregister(pdata); flush_workqueue(pdata->an_workqueue); destroy_workqueue(pdata->an_workqueue); diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig index bd8c80c0b71c..6a8d74aeb69f 100644 --- a/drivers/net/ethernet/broadcom/Kconfig +++ b/drivers/net/ethernet/broadcom/Kconfig @@ -110,7 +110,7 @@ config TIGON3 depends on PCI select PHYLIB select HWMON - select PTP_1588_CLOCK + imply PTP_1588_CLOCK ---help--- This driver supports Broadcom Tigon3 based gigabit Ethernet cards. @@ -120,7 +120,7 @@ config TIGON3 config BNX2X tristate "Broadcom NetXtremeII 10Gb support" depends on PCI - select PTP_1588_CLOCK + imply PTP_1588_CLOCK select FW_LOADER select ZLIB_INFLATE select LIBCRC32C diff --git a/drivers/net/ethernet/cavium/Kconfig b/drivers/net/ethernet/cavium/Kconfig index 92f411c9f0df..2e64a966617a 100644 --- a/drivers/net/ethernet/cavium/Kconfig +++ b/drivers/net/ethernet/cavium/Kconfig @@ -53,7 +53,7 @@ config THUNDER_NIC_RGX config LIQUIDIO tristate "Cavium LiquidIO support" depends on 64BIT - select PTP_1588_CLOCK + imply PTP_1588_CLOCK select FW_LOADER select LIBCRC32C ---help--- diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig index d1ca45fbb164..5eb9280973fb 100644 --- a/drivers/net/ethernet/freescale/Kconfig +++ b/drivers/net/ethernet/freescale/Kconfig @@ -25,7 +25,7 @@ config FEC ARCH_MXC || SOC_IMX28) default ARCH_MXC || SOC_IMX28 if ARM select PHYLIB - select PTP_1588_CLOCK + imply PTP_1588_CLOCK ---help--- Say Y here if you want to use the built-in 10/100 Fast ethernet controller on some Motorola ColdFire and Freescale i.MX processors. diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index c0e17433f623..1349b45f014d 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -58,7 +58,7 @@ config E1000E tristate "Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support" depends on PCI && (!SPARC32 || BROKEN) select CRC32 - select PTP_1588_CLOCK + imply PTP_1588_CLOCK ---help--- This driver supports the PCI-Express Intel(R) PRO/1000 gigabit ethernet family of adapters. For PCI or PCI-X e1000 adapters, @@ -83,7 +83,7 @@ config E1000E_HWTS config IGB tristate "Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support" depends on PCI - select PTP_1588_CLOCK + imply PTP_1588_CLOCK select I2C select I2C_ALGOBIT ---help--- @@ -156,7 +156,7 @@ config IXGBE tristate "Intel(R) 10GbE PCI Express adapters support" depends on PCI select MDIO - select PTP_1588_CLOCK + imply PTP_1588_CLOCK ---help--- This driver supports Intel(R) 10GbE PCI Express family of adapters. For more information on how to identify your adapter, go @@ -213,7 +213,7 @@ config IXGBEVF config I40E tristate "Intel(R) Ethernet Controller XL710 Family support" - select PTP_1588_CLOCK + imply PTP_1588_CLOCK depends on PCI ---help--- This driver supports Intel(R) Ethernet Controller XL710 Family of @@ -264,7 +264,7 @@ config FM10K tristate "Intel(R) FM10000 Ethernet Switch Host Interface Support" default n depends on PCI_MSI - select PTP_1588_CLOCK + imply PTP_1588_CLOCK ---help--- This driver supports Intel(R) FM10000 Ethernet Switch Host Interface. For more information on how to identify your adapter, diff --git a/drivers/net/ethernet/mellanox/mlx4/Kconfig b/drivers/net/ethernet/mellanox/mlx4/Kconfig index 5098e7f21987..22b1cc012bc9 100644 --- a/drivers/net/ethernet/mellanox/mlx4/Kconfig +++ b/drivers/net/ethernet/mellanox/mlx4/Kconfig @@ -7,7 +7,7 @@ config MLX4_EN depends on MAY_USE_DEVLINK depends on PCI select MLX4_CORE - select PTP_1588_CLOCK + imply PTP_1588_CLOCK ---help--- This driver supports Mellanox Technologies ConnectX Ethernet devices. diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig index aae46884bf93..2cd841590e70 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig +++ b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig @@ -14,7 +14,7 @@ config MLX5_CORE config MLX5_CORE_EN bool "Mellanox Technologies ConnectX-4 Ethernet support" depends on NETDEVICES && ETHERNET && PCI && MLX5_CORE - select PTP_1588_CLOCK + imply PTP_1588_CLOCK default n ---help--- Ethernet support in Mellanox Technologies ConnectX-4 NIC. diff --git a/drivers/net/ethernet/renesas/Kconfig b/drivers/net/ethernet/renesas/Kconfig index 85ec447c2d18..27be51f0a421 100644 --- a/drivers/net/ethernet/renesas/Kconfig +++ b/drivers/net/ethernet/renesas/Kconfig @@ -37,7 +37,7 @@ config RAVB select MII select MDIO_BITBANG select PHYLIB - select PTP_1588_CLOCK + imply PTP_1588_CLOCK help Renesas Ethernet AVB device driver. This driver supports the following SoCs: diff --git a/drivers/net/ethernet/samsung/Kconfig b/drivers/net/ethernet/samsung/Kconfig index 2360d8150777..fbd5e06654c6 100644 --- a/drivers/net/ethernet/samsung/Kconfig +++ b/drivers/net/ethernet/samsung/Kconfig @@ -21,7 +21,7 @@ config SXGBE_ETH depends on HAS_IOMEM && HAS_DMA select PHYLIB select CRC32 - select PTP_1588_CLOCK + imply PTP_1588_CLOCK ---help--- This is the driver for the SXGBE 10G Ethernet IP block found on Samsung platforms. diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig index 4dd92b7b80f4..83f4766a1da0 100644 --- a/drivers/net/ethernet/sfc/Kconfig +++ b/drivers/net/ethernet/sfc/Kconfig @@ -5,7 +5,7 @@ config SFC select CRC32 select I2C select I2C_ALGOBIT - select PTP_1588_CLOCK + imply PTP_1588_CLOCK ---help--- This driver supports 10/40-gigabit Ethernet cards based on the Solarflare SFC4000, SFC9000-family and SFC9100-family diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index 3818c5e06eba..139c85fa6a4d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -4,7 +4,7 @@ config STMMAC_ETH select MII select PHYLIB select CRC32 - select PTP_1588_CLOCK + imply PTP_1588_CLOCK select RESET_CONTROLLER ---help--- This is the driver for the Ethernet IPs are built around a diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig index 9904d740d528..61b835a7e6ae 100644 --- a/drivers/net/ethernet/ti/Kconfig +++ b/drivers/net/ethernet/ti/Kconfig @@ -76,7 +76,7 @@ config TI_CPSW config TI_CPTS bool "TI Common Platform Time Sync (CPTS) Support" depends on TI_CPSW - select PTP_1588_CLOCK + imply PTP_1588_CLOCK ---help--- This driver supports the Common Platform Time Sync unit of the CPSW Ethernet Switch. The unit can time stamp PTP UDP/IPv4 diff --git a/drivers/net/ethernet/tile/Kconfig b/drivers/net/ethernet/tile/Kconfig index f59a6c265331..bdfeaf3d4fce 100644 --- a/drivers/net/ethernet/tile/Kconfig +++ b/drivers/net/ethernet/tile/Kconfig @@ -9,7 +9,7 @@ config TILE_NET select CRC32 select TILE_GXIO_MPIPE if TILEGX select HIGH_RES_TIMERS if TILEGX - select PTP_1588_CLOCK if TILEGX + imply PTP_1588_CLOCK if TILEGX ---help--- This is a standard Linux network device driver for the on-chip Tilera Gigabit Ethernet and XAUI interfaces. diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig index ee3de3421f2d..0f7492f8ea23 100644 --- a/drivers/ptp/Kconfig +++ b/drivers/ptp/Kconfig @@ -28,7 +28,7 @@ config PTP_1588_CLOCK config PTP_1588_CLOCK_GIANFAR tristate "Freescale eTSEC as PTP clock" depends on GIANFAR - select PTP_1588_CLOCK + depends on PTP_1588_CLOCK default y help This driver adds support for using the eTSEC as a PTP @@ -42,7 +42,7 @@ config PTP_1588_CLOCK_GIANFAR config PTP_1588_CLOCK_IXP46X tristate "Intel IXP46x as PTP clock" depends on IXP4XX_ETH - select PTP_1588_CLOCK + depends on PTP_1588_CLOCK default y help This driver adds support for using the IXP46X as a PTP @@ -60,7 +60,7 @@ config DP83640_PHY tristate "Driver for the National Semiconductor DP83640 PHYTER" depends on NETWORK_PHY_TIMESTAMPING depends on PHYLIB - select PTP_1588_CLOCK + depends on PTP_1588_CLOCK ---help--- Supports the DP83640 PHYTER with IEEE 1588 features. @@ -76,7 +76,7 @@ config PTP_1588_CLOCK_PCH tristate "Intel PCH EG20T as PTP clock" depends on X86_32 || COMPILE_TEST depends on HAS_IOMEM && NET - select PTP_1588_CLOCK + imply PTP_1588_CLOCK help This driver adds support for using the PCH EG20T as a PTP clock. The hardware supports time stamping of PTP packets diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h index 5ad54fc66cf0..96699526d342 100644 --- a/include/linux/ptp_clock_kernel.h +++ b/include/linux/ptp_clock_kernel.h @@ -122,30 +122,6 @@ struct ptp_clock_info { struct ptp_clock; -/** - * ptp_clock_register() - register a PTP hardware clock driver - * - * @info: Structure describing the new clock. - * @parent: Pointer to the parent device of the new clock. - * - * Returns a valid pointer on success or PTR_ERR on failure. If PHC - * support is missing at the configuration level, this function - * returns NULL, and drivers are expected to gracefully handle that - * case separately. - */ - -extern struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, - struct device *parent); - -/** - * ptp_clock_unregister() - unregister a PTP hardware clock driver - * - * @ptp: The clock to remove from service. - */ - -extern int ptp_clock_unregister(struct ptp_clock *ptp); - - enum ptp_clock_events { PTP_CLOCK_ALARM, PTP_CLOCK_EXTTS, @@ -171,6 +147,31 @@ struct ptp_clock_event { }; }; +#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK) + +/** + * ptp_clock_register() - register a PTP hardware clock driver + * + * @info: Structure describing the new clock. + * @parent: Pointer to the parent device of the new clock. + * + * Returns a valid pointer on success or PTR_ERR on failure. If PHC + * support is missing at the configuration level, this function + * returns NULL, and drivers are expected to gracefully handle that + * case separately. + */ + +extern struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, + struct device *parent); + +/** + * ptp_clock_unregister() - unregister a PTP hardware clock driver + * + * @ptp: The clock to remove from service. + */ + +extern int ptp_clock_unregister(struct ptp_clock *ptp); + /** * ptp_clock_event() - notify the PTP layer about an event * @@ -202,4 +203,20 @@ extern int ptp_clock_index(struct ptp_clock *ptp); int ptp_find_pin(struct ptp_clock *ptp, enum ptp_pin_function func, unsigned int chan); +#else +static inline struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, + struct device *parent) +{ return NULL; } +static inline int ptp_clock_unregister(struct ptp_clock *ptp) +{ return 0; } +static inline void ptp_clock_event(struct ptp_clock *ptp, + struct ptp_clock_event *event) +{ } +static inline int ptp_clock_index(struct ptp_clock *ptp) +{ return -1; } +static inline int ptp_find_pin(struct ptp_clock *ptp, + enum ptp_pin_function func, unsigned int chan) +{ return -1; } +#endif + #endif -- cgit v1.2.3 From 74ba181e61c6accf9066d6980f44588de2f854f6 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 11 Nov 2016 00:10:08 -0500 Subject: timer: Move sys_alarm from timer.c to itimer.c Move the only user of alarm_setitimer to itimer.c where it is defined. This allows for making alarm_setitimer static, and dropping it from the build when __ARCH_WANT_SYS_ALARM is not defined. Signed-off-by: Nicolas Pitre Acked-by: John Stultz Cc: Paul Bolle Cc: linux-kbuild@vger.kernel.org Cc: netdev@vger.kernel.org Cc: Richard Cochran Cc: Josh Triplett Cc: Michal Marek Cc: Edward Cree Link: http://lkml.kernel.org/r/1478841010-28605-5-git-send-email-nicolas.pitre@linaro.org Signed-off-by: Thomas Gleixner --- include/linux/time.h | 2 -- kernel/time/itimer.c | 15 ++++++++++++++- kernel/time/timer.c | 13 ------------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/include/linux/time.h b/include/linux/time.h index 4cea09d94208..23f0f5ce3090 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -172,8 +172,6 @@ extern int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue); extern int do_getitimer(int which, struct itimerval *value); -extern unsigned int alarm_setitimer(unsigned int seconds); - extern long do_utimes(int dfd, const char __user *filename, struct timespec *times, int flags); struct tms; diff --git a/kernel/time/itimer.c b/kernel/time/itimer.c index 1d5c7204ddc9..2b9f45bc955d 100644 --- a/kernel/time/itimer.c +++ b/kernel/time/itimer.c @@ -238,6 +238,8 @@ again: return 0; } +#ifdef __ARCH_WANT_SYS_ALARM + /** * alarm_setitimer - set alarm in seconds * @@ -250,7 +252,7 @@ again: * On 32 bit machines the seconds value is limited to (INT_MAX/2) to avoid * negative timeval settings which would cause immediate expiry. */ -unsigned int alarm_setitimer(unsigned int seconds) +static unsigned int alarm_setitimer(unsigned int seconds) { struct itimerval it_new, it_old; @@ -275,6 +277,17 @@ unsigned int alarm_setitimer(unsigned int seconds) return it_old.it_value.tv_sec; } +/* + * For backwards compatibility? This can be done in libc so Alpha + * and all newer ports shouldn't need it. + */ +SYSCALL_DEFINE1(alarm, unsigned int, seconds) +{ + return alarm_setitimer(seconds); +} + +#endif + SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value, struct itimerval __user *, ovalue) { diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 88aab86a4594..42d27aa242b9 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1662,19 +1662,6 @@ void run_local_timers(void) raise_softirq(TIMER_SOFTIRQ); } -#ifdef __ARCH_WANT_SYS_ALARM - -/* - * For backwards compatibility? This can be done in libc so Alpha - * and all newer ports shouldn't need it. - */ -SYSCALL_DEFINE1(alarm, unsigned int, seconds) -{ - return alarm_setitimer(seconds); -} - -#endif - static void process_timeout(unsigned long __data) { wake_up_process((struct task_struct *)__data); -- cgit v1.2.3 From 53d3eaa31508222e445b489f3c3ac4c63542a4ef Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 11 Nov 2016 00:10:09 -0500 Subject: posix_cpu_timers: Move the add_device_randomness() call to a proper place There is no logical relation between add_device_randomness() and posix_cpu_timers_exit(). Let's move the former to where the later is called. This way, when posix-cpu-timers.c is compiled out, there is no need to worry about not losing a call to add_device_randomness(). Signed-off-by: Nicolas Pitre Acked-by: John Stultz Cc: Paul Bolle Cc: linux-kbuild@vger.kernel.org Cc: netdev@vger.kernel.org Cc: Richard Cochran Cc: Josh Triplett Cc: Michal Marek Cc: Edward Cree Link: http://lkml.kernel.org/r/1478841010-28605-6-git-send-email-nicolas.pitre@linaro.org Signed-off-by: Thomas Gleixner --- kernel/exit.c | 4 ++++ kernel/time/posix-cpu-timers.c | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index 9d68c45ebbe3..d16bcdd89dbe 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -116,6 +117,9 @@ static void __exit_signal(struct task_struct *tsk) sig->curr_target = next_thread(tsk); } + add_device_randomness((const void*) &tsk->se.sum_exec_runtime, + sizeof(unsigned long long)); + /* * Accumulate here the counters for all threads as they die. We could * skip the group leader because it is the last user of signal_struct, diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index 39008d78927a..e582f20f47a4 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -447,10 +446,7 @@ static void cleanup_timers(struct list_head *head) */ void posix_cpu_timers_exit(struct task_struct *tsk) { - add_device_randomness((const void*) &tsk->se.sum_exec_runtime, - sizeof(unsigned long long)); cleanup_timers(tsk->cpu_timers); - } void posix_cpu_timers_exit_group(struct task_struct *tsk) { -- cgit v1.2.3 From baa73d9e478ff32d62f3f9422822b59dd9a95a21 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 11 Nov 2016 00:10:10 -0500 Subject: posix-timers: Make them configurable Some embedded systems have no use for them. This removes about 25KB from the kernel binary size when configured out. Corresponding syscalls are routed to a stub logging the attempt to use those syscalls which should be enough of a clue if they were disabled without proper consideration. They are: timer_create, timer_gettime: timer_getoverrun, timer_settime, timer_delete, clock_adjtime, setitimer, getitimer, alarm. The clock_settime, clock_gettime, clock_getres and clock_nanosleep syscalls are replaced by simple wrappers compatible with CLOCK_REALTIME, CLOCK_MONOTONIC and CLOCK_BOOTTIME only which should cover the vast majority of use cases with very little code. Signed-off-by: Nicolas Pitre Acked-by: Richard Cochran Acked-by: Thomas Gleixner Acked-by: John Stultz Reviewed-by: Josh Triplett Cc: Paul Bolle Cc: linux-kbuild@vger.kernel.org Cc: netdev@vger.kernel.org Cc: Michal Marek Cc: Edward Cree Link: http://lkml.kernel.org/r/1478841010-28605-7-git-send-email-nicolas.pitre@linaro.org Signed-off-by: Thomas Gleixner --- arch/alpha/kernel/osf_sys.c | 8 +++ drivers/char/Kconfig | 1 + drivers/ptp/Kconfig | 2 +- fs/exec.c | 2 + init/Kconfig | 17 ++++++ kernel/compat.c | 8 +++ kernel/exit.c | 11 +++- kernel/fork.c | 2 + kernel/signal.c | 6 +++ kernel/sys.c | 3 +- kernel/time/Makefile | 10 +++- kernel/time/alarmtimer.c | 6 ++- kernel/time/posix-stubs.c | 123 ++++++++++++++++++++++++++++++++++++++++++++ kernel/time/timer.c | 3 +- security/selinux/hooks.c | 11 ++-- 15 files changed, 200 insertions(+), 13 deletions(-) create mode 100644 kernel/time/posix-stubs.c diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index ffb93f499c83..56e427c7aa3c 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -1029,11 +1029,16 @@ SYSCALL_DEFINE2(osf_settimeofday, struct timeval32 __user *, tv, return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); } +asmlinkage long sys_ni_posix_timers(void); + SYSCALL_DEFINE2(osf_getitimer, int, which, struct itimerval32 __user *, it) { struct itimerval kit; int error; + if (!IS_ENABLED(CONFIG_POSIX_TIMERS)) + return sys_ni_posix_timers(); + error = do_getitimer(which, &kit); if (!error && put_it32(it, &kit)) error = -EFAULT; @@ -1047,6 +1052,9 @@ SYSCALL_DEFINE3(osf_setitimer, int, which, struct itimerval32 __user *, in, struct itimerval kin, kout; int error; + if (!IS_ENABLED(CONFIG_POSIX_TIMERS)) + return sys_ni_posix_timers(); + if (in) { if (get_it32(&kin, in)) return -EFAULT; diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index dcc09739a54e..45ba878ae025 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -542,6 +542,7 @@ config HANGCHECK_TIMER config MMTIMER tristate "MMTIMER Memory mapped RTC for SGI Altix" depends on IA64_GENERIC || IA64_SGI_SN2 + depends on POSIX_TIMERS default y help The mmtimer device allows direct userspace access to the diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig index 0f7492f8ea23..bdce33291161 100644 --- a/drivers/ptp/Kconfig +++ b/drivers/ptp/Kconfig @@ -6,7 +6,7 @@ menu "PTP clock support" config PTP_1588_CLOCK tristate "PTP clock support" - depends on NET + depends on NET && POSIX_TIMERS select PPS select NET_PTP_CLASSIFY help diff --git a/fs/exec.c b/fs/exec.c index 4e497b9ee71e..923c57d96899 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1169,8 +1169,10 @@ no_thread_group: /* we have changed execution domain */ tsk->exit_signal = SIGCHLD; +#ifdef CONFIG_POSIX_TIMERS exit_itimers(sig); flush_itimer_signals(); +#endif if (atomic_read(&oldsighand->count) != 1) { struct sighand_struct *newsighand; diff --git a/init/Kconfig b/init/Kconfig index 34407f15e6d3..456e0b891238 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1445,6 +1445,23 @@ config SYSCTL_SYSCALL If unsure say N here. +config POSIX_TIMERS + bool "Posix Clocks & timers" if EXPERT + default y + help + This includes native support for POSIX timers to the kernel. + Some embedded systems have no use for them and therefore they + can be configured out to reduce the size of the kernel image. + + When this option is disabled, the following syscalls won't be + available: timer_create, timer_gettime: timer_getoverrun, + timer_settime, timer_delete, clock_adjtime, getitimer, + setitimer, alarm. Furthermore, the clock_settime, clock_gettime, + clock_getres and clock_nanosleep syscalls will be limited to + CLOCK_REALTIME, CLOCK_MONOTONIC and CLOCK_BOOTTIME only. + + If unsure say y. + config KALLSYMS bool "Load all symbols for debugging/ksymoops" if EXPERT default y diff --git a/kernel/compat.c b/kernel/compat.c index 333d364be29d..b3a047f208a7 100644 --- a/kernel/compat.c +++ b/kernel/compat.c @@ -307,12 +307,17 @@ static inline long put_compat_itimerval(struct compat_itimerval __user *o, __put_user(i->it_value.tv_usec, &o->it_value.tv_usec))); } +asmlinkage long sys_ni_posix_timers(void); + COMPAT_SYSCALL_DEFINE2(getitimer, int, which, struct compat_itimerval __user *, it) { struct itimerval kit; int error; + if (!IS_ENABLED(CONFIG_POSIX_TIMERS)) + return sys_ni_posix_timers(); + error = do_getitimer(which, &kit); if (!error && put_compat_itimerval(it, &kit)) error = -EFAULT; @@ -326,6 +331,9 @@ COMPAT_SYSCALL_DEFINE3(setitimer, int, which, struct itimerval kin, kout; int error; + if (!IS_ENABLED(CONFIG_POSIX_TIMERS)) + return sys_ni_posix_timers(); + if (in) { if (get_compat_itimerval(&kin, in)) return -EFAULT; diff --git a/kernel/exit.c b/kernel/exit.c index d16bcdd89dbe..684de019b674 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -92,11 +92,10 @@ static void __exit_signal(struct task_struct *tsk) lockdep_tasklist_lock_is_held()); spin_lock(&sighand->siglock); +#ifdef CONFIG_POSIX_TIMERS posix_cpu_timers_exit(tsk); if (group_dead) { posix_cpu_timers_exit_group(tsk); - tty = sig->tty; - sig->tty = NULL; } else { /* * This can only happen if the caller is de_thread(). @@ -105,7 +104,13 @@ static void __exit_signal(struct task_struct *tsk) */ if (unlikely(has_group_leader_pid(tsk))) posix_cpu_timers_exit_group(tsk); + } +#endif + if (group_dead) { + tty = sig->tty; + sig->tty = NULL; + } else { /* * If there is any task waiting for the group exit * then notify it: @@ -803,8 +808,10 @@ void __noreturn do_exit(long code) acct_update_integrals(tsk); group_dead = atomic_dec_and_test(&tsk->signal->live); if (group_dead) { +#ifdef CONFIG_POSIX_TIMERS hrtimer_cancel(&tsk->signal->real_timer); exit_itimers(tsk->signal); +#endif if (tsk->mm) setmax_mm_hiwater_rss(&tsk->signal->maxrss, tsk->mm); } diff --git a/kernel/fork.c b/kernel/fork.c index 623259fc794d..17da35fa77e7 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1342,8 +1342,10 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) seqlock_init(&sig->stats_lock); prev_cputime_init(&sig->prev_cputime); +#ifdef CONFIG_POSIX_TIMERS hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); sig->real_timer.function = it_real_fn; +#endif task_lock(current->group_leader); memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim); diff --git a/kernel/signal.c b/kernel/signal.c index 75761acc77cf..29a410780aa9 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -427,6 +427,7 @@ void flush_signals(struct task_struct *t) spin_unlock_irqrestore(&t->sighand->siglock, flags); } +#ifdef CONFIG_POSIX_TIMERS static void __flush_itimer_signals(struct sigpending *pending) { sigset_t signal, retain; @@ -460,6 +461,7 @@ void flush_itimer_signals(void) __flush_itimer_signals(&tsk->signal->shared_pending); spin_unlock_irqrestore(&tsk->sighand->siglock, flags); } +#endif void ignore_signals(struct task_struct *t) { @@ -567,6 +569,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) if (!signr) { signr = __dequeue_signal(&tsk->signal->shared_pending, mask, info); +#ifdef CONFIG_POSIX_TIMERS /* * itimer signal ? * @@ -590,6 +593,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) hrtimer_restart(tmr); } } +#endif } recalc_sigpending(); @@ -611,6 +615,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) */ current->jobctl |= JOBCTL_STOP_DEQUEUED; } +#ifdef CONFIG_POSIX_TIMERS if ((info->si_code & __SI_MASK) == __SI_TIMER && info->si_sys_private) { /* * Release the siglock to ensure proper locking order @@ -622,6 +627,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) do_schedule_next_timer(info); spin_lock(&tsk->sighand->siglock); } +#endif return signr; } diff --git a/kernel/sys.c b/kernel/sys.c index 89d5be418157..78c9fb7dd680 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1416,7 +1416,8 @@ int do_prlimit(struct task_struct *tsk, unsigned int resource, * applications, so we live with it */ if (!retval && new_rlim && resource == RLIMIT_CPU && - new_rlim->rlim_cur != RLIM_INFINITY) + new_rlim->rlim_cur != RLIM_INFINITY && + IS_ENABLED(CONFIG_POSIX_TIMERS)) update_rlimit_cpu(tsk, new_rlim->rlim_cur); out: read_unlock(&tasklist_lock); diff --git a/kernel/time/Makefile b/kernel/time/Makefile index 49eca0beed32..976840d29a71 100644 --- a/kernel/time/Makefile +++ b/kernel/time/Makefile @@ -1,6 +1,12 @@ -obj-y += time.o timer.o hrtimer.o itimer.o posix-timers.o posix-cpu-timers.o +obj-y += time.o timer.o hrtimer.o obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o -obj-y += timeconv.o timecounter.o posix-clock.o alarmtimer.o +obj-y += timeconv.o timecounter.o alarmtimer.o + +ifeq ($(CONFIG_POSIX_TIMERS),y) + obj-y += posix-timers.o posix-cpu-timers.o posix-clock.o itimer.o +else + obj-y += posix-stubs.o +endif obj-$(CONFIG_GENERIC_CLOCKEVENTS) += clockevents.o tick-common.o ifeq ($(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST),y) diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 12dd190634ab..a15caa3d1721 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -846,8 +846,10 @@ static int __init alarmtimer_init(void) alarmtimer_rtc_timer_init(); - posix_timers_register_clock(CLOCK_REALTIME_ALARM, &alarm_clock); - posix_timers_register_clock(CLOCK_BOOTTIME_ALARM, &alarm_clock); + if (IS_ENABLED(CONFIG_POSIX_TIMERS)) { + posix_timers_register_clock(CLOCK_REALTIME_ALARM, &alarm_clock); + posix_timers_register_clock(CLOCK_BOOTTIME_ALARM, &alarm_clock); + } /* Initialize alarm bases */ alarm_bases[ALARM_REALTIME].base_clockid = CLOCK_REALTIME; diff --git a/kernel/time/posix-stubs.c b/kernel/time/posix-stubs.c new file mode 100644 index 000000000000..cd6716e115e8 --- /dev/null +++ b/kernel/time/posix-stubs.c @@ -0,0 +1,123 @@ +/* + * Dummy stubs used when CONFIG_POSIX_TIMERS=n + * + * Created by: Nicolas Pitre, July 2016 + * Copyright: (C) 2016 Linaro Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +asmlinkage long sys_ni_posix_timers(void) +{ + pr_err_once("process %d (%s) attempted a POSIX timer syscall " + "while CONFIG_POSIX_TIMERS is not set\n", + current->pid, current->comm); + return -ENOSYS; +} + +#define SYS_NI(name) SYSCALL_ALIAS(sys_##name, sys_ni_posix_timers) + +SYS_NI(timer_create); +SYS_NI(timer_gettime); +SYS_NI(timer_getoverrun); +SYS_NI(timer_settime); +SYS_NI(timer_delete); +SYS_NI(clock_adjtime); +SYS_NI(getitimer); +SYS_NI(setitimer); +#ifdef __ARCH_WANT_SYS_ALARM +SYS_NI(alarm); +#endif + +/* + * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC + * as it is easy to remain compatible with little code. CLOCK_BOOTTIME + * is also included for convenience as at least systemd uses it. + */ + +SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, + const struct timespec __user *, tp) +{ + struct timespec new_tp; + + if (which_clock != CLOCK_REALTIME) + return -EINVAL; + if (copy_from_user(&new_tp, tp, sizeof (*tp))) + return -EFAULT; + return do_sys_settimeofday(&new_tp, NULL); +} + +SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, + struct timespec __user *,tp) +{ + struct timespec kernel_tp; + + switch (which_clock) { + case CLOCK_REALTIME: ktime_get_real_ts(&kernel_tp); break; + case CLOCK_MONOTONIC: ktime_get_ts(&kernel_tp); break; + case CLOCK_BOOTTIME: get_monotonic_boottime(&kernel_tp); break; + default: return -EINVAL; + } + if (copy_to_user(tp, &kernel_tp, sizeof (kernel_tp))) + return -EFAULT; + return 0; +} + +SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp) +{ + struct timespec rtn_tp = { + .tv_sec = 0, + .tv_nsec = hrtimer_resolution, + }; + + switch (which_clock) { + case CLOCK_REALTIME: + case CLOCK_MONOTONIC: + case CLOCK_BOOTTIME: + if (copy_to_user(tp, &rtn_tp, sizeof(rtn_tp))) + return -EFAULT; + return 0; + default: + return -EINVAL; + } +} + +SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, + const struct timespec __user *, rqtp, + struct timespec __user *, rmtp) +{ + struct timespec t; + + switch (which_clock) { + case CLOCK_REALTIME: + case CLOCK_MONOTONIC: + case CLOCK_BOOTTIME: + if (copy_from_user(&t, rqtp, sizeof (struct timespec))) + return -EFAULT; + if (!timespec_valid(&t)) + return -EINVAL; + return hrtimer_nanosleep(&t, rmtp, flags & TIMER_ABSTIME ? + HRTIMER_MODE_ABS : HRTIMER_MODE_REL, + which_clock); + default: + return -EINVAL; + } +} + +#ifdef CONFIG_COMPAT +long clock_nanosleep_restart(struct restart_block *restart_block) +{ + return hrtimer_nanosleep_restart(restart_block); +} +#endif diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 42d27aa242b9..e2892e454fe3 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1601,7 +1601,8 @@ void update_process_times(int user_tick) irq_work_tick(); #endif scheduler_tick(); - run_posix_cpu_timers(p); + if (IS_ENABLED(CONFIG_POSIX_TIMERS)) + run_posix_cpu_timers(p); } /** diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 09fd6108e421..38b79d797aaf 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2525,7 +2525,8 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm) rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur); } task_unlock(current); - update_rlimit_cpu(current, rlimit(RLIMIT_CPU)); + if (IS_ENABLED(CONFIG_POSIX_TIMERS)) + update_rlimit_cpu(current, rlimit(RLIMIT_CPU)); } } @@ -2555,9 +2556,11 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm) */ rc = avc_has_perm(osid, sid, SECCLASS_PROCESS, PROCESS__SIGINH, NULL); if (rc) { - memset(&itimer, 0, sizeof itimer); - for (i = 0; i < 3; i++) - do_setitimer(i, &itimer, NULL); + if (IS_ENABLED(CONFIG_POSIX_TIMERS)) { + memset(&itimer, 0, sizeof itimer); + for (i = 0; i < 3; i++) + do_setitimer(i, &itimer, NULL); + } spin_lock_irq(¤t->sighand->siglock); if (!fatal_signal_pending(current)) { flush_sigqueue(¤t->pending); -- cgit v1.2.3 From d8ec7595a013237f82d965dcf981571aeb41855b Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 4 Oct 2016 11:12:09 -0700 Subject: clocksource/drivers/arm_arch_timer: Don't assume clock runs in suspend The ARM specifies that the system counter "must be implemented in an always-on power domain," and so we try to use the counter as a source of timekeeping across suspend/resume. Unfortunately, some SoCs (e.g., Rockchip's RK3399) do not keep the counter ticking properly when switched from their high-power clock to the lower-power clock used in system suspend. Support this quirk by adding a new device tree property. Signed-off-by: Brian Norris Reviewed-by: Douglas Anderson Acked-by: Marc Zyngier Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/arm/arch_timer.txt | 5 +++++ drivers/clocksource/arm_arch_timer.c | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/arch_timer.txt b/Documentation/devicetree/bindings/arm/arch_timer.txt index ef5fbe9a77c7..ad440a2b8051 100644 --- a/Documentation/devicetree/bindings/arm/arch_timer.txt +++ b/Documentation/devicetree/bindings/arm/arch_timer.txt @@ -38,6 +38,11 @@ to deliver its interrupts via SPIs. architecturally-defined reset values. Only supported for 32-bit systems which follow the ARMv7 architected reset values. +- arm,no-tick-in-suspend : The main counter does not tick when the system is in + low-power system suspend on some SoCs. This behavior does not match the + Architecture Reference Manual's specification that the system counter "must + be implemented in an always-on power domain." + Example: diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 73c487da6d2a..a2503db7e533 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -81,6 +81,7 @@ static struct clock_event_device __percpu *arch_timer_evt; static enum ppi_nr arch_timer_uses_ppi = VIRT_PPI; static bool arch_timer_c3stop; static bool arch_timer_mem_use_virtual; +static bool arch_counter_suspend_stop; static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM); @@ -576,7 +577,7 @@ static struct clocksource clocksource_counter = { .rating = 400, .read = arch_counter_read, .mask = CLOCKSOURCE_MASK(56), - .flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; static struct cyclecounter cyclecounter = { @@ -616,6 +617,8 @@ static void __init arch_counter_register(unsigned type) arch_timer_read_counter = arch_counter_get_cntvct_mem; } + if (!arch_counter_suspend_stop) + clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP; start_count = arch_timer_read_counter(); clocksource_register_hz(&clocksource_counter, arch_timer_rate); cyclecounter.mult = clocksource_counter.mult; @@ -907,6 +910,10 @@ static int __init arch_timer_of_init(struct device_node *np) of_property_read_bool(np, "arm,cpu-registers-not-fw-configured")) arch_timer_uses_ppi = PHYS_SECURE_PPI; + /* On some systems, the counter stops ticking when in suspend. */ + arch_counter_suspend_stop = of_property_read_bool(np, + "arm,no-tick-in-suspend"); + return arch_timer_init(); } CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init); -- cgit v1.2.3 From e6186820a74546ac201a6669ebbee42399583b8b Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 4 Oct 2016 11:12:10 -0700 Subject: arm64: dts: rockchip: Arch counter doesn't tick in system suspend The "arm,no-tick-in-suspend" property was introduced to note implementations where the system counter does not quite follow the ARM specification that it "must be implemented in an always-on power domain". Particularly, RK3399's counter stops ticking when we switch from the 24MHz clock to the 32KHz clock in low-power suspend, so let's mark it as such. Signed-off-by: Brian Norris Reviewed-by: Douglas Anderson Signed-off-by: Daniel Lezcano --- arch/arm64/boot/dts/rockchip/rk3399.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index b65c193dc64e..d85b65182de2 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -174,6 +174,7 @@ , , ; + arm,no-tick-in-suspend; }; xin24m: xin24m { -- cgit v1.2.3 From f947ee147e0895d5c0ef18e81ca7a4e4219739e3 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 26 Oct 2016 00:35:50 -0700 Subject: clocksource/drivers/arm_arch_timer: Map frame with of_io_request_and_map() Let's use the of_io_request_and_map() API so that the frame region is protected and shows up in /proc/iomem. Signed-off-by: Stephen Boyd Signed-off-by: Daniel Lezcano Acked-by: Marc Zyngier --- drivers/clocksource/arm_arch_timer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index a2503db7e533..02fef6830e72 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -971,8 +971,9 @@ static int __init arch_timer_mem_init(struct device_node *np) } ret= -ENXIO; - base = arch_counter_base = of_iomap(best_frame, 0); - if (!base) { + base = arch_counter_base = of_io_request_and_map(best_frame, 0, + "arch_mem_timer"); + if (IS_ERR(base)) { pr_err("arch_timer: Can't map frame's registers\n"); goto out; } -- cgit v1.2.3 From 84c39b8b7d46883f7a7514c7d55909831aa846fd Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 21 Sep 2016 23:03:57 +0530 Subject: clocksource/drivers/bcm2835_timer: Unmap region obtained by of_iomap Free memory mapping, if bcm2835_timer_init is not successful. Signed-off-by: Arvind Yadav Reviewed-by: Eric Anholt Signed-off-by: Daniel Lezcano --- drivers/clocksource/bcm2835_timer.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/clocksource/bcm2835_timer.c b/drivers/clocksource/bcm2835_timer.c index e71acf231c89..f2f29d2be1cf 100644 --- a/drivers/clocksource/bcm2835_timer.c +++ b/drivers/clocksource/bcm2835_timer.c @@ -96,7 +96,7 @@ static int __init bcm2835_timer_init(struct device_node *node) ret = of_property_read_u32(node, "clock-frequency", &freq); if (ret) { pr_err("Can't read clock-frequency"); - return ret; + goto err_iounmap; } system_clock = base + REG_COUNTER_LO; @@ -108,13 +108,15 @@ static int __init bcm2835_timer_init(struct device_node *node) irq = irq_of_parse_and_map(node, DEFAULT_TIMER); if (irq <= 0) { pr_err("Can't parse IRQ"); - return -EINVAL; + ret = -EINVAL; + goto err_iounmap; } timer = kzalloc(sizeof(*timer), GFP_KERNEL); if (!timer) { pr_err("Can't allocate timer struct\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err_iounmap; } timer->control = base + REG_CONTROL; @@ -133,7 +135,7 @@ static int __init bcm2835_timer_init(struct device_node *node) ret = setup_irq(irq, &timer->act); if (ret) { pr_err("Can't set up timer IRQ\n"); - return ret; + goto err_iounmap; } clockevents_config_and_register(&timer->evt, freq, 0xf, 0xffffffff); @@ -141,6 +143,10 @@ static int __init bcm2835_timer_init(struct device_node *node) pr_info("bcm2835: system timer (irq = %d)\n", irq); return 0; + +err_iounmap: + iounmap(base); + return ret; } CLOCKSOURCE_OF_DECLARE(bcm2835, "brcm,bcm2835-system-timer", bcm2835_timer_init); -- cgit v1.2.3 From a109ded26c8c85c17872c8f61e8979c5d650004d Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 28 Nov 2016 14:35:18 -0800 Subject: selftests/timers: Fix spelling mistake "Asyncrhonous" -> "Asynchronous" Trivial fix to spelling mistake Signed-off-by: Colin Ian King Signed-off-by: John Stultz Cc: Prarit Bhargava Cc: Richard Cochran Cc: Shuah Khan Link: http://lkml.kernel.org/r/1480372524-15181-2-git-send-email-john.stultz@linaro.org Signed-off-by: Thomas Gleixner --- tools/testing/selftests/timers/skew_consistency.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/timers/skew_consistency.c b/tools/testing/selftests/timers/skew_consistency.c index 5562f84ee07c..2a996e072259 100644 --- a/tools/testing/selftests/timers/skew_consistency.c +++ b/tools/testing/selftests/timers/skew_consistency.c @@ -57,7 +57,7 @@ int main(int argv, char **argc) pid_t pid; - printf("Running Asyncrhonous Frequency Changing Tests...\n"); + printf("Running Asynchronous Frequency Changing Tests...\n"); pid = fork(); if (!pid) -- cgit v1.2.3 From ba58d1020a54933c6b087a3107661c8513556cb8 Mon Sep 17 00:00:00 2001 From: Chen Yu Date: Mon, 28 Nov 2016 14:35:19 -0800 Subject: timekeeping: Ignore the bogus sleep time if pm_trace is enabled Power management suspend/resume tracing (ab)uses the RTC to store suspend/resume information persistently. As a consequence the RTC value is clobbered when timekeeping is resumed and tries to inject the sleep time. Commit a4f8f6667f09 ("timekeeping: Cap array access in timekeeping_debug") plugged a out of bounds array access in the timekeeping debug code which was caused by the clobbered RTC value, but we still use the clobbered RTC value for sleep time injection into kernel timekeeping, which will result in random adjustments depending on the stored "hash" value. To prevent this keep track of the RTC clobbering and ignore the invalid RTC timestamp at resume. If the system resumed successfully clear the flag, which marks the RTC as unusable, warn the user about the RTC clobber and recommend to adjust the RTC with 'ntpdate' or 'rdate'. [jstultz: Fixed up pr_warn formating, and implemented suggestions from Ingo] [ tglx: Rewrote changelog ] Originally-from: Thomas Gleixner Signed-off-by: Chen Yu Signed-off-by: John Stultz Acked-by: Pavel Machek Acked-by: Thomas Gleixner Cc: Prarit Bhargava Cc: "Rafael J. Wysocki" Cc: Richard Cochran Cc: Xunlei Pang Cc: Len Brown Link: http://lkml.kernel.org/r/1480372524-15181-3-git-send-email-john.stultz@linaro.org Signed-off-by: Thomas Gleixner --- arch/x86/kernel/rtc.c | 9 +++++++++ drivers/base/power/trace.c | 27 +++++++++++++++++++++++++++ drivers/rtc/rtc-cmos.c | 7 +++++++ include/linux/mc146818rtc.h | 1 + include/linux/pm-trace.h | 9 ++++++++- 5 files changed, 52 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c index 79c6311cd912..5b21cb7d84d6 100644 --- a/arch/x86/kernel/rtc.c +++ b/arch/x86/kernel/rtc.c @@ -64,6 +64,15 @@ void mach_get_cmos_time(struct timespec *now) unsigned int status, year, mon, day, hour, min, sec, century = 0; unsigned long flags; + /* + * If pm_trace abused the RTC as storage, set the timespec to 0, + * which tells the caller that this RTC value is unusable. + */ + if (!pm_trace_rtc_valid()) { + now->tv_sec = now->tv_nsec = 0; + return; + } + spin_lock_irqsave(&rtc_lock, flags); /* diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c index efec10b49d59..1cda505d6a85 100644 --- a/drivers/base/power/trace.c +++ b/drivers/base/power/trace.c @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -74,6 +75,9 @@ #define DEVSEED (7919) +bool pm_trace_rtc_abused __read_mostly; +EXPORT_SYMBOL_GPL(pm_trace_rtc_abused); + static unsigned int dev_hash_value; static int set_magic_time(unsigned int user, unsigned int file, unsigned int device) @@ -104,6 +108,7 @@ static int set_magic_time(unsigned int user, unsigned int file, unsigned int dev time.tm_min = (n % 20) * 3; n /= 20; mc146818_set_time(&time); + pm_trace_rtc_abused = true; return n ? -1 : 0; } @@ -239,9 +244,31 @@ int show_trace_dev_match(char *buf, size_t size) return ret; } +static int +pm_trace_notify(struct notifier_block *nb, unsigned long mode, void *_unused) +{ + switch (mode) { + case PM_POST_HIBERNATION: + case PM_POST_SUSPEND: + if (pm_trace_rtc_abused) { + pm_trace_rtc_abused = false; + pr_warn("Possible incorrect RTC due to pm_trace, please use 'ntpdate' or 'rdate' to reset it.\n"); + } + break; + default: + break; + } + return 0; +} + +static struct notifier_block pm_trace_nb = { + .notifier_call = pm_trace_notify, +}; + static int early_resume_init(void) { hash_value_early_read = read_magic_time(); + register_pm_notifier(&pm_trace_nb); return 0; } diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index dd3d59806ffa..b27a18968a1a 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -191,6 +191,13 @@ static inline void cmos_write_bank2(unsigned char val, unsigned char addr) static int cmos_read_time(struct device *dev, struct rtc_time *t) { + /* + * If pm_trace abused the RTC for storage, set the timespec to 0, + * which tells the caller that this RTC value is unusable. + */ + if (!pm_trace_rtc_valid()) + return -EIO; + /* REVISIT: if the clock has a "century" register, use * that instead of the heuristic in mc146818_get_time(). * That'll make Y3K compatility (year > 2070) easy! diff --git a/include/linux/mc146818rtc.h b/include/linux/mc146818rtc.h index a585b4b5fa0e..0661af17a758 100644 --- a/include/linux/mc146818rtc.h +++ b/include/linux/mc146818rtc.h @@ -16,6 +16,7 @@ #include /* register access macros */ #include #include +#include #ifdef __KERNEL__ #include /* spinlock_t */ diff --git a/include/linux/pm-trace.h b/include/linux/pm-trace.h index ecbde7a5548e..7b78793f07d7 100644 --- a/include/linux/pm-trace.h +++ b/include/linux/pm-trace.h @@ -1,11 +1,17 @@ #ifndef PM_TRACE_H #define PM_TRACE_H +#include #ifdef CONFIG_PM_TRACE #include -#include extern int pm_trace_enabled; +extern bool pm_trace_rtc_abused; + +static inline bool pm_trace_rtc_valid(void) +{ + return !pm_trace_rtc_abused; +} static inline int pm_trace_is_enabled(void) { @@ -24,6 +30,7 @@ extern int show_trace_dev_match(char *buf, size_t size); #else +static inline bool pm_trace_rtc_valid(void) { return true; } static inline int pm_trace_is_enabled(void) { return 0; } #define TRACE_DEVICE(dev) do { } while (0) -- cgit v1.2.3 From ec4101e8903e318b9fd4e3bbf72b1eaba53c64e1 Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Mon, 28 Nov 2016 14:35:20 -0800 Subject: timekeeping/clocksource_cyc2ns: Document intended range limitation The "cycles" argument should not be an absolute clocksource cycle value, as the implementation's arithmetic will overflow relatively easily with wide (64 bit) clocksource counters. For performance, the implementation is simple and fast, since the function is intended for only relatively small delta values of clocksource cycles. [jstultz: Fixed up to merge against HEAD & commit message tweaks, also included rewording suggestion by Ingo] Signed-off-by: Chris Metcalf Signed-off-by: John Stultz Cc: Prarit Bhargava Cc: Richard Cochran Link: http://lkml.kernel.org/r/1480372524-15181-4-git-send-email-john.stultz@linaro.org Signed-off-by: Thomas Gleixner --- include/linux/clocksource.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 08398182f56e..65602d395a52 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -169,7 +169,10 @@ static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant) * @mult: cycle to nanosecond multiplier * @shift: cycle to nanosecond divisor (power of two) * - * Converts cycles to nanoseconds, using the given mult and shift. + * Converts clocksource cycles to nanoseconds, using the given @mult and @shift. + * The code is optimized for performance and is not intended to work + * with absolute clocksource cycles (as those will easily overflow), + * but is only intended to be used with relative (delta) clocksource cycles. * * XXX - This could use some mult_lxl_ll() asm optimization */ -- cgit v1.2.3 From 948a5312f41658f7b76a598a139ef1f4dea09ca9 Mon Sep 17 00:00:00 2001 From: Joel Fernandes Date: Mon, 28 Nov 2016 14:35:22 -0800 Subject: timekeeping: Add a fast and NMI safe boot clock This boot clock can be used as a tracing clock and will account for suspend time. To keep it NMI safe since we're accessing from tracing, we're not using a separate timekeeper with updates to monotonic clock and boot offset protected with seqlocks. This has the following minor side effects: (1) Its possible that a timestamp be taken after the boot offset is updated but before the timekeeper is updated. If this happens, the new boot offset is added to the old timekeeping making the clock appear to update slightly earlier: CPU 0 CPU 1 timekeeping_inject_sleeptime64() __timekeeping_inject_sleeptime(tk, delta); timestamp(); timekeeping_update(tk, TK_CLEAR_NTP...); (2) On 32-bit systems, the 64-bit boot offset (tk->offs_boot) may be partially updated. Since the tk->offs_boot update is a rare event, this should be a rare occurrence which postprocessing should be able to handle. Signed-off-by: Joel Fernandes Signed-off-by: John Stultz Reviewed-by: Thomas Gleixner Cc: Prarit Bhargava Cc: Richard Cochran Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1480372524-15181-6-git-send-email-john.stultz@linaro.org Signed-off-by: Thomas Gleixner --- include/linux/timekeeping.h | 1 + kernel/time/timekeeping.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h index 09168c52ab64..361f8bf1429d 100644 --- a/include/linux/timekeeping.h +++ b/include/linux/timekeeping.h @@ -249,6 +249,7 @@ static inline u64 ktime_get_raw_ns(void) extern u64 ktime_get_mono_fast_ns(void); extern u64 ktime_get_raw_fast_ns(void); +extern u64 ktime_get_boot_fast_ns(void); /* * Timespec interfaces utilizing the ktime based ones diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 37dec7e3db43..b2286e94c934 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -425,6 +425,35 @@ u64 ktime_get_raw_fast_ns(void) } EXPORT_SYMBOL_GPL(ktime_get_raw_fast_ns); +/** + * ktime_get_boot_fast_ns - NMI safe and fast access to boot clock. + * + * To keep it NMI safe since we're accessing from tracing, we're not using a + * separate timekeeper with updates to monotonic clock and boot offset + * protected with seqlocks. This has the following minor side effects: + * + * (1) Its possible that a timestamp be taken after the boot offset is updated + * but before the timekeeper is updated. If this happens, the new boot offset + * is added to the old timekeeping making the clock appear to update slightly + * earlier: + * CPU 0 CPU 1 + * timekeeping_inject_sleeptime64() + * __timekeeping_inject_sleeptime(tk, delta); + * timestamp(); + * timekeeping_update(tk, TK_CLEAR_NTP...); + * + * (2) On 32-bit systems, the 64-bit boot offset (tk->offs_boot) may be + * partially updated. Since the tk->offs_boot update is a rare event, this + * should be a rare occurrence which postprocessing should be able to handle. + */ +u64 notrace ktime_get_boot_fast_ns(void) +{ + struct timekeeper *tk = &tk_core.timekeeper; + + return (ktime_get_mono_fast_ns() + ktime_to_ns(tk->offs_boot)); +} +EXPORT_SYMBOL_GPL(ktime_get_boot_fast_ns); + /* Suspend-time cycles value for halted fast timekeeper. */ static cycle_t cycles_at_suspend; -- cgit v1.2.3 From 80ec3552107ac16a836dbff4cf3c23fdd3256ee3 Mon Sep 17 00:00:00 2001 From: Joel Fernandes Date: Mon, 28 Nov 2016 14:35:23 -0800 Subject: trace: Add an option for boot clock as trace clock Unlike monotonic clock, boot clock as a trace clock will account for time spent in suspend useful for tracing suspend/resume. This uses earlier introduced infrastructure for using the fast boot clock. Signed-off-by: Joel Fernandes Signed-off-by: John Stultz Reviewed-by: Thomas Gleixner Acked-by: Steven Rostedt Cc: Prarit Bhargava Cc: Richard Cochran Link: http://lkml.kernel.org/r/1480372524-15181-7-git-send-email-john.stultz@linaro.org Signed-off-by: Thomas Gleixner --- kernel/trace/trace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 8696ce6bf2f6..f7b64db285df 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1125,6 +1125,7 @@ static struct { { trace_clock, "perf", 1 }, { ktime_get_mono_fast_ns, "mono", 1 }, { ktime_get_raw_fast_ns, "mono_raw", 1 }, + { ktime_get_boot_fast_ns, "boot", 1 }, ARCH_TRACE_CLOCKS }; -- cgit v1.2.3 From 2924ecd441f3c12da59b297daade265f49d0831b Mon Sep 17 00:00:00 2001 From: Joel Fernandes Date: Mon, 28 Nov 2016 14:35:24 -0800 Subject: trace: Update documentation for mono, mono_raw and boot clock Documentation was missing for mono and mono_raw, add them and also for the boot clock introduced in this series. Signed-off-by: Joel Fernandes Signed-off-by: John Stultz Reviewed-by: Thomas Gleixner Acked-by: Steven Rostedt Cc: Prarit Bhargava Cc: Richard Cochran Link: http://lkml.kernel.org/r/1480372524-15181-8-git-send-email-john.stultz@linaro.org Signed-off-by: Thomas Gleixner --- Documentation/trace/ftrace.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Documentation/trace/ftrace.txt b/Documentation/trace/ftrace.txt index 185c39fea2a0..5596e2d71d6d 100644 --- a/Documentation/trace/ftrace.txt +++ b/Documentation/trace/ftrace.txt @@ -362,6 +362,26 @@ of ftrace. Here is a list of some of the key files: to correlate events across hypervisor/guest if tb_offset is known. + mono: This uses the fast monotonic clock (CLOCK_MONOTONIC) + which is monotonic and is subject to NTP rate adjustments. + + mono_raw: + This is the raw monotonic clock (CLOCK_MONOTONIC_RAW) + which is montonic but is not subject to any rate adjustments + and ticks at the same rate as the hardware clocksource. + + boot: This is the boot clock (CLOCK_BOOTTIME) and is based on the + fast monotonic clock, but also accounts for time spent in + suspend. Since the clock access is designed for use in + tracing in the suspend path, some side effects are possible + if clock is accessed after the suspend time is accounted before + the fast mono clock is updated. In this case, the clock update + appears to happen slightly sooner than it normally would have. + Also on 32-bit systems, it's possible that the 64-bit boot offset + sees a partial update. These effects are rare and post + processing should be able to handle them. See comments in the + ktime_get_boot_fast_ns() function for more information. + To set a clock, simply echo the clock name into this file. echo global > trace_clock -- cgit v1.2.3 From 4a057549d6044c2dea47e80f8369a76225ec9d90 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Mon, 28 Nov 2016 14:35:21 -0800 Subject: alarmtimer: Add tracepoints for alarm timers Alarm timers are one of the mechanisms to wake up a system from suspend, but there exist no tracepoints to analyse which process/thread armed an alarmtimer. Add tracepoints for start/cancel/expire of individual alarm timers and one for tracing the suspend time decision when to resume the system. The following trace excerpt illustrates the new mechanism: Binder:3292_2-3304 [000] d..2 149.981123: alarmtimer_cancel: alarmtimer:ffffffc1319a7800 type:REALTIME expires:1325463120000000000 now:1325376810370370245 Binder:3292_2-3304 [000] d..2 149.981136: alarmtimer_start: alarmtimer:ffffffc1319a7800 type:REALTIME expires:1325376840000000000 now:1325376810370384591 Binder:3292_9-3953 [000] d..2 150.212991: alarmtimer_cancel: alarmtimer:ffffffc1319a5a00 type:BOOTTIME expires:179552000000 now:150154008122 Binder:3292_9-3953 [000] d..2 150.213006: alarmtimer_start: alarmtimer:ffffffc1319a5a00 type:BOOTTIME expires:179551000000 now:150154025622 system_server-3000 [002] ...1 162.701940: alarmtimer_suspend: alarmtimer type:REALTIME expires:1325376840000000000 The wakeup time which is selected at suspend time allows to map it back to the task arming the timer: Binder:3292_2. [ tglx: Store alarm timer expiry time instead of some useless RTC relative information, add proper type information for wakeups which are handled via the clock_nanosleep/freezer and massage the changelog. ] Signed-off-by: Baolin Wang Signed-off-by: John Stultz Acked-by: Steven Rostedt Cc: Prarit Bhargava Cc: Richard Cochran Link: http://lkml.kernel.org/r/1480372524-15181-5-git-send-email-john.stultz@linaro.org Signed-off-by: Thomas Gleixner --- include/linux/alarmtimer.h | 5 ++ include/trace/events/alarmtimer.h | 96 +++++++++++++++++++++++++++++++++++++++ kernel/time/alarmtimer.c | 53 +++++++++++++++++---- 3 files changed, 144 insertions(+), 10 deletions(-) create mode 100644 include/trace/events/alarmtimer.h diff --git a/include/linux/alarmtimer.h b/include/linux/alarmtimer.h index 9d8031257a90..c70aac13244a 100644 --- a/include/linux/alarmtimer.h +++ b/include/linux/alarmtimer.h @@ -10,7 +10,12 @@ enum alarmtimer_type { ALARM_REALTIME, ALARM_BOOTTIME, + /* Supported types end here */ ALARM_NUMTYPE, + + /* Used for tracing information. No usable types. */ + ALARM_REALTIME_FREEZER, + ALARM_BOOTTIME_FREEZER, }; enum alarmtimer_restart { diff --git a/include/trace/events/alarmtimer.h b/include/trace/events/alarmtimer.h new file mode 100644 index 000000000000..a1c108c16c9c --- /dev/null +++ b/include/trace/events/alarmtimer.h @@ -0,0 +1,96 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM alarmtimer + +#if !defined(_TRACE_ALARMTIMER_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_ALARMTIMER_H + +#include +#include +#include + +TRACE_DEFINE_ENUM(ALARM_REALTIME); +TRACE_DEFINE_ENUM(ALARM_BOOTTIME); +TRACE_DEFINE_ENUM(ALARM_REALTIME_FREEZER); +TRACE_DEFINE_ENUM(ALARM_BOOTTIME_FREEZER); + +#define show_alarm_type(type) __print_flags(type, " | ", \ + { 1 << ALARM_REALTIME, "REALTIME" }, \ + { 1 << ALARM_BOOTTIME, "BOOTTIME" }, \ + { 1 << ALARM_REALTIME_FREEZER, "REALTIME Freezer" }, \ + { 1 << ALARM_BOOTTIME_FREEZER, "BOOTTIME Freezer" }) + +TRACE_EVENT(alarmtimer_suspend, + + TP_PROTO(ktime_t expires, int flag), + + TP_ARGS(expires, flag), + + TP_STRUCT__entry( + __field(s64, expires) + __field(unsigned char, alarm_type) + ), + + TP_fast_assign( + __entry->expires = expires.tv64; + __entry->alarm_type = flag; + ), + + TP_printk("alarmtimer type:%s expires:%llu", + show_alarm_type((1 << __entry->alarm_type)), + __entry->expires + ) +); + +DECLARE_EVENT_CLASS(alarm_class, + + TP_PROTO(struct alarm *alarm, ktime_t now), + + TP_ARGS(alarm, now), + + TP_STRUCT__entry( + __field(void *, alarm) + __field(unsigned char, alarm_type) + __field(s64, expires) + __field(s64, now) + ), + + TP_fast_assign( + __entry->alarm = alarm; + __entry->alarm_type = alarm->type; + __entry->expires = alarm->node.expires.tv64; + __entry->now = now.tv64; + ), + + TP_printk("alarmtimer:%p type:%s expires:%llu now:%llu", + __entry->alarm, + show_alarm_type((1 << __entry->alarm_type)), + __entry->expires, + __entry->now + ) +); + +DEFINE_EVENT(alarm_class, alarmtimer_fired, + + TP_PROTO(struct alarm *alarm, ktime_t now), + + TP_ARGS(alarm, now) +); + +DEFINE_EVENT(alarm_class, alarmtimer_start, + + TP_PROTO(struct alarm *alarm, ktime_t now), + + TP_ARGS(alarm, now) +); + +DEFINE_EVENT(alarm_class, alarmtimer_cancel, + + TP_PROTO(struct alarm *alarm, ktime_t now), + + TP_ARGS(alarm, now) +); + +#endif /* _TRACE_ALARMTIMER_H */ + +/* This part must be outside protection */ +#include diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index a15caa3d1721..9b08ca391aed 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -26,6 +26,9 @@ #include #include +#define CREATE_TRACE_POINTS +#include + /** * struct alarm_base - Alarm timer bases * @lock: Lock for syncrhonized access to the base @@ -40,7 +43,9 @@ static struct alarm_base { clockid_t base_clockid; } alarm_bases[ALARM_NUMTYPE]; -/* freezer delta & lock used to handle clock_nanosleep triggered wakeups */ +/* freezer information to handle clock_nanosleep triggered wakeups */ +static enum alarmtimer_type freezer_alarmtype; +static ktime_t freezer_expires; static ktime_t freezer_delta; static DEFINE_SPINLOCK(freezer_delta_lock); @@ -194,6 +199,7 @@ static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer) } spin_unlock_irqrestore(&base->lock, flags); + trace_alarmtimer_fired(alarm, base->gettime()); return ret; } @@ -218,15 +224,16 @@ EXPORT_SYMBOL_GPL(alarm_expires_remaining); */ static int alarmtimer_suspend(struct device *dev) { - struct rtc_time tm; - ktime_t min, now; - unsigned long flags; + ktime_t min, now, expires; + int i, ret, type; struct rtc_device *rtc; - int i; - int ret; + unsigned long flags; + struct rtc_time tm; spin_lock_irqsave(&freezer_delta_lock, flags); min = freezer_delta; + expires = freezer_expires; + type = freezer_alarmtype; freezer_delta = ktime_set(0, 0); spin_unlock_irqrestore(&freezer_delta_lock, flags); @@ -247,8 +254,11 @@ static int alarmtimer_suspend(struct device *dev) if (!next) continue; delta = ktime_sub(next->expires, base->gettime()); - if (!min.tv64 || (delta.tv64 < min.tv64)) + if (!min.tv64 || (delta.tv64 < min.tv64)) { + expires = next->expires; min = delta; + type = i; + } } if (min.tv64 == 0) return 0; @@ -258,6 +268,8 @@ static int alarmtimer_suspend(struct device *dev) return -EBUSY; } + trace_alarmtimer_suspend(expires, type); + /* Setup an rtc timer to fire that far in the future */ rtc_timer_cancel(rtc, &rtctimer); rtc_read_time(rtc, &tm); @@ -295,15 +307,32 @@ static int alarmtimer_resume(struct device *dev) static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type) { - ktime_t delta; + struct alarm_base *base; unsigned long flags; - struct alarm_base *base = &alarm_bases[type]; + ktime_t delta; + + switch(type) { + case ALARM_REALTIME: + base = &alarm_bases[ALARM_REALTIME]; + type = ALARM_REALTIME_FREEZER; + break; + case ALARM_BOOTTIME: + base = &alarm_bases[ALARM_BOOTTIME]; + type = ALARM_BOOTTIME_FREEZER; + break; + default: + WARN_ONCE(1, "Invalid alarm type: %d\n", type); + return; + } delta = ktime_sub(absexp, base->gettime()); spin_lock_irqsave(&freezer_delta_lock, flags); - if (!freezer_delta.tv64 || (delta.tv64 < freezer_delta.tv64)) + if (!freezer_delta.tv64 || (delta.tv64 < freezer_delta.tv64)) { freezer_delta = delta; + freezer_expires = absexp; + freezer_alarmtype = type; + } spin_unlock_irqrestore(&freezer_delta_lock, flags); } @@ -342,6 +371,8 @@ void alarm_start(struct alarm *alarm, ktime_t start) alarmtimer_enqueue(base, alarm); hrtimer_start(&alarm->timer, alarm->node.expires, HRTIMER_MODE_ABS); spin_unlock_irqrestore(&base->lock, flags); + + trace_alarmtimer_start(alarm, base->gettime()); } EXPORT_SYMBOL_GPL(alarm_start); @@ -390,6 +421,8 @@ int alarm_try_to_cancel(struct alarm *alarm) if (ret >= 0) alarmtimer_dequeue(base, alarm); spin_unlock_irqrestore(&base->lock, flags); + + trace_alarmtimer_cancel(alarm, base->gettime()); return ret; } EXPORT_SYMBOL_GPL(alarm_try_to_cancel); -- cgit v1.2.3 From 9c1645727b8fa90d07256fdfcc45bf831242a3ab Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 8 Dec 2016 20:49:32 +0000 Subject: timekeeping_Force_unsigned_clocksource_to_nanoseconds_conversion The clocksource delta to nanoseconds conversion is using signed math, but the delta is unsigned. This makes the conversion space smaller than necessary and in case of a multiplication overflow the conversion can become negative. The conversion is done with scaled math: s64 nsec_delta = ((s64)clkdelta * clk->mult) >> clk->shift; Shifting a signed integer right obvioulsy preserves the sign, which has interesting consequences: - Time jumps backwards - __iter_div_u64_rem() which is used in one of the calling code pathes will take forever to piecewise calculate the seconds/nanoseconds part. This has been reported by several people with different scenarios: David observed that when stopping a VM with a debugger: "It was essentially the stopped by debugger case. I forget exactly why, but the guest was being explicitly stopped from outside, it wasn't just scheduling lag. I think it was something in the vicinity of 10 minutes stopped." When lifting the stop the machine went dead. The stopped by debugger case is not really interesting, but nevertheless it would be a good thing not to die completely. But this was also observed on a live system by Liav: "When the OS is too overloaded, delta will get a high enough value for the msb of the sum delta * tkr->mult + tkr->xtime_nsec to be set, and so after the shift the nsec variable will gain a value similar to 0xffffffffff000000." Unfortunately this has been reintroduced recently with commit 6bd58f09e1d8 ("time: Add cycles to nanoseconds translation"). It had been fixed a year ago already in commit 35a4933a8959 ("time: Avoid signed overflow in timekeeping_get_ns()"). Though it's not surprising that the issue has been reintroduced because the function itself and the whole call chain uses s64 for the result and the propagation of it. The change in this recent commit is subtle: s64 nsec; - nsec = (d * m + n) >> s: + nsec = d * m + n; + nsec >>= s; d being type of cycle_t adds another level of obfuscation. This wouldn't have happened if the previous change to unsigned computation would have made the 'nsec' variable u64 right away and a follow up patch had cleaned up the whole call chain. There have been patches submitted which basically did a revert of the above patch leaving everything else unchanged as signed. Back to square one. This spawned a admittedly pointless discussion about potential users which rely on the unsigned behaviour until someone pointed out that it had been fixed before. The changelogs of said patches added further confusion as they made finally false claims about the consequences for eventual users which expect signed results. Despite delta being cycle_t, aka. u64, it's very well possible to hand in a signed negative value and the signed computation will happily return the correct result. But nobody actually sat down and analyzed the code which was added as user after the propably unintended signed conversion. Though in sensitive code like this it's better to analyze it proper and make sure that nothing relies on this than hunting the subtle wreckage half a year later. After analyzing all call chains it stands that no caller can hand in a negative value (which actually would work due to the s64 cast) and rely on the signed math to do the right thing. Change the conversion function to unsigned math. The conversion of all call chains is done in a follow up patch. This solves the starvation issue, which was caused by the negative result, but it does not solve the underlying problem. It merily procrastinates it. When the timekeeper update is deferred long enough that the unsigned multiplication overflows, then time going backwards is observable again. It does neither solve the issue of clocksources with a small counter width which will wrap around possibly several times and cause random time stamps to be generated. But those are usually not found on systems used for virtualization, so this is likely a non issue. I took the liberty to claim authorship for this simply because analyzing all callsites and writing the changelog took substantially more time than just making the simple s/s64/u64/ change and ignore the rest. Fixes: 6bd58f09e1d8 ("time: Add cycles to nanoseconds translation") Reported-by: David Gibson Reported-by: Liav Rehana Signed-off-by: Thomas Gleixner Reviewed-by: David Gibson Acked-by: Peter Zijlstra (Intel) Cc: Parit Bhargava Cc: Laurent Vivier Cc: "Christopher S. Hall" Cc: Chris Metcalf Cc: Richard Cochran Cc: John Stultz Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20161208204228.688545601@linutronix.de Signed-off-by: Thomas Gleixner --- kernel/time/timekeeping.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index b2286e94c934..bfe589e929e8 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -299,10 +299,10 @@ u32 (*arch_gettimeoffset)(void) = default_arch_gettimeoffset; static inline u32 arch_gettimeoffset(void) { return 0; } #endif -static inline s64 timekeeping_delta_to_ns(struct tk_read_base *tkr, +static inline u64 timekeeping_delta_to_ns(struct tk_read_base *tkr, cycle_t delta) { - s64 nsec; + u64 nsec; nsec = delta * tkr->mult + tkr->xtime_nsec; nsec >>= tkr->shift; -- cgit v1.2.3 From acc89612a70e370a5640fd77a83f15b7b94d85e4 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 8 Dec 2016 20:49:34 +0000 Subject: timekeeping: Make the conversion call chain consistently unsigned Propagating a unsigned value through signed variables and functions makes absolutely no sense and is just prone to (re)introduce subtle signed vs. unsigned issues as happened recently. Clean it up. Signed-off-by: Thomas Gleixner Reviewed-by: David Gibson Acked-by: Peter Zijlstra (Intel) Cc: Parit Bhargava Cc: Laurent Vivier Cc: "Christopher S. Hall" Cc: Chris Metcalf Cc: Richard Cochran Cc: Liav Rehana Cc: John Stultz Link: http://lkml.kernel.org/r/20161208204228.765843099@linutronix.de Signed-off-by: Thomas Gleixner --- kernel/time/timekeeping.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index bfe589e929e8..5244821643a4 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -311,7 +311,7 @@ static inline u64 timekeeping_delta_to_ns(struct tk_read_base *tkr, return nsec + arch_gettimeoffset(); } -static inline s64 timekeeping_get_ns(struct tk_read_base *tkr) +static inline u64 timekeeping_get_ns(struct tk_read_base *tkr) { cycle_t delta; @@ -319,8 +319,8 @@ static inline s64 timekeeping_get_ns(struct tk_read_base *tkr) return timekeeping_delta_to_ns(tkr, delta); } -static inline s64 timekeeping_cycles_to_ns(struct tk_read_base *tkr, - cycle_t cycles) +static inline u64 timekeeping_cycles_to_ns(struct tk_read_base *tkr, + cycle_t cycles) { cycle_t delta; @@ -652,7 +652,7 @@ static void timekeeping_forward_now(struct timekeeper *tk) { struct clocksource *clock = tk->tkr_mono.clock; cycle_t cycle_now, delta; - s64 nsec; + u64 nsec; cycle_now = tk->tkr_mono.read(clock); delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, tk->tkr_mono.mask); @@ -681,7 +681,7 @@ int __getnstimeofday64(struct timespec64 *ts) { struct timekeeper *tk = &tk_core.timekeeper; unsigned long seq; - s64 nsecs = 0; + u64 nsecs; do { seq = read_seqcount_begin(&tk_core.seq); @@ -721,7 +721,7 @@ ktime_t ktime_get(void) struct timekeeper *tk = &tk_core.timekeeper; unsigned int seq; ktime_t base; - s64 nsecs; + u64 nsecs; WARN_ON(timekeeping_suspended); @@ -764,7 +764,7 @@ ktime_t ktime_get_with_offset(enum tk_offsets offs) struct timekeeper *tk = &tk_core.timekeeper; unsigned int seq; ktime_t base, *offset = offsets[offs]; - s64 nsecs; + u64 nsecs; WARN_ON(timekeeping_suspended); @@ -808,7 +808,7 @@ ktime_t ktime_get_raw(void) struct timekeeper *tk = &tk_core.timekeeper; unsigned int seq; ktime_t base; - s64 nsecs; + u64 nsecs; do { seq = read_seqcount_begin(&tk_core.seq); @@ -833,8 +833,8 @@ void ktime_get_ts64(struct timespec64 *ts) { struct timekeeper *tk = &tk_core.timekeeper; struct timespec64 tomono; - s64 nsec; unsigned int seq; + u64 nsec; WARN_ON(timekeeping_suspended); @@ -922,8 +922,8 @@ void ktime_get_snapshot(struct system_time_snapshot *systime_snapshot) unsigned long seq; ktime_t base_raw; ktime_t base_real; - s64 nsec_raw; - s64 nsec_real; + u64 nsec_raw; + u64 nsec_real; cycle_t now; WARN_ON_ONCE(timekeeping_suspended); @@ -1081,7 +1081,7 @@ int get_device_system_crosststamp(int (*get_time_fn) cycle_t cycles, now, interval_start; unsigned int clock_was_set_seq = 0; ktime_t base_real, base_raw; - s64 nsec_real, nsec_raw; + u64 nsec_real, nsec_raw; u8 cs_was_changed_seq; unsigned long seq; bool do_interp; @@ -1394,7 +1394,7 @@ void getrawmonotonic64(struct timespec64 *ts) struct timekeeper *tk = &tk_core.timekeeper; struct timespec64 ts64; unsigned long seq; - s64 nsecs; + u64 nsecs; do { seq = read_seqcount_begin(&tk_core.seq); -- cgit v1.2.3 From cbd99e3b289e43000c29aa4aa9b94b394cdc68bd Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 8 Dec 2016 20:49:36 +0000 Subject: timekeeping: Get rid of pointless typecasts cycle_t is defined as u64, so casting it to u64 is a pointless and confusing exercise. cycle_t should simply go away and be replaced with a plain u64 to avoid further confusion. Signed-off-by: Thomas Gleixner Reviewed-by: David Gibson Acked-by: Peter Zijlstra (Intel) Cc: Parit Bhargava Cc: Laurent Vivier Cc: "Christopher S. Hall" Cc: Chris Metcalf Cc: Richard Cochran Cc: Liav Rehana Cc: John Stultz Link: http://lkml.kernel.org/r/20161208204228.844699737@linutronix.de Signed-off-by: Thomas Gleixner --- kernel/time/timekeeping.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 5244821643a4..82e1b5cbebbb 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -258,10 +258,9 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock) tk->cycle_interval = interval; /* Go back from cycles -> shifted ns */ - tk->xtime_interval = (u64) interval * clock->mult; + tk->xtime_interval = interval * clock->mult; tk->xtime_remainder = ntpinterval - tk->xtime_interval; - tk->raw_interval = - ((u64) interval * clock->mult) >> clock->shift; + tk->raw_interval = (interval * clock->mult) >> clock->shift; /* if changing clocks, convert xtime_nsec shift units */ if (old_clock) { -- cgit v1.2.3 From c029a2bec66e42e57538cb65e28618baf6a4b311 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 8 Dec 2016 20:49:38 +0000 Subject: timekeeping: Use mul_u64_u32_shr() instead of open coding it The resume code must deal with a clocksource delta which is potentially big enough to overflow the 64bit mult. Replace the open coded handling with the proper function. Signed-off-by: Thomas Gleixner Reviewed-by: David Gibson Acked-by: Peter Zijlstra (Intel) Cc: Parit Bhargava Cc: Laurent Vivier Cc: "Christopher S. Hall" Cc: Chris Metcalf Cc: Richard Cochran Cc: Liav Rehana Cc: John Stultz Link: http://lkml.kernel.org/r/20161208204228.921674404@linutronix.de Signed-off-by: Thomas Gleixner --- kernel/time/timekeeping.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 82e1b5cbebbb..da233cdf89b0 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1644,7 +1644,7 @@ void timekeeping_resume(void) struct clocksource *clock = tk->tkr_mono.clock; unsigned long flags; struct timespec64 ts_new, ts_delta; - cycle_t cycle_now, cycle_delta; + cycle_t cycle_now; sleeptime_injected = false; read_persistent_clock64(&ts_new); @@ -1670,27 +1670,11 @@ void timekeeping_resume(void) cycle_now = tk->tkr_mono.read(clock); if ((clock->flags & CLOCK_SOURCE_SUSPEND_NONSTOP) && cycle_now > tk->tkr_mono.cycle_last) { - u64 num, max = ULLONG_MAX; - u32 mult = clock->mult; - u32 shift = clock->shift; - s64 nsec = 0; - - cycle_delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, - tk->tkr_mono.mask); - - /* - * "cycle_delta * mutl" may cause 64 bits overflow, if the - * suspended time is too long. In that case we need do the - * 64 bits math carefully - */ - do_div(max, mult); - if (cycle_delta > max) { - num = div64_u64(cycle_delta, max); - nsec = (((u64) max * mult) >> shift) * num; - cycle_delta -= num * max; - } - nsec += ((u64) cycle_delta * mult) >> shift; + u64 nsec, cyc_delta; + cyc_delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, + tk->tkr_mono.mask); + nsec = mul_u64_u32_shr(cyc_delta, clock->mult, clock->shift); ts_delta = ns_to_timespec64(nsec); sleeptime_injected = true; } else if (timespec64_compare(&ts_new, &timekeeping_suspend_time) > 0) { -- cgit v1.2.3