#!/usr/bin/env fuchsia-vendored-python
# Copyright 2021 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.
"""
Script for checking that all vtables in an elf file are in rodata. This script
provides different "modes" for quick checking of different files/project
layouts.

Usage (append -h for details):

  # Check an individual file.
  $ ./scripts/clang/check-vtable-rodata.py file [filename]

  # Check all vtables in binaries provided by the fuchsia toolchain
  $ ./scripts/clang/check-vtable-rodata.py toolchain [toolchain_dir]

  # Check all vtables in binaries provided by an llvm multilib directory.
  $ ./scripts/clang/check-vtable-rodata.py multilib [multilib_dir]

  # Check all vtables in binaries provided in a fuchsia build directory.
  $ ./scripts/clang/check-vtable-rodata.py fuchsia [fuchsia_dir]

  # Exclude checking specific vtable symbols
  $ ./scripts/clang/check-vtable-rodata.py --exclude 'vtable for ...' file [filename]
"""

import argparse
import os.path
import platform
import subprocess
from pathlib import Path


class RawDescriptionDefaultArgsHelpFormatter(
    argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter
):
    pass


if platform.system() == "Darwin":
    target = "mac-x64"
elif platform.system() == "Linux":
    if platform.machine() == "x86_64":
        target = "linux-x64"
    elif platform.machine() == "aarch64":
        target = "linux-arm64"
    else:
        raise Exception(
            "Clang toolchain not provided for platform machine "
            + platform.machine()
        )

# Point to the readelf provided in the clang toolchain.
DEFAULT_READELF = (
    Path(__file__).parent.parent.parent
    / "prebuilt"
    / "third_party"
    / "clang"
    / target
    / "bin"
    / "llvm-readelf"
)


def is_elf_file(filename):
    """Check if a file is an ELF file."""
    with open(filename, "rb") as f:
        return f.read(4) == b"\x7fELF"


def is_elf_dso(filename, readelf):
    """Check if a file is an ELF shared library."""
    try:
        result = subprocess.check_output(
            [str(readelf), "-hW", filename], text=True
        )
    except subprocess.CalledProcessError:
        return False
    for line in result.split("\n"):
        parts = line.split()
        if not parts:
            continue

        if parts[0] == "Type:":
            type = parts[1]
            if type == "DYN":
                return True

    # Note that the readelf could fail here if the file could not have been parsed
    # by readelf in the first place.
    return False


def find_vtable_symbols(filename, readelf):
    """Collect a map of all symbols and their sections in an elf file."""
    symbols = {}

    # Lines will look like:
    #
    #   1: 0000000000000000     0 FUNC    GLOBAL DEFAULT   UND std::terminate()
    #
    # Which will have 8 parts unless the Name is not provided
    numparts = 8

    result = subprocess.check_output(
        [str(readelf), "-W", "--demangle", "--symbols", filename], text=True
    )
    for line in result.split("\n"):
        parts = line.split(maxsplit=numparts - 1)
        if len(parts) != numparts:
            continue

        symbol = parts[-1]
        section = parts[-2]
        if not section.isdigit():
            continue

        if not symbol.startswith("vtable for "):
            continue

        symbols[symbol.strip()] = int(section)

    return symbols


def parse_section(line):
    """Return a tuple of the section number and name in a line from
    `readelf -W --sections`. If one couldn't be parsed from here, return None.
    """
    numstart = None
    numend = None
    for i, c in enumerate(line):
        if numstart is None:
            if c == "[":
                numstart = i + 1
        elif numend is None:
            # Start parsing the number
            if c == "]":
                numend = i
                break

    if (numstart is None) or (numend is None):
        return None

    try:
        section_num = int(line[numstart:numend].strip())
    except ValueError:
        return None

    name = line[numend + 1 :].split(maxsplit=1)[0]
    if name == "NULL":
        assert section_num == 0, "Expected the null section to be 0"

    return section_num, name


def find_sections(filename, readelf):
    """Collect a map of all sections."""
    sections = []

    result = subprocess.check_output(
        [str(readelf), "-W", "--sections", filename], text=True
    )
    for line in result.split("\n"):
        result = parse_section(line)
        if result is None:
            continue

        section_num, name = result
        assert (
            len(sections) == section_num
        ), f"Expected '{name}' to correspond to section number {len(sections)} but is instead section number {section_num}"
        sections.append(name)

    assert sections, f"Found no sections for '{filename}'"
    return sections


