mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
ldgen: determinism in mapping rule order
This MR imposes some determinism in the mapping rule order in the output file. For each section, the archives are arranged alphabetically (ascending), and the mapping rules in each archive are arranged by increasing specificity then alphabetically (ascending). The default rules remain the very first rule for each section.
This commit is contained in:
parent
44d1c90d25
commit
ccbca45709
@ -322,8 +322,6 @@ class GenerationModel:
|
|||||||
return scheme_dictionary
|
return scheme_dictionary
|
||||||
|
|
||||||
def generate_rules(self, sdkconfig, sections_infos):
|
def generate_rules(self, sdkconfig, sections_infos):
|
||||||
placement_rules = collections.defaultdict(list)
|
|
||||||
|
|
||||||
scheme_dictionary = self._build_scheme_dictionary()
|
scheme_dictionary = self._build_scheme_dictionary()
|
||||||
|
|
||||||
# Generate default rules
|
# Generate default rules
|
||||||
@ -373,14 +371,19 @@ class GenerationModel:
|
|||||||
for mapping_rules in all_mapping_rules.values():
|
for mapping_rules in all_mapping_rules.values():
|
||||||
self._create_exclusions(mapping_rules, default_rules, sections_infos)
|
self._create_exclusions(mapping_rules, default_rules, sections_infos)
|
||||||
|
|
||||||
|
placement_rules = collections.defaultdict(list)
|
||||||
|
|
||||||
# Add the default rules grouped by target
|
# Add the default rules grouped by target
|
||||||
for default_rule in default_rules:
|
for default_rule in default_rules:
|
||||||
existing_rules = placement_rules[default_rule.target]
|
existing_rules = placement_rules[default_rule.target]
|
||||||
if default_rule.get_section_names():
|
if default_rule.get_section_names():
|
||||||
existing_rules.append(default_rule)
|
existing_rules.append(default_rule)
|
||||||
|
|
||||||
for mapping_rules in all_mapping_rules.values():
|
archives = sorted(all_mapping_rules.keys(), key=lambda a: a.replace("_a", ".a"))
|
||||||
|
|
||||||
|
for archive in archives:
|
||||||
# Add the mapping rules grouped by target
|
# Add the mapping rules grouped by target
|
||||||
|
mapping_rules = sorted(all_mapping_rules[archive], key=lambda m: (m.specificity, str(m)))
|
||||||
for mapping_rule in mapping_rules:
|
for mapping_rule in mapping_rules:
|
||||||
existing_rules = placement_rules[mapping_rule.target]
|
existing_rules = placement_rules[mapping_rule.target]
|
||||||
if mapping_rule.get_section_names():
|
if mapping_rule.get_section_names():
|
||||||
|
@ -1176,6 +1176,65 @@ class GenerationModelTest(unittest.TestCase):
|
|||||||
|
|
||||||
self._compare_rules(expected, actual)
|
self._compare_rules(expected, actual)
|
||||||
|
|
||||||
|
def test_rules_order(self):
|
||||||
|
# The fragments are structured such that ldgen will:
|
||||||
|
# - parse freertos2 mapping first
|
||||||
|
# - entry for prvCheckPendingReadyList is parsed first before prvCheckDelayedList
|
||||||
|
# We expect that despite this, ldgen will output rules in a set order:
|
||||||
|
# by increasing specificity and alphabetically
|
||||||
|
rules_order_mapping_1 = """
|
||||||
|
[mapping]
|
||||||
|
archive: libfreertos2.a
|
||||||
|
entries:
|
||||||
|
croutine2 (noflash_text)
|
||||||
|
croutine (noflash_text)
|
||||||
|
"""
|
||||||
|
|
||||||
|
rules_order_mapping_2 = """
|
||||||
|
[mapping]
|
||||||
|
archive: libfreertos.a
|
||||||
|
entries:
|
||||||
|
croutine:prvCheckPendingReadyList (noflash_text)
|
||||||
|
croutine:prvCheckDelayedList (noflash_text)
|
||||||
|
"""
|
||||||
|
|
||||||
|
self._add_mapping(rules_order_mapping_2)
|
||||||
|
self._add_mapping(rules_order_mapping_1)
|
||||||
|
|
||||||
|
actual = self.model.generate_rules(self.sdkconfig, self.sections_info)
|
||||||
|
|
||||||
|
expected = self._generate_default_rules()
|
||||||
|
|
||||||
|
flash_text_default = self._get_default("flash_text", expected)
|
||||||
|
|
||||||
|
iram0_text_E1 = PlacementRule("libfreertos2.a", "croutine2", None, self.model.sections["text"].entries, "iram0_text")
|
||||||
|
iram0_text_E2 = PlacementRule("libfreertos2.a", "croutine", None, self.model.sections["text"].entries, "iram0_text")
|
||||||
|
iram0_text_E3 = PlacementRule("libfreertos.a", "croutine", "prvCheckPendingReadyList", self.model.sections["text"].entries, "iram0_text")
|
||||||
|
iram0_text_E4 = PlacementRule("libfreertos.a", "croutine", "prvCheckDelayedList", self.model.sections["text"].entries, "iram0_text")
|
||||||
|
|
||||||
|
flash_text_extra = PlacementRule("libfreertos.a", "croutine", None, [".text.*", ".literal.*"], "flash_text")
|
||||||
|
|
||||||
|
# Add the exclusions
|
||||||
|
flash_text_default.add_exclusion(iram0_text_E1, self.sections_info)
|
||||||
|
flash_text_default.add_exclusion(iram0_text_E2, self.sections_info)
|
||||||
|
|
||||||
|
flash_text_default.add_exclusion(flash_text_extra, self.sections_info)
|
||||||
|
flash_text_extra.add_exclusion(iram0_text_E3, self.sections_info)
|
||||||
|
flash_text_extra.add_exclusion(iram0_text_E4, self.sections_info)
|
||||||
|
|
||||||
|
# Add the rules, arranged by expected order
|
||||||
|
expected["flash_text"].append(flash_text_extra)
|
||||||
|
expected["iram0_text"].append(iram0_text_E4)
|
||||||
|
expected["iram0_text"].append(iram0_text_E3)
|
||||||
|
expected["iram0_text"].append(iram0_text_E2)
|
||||||
|
expected["iram0_text"].append(iram0_text_E1)
|
||||||
|
|
||||||
|
# Perform general comparison for all sections
|
||||||
|
self._compare_rules(expected, actual)
|
||||||
|
|
||||||
|
# Perform ordered comparison
|
||||||
|
self.assertListEqual(actual["flash_text"], expected["flash_text"])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
Reference in New Issue
Block a user