1 |
vapier 14/07/30 04:34:09 |
2 |
|
3 |
Modified: lddtree.py |
4 |
Log: |
5 |
lddtree.py: when searching for libs, make sure we resolve symlinks inside the root before checking if they exist |
6 |
|
7 |
Revision Changes Path |
8 |
1.49 pax-utils/lddtree.py |
9 |
|
10 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/pax-utils/lddtree.py?rev=1.49&view=markup |
11 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/pax-utils/lddtree.py?rev=1.49&content-type=text/plain |
12 |
diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/pax-utils/lddtree.py?r1=1.48&r2=1.49 |
13 |
|
14 |
Index: lddtree.py |
15 |
=================================================================== |
16 |
RCS file: /var/cvsroot/gentoo-projects/pax-utils/lddtree.py,v |
17 |
retrieving revision 1.48 |
18 |
retrieving revision 1.49 |
19 |
diff -u -r1.48 -r1.49 |
20 |
--- lddtree.py 30 Jul 2014 04:28:41 -0000 1.48 |
21 |
+++ lddtree.py 30 Jul 2014 04:34:09 -0000 1.49 |
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.48 2014/07/30 04:28:41 vapier Exp $ |
27 |
+# $Header: /var/cvsroot/gentoo-projects/pax-utils/lddtree.py,v 1.49 2014/07/30 04:34:09 vapier Exp $ |
28 |
|
29 |
# TODO: Handle symlinks. |
30 |
|
31 |
@@ -60,6 +60,30 @@ |
32 |
return os.path.normpath(path).replace('//', '/') |
33 |
|
34 |
|
35 |
+def readlink(path, root, prefixed=False): |
36 |
+ """Like os.readlink(), but relative to a |root| |
37 |
+ |
38 |
+ Args: |
39 |
+ path: The symlink to read |
40 |
+ root: The path to use for resolving absolute symlinks |
41 |
+ prefixed: When False, the |path| must not have |root| prefixed to it, nor |
42 |
+ will the return value have |root| prefixed. When True, |path| |
43 |
+ must have |root| prefixed, and the return value will have |root| |
44 |
+ added. |
45 |
+ |
46 |
+ Returns: |
47 |
+ A fully resolved symlink path |
48 |
+ """ |
49 |
+ root = root.rstrip('/') |
50 |
+ if prefixed: |
51 |
+ path = path[len(root):] |
52 |
+ |
53 |
+ while os.path.islink(root + path): |
54 |
+ path = os.path.join(os.path.dirname(path), os.readlink(root + path)) |
55 |
+ |
56 |
+ return (root + path) if prefixed else path |
57 |
+ |
58 |
+ |
59 |
def makedirs(path): |
60 |
"""Like os.makedirs(), but ignore EEXIST errors""" |
61 |
try: |
62 |
@@ -249,27 +273,36 @@ |
63 |
elf1.header['e_machine'] == elf2.header['e_machine']) |
64 |
|
65 |
|
66 |
-def FindLib(elf, lib, ldpaths, debug=False): |
67 |
+def FindLib(elf, lib, ldpaths, root='/', debug=False): |
68 |
"""Try to locate a |lib| that is compatible to |elf| in the given |ldpaths| |
69 |
|
70 |
Args: |
71 |
elf: The elf which the library should be compatible with (ELF wise) |
72 |
lib: The library (basename) to search for |
73 |
ldpaths: A list of paths to search |
74 |
+ root: The root path to resolve symlinks |
75 |
debug: Enable debug output |
76 |
|
77 |
Returns: |
78 |
the full path to the desired library |
79 |
""" |
80 |
dbg(debug, ' FindLib(%s)' % lib) |
81 |
+ |
82 |
for ldpath in ldpaths: |
83 |
path = os.path.join(ldpath, lib) |
84 |
- dbg(debug, ' checking:', path) |
85 |
+ target = readlink(path, root, prefixed=True) |
86 |
+ if path != target: |
87 |
+ dbg(debug, ' checking: %s -> %s' % (path, target)) |
88 |
+ path = target |
89 |
+ else: |
90 |
+ dbg(debug, ' checking:', path) |
91 |
+ |
92 |
if os.path.exists(path): |
93 |
with open(path, 'rb') as f: |
94 |
libelf = ELFFile(f) |
95 |
if CompatibleELFs(elf, libelf): |
96 |
return path |
97 |
+ |
98 |
return None |
99 |
|
100 |
|
101 |
@@ -383,7 +416,7 @@ |
102 |
continue |
103 |
if all_ldpaths is None: |
104 |
all_ldpaths = rpaths + ldpaths['rpath'] + ldpaths['env'] + runpaths + ldpaths['runpath'] + ldpaths['conf'] + ldpaths['interp'] |
105 |
- fullpath = FindLib(elf, lib, all_ldpaths, debug=debug) |
106 |
+ fullpath = FindLib(elf, lib, all_ldpaths, root, debug=debug) |
107 |
_all_libs[lib] = { |
108 |
'path': fullpath, |
109 |
'needed': [], |
110 |
@@ -402,7 +435,7 @@ |
111 |
|
112 |
|
113 |
def _ShowVersion(_option, _opt, _value, _parser): |
114 |
- d = '$Id: lddtree.py,v 1.48 2014/07/30 04:28:41 vapier Exp $'.split() |
115 |
+ d = '$Id: lddtree.py,v 1.49 2014/07/30 04:34:09 vapier Exp $'.split() |
116 |
print('%s-%s %s %s' % (d[1].split('.')[0], d[2], d[3], d[4])) |
117 |
sys.exit(0) |