diff --git a/tools/ldgen/generation.py b/tools/ldgen/generation.py index addb6bdf33..3d5f63ca05 100644 --- a/tools/ldgen/generation.py +++ b/tools/ldgen/generation.py @@ -80,7 +80,7 @@ class PlacementRule(): def do_section_expansion(rule, section): if section in rule.get_section_names(): sections_in_obj = sections_infos.get_obj_sections(rule.archive, rule.obj) - expansions = [n for n in sections_in_obj or [] if fnmatch.fnmatch(n, section)] + expansions = fnmatch.filter(sections_in_obj, section) return expansions def remove_section_expansions(rule, section, expansions): @@ -253,11 +253,18 @@ class GenerationModel: DEFAULT_SCHEME = "default" - def __init__(self): + def __init__(self, check_mappings=False, check_mapping_exceptions=None): self.schemes = {} self.sections = {} self.mappings = {} + self.check_mappings = check_mappings + + if check_mapping_exceptions: + self.check_mapping_exceptions = check_mapping_exceptions + else: + self.check_mapping_exceptions = [] + def _add_mapping_rules(self, archive, obj, symbol, scheme_name, scheme_dict, rules): # Use an ordinary dictionary to raise exception on non-existing keys temp_dict = dict(scheme_dict) @@ -337,6 +344,14 @@ class GenerationModel: try: if not (obj == Mapping.MAPPING_ALL_OBJECTS and symbol is None and scheme_name == GenerationModel.DEFAULT_SCHEME): + + if self.check_mappings and mapping.name not in self.check_mapping_exceptions: + if not obj == Mapping.MAPPING_ALL_OBJECTS: + obj_section = sections_infos.get_obj_sections(archive, obj) + if not obj_section: + message = "'%s\:%s' not found" % (archive, obj) + raise GenerationException(message, mapping) + self._add_mapping_rules(archive, obj, symbol, scheme_name, scheme_dictionary, mapping_rules) except KeyError: message = GenerationException.UNDEFINED_REFERENCE + " to scheme '" + scheme_name + "'." @@ -623,17 +638,31 @@ class SectionsInfo(dict): return results def get_obj_sections(self, archive, obj): - stored = self.sections[archive] + res = [] + try: + stored = self.sections[archive] - # Parse the contents of the sections file - if not isinstance(stored, dict): - parsed = self._get_infos_from_file(stored) - stored = dict() - for content in parsed.contents: - sections = list(map(lambda s: s, content.sections)) - stored[content.object] = sections - self.sections[archive] = stored + # Parse the contents of the sections file on-demand, + # save the result for later + if not isinstance(stored, dict): + parsed = self._get_infos_from_file(stored) + stored = dict() + for content in parsed.contents: + sections = list(map(lambda s: s, content.sections)) + stored[content.object] = sections + self.sections[archive] = stored - for obj_key in stored.keys(): - if obj_key == obj + ".o" or obj_key == obj + ".c.obj": - return stored[obj_key] + try: + res = stored[obj + ".o"] + except KeyError: + try: + res = stored[obj + ".c.obj"] + except KeyError: + try: + res = stored[obj + ".cpp.obj"] + except KeyError: + res = stored[obj + ".S.obj"] + except KeyError: + pass + + return res diff --git a/tools/ldgen/ldgen.py b/tools/ldgen/ldgen.py index 0d2e2a1354..139a97d3ce 100755 --- a/tools/ldgen/ldgen.py +++ b/tools/ldgen/ldgen.py @@ -83,6 +83,18 @@ def main(): "--kconfig", "-k", help="IDF Kconfig file") + argparser.add_argument( + "--check-mapping", + help="Perform a check if a mapping (archive, obj, symbol) exists", + action='store_true' + ) + + argparser.add_argument( + "--check-mapping-exceptions", + help="Mappings exempted from check", + type=argparse.FileType("r") + ) + argparser.add_argument( "--env", "-e", action='append', default=[], @@ -106,6 +118,12 @@ def main(): kconfig_file = args.kconfig objdump = args.objdump + check_mapping = args.check_mapping + if args.check_mapping_exceptions: + check_mapping_exceptions = [line.strip() for line in args.check_mapping_exceptions] + else: + check_mapping_exceptions = None + try: sections_infos = SectionsInfo() for library in libraries_file: @@ -115,7 +133,7 @@ def main(): dump.name = library sections_infos.add_sections_info(dump) - generation_model = GenerationModel() + generation_model = GenerationModel(check_mapping, check_mapping_exceptions) _update_environment(args) # assign args.env and args.env_file to os.environ