From patchwork Thu May 14 12:30:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Rini X-Patchwork-Id: 245813 List-Id: U-Boot discussion From: trini at konsulko.com (Tom Rini) Date: Thu, 14 May 2020 08:30:00 -0400 Subject: [PATCH 01/10] kconfiglib: Update to the 14.1.0 release Message-ID: <20200514123009.5721-1-trini@konsulko.com> A large number of changes have happened upstream since our last sync in commit 65e05ddc1ae2 ("kconfiglib: Update to the 12.14.0 release"). The big motivation for this sync is support for user defined macros within Kconfig. Cc: Masahiro Yamada Signed-off-by: Tom Rini --- tools/buildman/kconfiglib.py | 614 +++++++++++++++++++++-------------- 1 file changed, 372 insertions(+), 242 deletions(-) diff --git a/tools/buildman/kconfiglib.py b/tools/buildman/kconfiglib.py index 3908985c7b29..c67895ced6b3 100644 --- a/tools/buildman/kconfiglib.py +++ b/tools/buildman/kconfiglib.py @@ -554,7 +554,7 @@ from glob import iglob from os.path import dirname, exists, expandvars, islink, join, realpath -VERSION = (12, 14, 0) +VERSION = (14, 1, 0) # File layout: @@ -773,8 +773,8 @@ class Kconfig(object): See Kconfig.load_config() as well. srctree: - The value of the $srctree environment variable when the configuration was - loaded, or the empty string if $srctree wasn't set. This gives nice + The value the $srctree environment variable had when the Kconfig instance + was created, or the empty string if $srctree wasn't set. This gives nice behavior with os.path.join(), which treats "" as the current directory, without adding "./". @@ -789,13 +789,22 @@ class Kconfig(object): if multiple configurations are loaded with different values for $srctree. config_prefix: - The value of the $CONFIG_ environment variable when the configuration was - loaded. This is the prefix used (and expected) on symbol names in .config - files and C headers. Defaults to "CONFIG_". Used in the same way in the C - tools. - - Like for srctree, only the value of $CONFIG_ when the configuration is - loaded matters. + The value the CONFIG_ environment variable had when the Kconfig instance + was created, or "CONFIG_" if CONFIG_ wasn't set. This is the prefix used + (and expected) on symbol names in .config files and C headers. Used in + the same way in the C tools. + + config_header: + The value the KCONFIG_CONFIG_HEADER environment variable had when the + Kconfig instance was created, or the empty string if + KCONFIG_CONFIG_HEADER wasn't set. This string is inserted verbatim at the + beginning of configuration files. See write_config(). + + header_header: + The value the KCONFIG_AUTOHEADER_HEADER environment variable had when the + Kconfig instance was created, or the empty string if + KCONFIG_AUTOHEADER_HEADER wasn't set. This string is inserted verbatim at + the beginning of header files. See write_autoconf(). filename/linenr: The current parsing location, for use in Python preprocessor functions. @@ -810,11 +819,13 @@ class Kconfig(object): "_warn_assign_no_prompt", "choices", "comments", + "config_header", "config_prefix", "const_syms", "defconfig_list", "defined_syms", "env_vars", + "header_header", "kconfig_filenames", "m", "menus", @@ -854,7 +865,7 @@ class Kconfig(object): # def __init__(self, filename="Kconfig", warn=True, warn_to_stderr=True, - encoding="utf-8"): + encoding="utf-8", suppress_traceback=False): """ Creates a new Kconfig object by parsing Kconfig files. Note that Kconfig files are not the same as .config files (which store @@ -919,7 +930,35 @@ class Kconfig(object): anyway. Related PEP: https://www.python.org/dev/peps/pep-0538/ + + suppress_traceback (default: False): + Helper for tools. When True, any EnvironmentError or KconfigError + generated during parsing is caught, the exception message is printed + to stderr together with the command name, and sys.exit(1) is called + (which generates SystemExit). + + This hides the Python traceback for "expected" errors like syntax + errors in Kconfig files. + + Other exceptions besides EnvironmentError and KconfigError are still + propagated when suppress_traceback is True. """ + try: + self._init(filename, warn, warn_to_stderr, encoding) + except (EnvironmentError, KconfigError) as e: + if suppress_traceback: + cmd = sys.argv[0] # Empty string if missing + if cmd: + cmd += ": " + # Some long exception messages have extra newlines for better + # formatting when reported as an unhandled exception. Strip + # them here. + sys.exit(cmd + str(e).strip()) + raise + + def _init(self, filename, warn, warn_to_stderr, encoding): + # See __init__() + self._encoding = encoding self.srctree = os.getenv("srctree", "") @@ -943,6 +982,9 @@ class Kconfig(object): self._unset_match = _re_match(r"# {}([^ ]+) is not set".format( self.config_prefix)) + self.config_header = os.getenv("KCONFIG_CONFIG_HEADER", "") + self.header_header = os.getenv("KCONFIG_AUTOHEADER_HEADER", "") + self.syms = {} self.const_syms = {} self.defined_syms = [] @@ -1038,8 +1080,9 @@ class Kconfig(object): self._readline = self._open(join(self.srctree, filename), "r").readline try: - # Parse the Kconfig files - self._parse_block(None, self.top_node, self.top_node) + # Parse the Kconfig files. Returns the last node, which we + # terminate with '.next = None'. + self._parse_block(None, self.top_node, self.top_node).next = None self.top_node.list = self.top_node.next self.top_node.next = None except UnicodeDecodeError as e: @@ -1245,7 +1288,7 @@ class Kconfig(object): self._warn("'{}' is not a valid value for the {} " "symbol {}. Assignment ignored." .format(val, TYPE_TO_STR[sym.orig_type], - _name_and_loc(sym)), + sym.name_and_loc), filename, linenr) continue @@ -1272,7 +1315,7 @@ class Kconfig(object): if not match: self._warn("malformed string literal in " "assignment to {}. Assignment ignored." - .format(_name_and_loc(sym)), + .format(sym.name_and_loc), filename, linenr) continue @@ -1341,7 +1384,7 @@ class Kconfig(object): user_val = sym.user_value msg = '{} set more than once. Old value "{}", new value "{}".'.format( - _name_and_loc(sym), user_val, new_val) + sym.name_and_loc, user_val, new_val) if user_val == new_val: if self.warn_assign_redun: @@ -1349,8 +1392,29 @@ class Kconfig(object): elif self.warn_assign_override: self._warn(msg, filename, linenr) - def write_autoconf(self, filename, - header="/* Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) */\n"): + def load_allconfig(self, filename): + """ + Helper for all*config. Loads (merges) the configuration file specified + by KCONFIG_ALLCONFIG, if any. See Documentation/kbuild/kconfig.txt in + the Linux kernel. + + Disables warnings for duplicated assignments within configuration files + for the duration of the call + (kconf.warn_assign_override/warn_assign_redun = False), and restores + the previous warning settings at the end. The KCONFIG_ALLCONFIG + configuration file is expected to override symbols. + + Exits with sys.exit() (which raises a SystemExit exception) and prints + an error to stderr if KCONFIG_ALLCONFIG is set but the configuration + file can't be opened. + + filename: + Command-specific configuration filename - "allyes.config", + "allno.config", etc. + """ + load_allconfig(self, filename) + + def write_autoconf(self, filename=None, header=None): r""" Writes out symbol values as a C header file, matching the format used by include/generated/autoconf.h in the kernel. @@ -1364,22 +1428,43 @@ class Kconfig(object): like the modification time and possibly triggering redundant work in build tools. - filename: - Self-explanatory. + filename (default: None): + Path to write header to. - header (default: "/* Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) */\n"): - Text that will be inserted verbatim at the beginning of the file. You - would usually want it enclosed in '/* */' to make it a C comment, - and include a final terminating newline. + If None (the default), the path in the environment variable + KCONFIG_AUTOHEADER is used if set, and "include/generated/autoconf.h" + otherwise. This is compatible with the C tools. + + header (default: None): + Text inserted verbatim at the beginning of the file. You would + usually want it enclosed in '/* */' to make it a C comment, and + include a trailing newline. + + If None (the default), the value of the environment variable + KCONFIG_AUTOHEADER_HEADER had when the Kconfig instance was created + will be used if it was set, and no header otherwise. See the + Kconfig.header_header attribute. + + Returns a string with a message saying that the header got saved, or + that there were no changes to it. This is meant to reduce boilerplate + in tools, which can do e.g. print(kconf.write_autoconf()). """ - self._write_if_changed(filename, self._autoconf_contents(header)) + if filename is None: + filename = os.getenv("KCONFIG_AUTOHEADER", + "include/generated/autoconf.h") + + if self._write_if_changed(filename, self._autoconf_contents(header)): + return "Kconfig header saved to '{}'".format(filename) + return "No change to Kconfig header in '{}'".format(filename) def _autoconf_contents(self, header): # write_autoconf() helper. Returns the contents to write as a string, - # with 'header' at the beginning. + # with 'header' or KCONFIG_AUTOHEADER_HEADER at the beginning. - # "".join()ed later - chunks = [header] + if header is None: + header = self.header_header + + chunks = [header] # "".join()ed later add = chunks.append for sym in self.unique_defined_syms: @@ -1415,9 +1500,8 @@ class Kconfig(object): return "".join(chunks) - def write_config(self, filename=None, - header="# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n", - save_old=True, verbose=None): + def write_config(self, filename=None, header=None, save_old=True, + verbose=None): r""" Writes out symbol values in the .config format. The format matches the C implementation, including ordering. @@ -1439,16 +1523,21 @@ class Kconfig(object): (OSError/IOError). KconfigError is never raised here. filename (default: None): - Filename to save configuration to (a string). + Path to write configuration to (a string). - If None (the default), the filename in the environment variable + If None (the default), the path in the environment variable KCONFIG_CONFIG is used if set, and ".config" otherwise. See standard_config_filename(). - header (default: "# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n"): - Text that will be inserted verbatim at the beginning of the file. You - would usually want each line to start with '#' to make it a comment, - and include a final terminating newline. + header (default: None): + Text inserted verbatim at the beginning of the file. You would + usually want each line to start with '#' to make it a comment, and + include a trailing newline. + + if None (the default), the value of the environment variable + KCONFIG_CONFIG_HEADER had when the Kconfig instance was created will + be used if it was set, and no header otherwise. See the + Kconfig.config_header attribute. save_old (default: True): If True and already exists, a copy of it will be saved to @@ -1481,7 +1570,7 @@ class Kconfig(object): contents = self._config_contents(header) if self._contents_eq(filename, contents): - return "No change to '{}'".format(filename) + return "No change to configuration in '{}'".format(filename) if save_old: _save_old(filename) @@ -1493,7 +1582,7 @@ class Kconfig(object): def _config_contents(self, header): # write_config() helper. Returns the contents to write as a string, - # with 'header' at the beginning. + # with 'header' or KCONFIG_CONFIG_HEADER at the beginning. # # More memory friendly would be to 'yield' the strings and # "".join(_config_contents()), but it was a bit slower on my system. @@ -1505,13 +1594,15 @@ class Kconfig(object): for sym in self.unique_defined_syms: sym._visited = False - # Did we just print an '# end of ...' comment? - after_end_comment = False + if header is None: + header = self.config_header - # "".join()ed later - chunks = [header] + chunks = [header] # "".join()ed later add = chunks.append + # Did we just print an '# end of ...' comment? + after_end_comment = False + node = self.top_node while 1: # Jump to the next node with an iterative tree walk @@ -1564,8 +1655,7 @@ class Kconfig(object): add("\n#\n# {}\n#\n".format(node.prompt[0])) after_end_comment = False - def write_min_config(self, filename, - header="# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n"): + def write_min_config(self, filename, header=None): """ Writes out a "minimal" configuration file, omitting symbols whose value matches their default value. The format matches the one produced by @@ -1581,31 +1671,35 @@ class Kconfig(object): (OSError/IOError). KconfigError is never raised here. filename: - Self-explanatory. + Path to write minimal configuration to. - header (default: "# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n"): - Text that will be inserted verbatim at the beginning of the file. You - would usually want each line to start with '#' to make it a comment, - and include a final terminating newline. + header (default: None): + Text inserted verbatim at the beginning of the file. You would + usually want each line to start with '#' to make it a comment, and + include a final terminating newline. - Returns a string with a message saying which file got saved. This is - meant to reduce boilerplate in tools, which can do e.g. + if None (the default), the value of the environment variable + KCONFIG_CONFIG_HEADER had when the Kconfig instance was created will + be used if it was set, and no header otherwise. See the + Kconfig.config_header attribute. + + Returns a string with a message saying the minimal configuration got + saved, or that there were no changes to it. This is meant to reduce + boilerplate in tools, which can do e.g. print(kconf.write_min_config()). """ - contents = self._min_config_contents(header) - if self._contents_eq(filename, contents): - return "No change to '{}'".format(filename) - - with self._open(filename, "w") as f: - f.write(contents) - - return "Minimal configuration saved to '{}'".format(filename) + if self._write_if_changed(filename, self._min_config_contents(header)): + return "Minimal configuration saved to '{}'".format(filename) + return "No change to minimal configuration in '{}'".format(filename) def _min_config_contents(self, header): # write_min_config() helper. Returns the contents to write as a string, - # with 'header' at the beginning. + # with 'header' or KCONFIG_CONFIG_HEADER at the beginning. - chunks = [header] + if header is None: + header = self.config_header + + chunks = [header] # "".join()ed later add = chunks.append for sym in self.unique_defined_syms: @@ -2122,9 +2216,9 @@ class Kconfig(object): # it's part of a different construct if self._reuse_tokens: self._reuse_tokens = False - # self._tokens_i is known to be 1 here, because _parse_properties() - # leaves it like that when it can't recognize a line (or parses - # a help text) + # self._tokens_i is known to be 1 here, because _parse_props() + # leaves it like that when it can't recognize a line (or parses a + # help text) return True # readline() returns '' over and over at EOF, which we rely on for help @@ -2141,7 +2235,7 @@ class Kconfig(object): self._tokens = self._tokenize(line) # Initialize to 1 instead of 0 to factor out code from _parse_block() - # and _parse_properties(). They immediately fetch self._tokens[0]. + # and _parse_props(). They immediately fetch self._tokens[0]. self._tokens_i = 1 return True @@ -2172,10 +2266,15 @@ class Kconfig(object): # differs, but it breaks stuff like write_config("/dev/null"), which is # used out there to force evaluation-related warnings to be generated. # This simple version is pretty failsafe and portable. + # + # Returns True if the file has changed and is updated, and False + # otherwise. - if not self._contents_eq(filename, contents): - with self._open(filename, "w") as f: - f.write(contents) + if self._contents_eq(filename, contents): + return False + with self._open(filename, "w") as f: + f.write(contents) + return True def _contents_eq(self, filename, contents): # Returns True if the contents of 'filename' is 'contents' (a string), @@ -2603,10 +2702,9 @@ class Kconfig(object): while 1: match = _name_special_search(s, i) - if match.group() == "$(": - s, i = self._expand_macro(s, match.start(), ()) - else: + if match.group() != "$(": return (s, match.start()) + s, i = self._expand_macro(s, match.start(), ()) def _expand_str(self, s, i): # Expands a quoted string starting at index 'i' in 's'. Handles both @@ -2649,14 +2747,12 @@ class Kconfig(object): # Returns the expanded 's' (including the part before the macro) and # the index of the first character after the expanded macro in 's'. - start = i + res = s[:i] i += 2 # Skip over "$(" - # Start of current macro argument - arg_start = i - - # Arguments of this macro call - new_args = [] + arg_start = i # Start of current macro argument + new_args = [] # Arguments of this macro call + nesting = 0 # Current parentheses nesting level while 1: match = _macro_special_search(s, i) @@ -2664,32 +2760,42 @@ class Kconfig(object): self._parse_error("missing end parenthesis in macro expansion") - if match.group() == ")": + if match.group() == "(": + nesting += 1 + i = match.end() + + elif match.group() == ")": + if nesting: + nesting -= 1 + i = match.end() + continue + # Found the end of the macro new_args.append(s[arg_start:match.start()]) - prefix = s[:start] - # $(1) is replaced by the first argument to the function, etc., # provided at least that many arguments were passed try: # Does the macro look like an integer, with a corresponding # argument? If so, expand it to the value of the argument. - prefix += args[int(new_args[0])] + res += args[int(new_args[0])] except (ValueError, IndexError): # Regular variables are just functions without arguments, # and also go through the function value path - prefix += self._fn_val(new_args) + res += self._fn_val(new_args) - return (prefix + s[match.end():], - len(prefix)) + return (res + s[match.end():], len(res)) elif match.group() == ",": + i = match.end() + if nesting: + continue + # Found the end of a macro argument new_args.append(s[arg_start:match.start()]) - arg_start = i = match.end() + arg_start = i else: # match.group() == "$(" # A nested macro call within the macro @@ -2796,7 +2902,7 @@ class Kconfig(object): # # prev: # The previous menu node. New nodes will be added after this one (by - # modifying their 'next' pointer). + # modifying 'next' pointers). # # 'prev' is reused to parse a list of child menu nodes (for a menu or # Choice): After parsing the children, the 'next' pointer is assigned @@ -2832,11 +2938,11 @@ class Kconfig(object): sym.nodes.append(node) - self._parse_properties(node) + self._parse_props(node) if node.is_menuconfig and not node.prompt: self._warn("the menuconfig symbol {} has no prompt" - .format(_name_and_loc(sym))) + .format(sym.name_and_loc)) # Equivalent to # @@ -2918,7 +3024,7 @@ class Kconfig(object): self.menus.append(node) - self._parse_properties(node) + self._parse_props(node) self._parse_block(_T_ENDMENU, node, node) node.list = node.next @@ -2938,7 +3044,7 @@ class Kconfig(object): self.comments.append(node) - self._parse_properties(node) + self._parse_props(node) prev.next = prev = node @@ -2970,7 +3076,7 @@ class Kconfig(object): choice.nodes.append(node) - self._parse_properties(node) + self._parse_props(node) self._parse_block(_T_ENDCHOICE, node, node) node.list = node.next @@ -2988,17 +3094,16 @@ class Kconfig(object): "no corresponding 'menu'" if t0 is _T_ENDMENU else "unrecognized construct") - # End of file reached. Terminate the final node and return it. + # End of file reached. Return the last node. if end_token: raise KconfigError( - "expected '{}' at end of '{}'" + "error: expected '{}' at end of '{}'" .format("endchoice" if end_token is _T_ENDCHOICE else "endif" if end_token is _T_ENDIF else "endmenu", self.filename)) - prev.next = None return prev def _parse_cond(self): @@ -3012,7 +3117,7 @@ class Kconfig(object): return expr - def _parse_properties(self, node): + def _parse_props(self, node): # Parses and adds properties to the MenuNode 'node' (type, 'prompt', # 'default's, etc.) Properties are later copied up to symbols and # choices in a separate pass after parsing, in e.g. @@ -3038,7 +3143,7 @@ class Kconfig(object): if t0 in _TYPE_TOKENS: # Relies on '_T_BOOL is BOOL', etc., to save a conversion - self._set_type(node, t0) + self._set_type(node.item, t0) if self._tokens[1] is not None: self._parse_prompt(node) @@ -3068,7 +3173,7 @@ class Kconfig(object): self._parse_cond())) elif t0 in _DEF_TOKEN_TO_TYPE: - self._set_type(node, _DEF_TOKEN_TO_TYPE[t0]) + self._set_type(node.item, _DEF_TOKEN_TO_TYPE[t0]) node.defaults.append((self._parse_expr(False), self._parse_cond())) @@ -3169,14 +3274,15 @@ class Kconfig(object): self._reuse_tokens = True return - def _set_type(self, node, new_type): + def _set_type(self, sc, new_type): + # Sets the type of 'sc' (symbol or choice) to 'new_type' + # UNKNOWN is falsy - if node.item.orig_type and node.item.orig_type is not new_type: + if sc.orig_type and sc.orig_type is not new_type: self._warn("{} defined with multiple types, {} will be used" - .format(_name_and_loc(node.item), - TYPE_TO_STR[new_type])) + .format(sc.name_and_loc, TYPE_TO_STR[new_type])) - node.item.orig_type = new_type + sc.orig_type = new_type def _parse_prompt(self, node): # 'prompt' properties override each other within a single definition of @@ -3184,7 +3290,7 @@ class Kconfig(object): # multiple times if node.prompt: - self._warn(_name_and_loc(node.item) + + self._warn(node.item.name_and_loc + " defined with multiple prompts in single location") prompt = self._tokens[1] @@ -3194,7 +3300,7 @@ class Kconfig(object): self._parse_error("expected prompt string") if prompt != prompt.strip(): - self._warn(_name_and_loc(node.item) + + self._warn(node.item.name_and_loc + " has leading or trailing whitespace in its prompt") # This avoid issues for e.g. reStructuredText documentation, where @@ -3205,7 +3311,7 @@ class Kconfig(object): def _parse_help(self, node): if node.help is not None: - self._warn(_name_and_loc(node.item) + " defined with more than " + self._warn(node.item.name_and_loc + " defined with more than " "one help text -- only the last one will be used") # Micro-optimization. This code is pretty hot. @@ -3261,7 +3367,7 @@ class Kconfig(object): self._line_after_help(line) def _empty_help(self, node, line): - self._warn(_name_and_loc(node.item) + + self._warn(node.item.name_and_loc + " has 'help' but empty help text") node.help = "" if line: @@ -3366,7 +3472,7 @@ class Kconfig(object): # The calculated sets might be larger than necessary as we don't do any # complex analysis of the expressions. - make_depend_on = _make_depend_on # Micro-optimization + depend_on = _depend_on # Micro-optimization # Only calculate _dependents for defined symbols. Constant and # undefined symbols could theoretically be selected/implied, but it @@ -3377,29 +3483,29 @@ class Kconfig(object): # The prompt conditions for node in sym.nodes: if node.prompt: - make_depend_on(sym, node.prompt[1]) + depend_on(sym, node.prompt[1]) # The default values and their conditions for value, cond in sym.defaults: - make_depend_on(sym, value) - make_depend_on(sym, cond) + depend_on(sym, value) + depend_on(sym, cond) # The reverse and weak reverse dependencies - make_depend_on(sym, sym.rev_dep) - make_depend_on(sym, sym.weak_rev_dep) + depend_on(sym, sym.rev_dep) + depend_on(sym, sym.weak_rev_dep) # The ranges along with their conditions for low, high, cond in sym.ranges: - make_depend_on(sym, low) - make_depend_on(sym, high) - make_depend_on(sym, cond) + depend_on(sym, low) + depend_on(sym, high) + depend_on(sym, cond) # The direct dependencies. This is usually redundant, as the direct # dependencies get propagated to properties, but it's needed to get # invalidation solid for 'imply', which only checks the direct # dependencies (even if there are no properties to propagate it # to). - make_depend_on(sym, sym.direct_dep) + depend_on(sym, sym.direct_dep) # In addition to the above, choice symbols depend on the choice # they're in, but that's handled automatically since the Choice is @@ -3412,11 +3518,11 @@ class Kconfig(object): # The prompt conditions for node in choice.nodes: if node.prompt: - make_depend_on(choice, node.prompt[1]) + depend_on(choice, node.prompt[1]) # The default symbol conditions for _, cond in choice.defaults: - make_depend_on(choice, cond) + depend_on(choice, cond) def _add_choice_deps(self): # Choices also depend on the choice symbols themselves, because the @@ -3641,26 +3747,26 @@ class Kconfig(object): if target_sym.orig_type not in _BOOL_TRISTATE_UNKNOWN: self._warn("{} selects the {} symbol {}, which is not " "bool or tristate" - .format(_name_and_loc(sym), + .format(sym.name_and_loc, TYPE_TO_STR[target_sym.orig_type], - _name_and_loc(target_sym))) + target_sym.name_and_loc)) for target_sym, _ in sym.implies: if target_sym.orig_type not in _BOOL_TRISTATE_UNKNOWN: self._warn("{} implies the {} symbol {}, which is not " "bool or tristate" - .format(_name_and_loc(sym), + .format(sym.name_and_loc, TYPE_TO_STR[target_sym.orig_type], - _name_and_loc(target_sym))) + target_sym.name_and_loc)) elif sym.orig_type: # STRING/INT/HEX for default, _ in sym.defaults: if default.__class__ is not Symbol: raise KconfigError( - "the {} symbol {} has a malformed default {} -- expected " - "a single symbol" - .format(TYPE_TO_STR[sym.orig_type], _name_and_loc(sym), - expr_str(default))) + "the {} symbol {} has a malformed default {} -- " + "expected a single symbol" + .format(TYPE_TO_STR[sym.orig_type], + sym.name_and_loc, expr_str(default))) if sym.orig_type is STRING: if not default.is_constant and not default.nodes and \ @@ -3671,22 +3777,22 @@ class Kconfig(object): # (and no symbol named 'foo' exists). self._warn("style: quotes recommended around " "default value for string symbol " - + _name_and_loc(sym)) + + sym.name_and_loc) elif not num_ok(default, sym.orig_type): # INT/HEX self._warn("the {0} symbol {1} has a non-{0} default {2}" .format(TYPE_TO_STR[sym.orig_type], - _name_and_loc(sym), - _name_and_loc(default))) + sym.name_and_loc, + default.name_and_loc)) if sym.selects or sym.implies: self._warn("the {} symbol {} has selects or implies" .format(TYPE_TO_STR[sym.orig_type], - _name_and_loc(sym))) + sym.name_and_loc)) else: # UNKNOWN self._warn("{} defined without a type" - .format(_name_and_loc(sym))) + .format(sym.name_and_loc)) if sym.ranges: @@ -3694,7 +3800,7 @@ class Kconfig(object): self._warn( "the {} symbol {} has ranges, but is not int or hex" .format(TYPE_TO_STR[sym.orig_type], - _name_and_loc(sym))) + sym.name_and_loc)) else: for low, high, _ in sym.ranges: if not num_ok(low, sym.orig_type) or \ @@ -3703,9 +3809,9 @@ class Kconfig(object): self._warn("the {0} symbol {1} has a non-{0} " "range [{2}, {3}]" .format(TYPE_TO_STR[sym.orig_type], - _name_and_loc(sym), - _name_and_loc(low), - _name_and_loc(high))) + sym.name_and_loc, + low.name_and_loc, + high.name_and_loc)) def _check_choice_sanity(self): # Checks various choice properties that are handiest to check after @@ -3714,43 +3820,43 @@ class Kconfig(object): def warn_select_imply(sym, expr, expr_type): msg = "the choice symbol {} is {} by the following symbols, but " \ "select/imply has no effect on choice symbols" \ - .format(_name_and_loc(sym), expr_type) + .format(sym.name_and_loc, expr_type) # si = select/imply for si in split_expr(expr, OR): - msg += "\n - " + _name_and_loc(split_expr(si, AND)[0]) + msg += "\n - " + split_expr(si, AND)[0].name_and_loc self._warn(msg) for choice in self.unique_choices: if choice.orig_type not in _BOOL_TRISTATE: self._warn("{} defined with type {}" - .format(_name_and_loc(choice), + .format(choice.name_and_loc, TYPE_TO_STR[choice.orig_type])) for node in choice.nodes: if node.prompt: break else: - self._warn(_name_and_loc(choice) + " defined without a prompt") + self._warn(choice.name_and_loc + " defined without a prompt") for default, _ in choice.defaults: if default.__class__ is not Symbol: raise KconfigError( "{} has a malformed default {}" - .format(_name_and_loc(choice), expr_str(default))) + .format(choice.name_and_loc, expr_str(default))) if default.choice is not choice: self._warn("the default selection {} of {} is not " "contained in the choice" - .format(_name_and_loc(default), - _name_and_loc(choice))) + .format(default.name_and_loc, + choice.name_and_loc)) for sym in choice.syms: if sym.defaults: self._warn("default on the choice symbol {} will have " "no effect, as defaults do not affect choice " - "symbols".format(_name_and_loc(sym))) + "symbols".format(sym.name_and_loc)) if sym.rev_dep is not sym.kconfig.n: warn_select_imply(sym, sym.rev_dep, "selected") @@ -3762,15 +3868,15 @@ class Kconfig(object): if node.parent.item is choice: if not node.prompt: self._warn("the choice symbol {} has no prompt" - .format(_name_and_loc(sym))) + .format(sym.name_and_loc)) elif node.prompt: self._warn("the choice symbol {} is defined with a " "prompt outside the choice" - .format(_name_and_loc(sym))) + .format(sym.name_and_loc)) def _parse_error(self, msg): - raise KconfigError("{}couldn't parse '{}': {}".format( + raise KconfigError("{}error: couldn't parse '{}': {}".format( "" if self.filename is None else "{}:{}: ".format(self.filename, self.linenr), self._line.strip(), msg)) @@ -3907,6 +4013,13 @@ class Symbol(object): The type as given in the Kconfig file, without any magic applied. Used when printing the symbol. + tri_value: + The tristate value of the symbol as an integer. One of 0, 1, 2, + representing n, m, y. Always 0 (n) for non-bool/tristate symbols. + + This is the symbol value that's used outside of relation expressions + (A, !A, A && B, A || B). + str_value: The value of the symbol as a string. Gives the value for string/int/hex symbols. For bool/tristate symbols, gives "n", "m", or "y". @@ -3914,17 +4027,20 @@ class Symbol(object): This is the symbol value that's used in relational expressions (A = B, A != B, etc.) - Gotcha: For int/hex symbols, the exact format of the value must often be - preserved (e.g., when writing a .config file), hence why you can't get it + Gotcha: For int/hex symbols, the exact format of the value is often + preserved (e.g. when writing a .config file), hence why you can't get it directly as an int. Do int(int_sym.str_value) or int(hex_sym.str_value, 16) to get the integer value. - tri_value: - The tristate value of the symbol as an integer. One of 0, 1, 2, - representing n, m, y. Always 0 (n) for non-bool/tristate symbols. + user_value: + The user value of the symbol. None if no user value has been assigned + (via Kconfig.load_config() or Symbol.set_value()). - This is the symbol value that's used outside of relation expressions - (A, !A, A && B, A || B). + Holds 0, 1, or 2 for bool/tristate symbols, and a string for the other + symbol types. + + WARNING: Do not assign directly to this. It will break things. Use + Symbol.set_value(). assignable: A tuple containing the tristate user values that can currently be @@ -3965,16 +4081,6 @@ class Symbol(object): The visibility of the symbol. One of 0, 1, 2, representing n, m, y. See the module documentation for an overview of symbol values and visibility. - user_value: - The user value of the symbol. None if no user value has been assigned - (via Kconfig.load_config() or Symbol.set_value()). - - Holds 0, 1, or 2 for bool/tristate symbols, and a string for the other - symbol types. - - WARNING: Do not assign directly to this. It will break things. Use - Symbol.set_value(). - config_string: The .config assignment string that would get written out for the symbol by Kconfig.write_config(). Returns the empty string if no .config @@ -4002,6 +4108,15 @@ class Symbol(object): though you might get some special symbols and possibly some "redundant" n-valued symbol entries in there. + name_and_loc: + Holds a string like + + "MY_SYMBOL (defined at foo/Kconfig:12, bar/Kconfig:14)" + + , giving the name of the symbol and its definition location(s). + + If the symbol is undefined, the location is given as "(undefined)". + nodes: A list of MenuNodes for this symbol. Will contain a single MenuNode for most symbols. Undefined and constant symbols have an empty nodes list. @@ -4232,7 +4347,7 @@ class Symbol(object): "being outside the active range ([{}, {}]) -- falling " "back on defaults" .format(num2str(user_val), TYPE_TO_STR[self.orig_type], - _name_and_loc(self), + self.name_and_loc, num2str(low), num2str(high))) else: # If the user value is well-formed and satisfies range @@ -4282,7 +4397,7 @@ class Symbol(object): self.kconfig._warn( "default value {} on {} clamped to {} due to " "being outside the active range ([{}, {}])" - .format(val_num, _name_and_loc(self), + .format(val_num, self.name_and_loc, num2str(clamp), num2str(low), num2str(high))) @@ -4323,7 +4438,7 @@ class Symbol(object): self.kconfig._warn( "The {} symbol {} is being evaluated in a logical context " "somewhere. It will always evaluate to n." - .format(TYPE_TO_STR[self.orig_type], _name_and_loc(self))) + .format(TYPE_TO_STR[self.orig_type], self.name_and_loc)) self._cached_tri_val = 0 return 0 @@ -4433,6 +4548,13 @@ class Symbol(object): return '{}{}="{}"\n' \ .format(self.kconfig.config_prefix, self.name, escape(val)) + @property + def name_and_loc(self): + """ + See the class documentation. + """ + return self.name + " " + _locs(self) + def set_value(self, value): """ Sets the user value of the symbol. @@ -4454,8 +4576,8 @@ class Symbol(object): value: The user value to give to the symbol. For bool and tristate symbols, n/m/y can be specified either as 0/1/2 (the usual format for tristate - values in Kconfiglib) or as one of the strings "n"/"m"/"y". For other - symbol types, pass a string. + values in Kconfiglib) or as one of the strings "n", "m", or "y". For + other symbol types, pass a string. Note that the value for an int/hex symbol is passed as a string, e.g. "123" or "0x0123". The format of this string is preserved in the @@ -4502,7 +4624,7 @@ class Symbol(object): "assignment ignored" .format(TRI_TO_STR[value] if value in TRI_TO_STR else "'{}'".format(value), - _name_and_loc(self), TYPE_TO_STR[self.orig_type])) + self.name_and_loc, TYPE_TO_STR[self.orig_type])) return False @@ -4790,7 +4912,7 @@ class Symbol(object): return if self.kconfig._warn_assign_no_prompt: - self.kconfig._warn(_name_and_loc(self) + " has no prompt, meaning " + self.kconfig._warn(self.name_and_loc + " has no prompt, meaning " "user values have no effect on it") def _str_default(self): @@ -4836,7 +4958,7 @@ class Symbol(object): msg = "{} has direct dependencies {} with value {}, but is " \ "currently being {}-selected by the following symbols:" \ - .format(_name_and_loc(self), expr_str(self.direct_dep), + .format(self.name_and_loc, expr_str(self.direct_dep), TRI_TO_STR[expr_value(self.direct_dep)], TRI_TO_STR[expr_value(self.rev_dep)]) @@ -4854,7 +4976,7 @@ class Symbol(object): msg += "\n - {}, with value {}, direct dependencies {} " \ "(value: {})" \ - .format(_name_and_loc(selecting_sym), + .format(selecting_sym.name_and_loc, selecting_sym.str_value, expr_str(selecting_sym.direct_dep), TRI_TO_STR[expr_value(selecting_sym.direct_dep)]) @@ -4938,12 +5060,21 @@ class Choice(object): Corresponding attributes have the same name in the Symbol and Choice classes, for consistency and compatibility. + str_value: + Like choice.tri_value, but gives the value as one of the strings + "n", "m", or "y" + + user_value: + The value (mode) selected by the user through Choice.set_value(). Either + 0, 1, or 2, or None if the user hasn't selected a mode. See + Symbol.user_value. + + WARNING: Do not assign directly to this. It will break things. Use + Choice.set_value() instead. + assignable: See the symbol class documentation. Gives the assignable values (modes). - visibility: - See the Symbol class documentation. Acts on the value (mode). - selection: The Symbol instance of the currently selected symbol. None if the Choice is not in y mode or has no selected symbol (due to unsatisfied @@ -4952,14 +5083,6 @@ class Choice(object): WARNING: Do not assign directly to this. It will break things. Call sym.set_value(2) on the choice symbol you want to select instead. - user_value: - The value (mode) selected by the user through Choice.set_value(). Either - 0, 1, or 2, or None if the user hasn't selected a mode. See - Symbol.user_value. - - WARNING: Do not assign directly to this. It will break things. Use - Choice.set_value() instead. - user_selection: The symbol selected by the user (by setting it to y). Ignored if the choice is not in y mode, but still remembered so that the choice "snaps @@ -4969,6 +5092,19 @@ class Choice(object): WARNING: Do not assign directly to this. It will break things. Call sym.set_value(2) on the choice symbol to be selected instead. + visibility: + See the Symbol class documentation. Acts on the value (mode). + + name_and_loc: + Holds a string like + + " (defined at foo/Kconfig:12)" + + , giving the name of the choice and its definition location(s). If the + choice has no name (isn't defined with 'choice MY_CHOICE'), then it will + be shown as "" before the list of locations (always a single one + in that case). + syms: List of symbols contained in the choice. @@ -5088,6 +5224,14 @@ class Choice(object): self._cached_vis = _visibility(self) return self._cached_vis + @property + def name_and_loc(self): + """ + See the class documentation. + """ + # Reuse the expression format, which is ''. + return standard_sc_expr_str(self) + " " + _locs(self) + @property def selection(self): """ @@ -5128,7 +5272,7 @@ class Choice(object): "assignment ignored" .format(TRI_TO_STR[value] if value in TRI_TO_STR else "'{}'".format(value), - _name_and_loc(self), TYPE_TO_STR[self.orig_type])) + self.name_and_loc, TYPE_TO_STR[self.orig_type])) return False @@ -5251,8 +5395,8 @@ class Choice(object): self._cached_selection = _NO_CACHED_SELECTION - # is_constant is checked by _make_depend_on(). Just set it to avoid - # having to special-case choices. + # is_constant is checked by _depend_on(). Just set it to avoid having + # to special-case choices. self.is_constant = self.is_optional = False # See Kconfig._build_dep() @@ -6050,25 +6194,32 @@ def unescape(s): _unescape_sub = re.compile(r"\\(.)").sub -def standard_kconfig(): +def standard_kconfig(description=None): """ - Helper for tools. Loads the top-level Kconfig specified as the first - command-line argument, or "Kconfig" if there are no command-line arguments. - Returns the Kconfig instance. + Argument parsing helper for tools that take a single optional Kconfig file + argument (default: Kconfig). Returns the Kconfig instance for the parsed + configuration. Uses argparse internally. + + Exits with sys.exit() (which raises SystemExit) on errors. - Exits with sys.exit() (which raises a SystemExit exception) and prints a - usage note to stderr if more than one command-line argument is passed. + description (default: None): + The 'description' passed to argparse.ArgumentParser(). + argparse.RawDescriptionHelpFormatter is used, so formatting is preserved. """ - if len(sys.argv) > 2: - sys.exit("usage: {} [Kconfig]".format(sys.argv[0])) + import argparse - # Only show backtraces for unexpected exceptions - try: - return Kconfig("Kconfig" if len(sys.argv) < 2 else sys.argv[1]) - except (EnvironmentError, KconfigError) as e: - # Some long exception messages have extra newlines for better - # formatting when reported as an unhandled exception. Strip them here. - sys.exit(str(e).strip()) + parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + description=description) + + parser.add_argument( + "kconfig", + metavar="KCONFIG", + default="Kconfig", + nargs="?", + help="Top-level Kconfig file (default: Kconfig)") + + return Kconfig(parser.parse_args().kconfig, suppress_traceback=True) def standard_config_filename(): @@ -6084,25 +6235,9 @@ def standard_config_filename(): def load_allconfig(kconf, filename): """ - Helper for all*config. Loads (merges) the configuration file specified by - KCONFIG_ALLCONFIG, if any. See Documentation/kbuild/kconfig.txt in the - Linux kernel. - - Disables warnings for duplicated assignments within configuration files for - the duration of the call (kconf.warn_assign_override/warn_assign_redun = False), - and restores the previous warning settings at the end. The - KCONFIG_ALLCONFIG configuration file is expected to override symbols. - - Exits with sys.exit() (which raises a SystemExit exception) and prints an - error to stderr if KCONFIG_ALLCONFIG is set but the configuration file - can't be opened. - - kconf: - Kconfig instance to load the configuration in. - - filename: - Command-specific configuration filename - "allyes.config", - "allno.config", etc. + Use Kconfig.load_allconfig() instead, which was added in Kconfiglib 13.4.0. + Supported for backwards compatibility. Might be removed at some point after + a long period of deprecation warnings. """ allconfig = os.getenv("KCONFIG_ALLCONFIG") if allconfig is None: @@ -6178,7 +6313,7 @@ def _visibility(sc): return vis -def _make_depend_on(sc, expr): +def _depend_on(sc, expr): # Adds 'sc' (symbol or choice) as a "dependee" to all symbols in 'expr'. # Constant symbols in 'expr' are skipped as they can never change value # anyway. @@ -6186,11 +6321,11 @@ def _make_depend_on(sc, expr): if expr.__class__ is tuple: # AND, OR, NOT, or relation - _make_depend_on(sc, expr[1]) + _depend_on(sc, expr[1]) # NOTs only have a single operand if expr[0] is not NOT: - _make_depend_on(sc, expr[2]) + _depend_on(sc, expr[2]) elif not expr.is_constant: # Non-constant symbol, or choice @@ -6286,20 +6421,16 @@ def _save_old(path): pass -def _name_and_loc(sc): - # Helper for giving the symbol/choice name and location(s) in e.g. warnings +def _locs(sc): + # Symbol/Choice.name_and_loc helper. Returns the "(defined at ...)" part of + # the string. 'sc' is a Symbol or Choice. - # Reuse the expression format. That way choices show up as - # '' - name = standard_sc_expr_str(sc) + if sc.nodes: + return "(defined at {})".format( + ", ".join("{0.filename}:{0.linenr}".format(node) + for node in sc.nodes)) - if not sc.nodes: - return name + " (undefined)" - - return "{} (defined at {})".format( - name, - ", ".join("{}:{}".format(node.filename, node.linenr) - for node in sc.nodes)) + return "(undefined)" # Menu manipulation @@ -6554,7 +6685,7 @@ def _found_dep_loop(loop, cur): msg += "the choice symbol " msg += "{}, with definition...\n\n{}\n\n" \ - .format(_name_and_loc(item), item) + .format(item.name_and_loc, item) # Small wart: Since we reuse the already calculated # Symbol/Choice._dependents sets for recursive dependency detection, we @@ -6578,7 +6709,7 @@ def _found_dep_loop(loop, cur): msg += "(imply-related dependencies: {})\n\n" \ .format(expr_str(item.rev_dep)) - msg += "...depends again on {}".format(_name_and_loc(loop[0])) + msg += "...depends again on " + loop[0].name_and_loc raise KconfigError(msg) @@ -6648,8 +6779,7 @@ def _error_if_fn(kconf, _, cond, msg): def _shell_fn(kconf, _, command): - # Only import as needed, to save some startup time - import subprocess + import subprocess # Only import as needed, to save some startup time stdout, stderr = subprocess.Popen( command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE @@ -7015,8 +7145,8 @@ _assignment_lhs_fragment_match = _re_match("[A-Za-z0-9_-]*") # variable assignment _assignment_rhs_match = _re_match(r"\s*(=|:=|\+=)\s*(.*)") -# Special characters/strings while expanding a macro (')', ',', and '$(') -_macro_special_search = _re_search(r"\)|,|\$\(") +# Special characters/strings while expanding a macro ('(', ')', ',', and '$(') +_macro_special_search = _re_search(r"\(|\)|,|\$\(") # Special characters/strings while expanding a string (quotes, '\', and '$(') _string_special_search = _re_search(r'"|\'|\\|\$\(') From patchwork Thu May 14 12:30:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Rini X-Patchwork-Id: 245805 List-Id: U-Boot discussion From: trini at konsulko.com (Tom Rini) Date: Thu, 14 May 2020 08:30:01 -0400 Subject: [PATCH 02/10] kconfig: Add scripts/Kconfig.include from v4.19 In-Reply-To: <20200514123009.5721-1-trini@konsulko.com> References: <20200514123009.5721-1-trini@konsulko.com> Message-ID: <20200514123009.5721-2-trini@konsulko.com> As part of re-syncing our Kconfig logic up to v4.19, we had missed adding this new file that includes helper macros. To quote the upstream commit e1cfdc0e72fc ("kconfig: add basic helper macros to scripts/Kconfig.include"): Kconfig got text processing tools like we see in Make. Add Kconfig helper macros to scripts/Kconfig.include like we collect Makefile macros in scripts/Kbuild.include. Cc: Masahiro Yamada Signed-off-by: Tom Rini --- Kconfig | 2 ++ scripts/Kconfig.include | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 scripts/Kconfig.include diff --git a/Kconfig b/Kconfig index 15f1a75c61ab..72b4439264a6 100644 --- a/Kconfig +++ b/Kconfig @@ -5,6 +5,8 @@ # mainmenu "U-Boot $(UBOOTVERSION) Configuration" +source "scripts/Kconfig.include" + # Allow defaults in arch-specific code to override any given here source "arch/Kconfig" diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include new file mode 100644 index 000000000000..dad5583451af --- /dev/null +++ b/scripts/Kconfig.include @@ -0,0 +1,30 @@ +# Kconfig helper macros + +# Convenient variables +comma := , +quote := " +squote := ' +empty := +space := $(empty) $(empty) +dollar := $ +right_paren := ) +left_paren := ( + +# $(if-success,,,) +# Return if exits with 0, otherwise. +if-success = $(shell,{ $(1); } >/dev/null 2>&1 && echo "$(2)" || echo "$(3)") + +# $(success,) +# Return y if exits with 0, n otherwise +success = $(if-success,$(1),y,n) + +# $(cc-option,) +# Return y if the compiler supports , n otherwise +cc-option = $(success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null) + +# $(ld-option,) +# Return y if the linker supports , n otherwise +ld-option = $(success,$(LD) -v $(1)) + +# gcc version including patch level +gcc-version := $(shell,$(srctree)/scripts/gcc-version.sh -p $(CC) | sed 's/^0*//') From patchwork Thu May 14 12:30:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Rini X-Patchwork-Id: 245804 List-Id: U-Boot discussion From: trini at konsulko.com (Tom Rini) Date: Thu, 14 May 2020 08:30:02 -0400 Subject: [PATCH 03/10] Don't start ad-hoc games with -Wno-maybe-initialized In-Reply-To: <20200514123009.5721-1-trini@konsulko.com> References: <20200514123009.5721-1-trini@konsulko.com> Message-ID: <20200514123009.5721-3-trini@konsulko.com> Borrowing from Linux commit 78a5255ffb6a ("Stop the ad-hoc games with -Wno-maybe-initialized") move to have maybe-initialized warnings be handled with building with W=2 instead of playing more guessing games with newer compilers. Signed-off-by: Tom Rini --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index a9d58ca7a0dc..951ecbd41cef 100644 --- a/Makefile +++ b/Makefile @@ -683,6 +683,9 @@ KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks) # disable stringop warnings in gcc 8+ KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation) +# Enabled with W=2, disabled by default as noisy +KBUILD_CFLAGS += $(call cc-disable-warning, maybe-uninitialized) + # change __FILE__ to the relative path from the srctree KBUILD_CFLAGS += $(call cc-option,-fmacro-prefix-map=$(srctree)/=) From patchwork Thu May 14 12:30:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Rini X-Patchwork-Id: 245806 List-Id: U-Boot discussion From: trini at konsulko.com (Tom Rini) Date: Thu, 14 May 2020 08:30:03 -0400 Subject: [PATCH 04/10] tegra: Convert from ACCESS_ONCE to READ/WRITE_ONCE In-Reply-To: <20200514123009.5721-1-trini@konsulko.com> References: <20200514123009.5721-1-trini@konsulko.com> Message-ID: <20200514123009.5721-4-trini@konsulko.com> In order to update our to a newer version that no longer provides ACCESS_ONCE() but only READ_ONCE()/WRITE_ONCE() we need to convert arch/arm/mach-tegra/ivc.c to the other macros. Cc: Tom Warren Signed-off-by: Tom Rini --- arch/arm/mach-tegra/ivc.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-tegra/ivc.c b/arch/arm/mach-tegra/ivc.c index a448f2df3028..325d61f6d3a7 100644 --- a/arch/arm/mach-tegra/ivc.c +++ b/arch/arm/mach-tegra/ivc.c @@ -123,11 +123,11 @@ static inline int tegra_ivc_channel_empty(struct tegra_ivc *ivc, { /* * This function performs multiple checks on the same values with - * security implications, so create snapshots with ACCESS_ONCE() to + * security implications, so create snapshots with READ_ONCE() to * ensure that these checks use the same values. */ - uint32_t w_count = ACCESS_ONCE(ch->w_count); - uint32_t r_count = ACCESS_ONCE(ch->r_count); + uint32_t w_count = READ_ONCE(ch->w_count); + uint32_t r_count = READ_ONCE(ch->r_count); /* * Perform an over-full check to prevent denial of service attacks where @@ -152,14 +152,14 @@ static inline int tegra_ivc_channel_full(struct tegra_ivc *ivc, * Invalid cases where the counters indicate that the queue is over * capacity also appear full. */ - return (ACCESS_ONCE(ch->w_count) - ACCESS_ONCE(ch->r_count)) >= + return (READ_ONCE(ch->w_count) - READ_ONCE(ch->r_count)) >= ivc->nframes; } static inline void tegra_ivc_advance_rx(struct tegra_ivc *ivc) { - ACCESS_ONCE(ivc->rx_channel->r_count) = - ACCESS_ONCE(ivc->rx_channel->r_count) + 1; + WRITE_ONCE(ivc->rx_channel->r_count, + READ_ONCE(ivc->rx_channel->r_count) + 1); if (ivc->r_pos == ivc->nframes - 1) ivc->r_pos = 0; @@ -169,8 +169,8 @@ static inline void tegra_ivc_advance_rx(struct tegra_ivc *ivc) static inline void tegra_ivc_advance_tx(struct tegra_ivc *ivc) { - ACCESS_ONCE(ivc->tx_channel->w_count) = - ACCESS_ONCE(ivc->tx_channel->w_count) + 1; + WRITE_ONCE(ivc->tx_channel->w_count, + READ_ONCE(ivc->tx_channel->w_count) + 1); if (ivc->w_pos == ivc->nframes - 1) ivc->w_pos = 0; @@ -231,7 +231,7 @@ static inline uint32_t tegra_ivc_channel_avail_count(struct tegra_ivc *ivc, * comment in tegra_ivc_channel_empty() for an explanation about * special over-full considerations. */ - return ACCESS_ONCE(ch->w_count) - ACCESS_ONCE(ch->r_count); + return READ_ONCE(ch->w_count) - READ_ONCE(ch->r_count); } int tegra_ivc_read_get_next_frame(struct tegra_ivc *ivc, void **frame) @@ -357,7 +357,7 @@ int tegra_ivc_channel_notified(struct tegra_ivc *ivc) /* Copy the receiver's state out of shared memory. */ offset = offsetof(struct tegra_ivc_channel_header, w_count); tegra_ivc_invalidate_counter(ivc, ivc->rx_channel, offset); - peer_state = ACCESS_ONCE(ivc->rx_channel->state); + peer_state = READ_ONCE(ivc->rx_channel->state); if (peer_state == ivc_state_sync) { /* From patchwork Thu May 14 12:30:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Rini X-Patchwork-Id: 245807 List-Id: U-Boot discussion From: trini at konsulko.com (Tom Rini) Date: Thu, 14 May 2020 08:30:04 -0400 Subject: [PATCH 05/10] x86: Convert from ACCESS_ONCE to READ/WRITE_ONCE In-Reply-To: <20200514123009.5721-1-trini@konsulko.com> References: <20200514123009.5721-1-trini@konsulko.com> Message-ID: <20200514123009.5721-5-trini@konsulko.com> In order to update our to a newer version that no longer provides ACCESS_ONCE() but only READ_ONCE()/WRITE_ONCE() we need to convert arch/x86/include/asm/atomic.h to the other macros. Cc: Simon Glass Cc: Bin Meng Signed-off-by: Tom Rini Reviewed-by: Simon Glass --- arch/x86/include/asm/atomic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h index 806f7873819e..002e36ba53e6 100644 --- a/arch/x86/include/asm/atomic.h +++ b/arch/x86/include/asm/atomic.h @@ -22,7 +22,7 @@ typedef struct { volatile int counter; } atomic_t; */ static inline int atomic_read(const atomic_t *v) { - return ACCESS_ONCE((v)->counter); + return READ_ONCE((v)->counter); } /** From patchwork Thu May 14 12:30:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Rini X-Patchwork-Id: 245808 List-Id: U-Boot discussion From: trini at konsulko.com (Tom Rini) Date: Thu, 14 May 2020 08:30:05 -0400 Subject: [PATCH 06/10] socfpga: Mark socfpga_fpga_add() as static inline in the non-FPGA case In-Reply-To: <20200514123009.5721-1-trini@konsulko.com> References: <20200514123009.5721-1-trini@konsulko.com> Message-ID: <20200514123009.5721-6-trini@konsulko.com> Unless we mark the function as 'static inline' it may end up being non-inlined by the compiled and result in duplicate functions. Cc: Marek Vasut Cc: Simon Goldschmidt Cc: Ley Foon Tan Signed-off-by: Tom Rini Acked-by: Marek Vasut --- arch/arm/mach-socfpga/include/mach/misc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-socfpga/include/mach/misc.h b/arch/arm/mach-socfpga/include/mach/misc.h index f6de1ccb4a01..a85c5aeef955 100644 --- a/arch/arm/mach-socfpga/include/mach/misc.h +++ b/arch/arm/mach-socfpga/include/mach/misc.h @@ -20,7 +20,7 @@ extern struct bsel bsel_str[]; #ifdef CONFIG_FPGA void socfpga_fpga_add(void *fpga_desc); #else -inline void socfpga_fpga_add(void *fpga_desc) {} +static inline void socfpga_fpga_add(void *fpga_desc) {} #endif #ifdef CONFIG_TARGET_SOCFPGA_GEN5 From patchwork Thu May 14 12:30:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Rini X-Patchwork-Id: 245812 List-Id: U-Boot discussion From: trini at konsulko.com (Tom Rini) Date: Thu, 14 May 2020 08:30:06 -0400 Subject: [PATCH 07/10] compiler*.h: sync include/linux/compiler*.h with Linux 5.7-rc5 In-Reply-To: <20200514123009.5721-1-trini@konsulko.com> References: <20200514123009.5721-1-trini@konsulko.com> Message-ID: <20200514123009.5721-7-trini@konsulko.com> Copy these from Linux v5.7-rc5 tag. This brings in some handy new attributes and is otherwise important to keep in sync. We drop the reference to smp_read_barrier_depends() as it is not relevant on the architectures we support at this time, based on where it's implemented in Linux today. We drop the call to kasan_check_read() as that is not relevant to U-Boot as well. Cc: Masahiro Yamada Signed-off-by: Tom Rini --- Kconfig | 3 + include/linux/compiler-clang.h | 44 ++- include/linux/compiler-gcc.h | 259 ++++---------- include/linux/compiler-intel.h | 17 +- include/linux/compiler.h | 502 +++++++++------------------- include/linux/compiler_attributes.h | 273 +++++++++++++++ include/linux/compiler_types.h | 237 +++++++++++++ lib/vsprintf.c | 2 - 8 files changed, 777 insertions(+), 560 deletions(-) create mode 100644 include/linux/compiler_attributes.h create mode 100644 include/linux/compiler_types.h diff --git a/Kconfig b/Kconfig index 72b4439264a6..37cc9445180f 100644 --- a/Kconfig +++ b/Kconfig @@ -71,6 +71,9 @@ config CC_COVERAGE Enabling this option will pass "--coverage" to gcc to compile and link code instrumented for coverage analysis. +config CC_HAS_ASM_INLINE + def_bool $(success,echo 'void foo(void) { asm inline (""); }' | $(CC) -x c - -c -o /dev/null) + config DISTRO_DEFAULTS bool "Select defaults suitable for booting general purpose Linux distributions" select AUTO_COMPLETE diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h index d1e49d52b640..333a6695a918 100644 --- a/include/linux/compiler-clang.h +++ b/include/linux/compiler-clang.h @@ -1,12 +1,44 @@ -#ifndef __LINUX_COMPILER_H +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LINUX_COMPILER_TYPES_H #error "Please don't include directly, include instead." #endif -/* Some compiler specific definitions are overwritten here - * for Clang compiler - */ +/* Compiler specific definitions for Clang compiler */ -#ifdef uninitialized_var -#undef uninitialized_var #define uninitialized_var(x) x = *(&(x)) + +/* same as gcc, this was present in clang-2.6 so we can assume it works + * with any version that can compile the kernel + */ +#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) + +/* all clang versions usable with the kernel support KASAN ABI version 5 */ +#define KASAN_ABI_VERSION 5 + +#if __has_feature(address_sanitizer) || __has_feature(hwaddress_sanitizer) +/* emulate gcc's __SANITIZE_ADDRESS__ flag */ +#define __SANITIZE_ADDRESS__ +#define __no_sanitize_address \ + __attribute__((no_sanitize("address", "hwaddress"))) +#else +#define __no_sanitize_address #endif + +/* + * Not all versions of clang implement the the type-generic versions + * of the builtin overflow checkers. Fortunately, clang implements + * __has_builtin allowing us to avoid awkward version + * checks. Unfortunately, we don't know which version of gcc clang + * pretends to be, so the macro may or may not be defined. + */ +#if __has_builtin(__builtin_mul_overflow) && \ + __has_builtin(__builtin_add_overflow) && \ + __has_builtin(__builtin_sub_overflow) +#define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1 +#endif + +/* The following are for compatibility with GCC, from compiler-gcc.h, + * and may be redefined here because they should not be shared with other + * compilers, like ICC. + */ +#define barrier() __asm__ __volatile__("" : : : "memory") diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 8d9e0794351c..d7ee4c6bad48 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -1,4 +1,5 @@ -#ifndef __LINUX_COMPILER_H +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LINUX_COMPILER_TYPES_H #error "Please don't include directly, include instead." #endif @@ -9,11 +10,14 @@ + __GNUC_MINOR__ * 100 \ + __GNUC_PATCHLEVEL__) +#if GCC_VERSION < 40600 +# error Sorry, your compiler is too old - please upgrade it. +#endif + /* Optimization barrier */ /* The "volatile" is due to gcc bugs */ -#define barrier() \ - __asm__ __volatile__("": : :"memory") +#define barrier() __asm__ __volatile__("": : :"memory") /* * This version is i.e. to prevent dead stores elimination on @ptr * where gcc and llvm may behave differently when otherwise using @@ -22,13 +26,12 @@ * clobbered. The issue is as follows: while the inline asm might * access any memory it wants, the compiler could have fit all of * @ptr into memory registers instead, and since @ptr never escaped - * from that, it proofed that the inline asm wasn't touching any of + * from that, it proved that the inline asm wasn't touching any of * it. This version works well with both compilers, i.e. we're telling * the compiler that the inline asm absolutely may see the contents * of @ptr. See also: https://llvm.org/bugs/show_bug.cgi?id=15495 */ -#define barrier_data(ptr) \ - __asm__ __volatile__("": :"r"(ptr) :"memory") +#define barrier_data(ptr) __asm__ __volatile__("": :"r"(ptr) :"memory") /* * This macro obfuscates arithmetic on a variable address so that gcc @@ -55,181 +58,54 @@ (typeof(ptr)) (__ptr + (off)); \ }) -/* Make the optimizer believe the variable can be manipulated arbitrarily. */ -#define OPTIMIZER_HIDE_VAR(var) \ - __asm__ ("" : "=r" (var) : "0" (var)) - -#ifdef __CHECKER__ -#define __must_be_array(a) 0 -#else -/* &a[0] degrades to a pointer: a different type from an array */ -#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) -#endif - -/* - * Force always-inline if the user requests it so via the .config, - * or if gcc is too old: - */ -#if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \ - !defined(CONFIG_OPTIMIZE_INLINING) || (__GNUC__ < 4) -#define inline inline __attribute__((always_inline)) notrace -#define __inline__ __inline__ __attribute__((always_inline)) notrace -#define __inline __inline __attribute__((always_inline)) notrace -#else -/* A lot of inline functions can cause havoc with function tracing */ -#define inline inline notrace -#define __inline__ __inline__ notrace -#define __inline __inline notrace -#endif - -#define __always_inline inline __attribute__((always_inline)) -#define noinline __attribute__((noinline)) - -#define __deprecated __attribute__((deprecated)) -#define __packed __attribute__((packed)) -#define __weak __attribute__((weak)) -#define __alias(symbol) __attribute__((alias(#symbol))) - /* - * it doesn't make sense on ARM (currently the only user of __naked) - * to trace naked functions because then mcount is called without - * stack and frame pointer being set up and there is no chance to - * restore the lr register to the value before mcount was called. - * - * The asm() bodies of naked functions often depend on standard calling - * conventions, therefore they must be noinline and noclone. - * - * GCC 4.[56] currently fail to enforce this, so we must do so ourselves. - * See GCC PR44290. - */ -#define __naked __attribute__((naked)) noinline __noclone notrace - -#define __noreturn __attribute__((noreturn)) - -/* - * From the GCC manual: - * - * Many functions have no effects except the return value and their - * return value depends only on the parameters and/or global - * variables. Such a function can be subject to common subexpression - * elimination and loop optimization just as an arithmetic operator - * would be. - * [...] + * A trick to suppress uninitialized variable warning without generating any + * code */ -#define __pure __attribute__((pure)) -#define __aligned(x) __attribute__((aligned(x))) -#define __printf(a, b) __attribute__((format(printf, a, b))) -#define __scanf(a, b) __attribute__((format(scanf, a, b))) -#define __attribute_const__ __attribute__((__const__)) -#define __maybe_unused __attribute__((unused)) -#define __always_unused __attribute__((unused)) - -/* gcc version specific checks */ - -#if GCC_VERSION < 30200 -# error Sorry, your compiler is too old - please upgrade it. -#endif - -#if GCC_VERSION < 30300 -# define __used __attribute__((__unused__)) -#else -# define __used __attribute__((__used__)) -#endif - -#ifdef CONFIG_GCOV_KERNEL -# if GCC_VERSION < 30400 -# error "GCOV profiling support for gcc versions below 3.4 not included" -# endif /* __GNUC_MINOR__ */ -#endif /* CONFIG_GCOV_KERNEL */ +#define uninitialized_var(x) x = x -#if GCC_VERSION >= 30400 -#define __must_check __attribute__((warn_unused_result)) +#ifdef CONFIG_RETPOLINE +#define __noretpoline __attribute__((__indirect_branch__("keep"))) #endif -#if GCC_VERSION >= 40000 +#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) -/* GCC 4.1.[01] miscompiles __weak */ -#ifdef __KERNEL__ -# if GCC_VERSION >= 40100 && GCC_VERSION <= 40101 -# error Your version of gcc miscompiles the __weak directive -# endif -#endif +#define __compiletime_object_size(obj) __builtin_object_size(obj, 0) -#define __used __attribute__((__used__)) -#define __compiler_offsetof(a, b) \ - __builtin_offsetof(a, b) +#define __compiletime_warning(message) __attribute__((__warning__(message))) +#define __compiletime_error(message) __attribute__((__error__(message))) -#if GCC_VERSION >= 40100 && GCC_VERSION < 40600 -# define __compiletime_object_size(obj) __builtin_object_size(obj, 0) +#if defined(LATENT_ENTROPY_PLUGIN) && !defined(__CHECKER__) +#define __latent_entropy __attribute__((latent_entropy)) #endif -#if GCC_VERSION >= 40300 -/* Mark functions as cold. gcc will assume any path leading to a call - * to them will be unlikely. This means a lot of manual unlikely()s - * are unnecessary now for any paths leading to the usual suspects - * like BUG(), printk(), panic() etc. [but let's keep them for now for - * older compilers] - * - * Early snapshots of gcc 4.3 don't support this and we can't detect this - * in the preprocessor, but we can live with this because they're unreleased. - * Maketime probing would be overkill here. +/* + * calling noreturn functions, __builtin_unreachable() and __builtin_trap() + * confuse the stack allocation in gcc, leading to overly large stack + * frames, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82365 * - * gcc also has a __attribute__((__hot__)) to move hot functions into - * a special section, but I don't see any sense in this right now in - * the kernel context + * Adding an empty inline assembly before it works around the problem */ -#define __cold __attribute__((__cold__)) - -#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) +#define barrier_before_unreachable() asm volatile("") -#ifndef __CHECKER__ -# define __compiletime_warning(message) __attribute__((warning(message))) -# define __compiletime_error(message) __attribute__((error(message))) -#endif /* __CHECKER__ */ -#endif /* GCC_VERSION >= 40300 */ - -#if GCC_VERSION >= 40500 /* * Mark a position in code as unreachable. This can be used to * suppress control flow warnings after asm blocks that transfer * control elsewhere. - * - * Early snapshots of gcc 4.5 don't support this and we can't detect - * this in the preprocessor, but we can live with this because they're - * unreleased. Really, we need to have autoconf for the kernel. - */ -#define unreachable() __builtin_unreachable() - -/* Mark a function definition as prohibited from being cloned. */ -#define __noclone __attribute__((__noclone__)) - -#endif /* GCC_VERSION >= 40500 */ - -#if GCC_VERSION >= 40600 -/* - * When used with Link Time Optimization, gcc can optimize away C functions or - * variables which are referenced only from assembly code. __visible tells the - * optimizer that something else uses this function or variable, thus preventing - * this. */ -#define __visible __attribute__((externally_visible)) -#endif - +#define unreachable() \ + do { \ + annotate_unreachable(); \ + barrier_before_unreachable(); \ + __builtin_unreachable(); \ + } while (0) -#if GCC_VERSION >= 40900 && !defined(__CHECKER__) -/* - * __assume_aligned(n, k): Tell the optimizer that the returned - * pointer can be assumed to be k modulo n. The second argument is - * optional (default 0), so we use a variadic macro to make the - * shorthand. - * - * Beware: Do not apply this to functions which may return - * ERR_PTRs. Also, it is probably unwise to apply it to functions - * returning extra information in the low bits (but in that case the - * compiler should see some alignment anyway, when the return value is - * massaged by 'flags = ptr & 3; ptr &= ~3;'). - */ -#define __assume_aligned(a, ...) __attribute__((__assume_aligned__(a, ## __VA_ARGS__))) +#if defined(RANDSTRUCT_PLUGIN) && !defined(__CHECKER__) +#define __randomize_layout __attribute__((randomize_layout)) +#define __no_randomize_layout __attribute__((no_randomize_layout)) +/* This anon struct can add padding, so only enable it under randstruct. */ +#define randomized_struct_fields_start struct { +#define randomized_struct_fields_end } __randomize_layout; #endif /* @@ -243,43 +119,56 @@ */ #define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) -#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP -#if GCC_VERSION >= 40400 +/* + * sparse (__CHECKER__) pretends to be gcc, but can't do constant + * folding in __builtin_bswap*() (yet), so don't set these for it. + */ +#if defined(CONFIG_ARCH_USE_BUILTIN_BSWAP) && !defined(__CHECKER__) #define __HAVE_BUILTIN_BSWAP32__ #define __HAVE_BUILTIN_BSWAP64__ -#endif -#if GCC_VERSION >= 40800 || (defined(__powerpc__) && GCC_VERSION >= 40600) +#if GCC_VERSION >= 40800 #define __HAVE_BUILTIN_BSWAP16__ #endif -#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */ +#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP && !__CHECKER__ */ -#if GCC_VERSION >= 50000 +#if GCC_VERSION >= 70000 +#define KASAN_ABI_VERSION 5 +#elif GCC_VERSION >= 50000 #define KASAN_ABI_VERSION 4 #elif GCC_VERSION >= 40902 #define KASAN_ABI_VERSION 3 #endif -#if GCC_VERSION >= 40902 -/* - * Tell the compiler that address safety instrumentation (KASAN) - * should not be applied to that function. - * Conflicts with inlining: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368 - */ +#if __has_attribute(__no_sanitize_address__) #define __no_sanitize_address __attribute__((no_sanitize_address)) +#else +#define __no_sanitize_address #endif -#endif /* gcc version >= 40000 specific checks */ - -#if !defined(__noclone) -#define __noclone /* not needed */ -#endif - -#if !defined(__no_sanitize_address) -#define __no_sanitize_address +#if GCC_VERSION >= 50100 +#define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1 #endif /* - * A trick to suppress uninitialized variable warning without generating any - * code + * Turn individual warnings and errors on and off locally, depending + * on version. */ -#define uninitialized_var(x) x = x +#define __diag_GCC(version, severity, s) \ + __diag_GCC_ ## version(__diag_GCC_ ## severity s) + +/* Severity used in pragma directives */ +#define __diag_GCC_ignore ignored +#define __diag_GCC_warn warning +#define __diag_GCC_error error + +#define __diag_str1(s) #s +#define __diag_str(s) __diag_str1(s) +#define __diag(s) _Pragma(__diag_str(GCC diagnostic s)) + +#if GCC_VERSION >= 80000 +#define __diag_GCC_8(s) __diag(s) +#else +#define __diag_GCC_8(s) +#endif + +#define __no_fgcse __attribute__((optimize("-fno-gcse"))) diff --git a/include/linux/compiler-intel.h b/include/linux/compiler-intel.h index d4c71132d07f..b17f3cd18334 100644 --- a/include/linux/compiler-intel.h +++ b/include/linux/compiler-intel.h @@ -1,22 +1,17 @@ -#ifndef __LINUX_COMPILER_H +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LINUX_COMPILER_TYPES_H #error "Please don't include directly, include instead." #endif #ifdef __ECC -/* Some compiler specific definitions are overwritten here - * for Intel ECC compiler - */ +/* Compiler specific definitions for Intel ECC compiler */ #include /* Intel ECC compiler doesn't support gcc specific asm stmts. * It uses intrinsics to do the equivalent things. */ -#undef barrier -#undef barrier_data -#undef RELOC_HIDE -#undef OPTIMIZER_HIDE_VAR #define barrier() __memory_barrier() #define barrier_data(ptr) barrier() @@ -32,14 +27,8 @@ */ #define OPTIMIZER_HIDE_VAR(var) barrier() -/* Intel ECC compiler doesn't support __builtin_types_compatible_p() */ -#define __must_be_array(a) 0 - #endif -#ifndef __HAVE_BUILTIN_BSWAP16__ /* icc has this, but it's called _bswap16 */ #define __HAVE_BUILTIN_BSWAP16__ #define __builtin_bswap16 _bswap16 -#endif - diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 0ea6c8fccaab..5e3b3c08e917 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -1,127 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __LINUX_COMPILER_H #define __LINUX_COMPILER_H -#ifndef __ASSEMBLY__ +#include -#ifdef __CHECKER__ -# define __user __attribute__((noderef, address_space(1))) -# define __kernel __attribute__((address_space(0))) -# define __safe __attribute__((safe)) -# define __force __attribute__((force)) -# define __nocast __attribute__((nocast)) -# define __iomem __attribute__((noderef, address_space(2))) -# define __must_hold(x) __attribute__((context(x,1,1))) -# define __acquires(x) __attribute__((context(x,0,1))) -# define __releases(x) __attribute__((context(x,1,0))) -# define __acquire(x) __context__(x,1) -# define __release(x) __context__(x,-1) -# define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0) -# define __percpu __attribute__((noderef, address_space(3))) -# define __pmem __attribute__((noderef, address_space(5))) -#ifdef CONFIG_SPARSE_RCU_POINTER -# define __rcu __attribute__((noderef, address_space(4))) -#else -# define __rcu -#endif -extern void __chk_user_ptr(const volatile void __user *); -extern void __chk_io_ptr(const volatile void __iomem *); -#else -# define __user -# define __kernel -# define __safe -# define __force -# define __nocast -# define __iomem -# define __chk_user_ptr(x) (void)0 -# define __chk_io_ptr(x) (void)0 -# define __builtin_warning(x, y...) (1) -# define __must_hold(x) -# define __acquires(x) -# define __releases(x) -# define __acquire(x) (void)0 -# define __release(x) (void)0 -# define __cond_lock(x,c) (c) -# define __percpu -# define __rcu -# define __pmem -#endif - -/* Indirect macros required for expanded argument pasting, eg. __LINE__. */ -#define ___PASTE(a,b) a##b -#define __PASTE(a,b) ___PASTE(a,b) +#ifndef __ASSEMBLY__ #ifdef __KERNEL__ -#ifdef __GNUC__ -#include -#endif - -#if defined(CC_USING_HOTPATCH) && !defined(__CHECKER__) -#define notrace __attribute__((hotpatch(0,0))) -#else -#define notrace __attribute__((no_instrument_function)) -#endif - -/* Intel compiler defines __GNUC__. So we will overwrite implementations - * coming from above header files here - */ -#ifdef __INTEL_COMPILER -# include -#endif - -/* Clang compiler defines __GNUC__. So we will overwrite implementations - * coming from above header files here - */ -#ifdef __clang__ -#include -#endif - -/* - * Generic compiler-dependent macros required for kernel - * build go below this comment. Actual compiler/compiler version - * specific implementations come from the above header files - */ - -struct ftrace_branch_data { - const char *func; - const char *file; - unsigned line; - union { - struct { - unsigned long correct; - unsigned long incorrect; - }; - struct { - unsigned long miss; - unsigned long hit; - }; - unsigned long miss_hit[2]; - }; -}; - /* * Note: DISABLE_BRANCH_PROFILING can be used by special lowlevel code * to disable branch tracing on a per file basis. */ #if defined(CONFIG_TRACE_BRANCH_PROFILING) \ && !defined(DISABLE_BRANCH_PROFILING) && !defined(__CHECKER__) -void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); +void ftrace_likely_update(struct ftrace_likely_data *f, int val, + int expect, int is_constant); #define likely_notrace(x) __builtin_expect(!!(x), 1) #define unlikely_notrace(x) __builtin_expect(!!(x), 0) -#define __branch_check__(x, expect) ({ \ - int ______r; \ - static struct ftrace_branch_data \ - __attribute__((__aligned__(4))) \ - __attribute__((section("_ftrace_annotated_branch"))) \ +#define __branch_check__(x, expect, is_constant) ({ \ + long ______r; \ + static struct ftrace_likely_data \ + __aligned(4) \ + __section(_ftrace_annotated_branch) \ ______f = { \ - .func = __func__, \ - .file = __FILE__, \ - .line = __LINE__, \ + .data.func = __func__, \ + .data.file = __FILE__, \ + .data.line = __LINE__, \ }; \ - ______r = likely_notrace(x); \ - ftrace_likely_update(&______f, ______r, expect); \ + ______r = __builtin_expect(!!(x), expect); \ + ftrace_likely_update(&______f, ______r, \ + expect, is_constant); \ ______r; \ }) @@ -131,10 +42,10 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); * written by Daniel Walker. */ # ifndef likely -# define likely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1)) +# define likely(x) (__branch_check__(x, 1, __builtin_constant_p(x))) # endif # ifndef unlikely -# define unlikely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0)) +# define unlikely(x) (__branch_check__(x, 0, __builtin_constant_p(x))) # endif #ifdef CONFIG_PROFILE_ALL_BRANCHES @@ -142,23 +53,24 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); * "Define 'is'", Bill Clinton * "Define 'if'", Steven Rostedt */ -#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) ) -#define __trace_if(cond) \ - if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ - ({ \ - int ______r; \ - static struct ftrace_branch_data \ - __attribute__((__aligned__(4))) \ - __attribute__((section("_ftrace_branch"))) \ - ______f = { \ - .func = __func__, \ - .file = __FILE__, \ - .line = __LINE__, \ - }; \ - ______r = !!(cond); \ - ______f.miss_hit[______r]++; \ - ______r; \ - })) +#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) ) + +#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond)) + +#define __trace_if_value(cond) ({ \ + static struct ftrace_branch_data \ + __aligned(4) \ + __section(_ftrace_branch) \ + __if_trace = { \ + .func = __func__, \ + .file = __FILE__, \ + .line = __LINE__, \ + }; \ + (cond) ? \ + (__if_trace.miss_hit[1]++,1) : \ + (__if_trace.miss_hit[0]++,0); \ +}) + #endif /* CONFIG_PROFILE_ALL_BRANCHES */ #else @@ -175,9 +87,76 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); # define barrier_data(ptr) barrier() #endif +/* workaround for GCC PR82365 if needed */ +#ifndef barrier_before_unreachable +# define barrier_before_unreachable() do { } while (0) +#endif + /* Unreachable code */ +#ifdef CONFIG_STACK_VALIDATION +/* + * These macros help objtool understand GCC code flow for unreachable code. + * The __COUNTER__ based labels are a hack to make each instance of the macros + * unique, to convince GCC not to merge duplicate inline asm statements. + */ +#define annotate_reachable() ({ \ + asm volatile("%c0:\n\t" \ + ".pushsection .discard.reachable\n\t" \ + ".long %c0b - .\n\t" \ + ".popsection\n\t" : : "i" (__COUNTER__)); \ +}) +#define annotate_unreachable() ({ \ + asm volatile("%c0:\n\t" \ + ".pushsection .discard.unreachable\n\t" \ + ".long %c0b - .\n\t" \ + ".popsection\n\t" : : "i" (__COUNTER__)); \ +}) +#define ASM_UNREACHABLE \ + "999:\n\t" \ + ".pushsection .discard.unreachable\n\t" \ + ".long 999b - .\n\t" \ + ".popsection\n\t" + +/* Annotate a C jump table to allow objtool to follow the code flow */ +#define __annotate_jump_table __section(.rodata..c_jump_table) + +#else +#define annotate_reachable() +#define annotate_unreachable() +#define __annotate_jump_table +#endif + +#ifndef ASM_UNREACHABLE +# define ASM_UNREACHABLE +#endif #ifndef unreachable -# define unreachable() do { } while (1) +# define unreachable() do { \ + annotate_unreachable(); \ + __builtin_unreachable(); \ +} while (0) +#endif + +/* + * KENTRY - kernel entry point + * This can be used to annotate symbols (functions or data) that are used + * without their linker symbol being referenced explicitly. For example, + * interrupt vector handlers, or functions in the kernel image that are found + * programatically. + * + * Not required for symbols exported with EXPORT_SYMBOL, or initcalls. Those + * are handled in their own way (with KEEP() in linker scripts). + * + * KENTRY can be avoided if the symbols in question are marked as KEEP() in the + * linker script. For example an architecture could KEEP() its entire + * boot/exception vector code rather than annotate each function and data. + */ +#ifndef KENTRY +# define KENTRY(sym) \ + extern typeof(sym) sym; \ + static const unsigned long __kentry_##sym \ + __used \ + __section("___kentry" "+" #sym ) \ + = (unsigned long)&sym; #endif #ifndef RELOC_HIDE @@ -188,7 +167,9 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); #endif #ifndef OPTIMIZER_HIDE_VAR -#define OPTIMIZER_HIDE_VAR(var) barrier() +/* Make the optimizer believe the variable can be manipulated arbitrarily. */ +#define OPTIMIZER_HIDE_VAR(var) \ + __asm__ ("" : "=r" (var) : "0" (var)) #endif /* Not-quite-unique ID. */ @@ -220,23 +201,21 @@ void __read_once_size(const volatile void *p, void *res, int size) #ifdef CONFIG_KASAN /* - * This function is not 'inline' because __no_sanitize_address confilcts + * We can't declare function 'inline' because __no_sanitize_address confilcts * with inlining. Attempt to inline it may cause a build failure. * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368 * '__maybe_unused' allows us to avoid defined-but-not-used warnings. */ -static __no_sanitize_address __maybe_unused -void __read_once_size_nocheck(const volatile void *p, void *res, int size) -{ - __READ_ONCE_SIZE; -} +# define __no_kasan_or_inline __no_sanitize_address notrace __maybe_unused #else -static __always_inline +# define __no_kasan_or_inline __always_inline +#endif + +static __no_kasan_or_inline void __read_once_size_nocheck(const volatile void *p, void *res, int size) { __READ_ONCE_SIZE; } -#endif static __always_inline void __write_once_size(volatile void *p, void *res, int size) { @@ -255,20 +234,21 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s /* * Prevent the compiler from merging or refetching reads or writes. The * compiler is also forbidden from reordering successive instances of - * READ_ONCE, WRITE_ONCE and ACCESS_ONCE (see below), but only when the - * compiler is aware of some particular ordering. One way to make the - * compiler aware of ordering is to put the two invocations of READ_ONCE, - * WRITE_ONCE or ACCESS_ONCE() in different C statements. + * READ_ONCE and WRITE_ONCE, but only when the compiler is aware of some + * particular ordering. One way to make the compiler aware of ordering is to + * put the two invocations of READ_ONCE or WRITE_ONCE in different C + * statements. * - * In contrast to ACCESS_ONCE these two macros will also work on aggregate - * data types like structs or unions. If the size of the accessed data - * type exceeds the word size of the machine (e.g., 32 bits or 64 bits) - * READ_ONCE() and WRITE_ONCE() will fall back to memcpy and print a - * compile-time warning. + * These two macros will also work on aggregate data types like structs or + * unions. If the size of the accessed data type exceeds the word size of + * the machine (e.g., 32 bits or 64 bits) READ_ONCE() and WRITE_ONCE() will + * fall back to memcpy(). There's at least two memcpy()s: one for the + * __builtin_memcpy() and then one for the macro doing the copy of variable + * - '__u' allocated on the stack. * * Their two major use cases are: (1) Mediating communication between * process-level code and irq/NMI handlers, all running on the same CPU, - * and (2) Ensuring that the compiler does not fold, spindle, or otherwise + * and (2) Ensuring that the compiler does not fold, spindle, or otherwise * mutilate accesses that either do not require ordering or that interact * with an explicit memory barrier or atomic instruction that provides the * required ordering. @@ -291,6 +271,12 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s */ #define READ_ONCE_NOCHECK(x) __READ_ONCE(x, 0) +static __no_kasan_or_inline +unsigned long read_word_at_a_time(const void *addr) +{ + return *(unsigned long *)addr; +} + #define WRITE_ONCE(x, val) \ ({ \ union { typeof(x) __val; char __c[1]; } __u = \ @@ -299,158 +285,28 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s __u.__val; \ }) -/** - * smp_cond_acquire() - Spin wait for cond with ACQUIRE ordering - * @cond: boolean expression to wait for - * - * Equivalent to using smp_load_acquire() on the condition variable but employs - * the control dependency of the wait to reduce the barrier on many platforms. - * - * The control dependency provides a LOAD->STORE order, the additional RMB - * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} order, - * aka. ACQUIRE. - */ -#define smp_cond_acquire(cond) do { \ - while (!(cond)) \ - cpu_relax(); \ - smp_rmb(); /* ctrl + rmb := acquire */ \ -} while (0) - -#endif /* __KERNEL__ */ - -#endif /* __ASSEMBLY__ */ - -#ifdef __KERNEL__ -/* - * Allow us to mark functions as 'deprecated' and have gcc emit a nice - * warning for each use, in hopes of speeding the functions removal. - * Usage is: - * int __deprecated foo(void) - */ -#ifndef __deprecated -# define __deprecated /* unimplemented */ -#endif - -#ifdef MODULE -#define __deprecated_for_modules __deprecated -#else -#define __deprecated_for_modules -#endif - -#ifndef __must_check -#define __must_check -#endif - -#ifndef CONFIG_ENABLE_MUST_CHECK -#undef __must_check -#define __must_check -#endif -#ifndef CONFIG_ENABLE_WARN_DEPRECATED -#undef __deprecated -#undef __deprecated_for_modules -#define __deprecated -#define __deprecated_for_modules -#endif - -/* - * Allow us to avoid 'defined but not used' warnings on functions and data, - * as well as force them to be emitted to the assembly file. - * - * As of gcc 3.4, static functions that are not marked with attribute((used)) - * may be elided from the assembly file. As of gcc 3.4, static data not so - * marked will not be elided, but this may change in a future gcc version. - * - * NOTE: Because distributions shipped with a backported unit-at-a-time - * compiler in gcc 3.3, we must define __used to be __attribute__((used)) - * for gcc >=3.3 instead of 3.4. - * - * In prior versions of gcc, such functions and data would be emitted, but - * would be warned about except with attribute((unused)). - * - * Mark functions that are referenced only in inline assembly as __used so - * the code is emitted even though it appears to be unreferenced. - */ -#ifndef __used -# define __used /* unimplemented */ -#endif - -#ifndef __maybe_unused -# define __maybe_unused /* unimplemented */ -#endif - -#ifndef __always_unused -# define __always_unused /* unimplemented */ -#endif - -#ifndef noinline -#define noinline -#endif - -/* - * Rather then using noinline to prevent stack consumption, use - * noinline_for_stack instead. For documentation reasons. - */ -#define noinline_for_stack noinline - -#ifndef __always_inline -#define __always_inline inline -#endif - #endif /* __KERNEL__ */ /* - * From the GCC manual: - * - * Many functions do not examine any values except their arguments, - * and have no effects except the return value. Basically this is - * just slightly more strict class than the `pure' attribute above, - * since function is not allowed to read global memory. - * - * Note that a function that has pointer arguments and examines the - * data pointed to must _not_ be declared `const'. Likewise, a - * function that calls a non-`const' function usually must not be - * `const'. It does not make sense for a `const' function to return - * `void'. - */ -#ifndef __attribute_const__ -# define __attribute_const__ /* unimplemented */ -#endif - -/* - * Tell gcc if a function is cold. The compiler will assume any path - * directly leading to the call is unlikely. + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visible to the compiler. */ +#define __ADDRESSABLE(sym) \ + static void * __section(.discard.addressable) __used \ + __PASTE(__addressable_##sym, __LINE__) = (void *)&sym; -#ifndef __cold -#define __cold -#endif - -/* Simple shorthand for a section definition */ -#ifndef __section -# define __section(S) __attribute__ ((__section__(#S))) -#endif - -#ifndef __visible -#define __visible -#endif - -/* - * Assume alignment of return value. +/** + * offset_to_ptr - convert a relative memory offset to an absolute pointer + * @off: the address of the 32-bit offset value */ -#ifndef __assume_aligned -#define __assume_aligned(a, ...) -#endif - - -/* Are two types/vars the same type (ignoring qualifiers)? */ -#ifndef __same_type -# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) -#endif +static inline void *offset_to_ptr(const int *off) +{ + return (void *)((unsigned long)off + *off); +} -/* Is this type a native word size -- useful for atomic operations */ -#ifndef __native_word -# define __native_word(t) (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long)) -#endif +#endif /* __ASSEMBLY__ */ /* Compile time object size, -1 for unknown */ #ifndef __compiletime_object_size @@ -461,29 +317,14 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s #endif #ifndef __compiletime_error # define __compiletime_error(message) -/* - * Sparse complains of variable sized arrays due to the temporary variable in - * __compiletime_assert. Unfortunately we can't just expand it out to make - * sparse see a constant array size without breaking compiletime_assert on old - * versions of GCC (e.g. 4.2.4), so hide the array from sparse altogether. - */ -# ifndef __CHECKER__ -# define __compiletime_error_fallback(condition) \ - do { ((void)sizeof(char[1 - 2 * condition])); } while (0) -# endif -#endif -#ifndef __compiletime_error_fallback -# define __compiletime_error_fallback(condition) do { } while (0) #endif #ifdef __OPTIMIZE__ # define __compiletime_assert(condition, msg, prefix, suffix) \ do { \ - bool __cond = !(condition); \ extern void prefix ## suffix(void) __compiletime_error(msg); \ - if (__cond) \ + if (!(condition)) \ prefix ## suffix(); \ - __compiletime_error_fallback(__cond); \ } while (0) #else # define __compiletime_assert(condition, msg, prefix, suffix) do { } while (0) @@ -502,58 +343,13 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s * compiler has support to do so. */ #define compiletime_assert(condition, msg) \ - _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) + _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) #define compiletime_assert_atomic_type(t) \ compiletime_assert(__native_word(t), \ "Need native word sized stores/loads for atomicity.") -/* - * Prevent the compiler from merging or refetching accesses. The compiler - * is also forbidden from reordering successive instances of ACCESS_ONCE(), - * but only when the compiler is aware of some particular ordering. One way - * to make the compiler aware of ordering is to put the two invocations of - * ACCESS_ONCE() in different C statements. - * - * ACCESS_ONCE will only work on scalar types. For union types, ACCESS_ONCE - * on a union member will work as long as the size of the member matches the - * size of the union and the size is smaller than word size. - * - * The major use cases of ACCESS_ONCE used to be (1) Mediating communication - * between process-level code and irq/NMI handlers, all running on the same CPU, - * and (2) Ensuring that the compiler does not fold, spindle, or otherwise - * mutilate accesses that either do not require ordering or that interact - * with an explicit memory barrier or atomic instruction that provides the - * required ordering. - * - * If possible use READ_ONCE()/WRITE_ONCE() instead. - */ -#define __ACCESS_ONCE(x) ({ \ - __maybe_unused typeof(x) __var = (__force typeof(x)) 0; \ - (volatile typeof(x) *)&(x); }) -#define ACCESS_ONCE(x) (*__ACCESS_ONCE(x)) - -/** - * lockless_dereference() - safely load a pointer for later dereference - * @p: The pointer to load - * - * Similar to rcu_dereference(), but for situations where the pointed-to - * object's lifetime is managed by something other than RCU. That - * "something other" might be reference counting or simple immortality. - */ -#define lockless_dereference(p) \ -({ \ - typeof(p) _________p1 = READ_ONCE(p); \ - smp_read_barrier_depends(); /* Dependency order vs. p above. */ \ - (_________p1); \ -}) +/* &a[0] degrades to a pointer: a different type from an array */ +#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) -/* Ignore/forbid kprobes attach on very low level functions marked by this attribute: */ -#ifdef CONFIG_KPROBES -# define __kprobes __attribute__((__section__(".kprobes.text"))) -# define nokprobe_inline __always_inline -#else -# define __kprobes -# define nokprobe_inline inline -#endif #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h new file mode 100644 index 000000000000..cdf016596659 --- /dev/null +++ b/include/linux/compiler_attributes.h @@ -0,0 +1,273 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LINUX_COMPILER_ATTRIBUTES_H +#define __LINUX_COMPILER_ATTRIBUTES_H + +/* + * The attributes in this file are unconditionally defined and they directly + * map to compiler attribute(s), unless one of the compilers does not support + * the attribute. In that case, __has_attribute is used to check for support + * and the reason is stated in its comment ("Optional: ..."). + * + * Any other "attributes" (i.e. those that depend on a configuration option, + * on a compiler, on an architecture, on plugins, on other attributes...) + * should be defined elsewhere (e.g. compiler_types.h or compiler-*.h). + * The intention is to keep this file as simple as possible, as well as + * compiler- and version-agnostic (e.g. avoiding GCC_VERSION checks). + * + * This file is meant to be sorted (by actual attribute name, + * not by #define identifier). Use the __attribute__((__name__)) syntax + * (i.e. with underscores) to avoid future collisions with other macros. + * Provide links to the documentation of each supported compiler, if it exists. + */ + +/* + * __has_attribute is supported on gcc >= 5, clang >= 2.9 and icc >= 17. + * In the meantime, to support 4.6 <= gcc < 5, we implement __has_attribute + * by hand. + * + * sparse does not support __has_attribute (yet) and defines __GNUC_MINOR__ + * depending on the compiler used to build it; however, these attributes have + * no semantic effects for sparse, so it does not matter. Also note that, + * in order to avoid sparse's warnings, even the unsupported ones must be + * defined to 0. + */ +#ifndef __has_attribute +# define __has_attribute(x) __GCC4_has_attribute_##x +# define __GCC4_has_attribute___assume_aligned__ (__GNUC_MINOR__ >= 9) +# define __GCC4_has_attribute___copy__ 0 +# define __GCC4_has_attribute___designated_init__ 0 +# define __GCC4_has_attribute___externally_visible__ 1 +# define __GCC4_has_attribute___noclone__ 1 +# define __GCC4_has_attribute___nonstring__ 0 +# define __GCC4_has_attribute___no_sanitize_address__ (__GNUC_MINOR__ >= 8) +# define __GCC4_has_attribute___fallthrough__ 0 +#endif + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alias-function-attribute + */ +#define __alias(symbol) __attribute__((__alias__(#symbol))) + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-aligned-function-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-aligned-type-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-aligned-variable-attribute + */ +#define __aligned(x) __attribute__((__aligned__(x))) +#define __aligned_largest __attribute__((__aligned__)) + +/* + * Note: users of __always_inline currently do not write "inline" themselves, + * which seems to be required by gcc to apply the attribute according + * to its docs (and also "warning: always_inline function might not be + * inlinable [-Wattributes]" is emitted). + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-always_005finline-function-attribute + * clang: mentioned + */ +#define __always_inline inline __attribute__((__always_inline__)) + +/* + * The second argument is optional (default 0), so we use a variadic macro + * to make the shorthand. + * + * Beware: Do not apply this to functions which may return + * ERR_PTRs. Also, it is probably unwise to apply it to functions + * returning extra information in the low bits (but in that case the + * compiler should see some alignment anyway, when the return value is + * massaged by 'flags = ptr & 3; ptr &= ~3;'). + * + * Optional: only supported since gcc >= 4.9 + * Optional: not supported by icc + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-assume_005faligned-function-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#assume-aligned + */ +#if __has_attribute(__assume_aligned__) +# define __assume_aligned(a, ...) __attribute__((__assume_aligned__(a, ## __VA_ARGS__))) +#else +# define __assume_aligned(a, ...) +#endif + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-cold-function-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html#index-cold-label-attribute + */ +#define __cold __attribute__((__cold__)) + +/* + * Note the long name. + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute + */ +#define __attribute_const__ __attribute__((__const__)) + +/* + * Optional: only supported since gcc >= 9 + * Optional: not supported by clang + * Optional: not supported by icc + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-copy-function-attribute + */ +#if __has_attribute(__copy__) +# define __copy(symbol) __attribute__((__copy__(symbol))) +#else +# define __copy(symbol) +#endif + +/* + * Don't. Just don't. See commit 771c035372a0 ("deprecate the '__deprecated' + * attribute warnings entirely and for good") for more information. + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-deprecated-function-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-deprecated-type-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-deprecated-variable-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Enumerator-Attributes.html#index-deprecated-enumerator-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#deprecated + */ +#define __deprecated + +/* + * Optional: only supported since gcc >= 5.1 + * Optional: not supported by clang + * Optional: not supported by icc + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-designated_005finit-type-attribute + */ +#if __has_attribute(__designated_init__) +# define __designated_init __attribute__((__designated_init__)) +#else +# define __designated_init +#endif + +/* + * Optional: not supported by clang + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-externally_005fvisible-function-attribute + */ +#if __has_attribute(__externally_visible__) +# define __visible __attribute__((__externally_visible__)) +#else +# define __visible +#endif + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-format-function-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#format + */ +#define __printf(a, b) __attribute__((__format__(printf, a, b))) +#define __scanf(a, b) __attribute__((__format__(scanf, a, b))) + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-gnu_005finline-function-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#gnu-inline + */ +#define __gnu_inline __attribute__((__gnu_inline__)) + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute + */ +#define __malloc __attribute__((__malloc__)) + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-mode-type-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-mode-variable-attribute + */ +#define __mode(x) __attribute__((__mode__(x))) + +/* + * Optional: not supported by clang + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noclone-function-attribute + */ +#if __has_attribute(__noclone__) +# define __noclone __attribute__((__noclone__)) +#else +# define __noclone +#endif + +/* + * Add the pseudo keyword 'fallthrough' so case statement blocks + * must end with any of these keywords: + * break; + * fallthrough; + * goto