#!/usr/bin/python
# Copyright 2012 Gentoo Foundation
# Copyright 2012 Mike Frysinger <vapier@gentoo.org>
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-projects/pax-utils/lddtree.py,v 1.16 2012/11/26 20:06:54 vapier Exp $

"""Read the ELF dependency tree and show it

This does not work like `ldd` in that we do not execute/load code (only read
files on disk), and we should the ELFs as a tree rather than a flat list.
"""

from __future__ import print_function

import glob
import errno
import optparse
import os
import shutil
import sys

from elftools.elf.elffile import ELFFile
from elftools.common import exceptions


def warn(msg, prefix='warning'):
	"""Write |msg| to stderr with a |prefix| before it"""
	print('%s: %s: %s' % (sys.argv[0], prefix, msg), file=sys.stderr)


def err(msg, status=1):
	"""Write |msg| to stderr and exit with |status|"""
	warn(msg, prefix='error')
	sys.exit(status)


def normpath(path):
	"""Normalize a path

	Python's os.path.normpath() doesn't handle some cases:
		// -> //
		//..// -> //
		//..//..// -> ///
	"""
	return os.path.normpath(path).replace('//', '/')


def dedupe(input):
	"""Remove all duplicates from input (keeping order)"""
	seen = {}
	return [seen.setdefault(x, x) for x in input if x not in seen]


def ParseLdPaths(str_ldpaths, root='', path=None):
	"""Parse the colon-delimited list of paths and apply ldso rules to each

	Note the special handling as dictated by the ldso:
	 - Empty paths are equivalent to $PWD
	 - $ORIGIN is expanded to the path of the given file
	 - (TODO) $LIB and friends

	Args:
	  str_ldpath: A colon-delimited string of paths
	  root: The path to prepend to all paths found
	Returns:
	  list of processed paths
	"""
	ldpaths = []
	for ldpath in str_ldpaths.split(':'):
		if ldpath == '':
			# The ldso treats "" paths as $PWD.
			ldpath = os.getcwd()
		else:
			ldpath = ldpath.replace('$ORIGIN', os.path.dirname(path))
		ldpaths.append(normpath(root + ldpath))
	return dedupe(ldpaths)


def ParseLdSoConf(ldso_conf, root='/', _first=True):
	"""Load all the paths from a given ldso config file

	This should handle comments, whitespace, and "include" statements.

	Args:
	  ldso_conf: The file to scan
	  root: The path to prepend to all paths found
	  _first: Recursive use only; is this the first ELF ?
	Returns:
	  list of paths found
	"""
	paths = []

	try:
		with open(ldso_conf) as f:
			for line in f.readlines():
				line = line.split('#', 1)[0].strip()
				if not line:
					continue
				if line.startswith('include '):
					line = line[8:]
					if line[0] == '/':
						line = root + line.lstrip('/')
					else:
						line = os.path.dirname(ldso_conf) + '/' + line
					for path in glob.glob(line):
						paths += ParseLdSoConf(path, root=root, _first=False)
				else:
					paths += [normpath(root + line)]
	except IOError as e:
		if e.errno != errno.ENOENT:
			warn(e)

	if _first:
		# XXX: Load paths from ldso itself.
		# Remove duplicate entries to speed things up.
		paths = dedupe(paths)

	return paths


def LoadLdpaths(root='/'):
	"""Load linker paths from common locations

	This parses the ld.so.conf and LD_LIBRARY_PATH env var.

	Args:
	  root: The root tree to prepend to paths
	Returns:
	  dict containing library paths to search
	"""
	ldpaths = {
		'conf': [],
		'env': [],
		'interp': [],
	}

	# Load up $LD_LIBRARY_PATH.
	ldpaths['env'] = []
	env_ldpath = os.environ.get('LD_LIBRARY_PATH')
	if not env_ldpath is None:
		if root != '/':
			warn('ignoring LD_LIBRARY_PATH due to ROOT usage')
		else:
			# XXX: If this contains $ORIGIN, we probably have to parse this
			# on a per-ELF basis so it can get turned into the right thing.
			ldpaths['env'] = ParseLdPaths(env_ldpath, path='')

	# Load up /etc/ld.so.conf.
	ldpaths['conf'] = ParseLdSoConf(root + 'etc/ld.so.conf', root=root)

	return ldpaths


