Gentoo Archives: gentoo-commits

From: "Anthony G. Basile" <blueness@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/elfix:master commit in: misc/ldd/
Date: Tue, 27 May 2014 17:35:42
Message-Id: 1401212272.d38e2718a641ce67d3caf598de5534e6ebef9e64.blueness@gentoo
1 commit: d38e2718a641ce67d3caf598de5534e6ebef9e64
2 Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
3 AuthorDate: Tue May 27 17:37:52 2014 +0000
4 Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
5 CommitDate: Tue May 27 17:37:52 2014 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=d38e2718
7
8 misc/ldd: initial commit of python ldd script
9
10 ---
11 misc/ldd/ldd.py | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12 1 file changed, 95 insertions(+)
13
14 diff --git a/misc/ldd/ldd.py b/misc/ldd/ldd.py
15 new file mode 100755
16 index 0000000..afb03b6
17 --- /dev/null
18 +++ b/misc/ldd/ldd.py
19 @@ -0,0 +1,95 @@
20 +#!/usr/bin/env python
21 +
22 +import sys
23 +import re, glob
24 +from optparse import OptionParser
25 +
26 +from elftools import __version__
27 +from elftools.common.exceptions import ELFError
28 +from elftools.common.py3compat import bytes2str
29 +from elftools.elf.elffile import ELFFile
30 +from elftools.elf.dynamic import DynamicSection
31 +
32 +class ReadElf(object):
33 + def __init__(self, file):
34 + """ file: stream object with the ELF file to read
35 + """
36 + self.elffile = ELFFile(file)
37 +
38 + def display_dynamic_dt_needed(self):
39 + """ Display the dynamic DT_NEEDED contained in the file
40 + """
41 + for section in self.elffile.iter_sections():
42 + if not isinstance(section, DynamicSection):
43 + continue
44 +
45 + for tag in section.iter_tags():
46 + if tag.entry.d_tag == 'DT_NEEDED':
47 + sys.stdout.write('\t%s\n' % bytes2str(tag.needed) )
48 +
49 +
50 +def ldpath(ld_so_conf='/etc/ld.so.conf'):
51 + """ Generate paths to search for libraries from ld.so.conf. Recursively
52 + parse included files. We assume correct syntax and the ld.so.cache
53 + is in sync with ld.so.conf.
54 + """
55 + with open(ld_so_conf, 'r') as path_file:
56 + lines = path_file.read()
57 + lines = re.sub('#.*', '', lines) # kill comments
58 + lines = list(re.split(':+|\s+|\t+|\n+|,+', lines)) # man 8 ldconfig
59 +
60 + include_globs = []
61 + for l in lines:
62 + if l == '':
63 + lines.remove('')
64 + if l == 'include':
65 + f = lines[lines.index(l) + 1]
66 + lines.remove(l)
67 + lines.remove(f)
68 + include_globs.append(f)
69 +
70 + include_files = []
71 + for g in include_globs:
72 + include_files = include_files + glob.glob('/etc/' + g)
73 + for c in include_files:
74 + lines = lines + ldpath(c)
75 +
76 + return list(set(lines))
77 +
78 +
79 +SCRIPT_DESCRIPTION = 'Print shared library dependencies'
80 +VERSION_STRING = '%%prog: based on pyelftools %s' % __version__
81 +
82 +def main():
83 + optparser = OptionParser(
84 + usage='usage: %prog <elf-file>',
85 + description=SCRIPT_DESCRIPTION,
86 + add_help_option=False, # -h is a real option of readelf
87 + prog='ldd.py',
88 + version=VERSION_STRING)
89 + optparser.add_option('-h', '--help',
90 + action='store_true', dest='help',
91 + help='Display this information')
92 + options, args = optparser.parse_args()
93 +
94 + #if options.help or len(args) == 0:
95 + #optparser.print_help()
96 + #sys.exit(0)
97 +
98 + for f in args:
99 + with open(f, 'rb') as file:
100 + try:
101 + readelf = ReadElf(file)
102 + if len(args) > 1:
103 + sys.stdout.write('%s : \n' % f)
104 + readelf.display_dynamic_dt_needed()
105 + except ELFError as ex:
106 + sys.stderr.write('ELF error: %s\n' % ex)
107 + sys.exit(1)
108 +
109 + lines = ldpath()
110 + print(lines)
111 +
112 +
113 +if __name__ == '__main__':
114 + main()