Pārlūkot izejas kodu

ldgen: allow checking mappings

Renz Bagaporo 5 gadi atpakaļ
vecāks
revīzija
8c6ec0bd48
2 mainītis faili ar 63 papildinājumiem un 17 dzēšanām
  1. 44 16
      tools/ldgen/generation.py
  2. 19 1
      tools/ldgen/ldgen.py

+ 44 - 16
tools/ldgen/generation.py

@@ -80,7 +80,6 @@ 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 = fnmatch.filter(sections_in_obj, section)
                 return expansions
 
@@ -254,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)
@@ -338,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 +637,31 @@ class SectionsInfo(dict):
         return results
 
     def get_obj_sections(self, archive, obj):
-        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
-
-        for obj_key in stored.keys():
-            if obj_key == obj + ".o" or obj_key == obj + ".c.obj":
-                return stored[obj_key]
+        res = []
+        try:
+            stored = self.sections[archive]
+
+            # 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
+
+            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

+ 19 - 1
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