def CompatibleELFs(elf1, elf2):
	"""See if two ELFs are compatible

	This compares the aspects of the ELF to see if they're compatible:
	bit size, endianness, machine type, and operating system.

	Args:
	  elf1: an ELFFile object
	  elf2: an ELFFile object
	Returns:
	  True if compatible, False otherwise
	"""
	osabis = frozenset([e.header['e_ident']['EI_OSABI'] for e in (elf1, elf2)])
	compat_sets = (
		frozenset(['ELFOSABI_NONE', 'ELFOSABI_SYSV', 'ELFOSABI_LINUX']),
	)
	return ((len(osabis) == 1 or any(osabis.issubset(x) for x in compat_sets)) and
		elf1.elfclass == elf2.elfclass and
		elf1.little_endian == elf2.little_endian and
		elf1.header['e_machine'] == elf2.header['e_machine'])


def FindLib(elf, lib, ldpaths):
	"""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
	Returns:
	  the full path to the desired library
	"""
	for ldpath in ldpaths:
		path = os.path.join(ldpath, lib)
		if os.path.exists(path):
			with open(path) as f:
				libelf = ELFFile(f)
				if CompatibleELFs(elf, libelf):
					return path
	return None


def ParseELF(path, root='/', ldpaths={'conf':[], 'env':[], 'interp':[]},
             _first=True, _all_libs={}):
	"""Parse the ELF dependency tree of the specified file

	Args:
	  path: The ELF to scan
	  root: The root tree to prepend to paths; this applies to interp and rpaths
	        only as |path| and |ldpaths| are expected to be prefixed already
	  ldpaths: dict containing library paths to search; should have the keys:
	           conf, env, interp
	  _first: Recursive use only; is this the first ELF ?
	  _all_libs: Recursive use only; dict of all libs we've seen
	Returns:
	  a dict containing information about all the ELFs; e.g.
		{
			'interp': '/lib64/ld-linux.so.2',
			'needed': ['libc.so.6', 'libcurl.so.4',],
			'libs': {
				'libc.so.6': {
					'path': '/lib64/libc.so.6',
					'needed': [],
				},
				'libcurl.so.4': {
					'path': '/usr/lib64/libcurl.so.4',
					'needed': ['libc.so.6', 'librt.so.1',],
				},
			},
		}
	"""
	if _first:
		_all_libs = {}
	ret = {
		'interp': None,
		'path': path,
		'needed': [],
		'libs': _all_libs,
	}

	with open(path) as f:
		elf = ELFFile(f)

		# If this is the first ELF, extract the interpreter.
		if _first:
			for segment in elf.iter_segments():
				if segment.header.p_type != 'PT_INTERP':
					continue

				interp = segment.get_interp_name()
				ret['interp'] = normpath(root + interp)
				ret['libs'][os.path.basename(interp)] = {
					'path': ret['interp'],
					'needed': [],
				}
				# XXX: Should read it and scan for /lib paths.
				ldpaths['interp'] = [
					normpath(root + os.path.dirname(interp)),
					normpath(root + '/usr' + os.path.dirname(interp)),
				]
				break

		# Parse the ELF's dynamic tags.
		libs = []
		rpaths = []
		runpaths = []
		for segment in elf.iter_segments():
			if segment.header.p_type != 'PT_DYNAMIC':
				continue

			for t in segment.iter_tags():
				if t.entry.d_tag == 'DT_RPATH':
					rpaths = ParseLdPaths(t.rpath, root=root, path=path)
				elif t.entry.d_tag == 'DT_RUNPATH':
					runpaths = ParseLdPaths(t.runpath, root=root, path=path)
				elif t.entry.d_tag == 'DT_NEEDED':
					libs.append(t.needed)
			if runpaths:
				# If both RPATH and RUNPATH are set, only the latter is used.
				rpath = []

			break
		ret['needed'] = libs

		# Search for the libs this ELF uses.
		all_ldpaths = None
		for lib in libs:
			if lib in _all_libs:
				continue
			if all_ldpaths is None:
				all_ldpaths = rpaths + ldpaths['env'] + runpaths + ldpaths['conf'] + ldpaths['interp']
			fullpath = FindLib(elf, lib, all_ldpaths)
			_all_libs[lib] = {
				'path': fullpath,
				'needed': [],
			}
			if fullpath:
				lret = ParseELF(fullpath, root, ldpaths, False, _all_libs)
				_all_libs[lib]['needed'] = lret['needed']

		del elf

	return ret


def _NormalizePath(option, _opt, value, parser):
	setattr(parser.values, option.dest, normpath(value))


