X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=buildtools%2Fpmdinfogen.py;h=2a44f17bdad6461efafd09bcee9be78c7b7f52f6;hb=6a4e4385767b598c41b6e97e8984907b373cd276;hp=0cca47ff14f7207d667028b78f2950ce9d7c926b;hpb=6c4bf8f42432d421ef162135d1e8c353a6ebe6dc;p=dpdk.git diff --git a/buildtools/pmdinfogen.py b/buildtools/pmdinfogen.py index 0cca47ff14..2a44f17bda 100755 --- a/buildtools/pmdinfogen.py +++ b/buildtools/pmdinfogen.py @@ -9,8 +9,14 @@ import json import sys import tempfile -from elftools.elf.elffile import ELFFile -from elftools.elf.sections import SymbolTableSection +try: + import elftools + from elftools.elf.elffile import ELFFile + from elftools.elf.sections import SymbolTableSection +except ImportError: + pass + +import coff class ELFSymbol: @@ -18,26 +24,28 @@ class ELFSymbol: self._image = image self._symbol = symbol - @property - def size(self): - return self._symbol["st_size"] - - @property - def value(self): - data = self._image.get_section_data(self._symbol["st_shndx"]) - base = self._symbol["st_value"] - return data[base:base + self.size] - @property def string_value(self): - value = self.value - return value[:-1].decode() if value else "" + size = self._symbol["st_size"] + value = self.get_value(0, size) + return coff.decode_asciiz(value) # not COFF-specific + + def get_value(self, offset, size): + section = self._symbol["st_shndx"] + data = self._image.get_section(section).data() + base = self._symbol["st_value"] + offset + return data[base : base + size] 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") @@ -45,18 +53,60 @@ class ELFImage: def is_big_endian(self): return not self._image.little_endian - def get_section_data(self, name): - return self._image.get_section(name).data() - def find_by_name(self, name): - symbol = self._symtab.get_symbol_by_name(name) - return ELFSymbol(self, symbol[0]) if symbol else None + 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): - yield ELFSymbol(self, symbol) + yield ELFSymbol(self._image, symbol) + + +class COFFSymbol: + def __init__(self, image, symbol): + self._image = image + self._symbol = symbol + + def get_value(self, offset, size): + value = self._symbol.get_value(offset) + return value[:size] if value else value + + @property + def string_value(self): + value = self._symbol.get_value(0) + return coff.decode_asciiz(value) if value else '' + + +class COFFImage: + def __init__(self, data): + self._image = coff.Image(data) + + @property + def is_big_endian(self): + return False + + def find_by_prefix(self, prefix): + for symbol in self._image.symbols: + if symbol.name.startswith(prefix): + yield COFFSymbol(self._image, symbol) + + def find_by_name(self, name): + for symbol in self._image.symbols: + if symbol.name == name: + return COFFSymbol(self._image, symbol) + return None def define_rte_pci_id(is_big_endian): @@ -117,19 +167,24 @@ class Driver: rte_pci_id = define_rte_pci_id(image.is_big_endian) - pci_id_size = ctypes.sizeof(rte_pci_id) - pci_ids_desc = rte_pci_id * (table_symbol.size // pci_id_size) - pci_ids = pci_ids_desc.from_buffer_copy(table_symbol.value) result = [] - for pci_id in pci_ids: + while True: + size = ctypes.sizeof(rte_pci_id) + offset = size * len(result) + data = table_symbol.get_value(offset, size) + if not data: + break + pci_id = rte_pci_id.from_buffer_copy(data) if not pci_id.device_id: break - result.append([ - pci_id.vendor_id, - pci_id.device_id, - pci_id.subsystem_vendor_id, - pci_id.subsystem_device_id, - ]) + result.append( + [ + pci_id.vendor_id, + pci_id.device_id, + pci_id.subsystem_vendor_id, + pci_id.subsystem_device_id, + ] + ) return result def dump(self, file): @@ -157,7 +212,10 @@ def dump_drivers(drivers, file): def parse_args(): parser = argparse.ArgumentParser() - parser.add_argument("input", help="input object file path or '-' for stdin") + parser.add_argument("format", help="object file format, 'elf' or 'coff'") + parser.add_argument( + "input", nargs='+', help="input object file path or '-' for stdin" + ) parser.add_argument("output", help="output C file path or '-' for stdout") return parser.parse_args() @@ -170,19 +228,46 @@ def open_input(path): return open(path, "rb") +def read_input(path): + if path == "-": + return sys.stdin.buffer.read() + with open(path, "rb") as file: + return file.read() + + +def load_image(fmt, path): + if fmt == "elf": + return ELFImage(open_input(path)) + if fmt == "coff": + return COFFImage(read_input(path)) + raise Exception("unsupported object file format") + + def open_output(path): if path == "-": return sys.stdout return open(path, "w") +def write_header(output): + output.write( + "static __attribute__((unused)) const char *generator = \"%s\";\n" % sys.argv[0] + ) + + def main(): args = parse_args() - infile = open_input(args.input) - image = ELFImage(infile) - drivers = load_drivers(image) + if args.input.count('-') > 1: + raise Exception("'-' input cannot be used multiple times") + if args.format == "elf" and "ELFFile" not in globals(): + raise Exception("elftools module not found") + output = open_output(args.output) - dump_drivers(drivers, output) + write_header(output) + for path in args.input: + image = load_image(args.format, path) + drivers = load_drivers(image) + dump_drivers(drivers, output) if __name__ == "__main__":