def check_vtables_in_dso(filename, readelf, excludes, output):
    assert isinstance(excludes, set)
    print("Checking", filename, file=output)

    symbols = find_vtable_symbols(filename, readelf)
    print("Found {} vtables".format(len(symbols)), file=output)

    sections = find_sections(filename, readelf)
    print("Found {} sections".format(len(sections)), file=output)

    # Find the rodata section.
    for i, section in enumerate(sections):
        if section == ".rodata":
            rodata = i
            break
    else:
        print("Could not find rodata in ", sections, file=output)
        return

    bad_vtables = []
    for vtable, section in symbols.items():
        if section != rodata and vtable not in excludes:
            bad_vtables.append(vtable)

    assert (
        not bad_vtables
    ), f"Found vtables that aren't in rodata:\n{str(bad_vtables)}"
    print("All vtables are in rodata :)", file=output)


def check_vtables_in_file(filename, readelf, excludes, output):
    if is_elf_file(filename):
        # FIXME: We should also be checking executables.
        check_vtables_in_dso(filename, readelf, excludes, output)
    else:
        print(
            "WARN: Could not recognize ELF file type for",
            filename,
            file=sys.stderr,
        )


def check_vtables_in_dir(dirname, readelf, excludes, output):
    assert os.path.exists(dirname), "{} does not exist".format(dirname)
    for root, _, files in os.walk(dirname):
        for file in files:
            path = os.path.join(root, file)
            check_vtables_in_file(path, readelf, excludes, output)


def check_file_main(args):
    filename = args.filename
    excludes = set(args.exclude)

    if os.path.isfile(filename):
        check_vtables_in_file(filename, args.readelf, excludes, args.output)
    else:
        check_vtables_in_dir(filename, args.readelf, excludes, args.output)

    return 0


def check_toolchain_main(args):
    excludes = set(args.exclude)
    check_vtables_in_dir(
        os.path.join(args.toolchain_dir, "lib", "aarch64-unknown-fuchsia"),
        args.readelf,
        excludes,
        args.output,
    )
    check_vtables_in_dir(
        os.path.join(args.toolchain_dir, "lib", "x86_64-unknown-fuchsia"),
        args.readelf,
        excludes,
        args.output,
    )
    return 0


def check_toolchain_multilib_main(args):
    excludes = set(args.exclude)

    targets = (
        "aarch64-unknown-fuchsia",
        "x86_64-unknown-fuchsia",
    )
    multilibs = (
        "relative-vtables",
        "relative-vtables+noexcept",
        "relative-vtables+asan",
        "relative-vtables+asan+noexcept",
    )

    for target in targets:
        for multilib in multilibs:
            p = Path(args.toolchain_dir) / "lib" / target / multilib
            check_vtables_in_dir(p, args.readelf, excludes, args.output)

    # Check hwasan if exists
    p = (
        Path(args.toolchain_dir)
        / "lib"
        / "aarch64-unknown-fuchsia"
        / "relative-vtables+hwasan"
    )
    if p.exists():
        check_vtables_in_dir(p, args.readelf, excludes, args.output)
    p = (
        Path(args.toolchain_dir)
        / "lib"
        / "aarch64-unknown-fuchsia"
        / "relative-vtables+hwasan+noexcept"
    )
    if p.exists():
        check_vtables_in_dir(p, args.readelf, excludes, args.output)

    return 0


def check_fuchsia_main(args):
    excludes = set(args.exclude)

    # Read files to check from binaries.json.
    with open(os.path.join(args.build, "binaries.json"), "r") as f:
        import json

        binaries = json.load(f)

    files = ["binaries.json"]
    for binary in binaries:
        if binary["os"] != "fuchsia":
            continue

        path = binary["debug"]
        if os.path.exists(path):
            check_vtables_in_file(path, args.readelf, excludes, args.output)
            files.append(path)
        else:
            print(
                f"Skipping {path}. This path does not exist.", file=args.output
            )

    if args.depfile:
        with open(args.depfile, "w") as depfile:
            depfile.write(f"{args.output.name}: {' '.join(files)}\n")

    return 0