def _ShowVersion(_option, _opt, _value, _parser):
	id = '$Id: lddtree.py,v 1.16 2012/11/26 20:06:54 vapier Exp $'.split()
	print('%s-%s %s %s' % (id[1].split('.')[0], id[2], id[3], id[4]))
	sys.exit(0)


def _ActionShow(options, elf):
	"""Show the dependency tree for this ELF"""
	def _show(lib, depth):
		chain_libs.append(lib)
		fullpath = elf['libs'][lib]['path']
		if options.list:
			print(fullpath or lib)
		else:
			print('%s%s => %s' % ('    ' * depth, lib, fullpath))

		new_libs = []
		for lib in elf['libs'][lib]['needed']:
			if lib in chain_libs:
				if not options.list:
					print('%s%s => !!! circular loop !!!' % ('    ' * depth, lib))
				continue
			if options.all or not lib in shown_libs:
				shown_libs.add(lib)
				new_libs.append(lib)

		for lib in new_libs:
			_show(lib, depth + 1)
		chain_libs.pop()

	shown_libs = set(elf['needed'])
	chain_libs = []
	interp = elf['interp']
	if interp:
		shown_libs.add(os.path.basename(interp))
	if options.list:
		print(elf['path'])
		if not interp is None:
			print(interp)
	else:
		print('%s (interpreter => %s)' % (elf['path'], interp))
	for lib in elf['needed']:
		_show(lib, 1)


def _ActionCopy(options, elf):
	"""Copy the ELF and its dependencies to a destination tree"""
	def _copy(src):
		if src is None:
			return

		dst = options.dest + src
		if os.path.exists(dst):
			# See if they're the same file.
			ostat = os.stat(src)
			nstat = os.stat(dst)
			for field in ('mode', 'mtime', 'size'):
				if getattr(ostat, 'st_' + field) != \
				   getattr(nstat, 'st_' + field):
					break
			else:
				return

		if options.verbose:
			print('%s -> %s' % (src, dst))

		try:
			os.makedirs(os.path.dirname(dst))
		except OSError as e:
			if e.errno != os.errno.EEXIST:
				raise
		try:
			shutil.copy2(src, dst)
			return
		except IOError:
			os.unlink(dst)
		shutil.copy2(src, dst)

	_copy(elf['path'])
	_copy(elf['interp'])
	for lib in elf['libs']:
		_copy(elf['libs'][lib]['path'])


def main(argv):
	parser = optparse.OptionParser("""%prog [options] <ELFs>

Display ELF dependencies as a tree""")
	parser.add_option('-a', '--all',
		action='store_true', default=False,
		help=('Show all duplicated dependencies'))
	parser.add_option('-R', '--root',
		dest='root', default=os.environ.get('ROOT', ''), type='string',
		action='callback', callback=_NormalizePath,
		help=('Show all duplicated dependencies'))
	parser.add_option('--copy-to-tree',
		dest='dest', default=None, type='string',
		action='callback', callback=_NormalizePath,
		help=('Copy all files to the specified tree'))
	parser.add_option('-l', '--list',
		action='store_true', default=False,
		help=('Display output in a simple list (easy for copying)'))
	parser.add_option('-x', '--debug',
		action='store_true', default=False,
		help=('Run with debugging'))
	parser.add_option('-v', '--verbose',
		action='store_true', default=False,
		help=('Be verbose'))
	parser.add_option('-V', '--version',
		action='callback', callback=_ShowVersion,
		help=('Show version information'))
	(options, paths) = parser.parse_args(argv)

	# Throw away argv[0].
	paths.pop(0)
	if options.root != '/':
		options.root += '/'

	if options.debug:
		print('root =', options.root)
		if options.dest:
			print('dest =', options.dest)
	if not paths:
		err('missing ELF files to scan')

	ldpaths = LoadLdpaths(options.root)
	if options.debug:
		print('ldpaths[conf] =', ldpaths['conf'])
		print('ldpaths[env]  =', ldpaths['env'])

	# Process all the files specified.
	ret = 0
	for path in paths:
		try:
			elf = ParseELF(path, options.root, ldpaths)
		except (exceptions.ELFError, IOError) as e:
			ret = 1
			warn('%s: %s' % (path, e))
			continue
		if options.dest is None:
			_ActionShow(options, elf)
		else:
			_ActionCopy(options, elf)
	return ret


if __name__ == '__main__':
	sys.exit(main(sys.argv))
