vapier 14/07/30 04:34:09 Modified: lddtree.py Log: lddtree.py: when searching for libs, make sure we resolve symlinks inside the root before checking if they exist
Revision Changes Path 1.49 pax-utils/lddtree.py file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/pax-utils/lddtree.py?rev=1.49&view=markup plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/pax-utils/lddtree.py?rev=1.49&content-type=text/plain diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/pax-utils/lddtree.py?r1=1.48&r2=1.49 Index: lddtree.py =================================================================== RCS file: /var/cvsroot/gentoo-projects/pax-utils/lddtree.py,v retrieving revision 1.48 retrieving revision 1.49 diff -u -r1.48 -r1.49 --- lddtree.py 30 Jul 2014 04:28:41 -0000 1.48 +++ lddtree.py 30 Jul 2014 04:34:09 -0000 1.49 @@ -4,7 +4,7 @@ # Copyright 2012-2014 The Chromium OS Authors # Use of this source code is governed by a BSD-style license (BSD-3) # pylint: disable=C0301 -# $Header: /var/cvsroot/gentoo-projects/pax-utils/lddtree.py,v 1.48 2014/07/30 04:28:41 vapier Exp $ +# $Header: /var/cvsroot/gentoo-projects/pax-utils/lddtree.py,v 1.49 2014/07/30 04:34:09 vapier Exp $ # TODO: Handle symlinks. @@ -60,6 +60,30 @@ return os.path.normpath(path).replace('//', '/') +def readlink(path, root, prefixed=False): + """Like os.readlink(), but relative to a |root| + + Args: + path: The symlink to read + root: The path to use for resolving absolute symlinks + prefixed: When False, the |path| must not have |root| prefixed to it, nor + will the return value have |root| prefixed. When True, |path| + must have |root| prefixed, and the return value will have |root| + added. + + Returns: + A fully resolved symlink path + """ + root = root.rstrip('/') + if prefixed: + path = path[len(root):] + + while os.path.islink(root + path): + path = os.path.join(os.path.dirname(path), os.readlink(root + path)) + + return (root + path) if prefixed else path + + def makedirs(path): """Like os.makedirs(), but ignore EEXIST errors""" try: @@ -249,27 +273,36 @@ elf1.header['e_machine'] == elf2.header['e_machine']) -def FindLib(elf, lib, ldpaths, debug=False): +def FindLib(elf, lib, ldpaths, root='/', debug=False): """Try to locate a |lib| that is compatible to |elf| in the given |ldpaths| Args: elf: The elf which the library should be compatible with (ELF wise) lib: The library (basename) to search for ldpaths: A list of paths to search + root: The root path to resolve symlinks debug: Enable debug output Returns: the full path to the desired library """ dbg(debug, ' FindLib(%s)' % lib) + for ldpath in ldpaths: path = os.path.join(ldpath, lib) - dbg(debug, ' checking:', path) + target = readlink(path, root, prefixed=True) + if path != target: + dbg(debug, ' checking: %s -> %s' % (path, target)) + path = target + else: + dbg(debug, ' checking:', path) + if os.path.exists(path): with open(path, 'rb') as f: libelf = ELFFile(f) if CompatibleELFs(elf, libelf): return path + return None @@ -383,7 +416,7 @@ continue if all_ldpaths is None: all_ldpaths = rpaths + ldpaths['rpath'] + ldpaths['env'] + runpaths + ldpaths['runpath'] + ldpaths['conf'] + ldpaths['interp'] - fullpath = FindLib(elf, lib, all_ldpaths, debug=debug) + fullpath = FindLib(elf, lib, all_ldpaths, root, debug=debug) _all_libs[lib] = { 'path': fullpath, 'needed': [], @@ -402,7 +435,7 @@ def _ShowVersion(_option, _opt, _value, _parser): - d = '$Id: lddtree.py,v 1.48 2014/07/30 04:28:41 vapier Exp $'.split() + d = '$Id: lddtree.py,v 1.49 2014/07/30 04:34:09 vapier Exp $'.split() print('%s-%s %s %s' % (d[1].split('.')[0], d[2], d[3], d[4])) sys.exit(0)
