buildtools: fix pmdinfogen with pyelftools < 0.24
authorDmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Mon, 25 Jan 2021 22:12:48 +0000 (01:12 +0300)
committerThomas Monjalon <thomas@monjalon.net>
Mon, 25 Jan 2021 23:39:34 +0000 (00:39 +0100)
pyelftools had some breaking changes [1] and API enhancements [2]
between 0.23 (used in Ubuntu 16.04) and 0.24. Ensure compatibility with
both legacy and modern versions.

[1]: https://github.com/eliben/pyelftools/pull/76
[2]: https://github.com/eliben/pyelftools/pull/56

Signed-off-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
buildtools/pmdinfogen.py

index 893a6c5..7a739ec 100755 (executable)
@@ -10,6 +10,7 @@ import sys
 import tempfile
 
 try:
+    import elftools
     from elftools.elf.elffile import ELFFile
     from elftools.elf.sections import SymbolTableSection
 except ImportError:
@@ -38,8 +39,13 @@ class ELFSymbol:
 
 class ELFImage:
     def __init__(self, data):
+        version = tuple(int(c) for c in elftools.__version__.split("."))
+        self._legacy_elftools = version < (0, 24)
+
         self._image = ELFFile(data)
-        self._symtab = self._image.get_section_by_name(".symtab")
+
+        section = b".symtab" if self._legacy_elftools else ".symtab"
+        self._symtab = self._image.get_section_by_name(section)
         if not isinstance(self._symtab, SymbolTableSection):
             raise Exception(".symtab section is not a symbol table")
 
@@ -48,10 +54,20 @@ class ELFImage:
         return not self._image.little_endian
 
     def find_by_name(self, name):
-        symbol = self._symtab.get_symbol_by_name(name)
+        symbol = self._get_symbol_by_name(name)
         return ELFSymbol(self._image, symbol[0]) if symbol else None
 
+    def _get_symbol_by_name(self, name):
+        if not self._legacy_elftools:
+            return self._symtab.get_symbol_by_name(name)
+        name = name.encode("utf-8")
+        for symbol in self._symtab.iter_symbols():
+            if symbol.name == name:
+                return [symbol]
+        return None
+
     def find_by_prefix(self, prefix):
+        prefix = prefix.encode("utf-8") if self._legacy_elftools else prefix
         for i in range(self._symtab.num_symbols()):
             symbol = self._symtab.get_symbol(i)
             if symbol.name.startswith(prefix):