1 |
vapier 14/07/30 04:16:25 |
2 |
|
3 |
Modified: lddtree.py |
4 |
Log: |
5 |
lddtree.py: rework debug handling and add a bit more throughout the processing |
6 |
|
7 |
Revision Changes Path |
8 |
1.47 pax-utils/lddtree.py |
9 |
|
10 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/pax-utils/lddtree.py?rev=1.47&view=markup |
11 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/pax-utils/lddtree.py?rev=1.47&content-type=text/plain |
12 |
diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/pax-utils/lddtree.py?r1=1.46&r2=1.47 |
13 |
|
14 |
Index: lddtree.py |
15 |
=================================================================== |
16 |
RCS file: /var/cvsroot/gentoo-projects/pax-utils/lddtree.py,v |
17 |
retrieving revision 1.46 |
18 |
retrieving revision 1.47 |
19 |
diff -u -r1.46 -r1.47 |
20 |
--- lddtree.py 30 Jul 2014 04:07:43 -0000 1.46 |
21 |
+++ lddtree.py 30 Jul 2014 04:16:25 -0000 1.47 |
22 |
@@ -4,7 +4,7 @@ |
23 |
# Copyright 2012-2014 The Chromium OS Authors |
24 |
# Use of this source code is governed by a BSD-style license (BSD-3) |
25 |
# pylint: disable=C0301 |
26 |
-# $Header: /var/cvsroot/gentoo-projects/pax-utils/lddtree.py,v 1.46 2014/07/30 04:07:43 vapier Exp $ |
27 |
+# $Header: /var/cvsroot/gentoo-projects/pax-utils/lddtree.py,v 1.47 2014/07/30 04:16:25 vapier Exp $ |
28 |
|
29 |
# TODO: Handle symlinks. |
30 |
|
31 |
@@ -38,6 +38,12 @@ |
32 |
sys.exit(status) |
33 |
|
34 |
|
35 |
+def dbg(debug, *args, **kwargs): |
36 |
+ """Pass |args| and |kwargs| to print() when |debug| is True""" |
37 |
+ if debug: |
38 |
+ print(*args, **kwargs) |
39 |
+ |
40 |
+ |
41 |
def bstr(buf): |
42 |
"""Decode the byte string into a string""" |
43 |
return buf.decode('utf-8') |
44 |
@@ -243,19 +249,22 @@ |
45 |
elf1.header['e_machine'] == elf2.header['e_machine']) |
46 |
|
47 |
|
48 |
-def FindLib(elf, lib, ldpaths): |
49 |
+def FindLib(elf, lib, ldpaths, debug=False): |
50 |
"""Try to locate a |lib| that is compatible to |elf| in the given |ldpaths| |
51 |
|
52 |
Args: |
53 |
- elf: the elf which the library should be compatible with (ELF wise) |
54 |
- lib: the library (basename) to search for |
55 |
- ldpaths: a list of paths to search |
56 |
+ elf: The elf which the library should be compatible with (ELF wise) |
57 |
+ lib: The library (basename) to search for |
58 |
+ ldpaths: A list of paths to search |
59 |
+ debug: Enable debug output |
60 |
|
61 |
Returns: |
62 |
the full path to the desired library |
63 |
""" |
64 |
+ dbg(debug, ' FindLib(%s)' % lib) |
65 |
for ldpath in ldpaths: |
66 |
path = os.path.join(ldpath, lib) |
67 |
+ dbg(debug, ' checking:', path) |
68 |
if os.path.exists(path): |
69 |
with open(path, 'rb') as f: |
70 |
libelf = ELFFile(f) |
71 |
@@ -265,7 +274,7 @@ |
72 |
|
73 |
|
74 |
def ParseELF(path, root='/', prefix='', ldpaths={'conf':[], 'env':[], 'interp':[]}, |
75 |
- _first=True, _all_libs={}): |
76 |
+ debug=False, _first=True, _all_libs={}): |
77 |
"""Parse the ELF dependency tree of the specified file |
78 |
|
79 |
Args: |
80 |
@@ -275,6 +284,7 @@ |
81 |
prefix: The path under |root| to search |
82 |
ldpaths: dict containing library paths to search; should have the keys: |
83 |
conf, env, interp |
84 |
+ debug: Enable debug output |
85 |
_first: Recursive use only; is this the first ELF ? |
86 |
_all_libs: Recursive use only; dict of all libs we've seen |
87 |
|
88 |
@@ -307,6 +317,8 @@ |
89 |
'libs': _all_libs, |
90 |
} |
91 |
|
92 |
+ dbg(debug, 'ParseELF(%s)' % path) |
93 |
+ |
94 |
with open(path, 'rb') as f: |
95 |
elf = ELFFile(f) |
96 |
|
97 |
@@ -317,6 +329,7 @@ |
98 |
continue |
99 |
|
100 |
interp = bstr(segment.get_interp_name()) |
101 |
+ dbg(debug, ' interp =', interp) |
102 |
ret['interp'] = normpath(root + interp) |
103 |
ret['libs'][os.path.basename(interp)] = { |
104 |
'path': ret['interp'], |
105 |
@@ -327,6 +340,7 @@ |
106 |
normpath(root + os.path.dirname(interp)), |
107 |
normpath(root + prefix + '/usr' + os.path.dirname(interp).lstrip(prefix)), |
108 |
] |
109 |
+ dbg(debug, ' ldpaths[interp] =', ldpaths['interp']) |
110 |
break |
111 |
|
112 |
# Parse the ELF's dynamic tags. |
113 |
@@ -356,6 +370,8 @@ |
114 |
# used at runtime to locate things. |
115 |
ldpaths['rpath'] = rpaths |
116 |
ldpaths['runpath'] = runpaths |
117 |
+ dbg(debug, ' ldpaths[rpath] =', rpaths) |
118 |
+ dbg(debug, ' ldpaths[runpath] =', runpaths) |
119 |
ret['rpath'] = rpaths |
120 |
ret['runpath'] = runpaths |
121 |
ret['needed'] = libs |
122 |
@@ -367,7 +383,7 @@ |
123 |
continue |
124 |
if all_ldpaths is None: |
125 |
all_ldpaths = rpaths + ldpaths['rpath'] + ldpaths['env'] + runpaths + ldpaths['runpath'] + ldpaths['conf'] + ldpaths['interp'] |
126 |
- fullpath = FindLib(elf, lib, all_ldpaths) |
127 |
+ fullpath = FindLib(elf, lib, all_ldpaths, debug=debug) |
128 |
_all_libs[lib] = { |
129 |
'path': fullpath, |
130 |
'needed': [], |
131 |
@@ -386,7 +402,7 @@ |
132 |
|
133 |
|
134 |
def _ShowVersion(_option, _opt, _value, _parser): |
135 |
- d = '$Id: lddtree.py,v 1.46 2014/07/30 04:07:43 vapier Exp $'.split() |
136 |
+ d = '$Id: lddtree.py,v 1.47 2014/07/30 04:16:25 vapier Exp $'.split() |
137 |
print('%s-%s %s %s' % (d[1].split('.')[0], d[2], d[3], d[4])) |
138 |
sys.exit(0) |
139 |
|
140 |
@@ -612,32 +628,33 @@ |
141 |
if options.skip_non_elfs and options.copy_non_elfs: |
142 |
parser.error('pick one handler for non-ELFs: skip or copy') |
143 |
|
144 |
- if options.debug: |
145 |
- print('root =', options.root) |
146 |
- if options.dest: |
147 |
- print('dest =', options.dest) |
148 |
+ dbg(options.debug, 'root =', options.root) |
149 |
+ if options.dest: |
150 |
+ dbg(options.debug, 'dest =', options.dest) |
151 |
if not paths: |
152 |
err('missing ELF files to scan') |
153 |
|
154 |
ldpaths = LoadLdpaths(options.root, options.prefix) |
155 |
- if options.debug: |
156 |
- print('ldpaths[conf] =', ldpaths['conf']) |
157 |
- print('ldpaths[env] =', ldpaths['env']) |
158 |
+ dbg(options.debug, 'ldpaths[conf] =', ldpaths['conf']) |
159 |
+ dbg(options.debug, 'ldpaths[env] =', ldpaths['env']) |
160 |
|
161 |
# Process all the files specified. |
162 |
ret = 0 |
163 |
for path in paths: |
164 |
+ dbg(options.debug, 'argv[x] =', path) |
165 |
# Only auto-prefix the path if the ELF is absolute. |
166 |
# If it's a relative path, the user most likely wants |
167 |
# the local path. |
168 |
if options.auto_root and path.startswith('/'): |
169 |
path = options.root + path.lstrip('/') |
170 |
+ dbg(options.debug, ' +auto-root =', path) |
171 |
|
172 |
matched = False |
173 |
for p in glob.iglob(path): |
174 |
matched = True |
175 |
try: |
176 |
- elf = ParseELF(p, options.root, options.prefix, ldpaths) |
177 |
+ elf = ParseELF(p, options.root, options.prefix, ldpaths, |
178 |
+ debug=options.debug) |
179 |
except exceptions.ELFError as e: |
180 |
if options.skip_non_elfs: |
181 |
continue |