#!/usr/bin/env python3.8
# Copyright 2020 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Verify the content of ELF binaries embedded in a package or filesystem.
This scripts takes as input a FINI manifest file and on success, will write
an empty stamp file.
"""

# System imports
import argparse
import os
import sys

# elfinfo is in //build/images/ while this script is in //build/dist/.
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'images'))
import elfinfo

from typing import Any, Iterable, List, Set, Dict, Tuple, Optional

# The general strategy for checking the ELF binaries within a package is
# the following:
#
# 1) libzircon.so should never appear inside a Fuchsia package, since
#    it is injected by the kernel into user processes at runtime. Its
#    presence in a manifest is a build error.
#
#    On the other hand, it will be listed as a dependency for most
#    binaries, but not necessarily all of them, and should be ignored
#    when that happens.
#
# 2) ld.so.1 is the dynamic loader and also serves as the C library,
#    which means any DT_NEEDED reference to libc.so is automatically
#    resolved at runtime to ld.so.1 instead.
#
#    It is thus a build error to have libc.so inside a Fuchsia package,
#    because the dynamic loader will never load these files!
#
# 3) ELF executables have a PT_INTERP section that will contain 'ld.so.1'
#    for Fuchsia regular binaries, and '<variant>/ld.so.1' for those built
#    with an instrumented variant (e.g. 'asan'). The library loader will
#    search for DT_NEEDED dependencies in '/lib' in the first case,
#    and '/lib/<variant>' in the second case, so check that these are
#    properly located there, as well as their own dependencies.
#
#    For now, it is an error to have a different PT_INTERP value, but
#    this may be relaxed in the future, for example to package Linux
#    and Android executables to be run inside Fuchsia containers.
#
# 4) Loadable modules are ELF shared libraries that are loaded at runtime
#    by binaries (or the Vulkan loader service) through dlopen(), these
#    can be located anywhere in the package. They may have DT_NEEDED
#    dependencies which will be looked up at runtime in the loading
#    executable's own library directory (i.e. '/lib' or '/lib/<variant>').
#
#    Because our build system is flexible enough to group regular and
#    instrumented executables in the same package, there is no 100%
#    fool-proof way to know which executable will load the module.
#
#    Moreover, one package can even contain a standalone module, without
#    its own dependencies, to be loaded from another package's component
#    which would provide them at runtime. This can happen for driver
#    modules for example.
#
#    Due to this, there is no attempt here to verify the dependencies
#    of modules, since doing so can only be performed with heuristics
#    that will fail at some point
#
# 5) Ignore files under data/, meta/ and lib/firmware, as they could be
#    any ELF binaries for non-Fuchsia systems, or for testing.
#
# 6) Verify that debug (unstripped) files for binaries are provided
#    in the build root directory, or toolchain-specific lib directories.
#    Missing entries just generate a WARNING, but are not an error
#    because they do happen in practice (e.g. for prebuilt driver
#    binaries), though are quite rare.
#


def rewrite_elf_needed(dep: str) -> Optional[str]:
    """Rewrite a DT_NEEDED dependency name.

  Args:
    dep: dependency name as it appears in ELF DT_NEEDED entry (e.g. 'libc.so')
  Returns:
    None if the dependency should be ignored, or the input dependency name,
    possibly rewritten for specific cases (e.g. 'libc.so' -> 'ld.so.1')
  """
    if dep == 'libzircon.so':
        # libzircon.so being injected by the kernel into user processes, it should
        # not appear in Fuchsia packages, and thus should be ignored.
        return None
    if dep == 'libc.so':
        # ld.so.1 acts as both the dynamic loader and C library, so any reference
        # to libc.so should be rewritten as 'ld.so.1'
        return 'ld.so.1'

    # For all other cases, just return the unmodified dependency name.
    return dep


def verify_elf_dependencies(
        binary: str, lib_dir: str, deps: Iterable[str],
        elf_entries: Dict[str, Any]) -> Tuple[List[str], List[str]]:
    """Verify the ELF dependencies of a given ELF binary.

  Args:
    binary: Name of the binary whose dependencies are verified.
    lib_dir: The target directory where all dependencies should be.
    deps: An iteration of dependency names, as they appear in DT_NEEDED
      entries.
    elf_entries: The global {target_path: elf_info} map.
  Returns:
    An (errors, libraries) tuple, where 'errors' is a list of error messages
    in case of failure, or an empty list on succcess, and 'libraries' is a
    list of libraries that were checked by this function.
  """
    # Note that we do allow circular dependencies because they do happen
    # in practice. In particular when generating instrumented binaries,
    # e.g. for the 'asan' case (omitting libzircon.so):
    #
    #     libc.so (a.k.a. ld.so.1)
    #       ^     ^         ^ |
    #       |     |         | v
    #       |     |    libclang_rt.asan.so
    #       |     |     | ^      ^
    #       |     |     v |      |
    #       |    libc++abi.so    |
    #       |     |              |
    #       |     v              |
    #     libunwind.so-----------'
    #
    errors = []
    libraries = []
    visited = set()
    queue = list(deps)
    while len(queue) > 0:
        dep = queue[0]
        queue = queue[1:]
        dep2 = rewrite_elf_needed(dep)
        if dep2 is None or dep2 in visited:
            continue
        visited.add(dep2)
        dep_target = os.path.join(lib_dir, dep2)
        info = elf_entries.get(dep_target)
        if not info:
            errors.append('%s missing dependency %s' % (binary, dep_target))
        else:
            libraries.append(dep_target)
            for subdep in info.needed:
                if subdep not in visited:
                    queue.append(subdep)

    return (errors, libraries)


def find_debug_file(
        filename: str,
        depfile_items: Set[str],
        toolchain_lib_dirs: List[str] = []) -> Optional[str]:
    """Find the debug version of a given ELF binary.

        Args:
          filename: input file path in build directory.
          toolchain_lib_dirs: a list of toolchain-specific lib directories
            which will be used to look for debug/.build-id/xx/xxxxxxx.debug
            files corresponding to the input files's build-id value.
          depfile_items: the set of examined files to be updated if needed.

        Returns
          Path to the debug file, if it exists, or None.
        """
    if os.path.exists(filename + '.debug'):
        # Zircon-specific toolchains currently write the debug files
        # for .../foo as .../foo.debug.
        debugfile = filename + '.debug'
    else:
        # Check for toolchain runtime libraries, which are stored under
        # {toolchain}/lib/.../libfoo.so, and whose unstripped file will
        # be under {toolchain}/lib/debug/.build-id/xx/xxxxxx.debug.
        lib_dir = None
        for dir in toolchain_lib_dirs:
            if os.path.realpath(filename).startswith(os.path.realpath(dir) +
                                                     os.sep):
                lib_dir = dir
                break
        if lib_dir:
            build_id_dir = os.path.join(lib_dir, 'debug', '.build-id')
            if not os.path.exists(build_id_dir):
                return None
            build_id = elfinfo.get_elf_info(filename).build_id
            # The build-id value is an hexadecimal string, used to locate the
            # debug file under debug/.build-id/XX/YYYYYY.debug where XX are its
            # first two chars, and YYYYYY is the rest (typically longer than
            # 6 chars).
            debugfile = os.path.join(
                build_id_dir, build_id[:2], build_id[2:] + '.debug')
            if not os.path.exists(debugfile):
                return None
            # Pass filename as fallback so we don't fallback to the build-id entry name.
            return debugfile
        else:
            # Otherwise, the Fuchsia build places unstripped files under
            # .../lib.unstripped/foo.so (for shared library or loadable module
            # .../foo.so) or .../exe.unstripped/bar (for executable .../bar).
            dir, file = os.path.split(filename)
            if file.endswith('.so') or '.so.' in file:
                subdir = 'lib.unstripped'
            else:
                subdir = 'exe.unstripped'
            debugfile = os.path.join(dir, subdir, file)
            while not os.path.exists(debugfile):
                # For dir/foo/bar, if dir/foo/exe.unstripped/bar
                # didn't exist, try dir/exe.unstripped/foo/bar.
                parent, dir = os.path.split(dir)
                if not parent or not dir:
                    return None
                dir, file = parent, os.path.join(dir, file)
                debugfile = os.path.join(dir, subdir, file)
            if not os.path.exists(debugfile):
                debugfile = os.path.join(subdir, filename)
                if not os.path.exists(debugfile):
                    return None
    depfile_items.add(debugfile)
    return debugfile


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        '--source-dir',
        default='.',
        help='Root directory for source paths. Default is current directory.')
    parser.add_argument(
        '--check-stripped',
        action='store_true',
        help='Verify that ELF binaries are stripped.')
    parser.add_argument(
        '--check-debug-files',
        action='store_true',
        help='Verify that each ELF binary has its own debug file available.' + \
             'this requires --toolchain-lib-dir to find toolchain-provided runtime debug files')
    parser.add_argument(
        '--toolchain-lib-dir',
        default=[],
        action='append',
        metavar='DIR',
        help=
        'Path to toolchain-provided lib directory. Can be used multiple times.')

    parser.add_argument(
        '--manifest', required=True, help='Input FINI manifest.')
    parser.add_argument('--stamp', required=True, help='Output stamp file.')
    parser.add_argument('--depfile', help='Output Ninja depfile.')

    args = parser.parse_args()

    # Read the input manifest into a {target: source} dictionary.
    manifest_entries = {}
    with open(args.manifest) as f:
        for line in f.readlines():
            line = line.rstrip()
            target, _, source = line.partition('=')
            assert source is not None, ('Invalid manifest line: [%s]' % line)

            source_file = os.path.join(args.source_dir, source)

            # Duplicate entries happen in some manifests, but they will have the
            # same content, so assert otherwise.
            if target in manifest_entries:
                assert manifest_entries[target] == source_file, (
                    'Duplicate entries for target "%s": %s vs %s' %
                    (target, source_file, manifest_entries[target]))

            assert os.path.exists(source_file), (
                'Missing source file for manifest line: %s' % line)
            manifest_entries[target] = source_file

    # Filter the input manifest entries to keep only the ELF ones
    # that are not under data/, lib/firmware/ or meta/
    depfile_items = set()
    elf_entries = {}
    for target, source_file in manifest_entries.items():
        if target.startswith('data/') or target.startswith(
                'lib/firmware/') or target.startswith('meta/'):
            continue

        depfile_items.add(source_file)
        info = elfinfo.get_elf_info(source_file)
        if info is not None:
            elf_entries[target] = info

    # errors contains a list of error strings corresponding to issues found in
    # the input manifest.
    #
    # extras contains non-error strings that are useful to dump when an error
    # occurs, and give more information about what was found in the manifest.
    # These should only be printed in case of errors, or ignored otherwise.
    errors = []
    extras = []

    # The set of all libraries visited when checking dependencies.
    visited_libraries = set()

    # Verify that libzircon.so or libc.so do not appear inside the package.
    for target, info in elf_entries.items():
        filename = os.path.basename(target)
        if filename in ('libzircon.so', 'libc.so'):
            errors.append(
                '%s should not be in this package (source=%s)!' %
                (target, info.filename))

    # First verify all executables, since we can find their library directory
    # from their PT_INTERP value, then check their dependencies recursively.
    for target, info in elf_entries.items():
        interp = info.interp
        if interp is None:
            continue

        interp_name = os.path.basename(interp)
        if interp_name != 'ld.so.1':
            errors.append(
                '%s has invalid or unsupported PT_INTERP value: %s' %
                (target, interp))
            continue

        lib_dir = os.path.join('lib', os.path.dirname(interp))
        extras.append(
            'Binary %s has interp %s, lib_dir %s' % (target, interp, lib_dir))

        binary_errors, binary_deps = verify_elf_dependencies(
            target, lib_dir, info.needed, elf_entries)

        errors += binary_errors
        visited_libraries.update(binary_deps)

    # Check that all binaries are stripped if necessary.
    if args.check_stripped:
        for target, info in elf_entries.items():
            if not info.stripped:
                errors.append(
                    '%s is not stripped: %s' % (target, info.filename))

    # Verify that all ELF files have their debug file available.
    # This is only a WARNING, not an error, since it can happen for
    # prebuilt drivers, or with Go binaries.
    if args.check_debug_files:
        for target, source_file in manifest_entries.items():
            if target in elf_entries:
                debugfile = find_debug_file(
                    source_file, depfile_items, args.toolchain_lib_dir)
                if debugfile is None:
                    print('WARNING: No debug file found for %s' % source_file)

    if errors:
        print(
            'ERRORS FOUND IN %s:\n%s' % (args.manifest, '\n'.join(errors)),
            file=sys.stderr)
        if extras:
            print('\n'.join(extras), file=sys.stderr)
        return 1

    if args.depfile:
        with open(args.depfile, 'w') as f:
            f.write(
                '%s: %s\n' % (args.manifest, ' '.join(sorted(depfile_items))))

    # Write the stamp file on success.
    with open(args.stamp, 'w') as f:
        f.write('')

    return 0


if __name__ == "__main__":
    sys.exit(main())
