Эх сурвалжийг харах

ldgen: fix sections info parsing

Fixes an issure where the first part of an object file name is not
included, due to matching the rule for a section entry previously.

Reduce depedency on matching literal strings in sections which might
change depending on toolchain (ex. matching 'elf32-xtensa-le')

Make sure parsing rule succeeds for the entirety of the sections info
string by adding 'parseAll=True'.

Add test for sections info parsing.
Renz Bagaporo 5 жил өмнө
parent
commit
711048bce0

+ 14 - 14
tools/ldgen/generation.py

@@ -21,7 +21,7 @@ import fnmatch
 
 from fragments import Sections, Scheme, Mapping, Fragment
 from pyparsing import Suppress, White, ParseException, Literal, Group, ZeroOrMore
-from pyparsing import Word, OneOrMore, nums, alphanums, alphas, Optional, restOfLine
+from pyparsing import Word, OneOrMore, nums, alphas, restOfLine, SkipTo
 from ldgen_common import LdGenFailure
 
 
@@ -608,7 +608,7 @@ class SectionsInfo(dict):
         results = None
 
         try:
-            results = parser.parseString(first_line)
+            results = parser.parseString(first_line, parseAll=True)
         except ParseException as p:
             raise ParseException("Parsing sections info for library " + sections_info_dump.name + " failed. " + p.message)
 
@@ -616,26 +616,26 @@ class SectionsInfo(dict):
         self.sections[archive] = SectionsInfo.__info(sections_info_dump.name, sections_info_dump.read())
 
     def _get_infos_from_file(self, info):
-        # Object file line: '{object}:  file format elf32-xtensa-le'
-        object = Fragment.ENTITY.setResultsName("object") + Literal(":").suppress() + Literal("file format elf32-xtensa-le").suppress()
+        # {object}:  file format elf32-xtensa-le
+        object_line = SkipTo(":").setResultsName("object") + Suppress(restOfLine)
 
-        # Sections table
-        header = Suppress(Literal("Sections:") + Literal("Idx") + Literal("Name") + Literal("Size") + Literal("VMA") +
-                          Literal("LMA") + Literal("File off") + Literal("Algn"))
-        entry = Word(nums).suppress() + Fragment.ENTITY + Suppress(OneOrMore(Word(alphanums, exact=8)) +
-                                                                   Word(nums + "*") + ZeroOrMore(Word(alphas.upper()) +
-                                                                   Optional(Literal(","))))
+        # Sections:
+        # Idx Name ...
+        section_start = Suppress(Literal("Sections:"))
+        section_header = Suppress(OneOrMore(Word(alphas)))
 
-        # Content is object file line + sections table
-        content = Group(object + header + Group(ZeroOrMore(entry)).setResultsName("sections"))
+        # 00 {section} 0000000 ...
+        #              CONTENTS, ALLOC, ....
+        section_entry = Suppress(Word(nums)) + SkipTo(' ') + Suppress(restOfLine) + \
+            Suppress(ZeroOrMore(Word(alphas) + Literal(",")) + Word(alphas))
 
+        content = Group(object_line + section_start + section_header + Group(OneOrMore(section_entry)).setResultsName("sections"))
         parser = Group(ZeroOrMore(content)).setResultsName("contents")
 
-        sections_info_text = info.content
         results = None
 
         try:
-            results = parser.parseString(sections_info_text)
+            results = parser.parseString(info.content, parseAll=True)
         except ParseException as p:
             raise ParseException("Unable to parse section info file " + info.filename + ". " + p.message)
 

+ 1 - 1
tools/ldgen/test/data/sections.info

@@ -1,4 +1,4 @@
-In archive /home/user/ãóç+ěščřžýáíé/build/esp-idf/freertos/libfreertos.a:
+In archive /home/user/build/esp-idf/freertos/libfreertos.a:
 
 FreeRTOS-openocd.c.obj:     file format elf32-xtensa-le
 

+ 19 - 0
tools/ldgen/test/data/sections_parse.info

@@ -0,0 +1,19 @@
+In archive /home/user/ãóç+ěščřžýáíé/build/esp-idf/freertos/libsections_parse.a:
+
+croutine.c.obj:     file format elf32-littleriscv
+
+Sections:
+Idx Name          Size      VMA       LMA       File off  Algn
+  0 .text         00000000  00000000  00000000  00000034  2**0
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+  1 .data         00000000  00000000  00000000  00000034  2**0
+                  CONTENTS, ALLOC, LOAD, DATA
+  2 .bss          00000000  00000000  00000000  00000034  2**0
+                  ALLOC
+
+FreeRTOS-openocd.c.obj:     file format elf32-xtensa-le // 'F' should not get included in match for 'CONTENTS, ALLOC, LOAD ...' prior
+
+Sections:
+Idx Name          Size      VMA       LMA       File off  Algn
+  0 .literal.prvCheckPendingReadyList 00000018  00000000  00000000  00000034  2**2
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE

+ 13 - 0
tools/ldgen/test/test_generation.py

@@ -1422,6 +1422,19 @@ entries:
         self.assertListEqual(actual["flash_text"], expected["flash_text"])
         self.assertListEqual(actual["iram0_text"], expected["iram0_text"])
 
+    def test_sections_info_parsing(self):
+
+        self.sections_info = SectionsInfo()
+
+        with open("data/sections_parse.info") as sections_info_file_obj:
+            self.sections_info.add_sections_info(sections_info_file_obj)
+
+        sections = self.sections_info.get_obj_sections("libsections_parse.a", "croutine")
+        self.assertEqual(set(sections), set([".text", ".data", ".bss"]))
+
+        sections = self.sections_info.get_obj_sections("libsections_parse.a", "FreeRTOS-openocd")
+        self.assertEqual(set(sections), set([".literal.prvCheckPendingReadyList"]))
+
 
 if __name__ == "__main__":
     unittest.main()