From: Yann Rouillard Date: Thu, 23 May 2013 22:43:51 +0000 (+0200) Subject: remove elfdump script and test X-Git-Tag: v0.22~57 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1f5f5952a6f1b37b583da3760b563c7911f28ad8;p=pyelftools.git remove elfdump script and test --- diff --git a/scripts/elfdump.py b/scripts/elfdump.py deleted file mode 100755 index 3eb7ffc..0000000 --- a/scripts/elfdump.py +++ /dev/null @@ -1,178 +0,0 @@ -#!/opt/csw/bin/python -#------------------------------------------------------------------------------- -# scripts/elfdump.py -# -# A clone of 'elfdump' in Python, based on the pyelftools library -# -# Eli Bendersky (eliben@gmail.com) -# Yann Rouillard (yann@pleiades.fr.eu.org) -# This code is in the public domain -#------------------------------------------------------------------------------- -import os, sys -from optparse import OptionParser -import string - -# 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.constants import SYMINFO_FLAGS -from elftools.elf.segments import InterpSegment -from elftools.elf.sections import SUNWSyminfoTableSection -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_syminfo_flags, describe_symbol_boundto, - ) -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 - - -class Elfdump(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 - - def display_syminfo_table(self): - """ Display the SUNW syminfo tables contained in the file - """ - syminfo_section = None - for section in self.elffile.iter_sections(): - if isinstance(section, SUNWSyminfoTableSection): - syminfo_section = section - break - - if syminfo_section: - # We need to dyntable to do get the soname names - dyntable = self.elffile.get_section_by_name('.dynamic') - - if section['sh_entsize'] == 0: - self._emitline("\nSymbol table '%s' has a sh_entsize of zero!" - % (bytes2str(section.name))) - return - - # The symbol table section pointed to in sh_link - symtable = self.elffile.get_section(section['sh_link']) - - self._emitline("\nSyminfo Section: %s" % bytes2str(section.name)) - self._emitline('%10s %-5s %10s %-24s %s' - % ('index', 'flags', '', 'bound to', 'symbol')) - - for nsym, syminfo in enumerate(section.iter_symbols(), start=1): - - # elfdump doesn't display anything for this kind of symbols - if not (syminfo['si_flags'] or syminfo['si_boundto']): - continue - - index = '' - if syminfo['si_flags'] & SYMINFO_FLAGS.SYMINFO_FLG_CAP: - boundto = '' - elif not isinstance(syminfo['si_boundto'], int): - boundto = describe_symbol_boundto(syminfo['si_boundto']) - else: - dyn_tag = dyntable.get_tag(syminfo['si_boundto']) - if syminfo['si_flags'] & SYMINFO_FLAGS.SYMINFO_FLG_FILTER: - boundto = bytes2str(dyn_tag.sunw_filter) - else: - boundto = bytes2str(dyn_tag.needed) - index = '[%d]' % syminfo['si_boundto'] - - # syminfo names are truncated to 24 chars, similarly to elfdump - self._emitline('%10s %-5s %10s %-24s %s' % ( - '[%d]' % (int(nsym)), - describe_syminfo_flags(syminfo['si_flags']), - index, - boundto, - bytes2str(syminfo.name))) - - def _emit(self, s=''): - """ Emit an object to output - """ - self.output.write(str(s)) - - def _emitline(self, s=''): - """ Emit an object to output, followed by a newline - """ - self.output.write(str(s) + '\n') - - -SCRIPT_DESCRIPTION = 'Dumps selected parts of an object file' -VERSION_STRING = '%%prog: based on pyelftools %s' % __version__ - - -def main(stream=None): - # parse the command-line arguments and invoke ReadElf - optparser = OptionParser( - usage='usage: %prog [options] ', - description=SCRIPT_DESCRIPTION, - add_help_option=False, # -h is a real option of readelf - prog='elfdump.py', - version=VERSION_STRING) - optparser.add_option('--help', - action='store_true', dest='help', - help='Display this information') - optparser.add_option('-y', - action='store_true', dest='show_syminfo', - help='dump the contents of the .SUNW_syminfo section') - - options, args = optparser.parse_args() - - if options.help or len(args) == 0: - optparser.print_help() - sys.exit(0) - - with open(args[0], 'rb') as file: - try: - readelf = Elfdump(file, stream or sys.stdout) - if options.show_syminfo: - readelf.display_syminfo_table() - except ELFError as ex: - sys.stderr.write('ELF error: %s\n' % ex) - sys.exit(1) - - -def profile_main(): - # Run 'main' redirecting its output to readelfout.txt - # Saves profiling information in readelf.profile - PROFFILE = 'elfdump.profile' - import cProfile - cProfile.run('main(open("elfdumpout.txt", "w"))', PROFFILE) - - # Dig in some profiling stats - import pstats - p = pstats.Stats(PROFFILE) - p.sort_stats('cumulative').print_stats(25) - - -#------------------------------------------------------------------------------- -if __name__ == '__main__': - main() - #profile_main() diff --git a/setup.py b/setup.py index 9cad128..63fe3b1 100644 --- a/setup.py +++ b/setup.py @@ -44,8 +44,7 @@ setup( 'elftools.construct', 'elftools.construct.lib', ], - scripts=['scripts/readelf.py', - 'scripts/elfdump.py'] + scripts=['scripts/readelf.py'] ) diff --git a/test/run_elfdump_tests.py b/test/run_elfdump_tests.py deleted file mode 100755 index 3d5f2e7..0000000 --- a/test/run_elfdump_tests.py +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/env python -#------------------------------------------------------------------------------- -# test/run_elfdump_tests.py -# -# Automatic test runner for elftools & elfdump -# -# Eli Bendersky (eliben@gmail.com) -# Yann Rouillard (yann@pleiades.fr.eu.org) -# This code is in the public domain -#------------------------------------------------------------------------------- -import os, sys -import re -from difflib import SequenceMatcher -from optparse import OptionParser -import logging -import platform -from utils import setup_syspath; setup_syspath() -from utils import run_exe, is_in_rootdir, dump_output_to_temp_files - - -# Create a global logger object -# -testlog = logging.getLogger('run_tests') -testlog.setLevel(logging.DEBUG) -testlog.addHandler(logging.StreamHandler(sys.stdout)) - -ELFDUMP_PATH = '/usr/ccs/bin/elfdump' - -def discover_testfiles(rootdir): - """ Discover test files in the given directory. Yield them one by one. - """ - for filename in os.listdir(rootdir): - name, ext = os.path.splitext(filename) - if ext == '.elf' and 'solaris' in name: - yield os.path.join(rootdir, filename) - - -def run_test_on_file(filename, verbose=False): - """ Runs a test on the given input filename. Return True if all test - runs succeeded. - """ - success = True - testlog.info("Test file '%s'" % filename) - for option in [ - '-y']: - if verbose: testlog.info("..option='%s'" % option) - # stdouts will be a 2-element list: output of elfdump and output - # of scripts/elfdump.py - stdouts = [] - for exe_path in [ELFDUMP_PATH, 'scripts/elfdump.py']: - args = [option, filename] - if verbose: testlog.info("....executing: '%s %s'" % ( - exe_path, ' '.join(args))) - rc, stdout = run_exe(exe_path, args) - if rc != 0: - testlog.error("@@ aborting - '%s' returned '%s'" % (exe_path, rc)) - return False - stdouts.append(stdout) - if verbose: testlog.info('....comparing output...') - rc, errmsg = compare_output(*stdouts) - if rc: - if verbose: testlog.info('.......................SUCCESS') - else: - success = False - testlog.info('.......................FAIL') - testlog.info('....for option "%s"' % option) - testlog.info('....Output #1 is elfdump, Output #2 is pyelftools') - testlog.info('@@ ' + errmsg) - dump_output_to_temp_files(testlog, *stdouts) - return success - - -def compare_output(s1, s2): - """ Compare stdout strings s1 and s2. - s1 is from elfdump, s2 from elftools elfdump.py - Return pair success, errmsg. If comparison succeeds, success is True - and errmsg is empty. Otherwise success is False and errmsg holds a - description of the mismatch. - - Note: this function contains some rather horrible hacks to ignore - differences which are not important for the verification of pyelftools. - This is due to some intricacies of binutils's elfdump which pyelftools - doesn't currently implement, or silly inconsistencies in the output of - elfdump, which I was reluctant to replicate. - Read the documentation for more details. - """ - def prepare_lines(s): - return [line for line in s.lower().splitlines() if line.strip() != ''] - def filter_elfdump_lines(lines): - filter_out = False - for line in lines: - if not filter_out: - yield line - - lines1 = prepare_lines(s1) - lines2 = prepare_lines(s2) - - lines1 = list(filter_elfdump_lines(lines1)) - - flag_after_symtable = False - - if len(lines1) != len(lines2): - return False, 'Number of lines different: %s vs %s' % ( - len(lines1), len(lines2)) - - for i in range(len(lines1)): - if 'symbol table' in lines1[i]: - flag_after_symtable = True - - # Compare ignoring whitespace - lines1_parts = lines1[i].split() - lines2_parts = lines2[i].split() - if ''.join(lines1_parts) != ''.join(lines2_parts): - ok = False - if not ok: - errmsg = 'Mismatch on line #%s:\n>>%s<<\n>>%s<<\n' % ( - i, lines1[i], lines2[i]) - return False, errmsg - return True, '' - - -def main(): - if not is_in_rootdir(): - testlog.error('Error: Please run me from the root dir of pyelftools!') - return 1 - - optparser = OptionParser( - usage='usage: %prog [options] [file] [file] ...', - prog='run_elfdump_tests.py') - optparser.add_option('-V', '--verbose', - action='store_true', dest='verbose', - help='Verbose output') - options, args = optparser.parse_args() - - if options.verbose: - testlog.info('Running in verbose mode') - testlog.info('Python executable = %s' % sys.executable) - testlog.info('elfdump path = %s' % READELF_PATH) - testlog.info('Given list of files: %s' % args) - - # If file names are given as command-line arguments, only these files - # are taken as inputs. Otherwise, autodiscovery is performed. - # - if len(args) > 0: - filenames = args - else: - filenames = list(discover_testfiles('test/testfiles')) - - success = True - for filename in filenames: - if success: - success = success and run_test_on_file( - filename, - verbose=options.verbose) - - if success: - testlog.info('\nConclusion: SUCCESS') - return 0 - else: - testlog.info('\nConclusion: FAIL') - return 1 - - -if __name__ == '__main__': - sys.exit(main()) -