X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=usertools%2Fdpdk-pmdinfo.py;h=f9ed7551769cdb9bd7fc97f1cdb3bd9379e7a2e8;hb=185fe122f4899f48569d0086c9dcacc431ef0967;hp=46c1be081b9047b50d533fcc9189eccfa84841ad;hpb=c6dab2a873f65c5a4ea9735aa24d9539426adba4;p=dpdk.git diff --git a/usertools/dpdk-pmdinfo.py b/usertools/dpdk-pmdinfo.py index 46c1be081b..f9ed755176 100755 --- a/usertools/dpdk-pmdinfo.py +++ b/usertools/dpdk-pmdinfo.py @@ -1,4 +1,6 @@ #!/usr/bin/env python +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2016 Neil Horman # ------------------------------------------------------------------------- # @@ -6,13 +8,15 @@ # # ------------------------------------------------------------------------- from __future__ import print_function +from __future__ import unicode_literals import json +import io import os import platform import string import sys from elftools.common.exceptions import ELFError -from elftools.common.py3compat import (byte2int, bytes2str, str2bytes) +from elftools.common.py3compat import byte2int from elftools.elf.elffile import ELFFile from optparse import OptionParser @@ -24,7 +28,9 @@ raw_output = False pcidb = None # =========================================== - +if sys.version_info.major < 3: + print("WARNING: Python 2 is deprecated for use in DPDK, and will not work in future releases.", file=sys.stderr) + print("Please use Python 3 instead", file=sys.stderr) class Vendor: """ @@ -211,7 +217,8 @@ class PCIIds: """ Reads the local file """ - self.contents = open(filename).readlines() + with io.open(filename, 'r', encoding='utf-8') as f: + self.contents = f.readlines() self.date = self.findDate(self.contents) def loadLocal(self): @@ -265,7 +272,13 @@ class ReadElf(object): return None except ValueError: # Not a number. Must be a name then - return self.elffile.get_section_by_name(str2bytes(spec)) + section = self.elffile.get_section_by_name(force_unicode(spec)) + if section is None: + # No match with a unicode name. + # Some versions of pyelftools (<= 0.23) store internal strings + # as bytes. Try again with the name encoded as bytes. + section = self.elffile.get_section_by_name(force_bytes(spec)) + return section def pretty_print_pmdinfo(self, pmdinfo): global pcidb @@ -337,7 +350,8 @@ class ReadElf(object): while endptr < len(data) and byte2int(data[endptr]) != 0: endptr += 1 - mystring = bytes2str(data[dataptr:endptr]) + # pyelftools may return byte-strings, force decode them + mystring = force_unicode(data[dataptr:endptr]) rc = mystring.find("PMD_INFO_STRING") if (rc != -1): self.parse_pmd_info_string(mystring) @@ -346,9 +360,10 @@ class ReadElf(object): def find_librte_eal(self, section): for tag in section.iter_tags(): - if tag.entry.d_tag == 'DT_NEEDED': - if "librte_eal" in tag.needed: - return tag.needed + # pyelftools may return byte-strings, force decode them + if force_unicode(tag.entry.d_tag) == 'DT_NEEDED': + if "librte_eal" in force_unicode(tag.needed): + return force_unicode(tag.needed) return None def search_for_autoload_path(self): @@ -371,7 +386,7 @@ class ReadElf(object): return (None, None) if raw_output is False: print("Scanning for autoload path in %s" % library) - scanfile = open(library, 'rb') + scanfile = io.open(library, 'rb') scanelf = ReadElf(scanfile, sys.stdout) except AttributeError: # Not a dynamic binary @@ -401,7 +416,8 @@ class ReadElf(object): while endptr < len(data) and byte2int(data[endptr]) != 0: endptr += 1 - mystring = bytes2str(data[dataptr:endptr]) + # pyelftools may return byte-strings, force decode them + mystring = force_unicode(data[dataptr:endptr]) rc = mystring.find("DPDK_PLUGIN_PATH") if (rc != -1): rc = mystring.find("=") @@ -414,8 +430,9 @@ class ReadElf(object): def get_dt_runpath(self, dynsec): for tag in dynsec.iter_tags(): - if tag.entry.d_tag == 'DT_RUNPATH': - return tag.runpath + # pyelftools may return byte-strings, force decode them + if force_unicode(tag.entry.d_tag) == 'DT_RUNPATH': + return force_unicode(tag.runpath) return "" def process_dt_needed_entries(self): @@ -436,16 +453,16 @@ class ReadElf(object): return for tag in dynsec.iter_tags(): - if tag.entry.d_tag == 'DT_NEEDED': - rc = tag.needed.find(b"librte_pmd") - if (rc != -1): - library = search_file(tag.needed, + # pyelftools may return byte-strings, force decode them + if force_unicode(tag.entry.d_tag) == 'DT_NEEDED': + if 'librte_pmd' in force_unicode(tag.needed): + library = search_file(force_unicode(tag.needed), runpath + ":" + ldlibpath + ":/usr/lib64:/lib64:/usr/lib:/lib") if library is not None: if raw_output is False: print("Scanning %s for pmd information" % library) - with open(library, 'rb') as file: + with io.open(library, 'rb') as file: try: libelf = ReadElf(file, sys.stdout) except ELFError: @@ -456,6 +473,20 @@ class ReadElf(object): file.close() +# compat: remove force_unicode & force_bytes when pyelftools<=0.23 support is +# dropped. +def force_unicode(s): + if hasattr(s, 'decode') and callable(s.decode): + s = s.decode('latin-1') # same encoding used in pyelftools py3compat + return s + + +def force_bytes(s): + if hasattr(s, 'encode') and callable(s.encode): + s = s.encode('latin-1') # same encoding used in pyelftools py3compat + return s + + def scan_autoload_path(autoload_path): global raw_output @@ -474,7 +505,7 @@ def scan_autoload_path(autoload_path): scan_autoload_path(dpath) if os.path.isfile(dpath): try: - file = open(dpath, 'rb') + file = io.open(dpath, 'rb') readelf = ReadElf(file, sys.stdout) except ELFError: # this is likely not an elf file, skip it @@ -501,7 +532,7 @@ def scan_for_autoload_pmds(dpdk_path): print("Must specify a file name") return - file = open(dpdk_path, 'rb') + file = io.open(dpdk_path, 'rb') try: readelf = ReadElf(file, sys.stdout) except ElfError: @@ -510,7 +541,7 @@ def scan_for_autoload_pmds(dpdk_path): return (autoload_path, scannedfile) = readelf.search_for_autoload_path() - if (autoload_path is None or autoload_path is ""): + if not autoload_path: if (raw_output is False): print("No autoload path configured in %s" % dpdk_path) return @@ -532,7 +563,10 @@ def main(stream=None): pcifile_default = "./pci.ids" # For unknown OS's assume local file if platform.system() == 'Linux': - pcifile_default = "/usr/share/hwdata/pci.ids" + # hwdata is the legacy location, misc is supported going forward + pcifile_default = "/usr/share/misc/pci.ids" + if not os.path.exists(pcifile_default): + pcifile_default = "/usr/share/hwdata/pci.ids" elif platform.system() == 'FreeBSD': pcifile_default = "/usr/local/share/pciids/pci.ids" if not os.path.exists(pcifile_default): @@ -593,7 +627,7 @@ def main(stream=None): print("File not found") sys.exit(1) - with open(myelffile, 'rb') as file: + with io.open(myelffile, 'rb') as file: try: readelf = ReadElf(file, sys.stdout) readelf.process_dt_needed_entries()