[gentoo-commits] proj/elfix:master commit in: misc/ldd/
commit: a32f1be0a8aa82db6d1b4992b8c13793538e8870 Author: Anthony G. Basile blueness AT gentoo DOT org AuthorDate: Wed Jun 4 00:20:34 2014 + Commit: Anthony G. Basile blueness AT gentoo DOT org CommitDate: Wed Jun 4 00:20:34 2014 + URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=a32f1be0 misc/ldd: add caching to speed up recursion --- misc/ldd/ldd.py | 34 +++--- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/misc/ldd/ldd.py b/misc/ldd/ldd.py index 3574137..447614e 100755 --- a/misc/ldd/ldd.py +++ b/misc/ldd/ldd.py @@ -76,23 +76,35 @@ def ldpaths(ld_so_conf='/etc/ld.so.conf'): return paths +# We cache the dependencies for speed. The structure is +# { ELFClass : { SONAME : library, ... }, ELFClass : ... } +cache = {} + def dynamic_dt_needed_paths( dt_needed, eclass, paths): Search library paths for the library file corresponding to the given DT_NEEDED and ELF Class. +global cache +if not eclass in cache: +cache[eclass] = {} + dt_needed_paths = {} for n in dt_needed: -for p in paths: -lib = p + os.sep + n -if os.path.exists(lib): -with open(lib, 'rb') as file: -try: -readlib = ReadElf(file) -if eclass == readlib.elf_class(): -dt_needed_paths[n] = lib -except ELFError as ex: -sys.stderr.write('ELF error: %s\n' % ex) -sys.exit(1) +if n in cache[eclass].keys(): + dt_needed_paths[n] = cache[eclass][n] +else: +for p in paths: +lib = p + os.sep + n +if os.path.exists(lib): +with open(lib, 'rb') as file: +try: +readlib = ReadElf(file) +if eclass == readlib.elf_class(): +dt_needed_paths[n] = lib +cache[eclass][n] = lib +except ELFError as ex: +sys.stderr.write('ELF error: %s\n' % ex) +sys.exit(1) return dt_needed_paths
[gentoo-commits] proj/elfix:master commit in: misc/ldd/
commit: 0ebc3cb8dc5588d7be43b07cfd24fed93e8523a2 Author: Anthony G. Basile blueness AT gentoo DOT org AuthorDate: Sun Jun 1 02:10:27 2014 + Commit: Anthony G. Basile blueness AT gentoo DOT org CommitDate: Sun Jun 1 02:10:27 2014 + URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=0ebc3cb8 misc/ldd: recursively search all_dt_needed_paths --- misc/ldd/ldd.py | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/misc/ldd/ldd.py b/misc/ldd/ldd.py index 1819607..3574137 100755 --- a/misc/ldd/ldd.py +++ b/misc/ldd/ldd.py @@ -78,7 +78,7 @@ def ldpaths(ld_so_conf='/etc/ld.so.conf'): def dynamic_dt_needed_paths( dt_needed, eclass, paths): Search library paths for the library file corresponding -to the DT_NEEDED and ELF Class. +to the given DT_NEEDED and ELF Class. dt_needed_paths = {} for n in dt_needed: @@ -97,20 +97,25 @@ def dynamic_dt_needed_paths( dt_needed, eclass, paths): return dt_needed_paths -def all_dt_needed_paths(f, paths): +def all_dynamic_dt_needed_paths(f, paths): + Return a dictionary of all the DT_NEEDED = Library Paths for +a given ELF file obtained by recursively following linkage. + with open(f, 'rb') as file: try: readelf = ReadElf(file) eclass = readelf.elf_class() # This needs to be iterated until we traverse the entire linkage tree dt_needed = readelf.dynamic_dt_needed() -dt_needed_paths = dynamic_dt_needed_paths( dt_needed, eclass, paths) +dt_needed_paths = dynamic_dt_needed_paths(dt_needed, eclass, paths) for n, lib in dt_needed_paths.items(): -sys.stdout.write('\t%s = %s\n' % (n, lib)) +dt_needed_paths = dict(all_dynamic_dt_needed_paths(lib, paths), **dt_needed_paths) except ELFError as ex: sys.stderr.write('ELF error: %s\n' % ex) sys.exit(1) +return dt_needed_paths + SCRIPT_DESCRIPTION = 'Print shared library dependencies' VERSION_STRING = '%%prog: based on pyelftools %s' % __version__ @@ -136,7 +141,9 @@ def main(): for f in args: if len(args) 1: sys.stdout.write('%s : \n' % f) -all_dt_needed_paths(f, paths) +all_dt_needed_paths = all_dynamic_dt_needed_paths(f, paths) +for n, lib in all_dt_needed_paths.items(): +sys.stdout.write('\t%s = %s\n' % (n, lib)) if __name__ == '__main__': main()
[gentoo-commits] proj/elfix:master commit in: misc/ldd/
commit: b196a92359419799bd414be7f5643fd5b8545e37 Author: Anthony G. Basile blueness AT gentoo DOT org AuthorDate: Wed May 28 16:32:49 2014 + Commit: Anthony G. Basile blueness AT gentoo DOT org CommitDate: Wed May 28 16:32:49 2014 + URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=b196a923 misc/ldd: refactor all_dt_needed_paths for recursion --- misc/ldd/ldd.py | 33 +++-- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/misc/ldd/ldd.py b/misc/ldd/ldd.py index 5a15786..1819607 100755 --- a/misc/ldd/ldd.py +++ b/misc/ldd/ldd.py @@ -96,6 +96,22 @@ def dynamic_dt_needed_paths( dt_needed, eclass, paths): return dt_needed_paths + +def all_dt_needed_paths(f, paths): +with open(f, 'rb') as file: +try: +readelf = ReadElf(file) +eclass = readelf.elf_class() +# This needs to be iterated until we traverse the entire linkage tree +dt_needed = readelf.dynamic_dt_needed() +dt_needed_paths = dynamic_dt_needed_paths( dt_needed, eclass, paths) +for n, lib in dt_needed_paths.items(): +sys.stdout.write('\t%s = %s\n' % (n, lib)) +except ELFError as ex: +sys.stderr.write('ELF error: %s\n' % ex) +sys.exit(1) + + SCRIPT_DESCRIPTION = 'Print shared library dependencies' VERSION_STRING = '%%prog: based on pyelftools %s' % __version__ @@ -118,20 +134,9 @@ def main(): paths = ldpaths() for f in args: -with open(f, 'rb') as file: -try: -readelf = ReadElf(file) -if len(args) 1: -sys.stdout.write('%s : \n' % f) -eclass = readelf.elf_class() -# This needs to be iterated until we traverse the entire linkage tree -dt_needed = readelf.dynamic_dt_needed() -dt_needed_paths = dynamic_dt_needed_paths( dt_needed, eclass, paths) -for n, lib in dt_needed_paths.items(): -sys.stdout.write('\t%s = %s\n' % (n, lib)) -except ELFError as ex: -sys.stderr.write('ELF error: %s\n' % ex) -sys.exit(1) +if len(args) 1: +sys.stdout.write('%s : \n' % f) +all_dt_needed_paths(f, paths) if __name__ == '__main__': main()
[gentoo-commits] proj/elfix:master commit in: misc/ldd/
commit: d38e2718a641ce67d3caf598de5534e6ebef9e64 Author: Anthony G. Basile blueness AT gentoo DOT org AuthorDate: Tue May 27 17:37:52 2014 + Commit: Anthony G. Basile blueness AT gentoo DOT org CommitDate: Tue May 27 17:37:52 2014 + URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=d38e2718 misc/ldd: initial commit of python ldd script --- misc/ldd/ldd.py | 95 + 1 file changed, 95 insertions(+) diff --git a/misc/ldd/ldd.py b/misc/ldd/ldd.py new file mode 100755 index 000..afb03b6 --- /dev/null +++ b/misc/ldd/ldd.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python + +import sys +import re, glob +from optparse import OptionParser + +from elftools import __version__ +from elftools.common.exceptions import ELFError +from elftools.common.py3compat import bytes2str +from elftools.elf.elffile import ELFFile +from elftools.elf.dynamic import DynamicSection + +class ReadElf(object): +def __init__(self, file): + file: stream object with the ELF file to read + +self.elffile = ELFFile(file) + +def display_dynamic_dt_needed(self): + Display the dynamic DT_NEEDED contained in the file + +for section in self.elffile.iter_sections(): +if not isinstance(section, DynamicSection): +continue + +for tag in section.iter_tags(): +if tag.entry.d_tag == 'DT_NEEDED': +sys.stdout.write('\t%s\n' % bytes2str(tag.needed) ) + + +def ldpath(ld_so_conf='/etc/ld.so.conf'): + Generate paths to search for libraries from ld.so.conf. Recursively +parse included files. We assume correct syntax and the ld.so.cache +is in sync with ld.so.conf. + +with open(ld_so_conf, 'r') as path_file: +lines = path_file.read() +lines = re.sub('#.*', '', lines) # kill comments +lines = list(re.split(':+|\s+|\t+|\n+|,+', lines)) # man 8 ldconfig + +include_globs = [] +for l in lines: +if l == '': + lines.remove('') +if l == 'include': +f = lines[lines.index(l) + 1] +lines.remove(l) +lines.remove(f) +include_globs.append(f) + +include_files = [] +for g in include_globs: +include_files = include_files + glob.glob('/etc/' + g) +for c in include_files: +lines = lines + ldpath(c) + +return list(set(lines)) + + +SCRIPT_DESCRIPTION = 'Print shared library dependencies' +VERSION_STRING = '%%prog: based on pyelftools %s' % __version__ + +def main(): +optparser = OptionParser( +usage='usage: %prog elf-file', +description=SCRIPT_DESCRIPTION, +add_help_option=False, # -h is a real option of readelf +prog='ldd.py', +version=VERSION_STRING) +optparser.add_option('-h', '--help', +action='store_true', dest='help', +help='Display this information') +options, args = optparser.parse_args() + +#if options.help or len(args) == 0: +#optparser.print_help() +#sys.exit(0) + +for f in args: +with open(f, 'rb') as file: +try: +readelf = ReadElf(file) +if len(args) 1: +sys.stdout.write('%s : \n' % f) +readelf.display_dynamic_dt_needed() +except ELFError as ex: +sys.stderr.write('ELF error: %s\n' % ex) +sys.exit(1) + +lines = ldpath() +print(lines) + + +if __name__ == '__main__': +main()
[gentoo-commits] proj/elfix:master commit in: misc/ldd/
commit: 54102922da2df25535d066899b00f85ff6ea938b Author: Anthony G. Basile blueness AT gentoo DOT org AuthorDate: Tue May 27 23:27:10 2014 + Commit: Anthony G. Basile blueness AT gentoo DOT org CommitDate: Tue May 27 23:27:10 2014 + URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=54102922 misc/ldd: add code to search paths --- misc/ldd/ldd.py | 62 - 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/misc/ldd/ldd.py b/misc/ldd/ldd.py index afb03b6..4d6f500 100755 --- a/misc/ldd/ldd.py +++ b/misc/ldd/ldd.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -import sys +import os, sys import re, glob from optparse import OptionParser @@ -9,6 +9,7 @@ from elftools.common.exceptions import ELFError from elftools.common.py3compat import bytes2str from elftools.elf.elffile import ELFFile from elftools.elf.dynamic import DynamicSection +from elftools.elf.descriptions import describe_ei_class class ReadElf(object): def __init__(self, file): @@ -16,19 +17,31 @@ class ReadElf(object): self.elffile = ELFFile(file) -def display_dynamic_dt_needed(self): - Display the dynamic DT_NEEDED contained in the file + +def elf_class(self): + Return the ELF Class + +header = self.elffile.header +e_ident = header['e_ident'] +return describe_ei_class(e_ident['EI_CLASS']) + +def dynamic_dt_needed(self): + Return a list of the DT_NEEDED +dt_needed = [] for section in self.elffile.iter_sections(): if not isinstance(section, DynamicSection): continue for tag in section.iter_tags(): if tag.entry.d_tag == 'DT_NEEDED': -sys.stdout.write('\t%s\n' % bytes2str(tag.needed) ) +dt_needed.append(bytes2str(tag.needed)) +#sys.stdout.write('\t%s\n' % bytes2str(tag.needed) ) + +return dt_needed -def ldpath(ld_so_conf='/etc/ld.so.conf'): +def ldpaths(ld_so_conf='/etc/ld.so.conf'): Generate paths to search for libraries from ld.so.conf. Recursively parse included files. We assume correct syntax and the ld.so.cache is in sync with ld.so.conf. @@ -38,25 +51,33 @@ def ldpath(ld_so_conf='/etc/ld.so.conf'): lines = re.sub('#.*', '', lines) # kill comments lines = list(re.split(':+|\s+|\t+|\n+|,+', lines)) # man 8 ldconfig +paths = [] include_globs = [] for l in lines: if l == '': - lines.remove('') +continue if l == 'include': f = lines[lines.index(l) + 1] -lines.remove(l) -lines.remove(f) include_globs.append(f) +continue +if l not in include_globs: +paths.append(os.path.realpath(l)) include_files = [] for g in include_globs: include_files = include_files + glob.glob('/etc/' + g) for c in include_files: -lines = lines + ldpath(c) +paths = paths + ldpaths(os.path.realpath(c)) -return list(set(lines)) +return list(set(paths)) +def dynamic_dt_needed_paths( dt_needed, eclass, paths): +for n in dt_needed: +for p in paths: +print('%s' % p + '/' + n) +return + SCRIPT_DESCRIPTION = 'Print shared library dependencies' VERSION_STRING = '%%prog: based on pyelftools %s' % __version__ @@ -72,9 +93,13 @@ def main(): help='Display this information') options, args = optparser.parse_args() -#if options.help or len(args) == 0: -#optparser.print_help() -#sys.exit(0) +if options.help or len(args) == 0: +optparser.print_help() +sys.exit(0) + +paths = ldpaths() +print(paths) +sys.exit(0) for f in args: with open(f, 'rb') as file: @@ -82,14 +107,15 @@ def main(): readelf = ReadElf(file) if len(args) 1: sys.stdout.write('%s : \n' % f) -readelf.display_dynamic_dt_needed() +eclass = readelf.elf_class() +#sys.stdout.write('\t%s\n' % eclass) +dt_needed = readelf.dynamic_dt_needed() +dt_needed_paths = dynamic_dt_needed_paths( dt_needed, eclass, paths) +for n in dt_needed: +sys.stdout.write('\t%s\n' % n ) except ELFError as ex: sys.stderr.write('ELF error: %s\n' % ex) sys.exit(1) -lines = ldpath() -print(lines) - - if __name__ == '__main__': main()
[gentoo-commits] proj/elfix:master commit in: misc/ldd/
commit: 8209b9955e06f2238c7c4d2732652e7fb0f3c977 Author: Anthony G. Basile blueness AT gentoo DOT org AuthorDate: Tue May 27 23:46:25 2014 + Commit: Anthony G. Basile blueness AT gentoo DOT org CommitDate: Tue May 27 23:46:25 2014 + URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=8209b995 misc/ldd: correct logic for ldpaths() --- misc/ldd/ldd.py | 24 ++-- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/misc/ldd/ldd.py b/misc/ldd/ldd.py index 4d6f500..c1bcc19 100755 --- a/misc/ldd/ldd.py +++ b/misc/ldd/ldd.py @@ -53,15 +53,17 @@ def ldpaths(ld_so_conf='/etc/ld.so.conf'): paths = [] include_globs = [] -for l in lines: -if l == '': +for i in range(0,len(lines)): +if lines[i] == '': continue -if l == 'include': -f = lines[lines.index(l) + 1] +if lines[i] == 'include': +f = lines[i + 1] include_globs.append(f) continue -if l not in include_globs: -paths.append(os.path.realpath(l)) +if lines[i] not in include_globs: +real_path = os.path.realpath(lines[i]) +if os.path.exists(real_path): +paths.append(real_path) include_files = [] for g in include_globs: @@ -69,13 +71,17 @@ def ldpaths(ld_so_conf='/etc/ld.so.conf'): for c in include_files: paths = paths + ldpaths(os.path.realpath(c)) -return list(set(paths)) +paths = list(set(paths)) +paths.sort() +return paths def dynamic_dt_needed_paths( dt_needed, eclass, paths): for n in dt_needed: for p in paths: -print('%s' % p + '/' + n) +lib = p + os.sep + n +if os.path.exists(lib): +print('%s' % lib) return SCRIPT_DESCRIPTION = 'Print shared library dependencies' @@ -98,8 +104,6 @@ def main(): sys.exit(0) paths = ldpaths() -print(paths) -sys.exit(0) for f in args: with open(f, 'rb') as file:
[gentoo-commits] proj/elfix:master commit in: misc/ldd/
commit: c86a02ad95c04a839ec79841d728b8ac83896dc7 Author: Anthony G. Basile blueness AT gentoo DOT org AuthorDate: Wed May 28 00:07:43 2014 + Commit: Anthony G. Basile blueness AT gentoo DOT org CommitDate: Wed May 28 00:07:56 2014 + URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=c86a02ad misc/ldd: 'soname = paths' at depth = 1 only --- misc/ldd/ldd.py | 18 +- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/misc/ldd/ldd.py b/misc/ldd/ldd.py index c1bcc19..34d6642 100755 --- a/misc/ldd/ldd.py +++ b/misc/ldd/ldd.py @@ -77,12 +77,21 @@ def ldpaths(ld_so_conf='/etc/ld.so.conf'): def dynamic_dt_needed_paths( dt_needed, eclass, paths): +dt_needed_paths = {} for n in dt_needed: for p in paths: lib = p + os.sep + n if os.path.exists(lib): -print('%s' % lib) -return +with open(lib, 'rb') as file: +try: +readlib = ReadElf(file) +if eclass == readlib.elf_class(): +dt_needed_paths[n] = lib +except ELFError as ex: +sys.stderr.write('ELF error: %s\n' % ex) +sys.exit(1) + +return dt_needed_paths SCRIPT_DESCRIPTION = 'Print shared library dependencies' VERSION_STRING = '%%prog: based on pyelftools %s' % __version__ @@ -112,11 +121,10 @@ def main(): if len(args) 1: sys.stdout.write('%s : \n' % f) eclass = readelf.elf_class() -#sys.stdout.write('\t%s\n' % eclass) dt_needed = readelf.dynamic_dt_needed() dt_needed_paths = dynamic_dt_needed_paths( dt_needed, eclass, paths) -for n in dt_needed: -sys.stdout.write('\t%s\n' % n ) +for n, lib in dt_needed_paths.items(): +sys.stdout.write('\t%s = %s\n' % (n, lib)) except ELFError as ex: sys.stderr.write('ELF error: %s\n' % ex) sys.exit(1)
[gentoo-commits] proj/elfix:master commit in: misc/ldd/
commit: 88ba3abb4737cf252c7a15588b2f45e6ed37fb83 Author: Anthony G. Basile blueness AT gentoo DOT org AuthorDate: Wed May 28 00:18:46 2014 + Commit: Anthony G. Basile blueness AT gentoo DOT org CommitDate: Wed May 28 00:18:46 2014 + URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=88ba3abb misc/ldd: add some comments --- misc/ldd/ldd.py | 4 1 file changed, 4 insertions(+) diff --git a/misc/ldd/ldd.py b/misc/ldd/ldd.py index 34d6642..5a15786 100755 --- a/misc/ldd/ldd.py +++ b/misc/ldd/ldd.py @@ -77,6 +77,9 @@ def ldpaths(ld_so_conf='/etc/ld.so.conf'): def dynamic_dt_needed_paths( dt_needed, eclass, paths): + Search library paths for the library file corresponding +to the DT_NEEDED and ELF Class. + dt_needed_paths = {} for n in dt_needed: for p in paths: @@ -121,6 +124,7 @@ def main(): if len(args) 1: sys.stdout.write('%s : \n' % f) eclass = readelf.elf_class() +# This needs to be iterated until we traverse the entire linkage tree dt_needed = readelf.dynamic_dt_needed() dt_needed_paths = dynamic_dt_needed_paths( dt_needed, eclass, paths) for n, lib in dt_needed_paths.items():