1 |
commit: 54102922da2df25535d066899b00f85ff6ea938b |
2 |
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
3 |
AuthorDate: Tue May 27 23:27:10 2014 +0000 |
4 |
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
5 |
CommitDate: Tue May 27 23:27:10 2014 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=54102922 |
7 |
|
8 |
misc/ldd: add code to search paths |
9 |
|
10 |
--- |
11 |
misc/ldd/ldd.py | 62 ++++++++++++++++++++++++++++++++++++++++----------------- |
12 |
1 file changed, 44 insertions(+), 18 deletions(-) |
13 |
|
14 |
diff --git a/misc/ldd/ldd.py b/misc/ldd/ldd.py |
15 |
index afb03b6..4d6f500 100755 |
16 |
--- a/misc/ldd/ldd.py |
17 |
+++ b/misc/ldd/ldd.py |
18 |
@@ -1,6 +1,6 @@ |
19 |
#!/usr/bin/env python |
20 |
|
21 |
-import sys |
22 |
+import os, sys |
23 |
import re, glob |
24 |
from optparse import OptionParser |
25 |
|
26 |
@@ -9,6 +9,7 @@ from elftools.common.exceptions import ELFError |
27 |
from elftools.common.py3compat import bytes2str |
28 |
from elftools.elf.elffile import ELFFile |
29 |
from elftools.elf.dynamic import DynamicSection |
30 |
+from elftools.elf.descriptions import describe_ei_class |
31 |
|
32 |
class ReadElf(object): |
33 |
def __init__(self, file): |
34 |
@@ -16,19 +17,31 @@ class ReadElf(object): |
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 |
+ def elf_class(self): |
42 |
+ """ Return the ELF Class |
43 |
+ """ |
44 |
+ header = self.elffile.header |
45 |
+ e_ident = header['e_ident'] |
46 |
+ return describe_ei_class(e_ident['EI_CLASS']) |
47 |
+ |
48 |
+ def dynamic_dt_needed(self): |
49 |
+ """ Return a list of the DT_NEEDED |
50 |
""" |
51 |
+ dt_needed = [] |
52 |
for section in self.elffile.iter_sections(): |
53 |
if not isinstance(section, DynamicSection): |
54 |
continue |
55 |
|
56 |
for tag in section.iter_tags(): |
57 |
if tag.entry.d_tag == 'DT_NEEDED': |
58 |
- sys.stdout.write('\t%s\n' % bytes2str(tag.needed) ) |
59 |
+ dt_needed.append(bytes2str(tag.needed)) |
60 |
+ #sys.stdout.write('\t%s\n' % bytes2str(tag.needed) ) |
61 |
+ |
62 |
+ return dt_needed |
63 |
|
64 |
|
65 |
-def ldpath(ld_so_conf='/etc/ld.so.conf'): |
66 |
+def ldpaths(ld_so_conf='/etc/ld.so.conf'): |
67 |
""" Generate paths to search for libraries from ld.so.conf. Recursively |
68 |
parse included files. We assume correct syntax and the ld.so.cache |
69 |
is in sync with ld.so.conf. |
70 |
@@ -38,25 +51,33 @@ def ldpath(ld_so_conf='/etc/ld.so.conf'): |
71 |
lines = re.sub('#.*', '', lines) # kill comments |
72 |
lines = list(re.split(':+|\s+|\t+|\n+|,+', lines)) # man 8 ldconfig |
73 |
|
74 |
+ paths = [] |
75 |
include_globs = [] |
76 |
for l in lines: |
77 |
if l == '': |
78 |
- lines.remove('') |
79 |
+ continue |
80 |
if l == 'include': |
81 |
f = lines[lines.index(l) + 1] |
82 |
- lines.remove(l) |
83 |
- lines.remove(f) |
84 |
include_globs.append(f) |
85 |
+ continue |
86 |
+ if l not in include_globs: |
87 |
+ paths.append(os.path.realpath(l)) |
88 |
|
89 |
include_files = [] |
90 |
for g in include_globs: |
91 |
include_files = include_files + glob.glob('/etc/' + g) |
92 |
for c in include_files: |
93 |
- lines = lines + ldpath(c) |
94 |
+ paths = paths + ldpaths(os.path.realpath(c)) |
95 |
|
96 |
- return list(set(lines)) |
97 |
+ return list(set(paths)) |
98 |
|
99 |
|
100 |
+def dynamic_dt_needed_paths( dt_needed, eclass, paths): |
101 |
+ for n in dt_needed: |
102 |
+ for p in paths: |
103 |
+ print('%s' % p + '/' + n) |
104 |
+ return |
105 |
+ |
106 |
SCRIPT_DESCRIPTION = 'Print shared library dependencies' |
107 |
VERSION_STRING = '%%prog: based on pyelftools %s' % __version__ |
108 |
|
109 |
@@ -72,9 +93,13 @@ def main(): |
110 |
help='Display this information') |
111 |
options, args = optparser.parse_args() |
112 |
|
113 |
- #if options.help or len(args) == 0: |
114 |
- #optparser.print_help() |
115 |
- #sys.exit(0) |
116 |
+ if options.help or len(args) == 0: |
117 |
+ optparser.print_help() |
118 |
+ sys.exit(0) |
119 |
+ |
120 |
+ paths = ldpaths() |
121 |
+ print(paths) |
122 |
+ sys.exit(0) |
123 |
|
124 |
for f in args: |
125 |
with open(f, 'rb') as file: |
126 |
@@ -82,14 +107,15 @@ def main(): |
127 |
readelf = ReadElf(file) |
128 |
if len(args) > 1: |
129 |
sys.stdout.write('%s : \n' % f) |
130 |
- readelf.display_dynamic_dt_needed() |
131 |
+ eclass = readelf.elf_class() |
132 |
+ #sys.stdout.write('\t%s\n' % eclass) |
133 |
+ dt_needed = readelf.dynamic_dt_needed() |
134 |
+ dt_needed_paths = dynamic_dt_needed_paths( dt_needed, eclass, paths) |
135 |
+ for n in dt_needed: |
136 |
+ sys.stdout.write('\t%s\n' % n ) |
137 |
except ELFError as ex: |
138 |
sys.stderr.write('ELF error: %s\n' % ex) |
139 |
sys.exit(1) |
140 |
|
141 |
- lines = ldpath() |
142 |
- print(lines) |
143 |
- |
144 |
- |
145 |
if __name__ == '__main__': |
146 |
main() |