def main():
    parser = argparse.ArgumentParser(
        description="Script for checking that all vtables in an ELF file are in .rodata",
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    )
    parser.add_argument(
        "--readelf", default=DEFAULT_READELF, help="readelf executable to use"
    )
    parser.add_argument(
        "--exclude",
        action="append",
        default=[],
        help="Do not check if this class is in rodata.",
    )
    parser.add_argument(
        "-o",
        "--output",
        type=argparse.FileType("w"),
        default="-",
        help="If provided, write to this output file rather than stdout",
    )

    subparsers = parser.add_subparsers(
        dest="mode", help="Choose which mode this tool should run with."
    )

    file_parser = subparsers.add_parser(
        "file", description="Check vtables in a single ELF file."
    )
    file_parser.add_argument(
        "filename",
        type=os.path.abspath,
        help="Path to ELF file to or directory to recursively search through for ELF files",
    )

    toolchain_parser = subparsers.add_parser(
        "toolchain",
        description="""
Script for checking that all vtables in an ELF file are in .rodata. This will
check all relevant fuchsia-target executables and DSOs in a clang toolchain
(libc++, libunwind, etc). This includes:

- ${toolchain_dir}/lib/aarch64-unknown-fuchsia/
- ${toolchain_dir}/lib/x86_64-unknown-fuchsia/
""",
        formatter_class=RawDescriptionDefaultArgsHelpFormatter,
    )
    toolchain_parser.add_argument(
        "toolchain_dir",
        type=os.path.abspath,
        help="Path to the clang toolchain build directory",
    )

    fuchsia_parser = subparsers.add_parser(
        "fuchsia",
        description="""
Script for checking that all vtables in an ELF file are in .rodata. This will
check all relevant fuchsia-target executables and DSOs in a fuchsia build.
""",
        formatter_class=RawDescriptionDefaultArgsHelpFormatter,
    )
    fuchsia_parser.add_argument(
        "build",
        type=os.path.abspath,
        help="Path to either the GN or ZN fuchsia build directory.",
    )
    fuchsia_parser.add_argument(
        "--depfile", help="If provided, create this depfile."
    )

    multilib_parser = subparsers.add_parser(
        "multilib",
        description="""
Script for checking that all vtables in an ELF file are in .rodata. This will
check all relevant fuchsia-target executables and DSOs in a clang toolchain
(libc++, libunwind, etc). This includes:

Script for checking that all vtables in an ELF file are in .rodata. This will
check all relevant fuchsia-target executables and DSOs in the relative-vtables
multilib variant of a clang toolchain (libc++, libunwind, etc). This includes:

- ${toolchain_dir}/lib/x86_64-unknown-fuchsia/relative-vtables/
- ${toolchain_dir}/lib/x86_64-unknown-fuchsia/relative-vtables+noexcept/
- ${toolchain_dir}/lib/x86_64-unknown-fuchsia/relative-vtables+asan/
- ${toolchain_dir}/lib/x86_64-unknown-fuchsia/relative-vtables+asan+noexcept/
- ${toolchain_dir}/lib/aarch64-unknown-fuchsia/relative-vtables/
- ${toolchain_dir}/lib/aarch64-unknown-fuchsia/relative-vtables+noexcept/
- ${toolchain_dir}/lib/aarch64-unknown-fuchsia/relative-vtables+asan/
- ${toolchain_dir}/lib/aarch64-unknown-fuchsia/relative-vtables+asan+noexcept/
- ${toolchain_dir}/lib/aarch64-unknown-fuchsia/relative-vtables+hwasan/
- ${toolchain_dir}/lib/aarch64-unknown-fuchsia/relative-vtables+hwasan+noexcept/
""",
        formatter_class=RawDescriptionDefaultArgsHelpFormatter,
    )
    multilib_parser.add_argument(
        "toolchain_dir",
        type=os.path.abspath,
        help="Path to the clang toolchain build directory",
    )

    file_parser.set_defaults(func=check_file_main)
    toolchain_parser.set_defaults(func=check_toolchain_main)
    multilib_parser.set_defaults(func=check_toolchain_multilib_main)
    fuchsia_parser.set_defaults(func=check_fuchsia_main)

    args = parser.parse_args()
    return args.func(args)


if __name__ == "__main__":
    import sys

    sys.exit(main())
