Merge branch 'feature/ldgen_output_determinism_v4.1' into 'release/v4.1'
ldgen: determinism in mapping rule order (v4.1) See merge request espressif/esp-idf!8661
This commit is contained in:
commit
8860c1b94c
2 changed files with 62 additions and 3 deletions
|
@ -322,8 +322,6 @@ class GenerationModel:
|
|||
return scheme_dictionary
|
||||
|
||||
def generate_rules(self, sections_infos):
|
||||
placement_rules = collections.defaultdict(list)
|
||||
|
||||
scheme_dictionary = self._build_scheme_dictionary()
|
||||
|
||||
# Generate default rules
|
||||
|
@ -353,14 +351,19 @@ class GenerationModel:
|
|||
for mapping_rules in all_mapping_rules.values():
|
||||
self._create_exclusions(mapping_rules, default_rules, sections_infos)
|
||||
|
||||
placement_rules = collections.defaultdict(list)
|
||||
|
||||
# Add the default rules grouped by target
|
||||
for default_rule in default_rules:
|
||||
existing_rules = placement_rules[default_rule.target]
|
||||
if default_rule.get_section_names():
|
||||
existing_rules.append(default_rule)
|
||||
|
||||
for mapping_rules in all_mapping_rules.values():
|
||||
archives = sorted(all_mapping_rules.keys())
|
||||
|
||||
for archive in archives:
|
||||
# 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:
|
||||
existing_rules = placement_rules[mapping_rule.target]
|
||||
if mapping_rule.get_section_names():
|
||||
|
|
|
@ -1366,6 +1366,62 @@ entries:
|
|||
|
||||
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
|
||||
test = u"""
|
||||
[mapping:freertos2]
|
||||
archive: libfreertos2.a
|
||||
entries:
|
||||
croutine2 (noflash_text)
|
||||
croutine (noflash_text)
|
||||
|
||||
[mapping:freertos]
|
||||
archive: libfreertos.a
|
||||
entries:
|
||||
croutine:prvCheckPendingReadyList (noflash_text)
|
||||
croutine:prvCheckDelayedList (noflash_text)
|
||||
"""
|
||||
self.add_fragments(test)
|
||||
|
||||
actual = self.model.generate_rules(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"])
|
||||
self.assertListEqual(actual["iram0_text"], expected["iram0_text"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
Loading…
Reference in a new issue