1 |
commit: 53cd005f5c80fbb93c56cb60e0d80d2635eb939f |
2 |
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Dec 26 03:42:02 2012 +0000 |
4 |
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Dec 26 03:42:02 2012 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=53cd005f |
7 |
|
8 |
misc/link_maps: refactorize indentation |
9 |
|
10 |
--- |
11 |
misc/link_maps | 318 ++++++++++++++++++++++++++++---------------------------- |
12 |
1 files changed, 158 insertions(+), 160 deletions(-) |
13 |
|
14 |
diff --git a/misc/link_maps b/misc/link_maps |
15 |
index 9b774bc..3707298 100755 |
16 |
--- a/misc/link_maps |
17 |
+++ b/misc/link_maps |
18 |
@@ -16,202 +16,200 @@ import pax |
19 |
import portage |
20 |
|
21 |
|
22 |
-""" |
23 |
-Return object_needed dictionary which has structure |
24 |
- |
25 |
- { |
26 |
- abi1 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... }, |
27 |
- abi2 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... }, |
28 |
- .... |
29 |
- } |
30 |
- |
31 |
-Here the sonames were obtained from the ELF object by scanelf -nm |
32 |
-(like readelf -d) during emerge. |
33 |
-""" |
34 |
def get_object_needed(): |
35 |
+ """ Return object_needed dictionary which has structure |
36 |
|
37 |
- vardb = portage.db[portage.root]["vartree"].dbapi |
38 |
+ { |
39 |
+ abi1 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... }, |
40 |
+ abi2 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... }, |
41 |
+ .... |
42 |
+ } |
43 |
|
44 |
- object_needed = {} |
45 |
+ Here the sonames were obtained from the ELF object by scanelf -nm |
46 |
+ (like readelf -d) during emerge. |
47 |
+ """ |
48 |
|
49 |
- for pkg in vardb.cpv_all(): |
50 |
- needs = vardb.aux_get(pkg, ['NEEDED.ELF.2'])[0].strip() |
51 |
- if not needs: #skip empty lines |
52 |
- continue |
53 |
- lines = re.split('\n', needs) |
54 |
- for line in lines: |
55 |
- link = re.split(';', line) |
56 |
- abi = link[0] |
57 |
- elf = link[1] |
58 |
- sonames = re.split(',', link[4]) |
59 |
- object_needed.setdefault(abi,{}).update({elf:sonames}) |
60 |
+ vardb = portage.db[portage.root]["vartree"].dbapi |
61 |
|
62 |
- return object_needed |
63 |
+ object_needed = {} |
64 |
|
65 |
+ for pkg in vardb.cpv_all(): |
66 |
+ needs = vardb.aux_get(pkg, ['NEEDED.ELF.2'])[0].strip() |
67 |
+ if not needs: #skip empty lines |
68 |
+ continue |
69 |
+ lines = re.split('\n', needs) |
70 |
+ for line in lines: |
71 |
+ link = re.split(';', line) |
72 |
+ abi = link[0] |
73 |
+ elf = link[1] |
74 |
+ sonames = re.split(',', link[4]) |
75 |
+ object_needed.setdefault(abi,{}).update({elf:sonames}) |
76 |
|
77 |
-""" |
78 |
-Return library2soname dictionary which has structure |
79 |
+ return object_needed |
80 |
|
81 |
- { full_path_to_library : (soname, abi), ... } |
82 |
|
83 |
-and its inverse which has structure |
84 |
- |
85 |
- { (soname, abi) : full_path_to_library, ... } |
86 |
-""" |
87 |
def get_libraries(): |
88 |
+ """ Return library2soname dictionary which has structure |
89 |
+ |
90 |
+ { full_path_to_library : (soname, abi), ... } |
91 |
|
92 |
- vardb = portage.db[portage.root]["vartree"].dbapi |
93 |
+ and its inverse which has structure |
94 |
|
95 |
- library2soname = {} |
96 |
- soname2library = {} |
97 |
+ { (soname, abi) : full_path_to_library, ... } |
98 |
+ """ |
99 |
|
100 |
- for pkg in vardb.cpv_all(): |
101 |
- needs = vardb.aux_get(pkg, ['NEEDED.ELF.2'])[0].strip() |
102 |
- if not needs: #skip empty lines |
103 |
- continue |
104 |
- lines = re.split('\n', needs) |
105 |
- for line in lines: |
106 |
- link = re.split(';', line) |
107 |
- abi = link[0] |
108 |
- elf = link[1] |
109 |
- soname = link[2] |
110 |
- if soname: #no soname => executable |
111 |
- library2soname[elf] = (soname,abi) |
112 |
- soname2library[(soname,abi)] = elf |
113 |
+ vardb = portage.db[portage.root]["vartree"].dbapi |
114 |
|
115 |
- return ( library2soname, soname2library ) |
116 |
+ library2soname = {} |
117 |
+ soname2library = {} |
118 |
|
119 |
+ for pkg in vardb.cpv_all(): |
120 |
+ needs = vardb.aux_get(pkg, ['NEEDED.ELF.2'])[0].strip() |
121 |
+ if not needs: #skip empty lines |
122 |
+ continue |
123 |
+ lines = re.split('\n', needs) |
124 |
+ for line in lines: |
125 |
+ link = re.split(';', line) |
126 |
+ abi = link[0] |
127 |
+ elf = link[1] |
128 |
+ soname = link[2] |
129 |
+ if soname: #no soname => executable |
130 |
+ library2soname[elf] = (soname,abi) |
131 |
+ soname2library[(soname,abi)] = elf |
132 |
|
133 |
-""" |
134 |
-Return soname_needed dictionary which has structure: |
135 |
+ return ( library2soname, soname2library ) |
136 |
|
137 |
- { |
138 |
- abi1: { soname: [ soname1, soname2, ... ], .... }, |
139 |
- abi2: { soname: [ soname1, soname2, ... ], .... }, |
140 |
- } |
141 |
|
142 |
-Here the soname1, soname2,... were obtained from soname's corresponding |
143 |
-ELF object by scanelf -n during emerge. |
144 |
-""" |
145 |
def get_soname_needed( object_needed, library2soname ): |
146 |
+ """ Return soname_needed dictionary which has structure: |
147 |
|
148 |
- soname_needed = {} |
149 |
+ { |
150 |
+ abi1: { soname: [ soname1, soname2, ... ], .... }, |
151 |
+ abi2: { soname: [ soname1, soname2, ... ], .... }, |
152 |
+ } |
153 |
|
154 |
- for abi in object_needed: |
155 |
- for elf in object_needed[abi]: |
156 |
- try: |
157 |
- (soname, abi_check) = library2soname[elf] |
158 |
- if abi != abi_check: |
159 |
- print("This should never happen!") |
160 |
- sys.exit(1) |
161 |
- soname_needed.setdefault(abi,{}).update({soname:object_needed[abi][elf]}) |
162 |
- except KeyError: |
163 |
- continue # no soname, its probably an executable |
164 |
+ Here the soname1, soname2,... were obtained from soname's corresponding |
165 |
+ ELF object by scanelf -n during emerge. |
166 |
+ """ |
167 |
|
168 |
- return soname_needed |
169 |
+ soname_needed = {} |
170 |
|
171 |
+ for abi in object_needed: |
172 |
+ for elf in object_needed[abi]: |
173 |
+ try: |
174 |
+ (soname, abi_check) = library2soname[elf] |
175 |
+ if abi != abi_check: |
176 |
+ print('This should never happen!') |
177 |
+ sys.exit(1) |
178 |
+ soname_needed.setdefault(abi,{}).update({soname:object_needed[abi][elf]}) |
179 |
+ except KeyError: |
180 |
+ continue # no soname, its probably an executable |
181 |
|
182 |
-""" |
183 |
-Expands the object_needed dictionary which has structure |
184 |
+ return soname_needed |
185 |
|
186 |
- { |
187 |
- abi1 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... }, |
188 |
- abi2 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... }, |
189 |
- .... |
190 |
- } |
191 |
|
192 |
-such that the soname's are traced all the way to the end of |
193 |
-the link chain. Here the sonames should be the same as those |
194 |
-obtained from the ELF object by ldd. |
195 |
-""" |
196 |
def expand_linkings( object_needed, soname2library ): |
197 |
- |
198 |
- for abi in object_needed: |
199 |
- for elf in object_needed[abi]: |
200 |
- while True: |
201 |
- found_new_soname = False |
202 |
- for so in object_needed[abi][elf]: # For all the first links ... |
203 |
- try: |
204 |
- for sn in object_needed[abi][soname2library[(so,abi)]]: # go to the next links ... |
205 |
- if sn in object_needed[abi][elf]: # skip if already included ... |
206 |
- continue |
207 |
- if not (sn,abi) in soname2library: # skip if vdso ... |
208 |
- continue |
209 |
- # This appends to the object_needed |
210 |
- # and soname_needed lists. No copy |
211 |
- # was done so its the same lists in |
212 |
- # memory for both, and its modified |
213 |
- # for both. |
214 |
- object_needed[abi][elf].append(sn) # otherwise collapse it back into |
215 |
- found_new_soname = True # first links of the chain. |
216 |
- |
217 |
- except KeyError: # Not all nodes in the chain have a next node |
218 |
- continue |
219 |
- |
220 |
- if not found_new_soname: # We're done, that last iteration found |
221 |
- break # no new nodes |
222 |
+ """ Expands the object_needed dictionary which has structure |
223 |
+ |
224 |
+ { |
225 |
+ abi1 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... }, |
226 |
+ abi2 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... }, |
227 |
+ .... |
228 |
+ } |
229 |
+ |
230 |
+ such that the soname's are traced all the way to the end of |
231 |
+ the link chain. Here the sonames should be the same as those |
232 |
+ obtained from the ELF object by ldd. |
233 |
+ """ |
234 |
+ |
235 |
+ for abi in object_needed: |
236 |
+ for elf in object_needed[abi]: |
237 |
+ while True: |
238 |
+ found_new_soname = False |
239 |
+ for so in object_needed[abi][elf]: # For all the first links ... |
240 |
+ try: |
241 |
+ for sn in object_needed[abi][soname2library[(so,abi)]]: # go to the next links ... |
242 |
+ if sn in object_needed[abi][elf]: # skip if already included ... |
243 |
+ continue |
244 |
+ if not (sn,abi) in soname2library: # skip if vdso ... |
245 |
+ continue |
246 |
+ # This appends to the object_needed |
247 |
+ # and soname_needed lists. No copy |
248 |
+ # was done so its the same lists in |
249 |
+ # memory for both, and its modified |
250 |
+ # for both. |
251 |
+ object_needed[abi][elf].append(sn) # otherwise collapse it back into |
252 |
+ found_new_soname = True # first links of the chain. |
253 |
+ |
254 |
+ except KeyError: # Not all nodes in the chain have a next node |
255 |
+ continue |
256 |
+ |
257 |
+ if not found_new_soname: # We're done, that last iteration found |
258 |
+ break # no new nodes |
259 |
|
260 |
|
261 |
def get_object_reverse_linkings( object_linkings ): |
262 |
- object_reverse_linkings = {} |
263 |
+ object_reverse_linkings = {} |
264 |
|
265 |
- for abi in object_linkings: |
266 |
- for elf in object_linkings[abi]: |
267 |
- for soname in object_linkings[abi][elf]: |
268 |
- object_reverse_linkings.setdefault(abi,{}).setdefault(soname,[]).append(elf) |
269 |
+ for abi in object_linkings: |
270 |
+ for elf in object_linkings[abi]: |
271 |
+ for soname in object_linkings[abi][elf]: |
272 |
+ object_reverse_linkings.setdefault(abi,{}).setdefault(soname,[]).append(elf) |
273 |
|
274 |
- return object_reverse_linkings |
275 |
+ return object_reverse_linkings |
276 |
|
277 |
|
278 |
def main(): |
279 |
|
280 |
- # Run as root to be able to real all files |
281 |
- uid = os.getuid() |
282 |
- if uid != 0: |
283 |
- print('RUN AS ROOT: cannot read all flags') |
284 |
- sys.exit(0) |
285 |
- |
286 |
- object_needed = get_object_needed() |
287 |
- ( library2soname, soname2library ) = get_libraries() |
288 |
- soname_needed = get_soname_needed( object_needed, library2soname ) |
289 |
- |
290 |
- # After the appending to needed in expand_linkings(), forward_needed |
291 |
- # and soname_needed have been extended through the entire chain of linking. |
292 |
- # If we want to keep only the object_needed and soname_needed, then do |
293 |
- # a copy before calling expand_linkings(). |
294 |
- expand_linkings( soname_needed, soname2library ) |
295 |
- |
296 |
- object_linkings = object_needed |
297 |
- object_needed = None |
298 |
- |
299 |
- soname_linkings = soname_needed |
300 |
- soname_needed = None |
301 |
- |
302 |
- object_reverse_linkings = get_object_reverse_linkings( object_linkings ) |
303 |
- |
304 |
- """ Print out all ELF objects and the NEEDED sonames and full library paths """ |
305 |
- for abi in object_linkings: |
306 |
- for elf in object_linkings[abi]: |
307 |
- sonames = object_linkings[abi][elf] |
308 |
- print("%s: %s" % (abi,elf)) |
309 |
- for soname in sorted(object_linkings[abi][elf]): |
310 |
- try: |
311 |
- print("\t%s\t=> %s" % (soname, soname2library[(soname,abi)])) |
312 |
- except KeyError: |
313 |
- print("\t%s\t=> %s " % (soname, '***')) |
314 |
- print("\n\n") |
315 |
- |
316 |
- """ Print out all ELF objects and the NEEDED sonames and full library paths """ |
317 |
- for abi in object_linkings: |
318 |
- for soname in object_reverse_linkings[abi]: |
319 |
- try: |
320 |
- print("%s: %s\t=> %s" % (abi, soname, soname2library[(soname,abi)])) |
321 |
- except KeyError: |
322 |
- print("%s: %s\t=>%s " % (abi, soname, '***')) |
323 |
- for elf in sorted(object_reverse_linkings[abi][soname]): |
324 |
- print("\t%s" % elf) |
325 |
- print("\n\n") |
326 |
+ # Run as root to be able to real all files |
327 |
+ uid = os.getuid() |
328 |
+ if uid != 0: |
329 |
+ print('RUN AS ROOT: cannot read all flags') |
330 |
+ sys.exit(0) |
331 |
+ |
332 |
+ object_needed = get_object_needed() |
333 |
+ ( library2soname, soname2library ) = get_libraries() |
334 |
+ soname_needed = get_soname_needed( object_needed, library2soname ) |
335 |
+ |
336 |
+ # After the appending to needed in expand_linkings(), forward_needed |
337 |
+ # and soname_needed have been extended through the entire chain of linking. |
338 |
+ # If we want to keep only the object_needed and soname_needed, then do |
339 |
+ # a copy before calling expand_linkings(). |
340 |
+ expand_linkings( soname_needed, soname2library ) |
341 |
+ |
342 |
+ object_linkings = object_needed |
343 |
+ object_needed = None |
344 |
+ |
345 |
+ soname_linkings = soname_needed |
346 |
+ soname_needed = None |
347 |
+ |
348 |
+ object_reverse_linkings = get_object_reverse_linkings( object_linkings ) |
349 |
+ |
350 |
+ layout = "{0:<30} => {1:<30}" |
351 |
+ |
352 |
+ """ Print out all ELF objects and the NEEDED sonames and full library paths """ |
353 |
+ for abi in object_linkings: |
354 |
+ for elf in object_linkings[abi]: |
355 |
+ sonames = object_linkings[abi][elf] |
356 |
+ print('%s: %s' % (abi,elf)) |
357 |
+ for soname in sorted(object_linkings[abi][elf]): |
358 |
+ try: |
359 |
+ print('\t%s' % layout.format(soname, soname2library[(soname,abi)])) |
360 |
+ except KeyError: |
361 |
+ print('\t%s' % layout.format(soname, '***' )) |
362 |
+ print('') |
363 |
+ |
364 |
+ """ Print out all ELF objects and the NEEDED sonames and full library paths """ |
365 |
+ for abi in object_linkings: |
366 |
+ for soname in object_reverse_linkings[abi]: |
367 |
+ try: |
368 |
+ print('%s: %s' % (abi, layout.format(soname, soname2library[(soname,abi)]))) |
369 |
+ except KeyError: |
370 |
+ print('%s: %s' % (abi, layout.format(soname, '***' ))) |
371 |
+ for elf in sorted(object_reverse_linkings[abi][soname]): |
372 |
+ print('\t%s' % elf) |
373 |
+ print('') |
374 |
|
375 |
|
376 |
if __name__ == '__main__': |
377 |
- main() |
378 |
+ main() |