From patchwork Mon May 16 20:41:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Horman X-Patchwork-Id: 12796 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 33812AD8C; Mon, 16 May 2016 22:42:30 +0200 (CEST) Received: from smtp.tuxdriver.com (charlotte.tuxdriver.com [70.61.120.58]) by dpdk.org (Postfix) with ESMTP id 5419FAD8B for ; Mon, 16 May 2016 22:42:28 +0200 (CEST) Received: from hmsreliant.think-freely.org ([2001:470:8:a08:7aac:c0ff:fec2:933b] helo=localhost) by smtp.tuxdriver.com with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.63) (envelope-from ) id 1b2PLI-0004Q6-VG; Mon, 16 May 2016 16:42:25 -0400 From: Neil Horman To: dev@dpdk.org Cc: Neil Horman , Bruce Richardson , Thomas Monjalon , Stephen Hemminger , Panu Matilainen Date: Mon, 16 May 2016 16:41:27 -0400 Message-Id: <1463431287-4551-5-git-send-email-nhorman@tuxdriver.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1463431287-4551-1-git-send-email-nhorman@tuxdriver.com> References: <1463431287-4551-1-git-send-email-nhorman@tuxdriver.com> X-Spam-Score: -1.0 (-) X-Spam-Status: No Subject: [dpdk-dev] [PATCH 4/4] pmd_hw_support.py: Add tool to query binaries for hw support information X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This tool searches for the primer sting PMD_DRIVER_INFO= in any ELF binary, and, if found parses the remainder of the string as a json encoded string, outputting the results in either a human readable or raw, script parseable format Signed-off-by: Neil Horman CC: Bruce Richardson CC: Thomas Monjalon CC: Stephen Hemminger CC: Panu Matilainen --- tools/pmd_hw_support.py | 174 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100755 tools/pmd_hw_support.py diff --git a/tools/pmd_hw_support.py b/tools/pmd_hw_support.py new file mode 100755 index 0000000..0669aca --- /dev/null +++ b/tools/pmd_hw_support.py @@ -0,0 +1,174 @@ +#!/usr/bin/python3 +#------------------------------------------------------------------------------- +# scripts/pmd_hw_support.py +# +# Utility to dump PMD_INFO_STRING support from an object file +# +#------------------------------------------------------------------------------- +import os, sys +from optparse import OptionParser +import string +import json + +# For running from development directory. It should take precedence over the +# installed pyelftools. +sys.path.insert(0, '.') + + +from elftools import __version__ +from elftools.common.exceptions import ELFError +from elftools.common.py3compat import ( + ifilter, byte2int, bytes2str, itervalues, str2bytes) +from elftools.elf.elffile import ELFFile +from elftools.elf.dynamic import DynamicSection, DynamicSegment +from elftools.elf.enums import ENUM_D_TAG +from elftools.elf.segments import InterpSegment +from elftools.elf.sections import SymbolTableSection +from elftools.elf.gnuversions import ( + GNUVerSymSection, GNUVerDefSection, + GNUVerNeedSection, + ) +from elftools.elf.relocation import RelocationSection +from elftools.elf.descriptions import ( + describe_ei_class, describe_ei_data, describe_ei_version, + describe_ei_osabi, describe_e_type, describe_e_machine, + describe_e_version_numeric, describe_p_type, describe_p_flags, + describe_sh_type, describe_sh_flags, + describe_symbol_type, describe_symbol_bind, describe_symbol_visibility, + describe_symbol_shndx, describe_reloc_type, describe_dyn_tag, + describe_ver_flags, + ) +from elftools.elf.constants import E_FLAGS +from elftools.dwarf.dwarfinfo import DWARFInfo +from elftools.dwarf.descriptions import ( + describe_reg_name, describe_attr_value, set_global_machine_arch, + describe_CFI_instructions, describe_CFI_register_rule, + describe_CFI_CFA_rule, + ) +from elftools.dwarf.constants import ( + DW_LNS_copy, DW_LNS_set_file, DW_LNE_define_file) +from elftools.dwarf.callframe import CIE, FDE + +raw_output = False; + +class ReadElf(object): + """ display_* methods are used to emit output into the output stream + """ + def __init__(self, file, output): + """ file: + stream object with the ELF file to read + + output: + output stream to write to + """ + self.elffile = ELFFile(file) + self.output = output + + # Lazily initialized if a debug dump is requested + self._dwarfinfo = None + + self._versioninfo = None + + def _section_from_spec(self, spec): + """ Retrieve a section given a "spec" (either number or name). + Return None if no such section exists in the file. + """ + try: + num = int(spec) + if num < self.elffile.num_sections(): + return self.elffile.get_section(num) + else: + return None + except ValueError: + # Not a number. Must be a name then + return self.elffile.get_section_by_name(str2bytes(spec)) + + def parse_pmd_info_string(self, mystring): + global raw_output + i = mystring.index("="); + mystring = mystring[i+2:] + pmdinfo = json.loads(mystring) + + if raw_output: + print(pmdinfo) + return + + print("PMD NAME: " + pmdinfo["name"]) + print("PMD TYPE: " + pmdinfo["type"]) + if (pmdinfo["type"] == "PMD_PDEV"): + print("PMD HW SUPPORT:") + print("VENDOR\t DEVICE\t SUBVENDOR\t SUBDEVICE") + for i in pmdinfo["pci_ids"]: + print("0x%04x\t 0x%04x\t 0x%04x\t\t 0x%04x" % (i[0], i[1], i[2], i[3])) + + print("") + + + def display_pmd_info_strings(self, section_spec): + """ Display a strings dump of a section. section_spec is either a + section number or a name. + """ + section = self._section_from_spec(section_spec) + if section is None: + return + + + found = False + data = section.data() + dataptr = 0 + + while dataptr < len(data): + while ( dataptr < len(data) and + not (32 <= byte2int(data[dataptr]) <= 127)): + dataptr += 1 + + if dataptr >= len(data): + break + + endptr = dataptr + while endptr < len(data) and byte2int(data[endptr]) != 0: + endptr += 1 + + found = True + mystring = bytes2str(data[dataptr:endptr]) + rc = mystring.find("PMD_INFO_STRING") + if (rc != -1): + self.parse_pmd_info_string(mystring) + + dataptr = endptr + + +def main(stream=None): + global raw_output + + optparser = OptionParser( + usage='usage: %prog [-h|-r] ', + description="Dump pmd hardware support info", + add_help_option=True, + prog='pmd_hw_support.py') + optparser.add_option('-r', '--raw', + action='store_true', dest='raw_output', + help='Dump raw json strings') + + options, args = optparser.parse_args() + + if options.raw_output: + raw_output = True + + with open(args[0], 'rb') as file: + try: + readelf = ReadElf(file, stream or sys.stdout) + + readelf.display_pmd_info_strings(".rodata") + sys.exit(0) + + except ELFError as ex: + sys.stderr.write('ELF error: %s\n' % ex) + sys.exit(1) + + +#------------------------------------------------------------------------------- +if __name__ == '__main__': + main() + +