#!/usr/bin/env fuchsia-vendored-python
# Copyright 2017 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.

from __future__ import print_function

from contextlib import contextmanager
from collections import namedtuple
import argparse
import json
import mmap
import os
import struct
import sys
import uuid

# Standard ELF constants.
ELFMAG = b"\x7fELF"
EI_CLASS = 4
ELFCLASS32 = 1
ELFCLASS64 = 2
EI_DATA = 5
ELFDATA2LSB = 1
ELFDATA2MSB = 2
ET_EXEC = 2
ET_DYN = 3
EM_386 = 3
EM_ARM = 40
EM_X86_64 = 62
EM_AARCH64 = 183
PT_LOAD = 1
PT_DYNAMIC = 2
PT_INTERP = 3
PT_NOTE = 4
PT_GNU_RELRO = 0x6474E552
PF_X = 1
PF_W = 2
PF_R = 4
DT_NEEDED = 1
DT_PLTRELSZ = 2
DT_STRTAB = 5
DT_RELA = 7
DT_RELASZ = 8
DT_REL = 17
DT_RELSZ = 18
DT_RELRSZ = 35
DT_RELR = 36
DT_PLTREL = 20
DT_SONAME = 14
DT_RELACOUNT = 0x6FFFFFF9
DT_RELCOUNT = 0x6FFFFFFA
NT_GNU_BUILD_ID = 3
SHT_SYMTAB = 2
SHF_ALLOC = 2

IS_PYTHON3 = sys.version_info[0] >= 3


class elf_note(
    namedtuple(
        "elf_note",
        [
            "name",
            "type",
            "desc",
        ],
    )
):
    # An ELF note is identified by (name_string, type_integer).
    def ident(self):
        return (self.name, self.type)

    def is_build_id(self):
        return self.ident() == ("GNU\0", NT_GNU_BUILD_ID)

    def build_id_hex(self):
        if self.is_build_id():
            return "".join(("%02x" % byte) for byte in self.desc)
        return None

    def __repr__(self):
        return "elf_note(%r, %#x, <%d bytes>)" % (
            self.name,
            self.type,
            len(self.desc),
        )


def gen_elf():
    # { 'Struct1': (ELFCLASS32 fields, ELFCLASS64 fields),
    #   'Struct2': fields_same_for_both, ... }
    elf_types = {
        "Ehdr": (
            [
                ("e_ident", "16s"),
                ("e_type", "H"),
                ("e_machine", "H"),
                ("e_version", "I"),
                ("e_entry", "I"),
                ("e_phoff", "I"),
                ("e_shoff", "I"),
                ("e_flags", "I"),
                ("e_ehsize", "H"),
                ("e_phentsize", "H"),
                ("e_phnum", "H"),
                ("e_shentsize", "H"),
                ("e_shnum", "H"),
                ("e_shstrndx", "H"),
            ],
            [
                ("e_ident", "16s"),
                ("e_type", "H"),
                ("e_machine", "H"),
                ("e_version", "I"),
                ("e_entry", "Q"),
                ("e_phoff", "Q"),
                ("e_shoff", "Q"),
                ("e_flags", "I"),
                ("e_ehsize", "H"),
                ("e_phentsize", "H"),
                ("e_phnum", "H"),
                ("e_shentsize", "H"),
                ("e_shnum", "H"),
                ("e_shstrndx", "H"),
            ],
        ),
        "Phdr": (
            [
                ("p_type", "I"),
                ("p_offset", "I"),
                ("p_vaddr", "I"),
                ("p_paddr", "I"),
                ("p_filesz", "I"),
                ("p_memsz", "I"),
                ("p_flags", "I"),
                ("p_align", "I"),
            ],
            [
                ("p_type", "I"),
                ("p_flags", "I"),
                ("p_offset", "Q"),
                ("p_vaddr", "Q"),
                ("p_paddr", "Q"),
                ("p_filesz", "Q"),
                ("p_memsz", "Q"),
                ("p_align", "Q"),
            ],
        ),
        "Shdr": (
            [
                ("sh_name", "L"),
                ("sh_type", "L"),
                ("sh_flags", "L"),
                ("sh_addr", "L"),
                ("sh_offset", "L"),
                ("sh_size", "L"),
                ("sh_link", "L"),
                ("sh_info", "L"),
                ("sh_addralign", "L"),
                ("sh_entsize", "L"),
            ],
            [
                ("sh_name", "L"),
                ("sh_type", "L"),
                ("sh_flags", "Q"),
                ("sh_addr", "Q"),
                ("sh_offset", "Q"),
                ("sh_size", "Q"),
                ("sh_link", "L"),
                ("sh_info", "L"),
                ("sh_addralign", "Q"),
                ("sh_entsize", "Q"),
            ],
        ),
        "Dyn": (
            [
                ("d_tag", "i"),
                ("d_val", "I"),
            ],
            [
                ("d_tag", "q"),
                ("d_val", "Q"),
            ],
        ),
        "Nhdr": [
            ("n_namesz", "I"),
            ("n_descsz", "I"),
            ("n_type", "I"),
        ],
        "dwarf2_line_header": [
            ("unit_length", "L"),
            ("version", "H"),
            ("header_length", "L"),
            ("minimum_instruction_length", "B"),
            ("default_is_stmt", "B"),
            ("line_base", "b"),
            ("line_range", "B"),
            ("opcode_base", "B"),
        ],
        "dwarf4_line_header": [
            ("unit_length", "L"),
            ("version", "H"),
            ("header_length", "L"),
            ("minimum_instruction_length", "B"),
            ("maximum_operations_per_instruction", "B"),
            ("default_is_stmt", "B"),
            ("line_base", "b"),
            ("line_range", "b"),
            ("opcode_base", "B"),
        ],
    }

    # There is an accessor for each struct, e.g. Ehdr.
    # Ehdr.read is a function like Struct.unpack_from.
    # Ehdr.size is the size of the struct.
    elf_accessor = namedtuple("elf_accessor", ["size", "read", "write", "pack"])

    # All the accessors for a format (class, byte-order) form one elf,
    # e.g. use elf.Ehdr and elf.Phdr.
    elf = namedtuple("elf", list(elf_types.keys()))

    def gen_accessors(is64, struct_byte_order):
        def make_accessor(type, decoder):
            return elf_accessor(
                size=decoder.size,
                read=lambda buffer, offset=0: type._make(
                    decoder.unpack_from(buffer, offset)
                ),
                write=lambda buffer, offset, x: decoder.pack_into(
                    buffer, offset, *x
                ),
                pack=lambda x: decoder.pack(*x),
            )

        for name, fields in elf_types.items():
            if isinstance(fields, tuple):
                fields = fields[1 if is64 else 0]
            type = namedtuple(name, [field_name for field_name, fmt in fields])
            decoder = struct.Struct(
                struct_byte_order + "".join(fmt for field_name, fmt in fields)
            )
            yield make_accessor(type, decoder)

    for elfclass, is64 in [(ELFCLASS32, False), (ELFCLASS64, True)]:
        for elf_bo, struct_bo in [(ELFDATA2LSB, "<"), (ELFDATA2MSB, ">")]:
            yield ((elfclass, elf_bo), elf(*gen_accessors(is64, struct_bo)))


# e.g. ELF[file[EI_CLASS], file[EI_DATA]].Ehdr.read(file).e_phnum
ELF = dict(gen_elf())


def get_elf_accessor(file):
    # If it looks like an ELF file, whip out the decoder ring.
    if file[: len(ELFMAG)] == ELFMAG:
        return ELF.get(
            (
                ord(file[EI_CLASS : EI_CLASS + 1]),
                ord(file[EI_DATA : EI_DATA + 1]),
            ),
            None,
        )
    return None


def gen_phdrs(file, elf, ehdr):
    for pos in range(0, ehdr.e_phnum * elf.Phdr.size, elf.Phdr.size):
        yield elf.Phdr.read(file, ehdr.e_phoff + pos)


def gen_shdrs(file, elf, ehdr):
    for pos in range(0, ehdr.e_shnum * elf.Shdr.size, elf.Shdr.size):
        yield elf.Shdr.read(file, ehdr.e_shoff + pos)


cpu = namedtuple(
    "cpu",
    [
        "e_machine",  # ELF e_machine int
        "llvm",  # LLVM triple CPU component
        "gn",  # GN target_cpu
    ],
)

ELF_MACHINE_TO_CPU = {
    elf: cpu(elf, llvm, gn)
    for elf, llvm, gn in [
        (EM_386, "i386", "x86"),
        (EM_ARM, "arm", "arm"),
        (EM_X86_64, "x86_64", "x64"),
        (EM_AARCH64, "aarch64", "arm64"),
    ]
}


@contextmanager
def mmapper(filename):
    """A context manager that yields (fd, file_contents) given a file name.
    This ensures that the mmap and file objects are closed at the end of the
    'with' statement."""
    fileobj = open(filename, "rb")
    fd = fileobj.fileno()
    size = os.fstat(fd).st_size
    if size == 0:
        # mmap can't handle empty files.
        try:
            yield fd, "", 0
        finally:
            fileobj.close()
    else:
        mmapobj = mmap.mmap(fd, 0, access=mmap.ACCESS_READ)
        try:
            yield fd, mmapobj, size
        finally:
            mmapobj.close()
            fileobj.close()


def makedirs(dirs):
    try:
        os.makedirs(dirs)
    except OSError as e:
        if e.errno != os.errno.EEXIST:
            raise e


elf_sizes = namedtuple(
    "elf_sizes",
    [
        "file",  # st_size
        "memory",  # lowest p_vaddr to highest p_memsz
        "rel",  # DT_RELSZ (+ DT_PLTRELSZ if matching)
        "rela",  # DT_RELASZ (+ DT_PLTRELSZ if matching)
        "relr",  # DT_RELRSZ
        "relcount",  # DT_RELCOUNT + DT_RELACOUNT
        "relro",  # PT_GNU_RELRO p_memsz
        "code",  # executable segment p_filesz
        "rodata",  # read-only data segment p_filesz
        "data",  # writable segment p_filesz
        "bss",  # writable segment p_memsz past p_filesz
    ],
)


# elf_info objects are only created by `get_elf_info` or the `copy` or
# `rename` methods.
class elf_info(
    namedtuple(
        "elf_info",
        [
            "filename",
            "sizes",  # elf_sizes
            "cpu",  # cpu tuple
            "notes",  # list of (ident, desc): selected notes
            "build_id",  # string: lowercase hex
            "stripped",  # bool: Has no symbols or .debug_* sections
            "interp",  # string or None: PT_INTERP (without \0)
            "soname",  # string or None: DT_SONAME
            "needed",  # list of strings: DT_NEEDED
        ],
    )
):
    def rename(self, filename):
        assert os.path.samefile(self.filename, filename)
        return self._replace(filename=filename)

    def with_soname(self, soname):
        return self._replace(soname=soname)

    def copy(self):
        return self._replace()

    def _replace(self, **kwargs):
        # Copy the tuple.
        clone = self.__class__(*super()._replace(**kwargs))
        # Copy the lazy state.
        clone.elf = self.elf
        if self.get_sources == clone.get_sources:
            raise Exception("uninitialized elf_info object!")
        clone.get_sources = self.get_sources
        return clone

    # This is replaced with a closure by the creator in get_elf_info.
    def get_sources(self):
        raise Exception("uninitialized elf_info object!")

    def strip(self, stripped_filename):
        """Write stripped output to the given file unless it already exists
        with identical contents.  Returns True iff the file was changed."""
        with mmapper(self.filename) as mapped:
            fd, file, filesize = mapped
            ehdr = self.elf.Ehdr.read(file)

            stripped_ehdr = ehdr._replace(e_shoff=0, e_shnum=0, e_shstrndx=0)
            stripped_size = max(
                phdr.p_offset + phdr.p_filesz
                for phdr in gen_phdrs(file, self.elf, ehdr)
                if phdr.p_type == PT_LOAD
            )
            assert (
                ehdr.e_phoff + (ehdr.e_phnum * ehdr.e_phentsize)
                <= stripped_size
            )

            def gen_stripped_contents():
                yield self.elf.Ehdr.pack(stripped_ehdr)
                yield file[self.elf.Ehdr.size : stripped_size]

            def old_file_matches():
                old_size = os.path.getsize(stripped_filename)
                new_size = sum(len(x) for x in gen_stripped_contents())
                if old_size != new_size:
                    return False
                with open(stripped_filename, "rb") as f:
                    for chunk in gen_stripped_contents():
                        if f.read(len(chunk)) != chunk:
                            return False
                return True

            if os.path.exists(stripped_filename):
                if old_file_matches():
                    return False
                else:
                    os.remove(stripped_filename)
            # Create the new file with the same mode as the original.
            with os.fdopen(
                os.open(
                    stripped_filename,
                    os.O_WRONLY | os.O_CREAT | os.O_EXCL,
                    os.fstat(fd).st_mode & 0o777,
                ),
                "wb",
            ) as stripped_file:
                stripped_file.write(self.elf.Ehdr.pack(stripped_ehdr))
                stripped_file.write(file[self.elf.Ehdr.size : stripped_size])
            return True


def get_elf_info(filename, match_notes=False):
    file = None
    elf = None
    ehdr = None
    phdrs = None

    # Yields an elf_note for each note in any PT_NOTE segment.
    def gen_notes():
        def round_up_to(size):
            return ((size + 3) // 4) * 4

        for phdr in phdrs:
            if phdr.p_type == PT_NOTE:
                pos = phdr.p_offset
                while pos < phdr.p_offset + phdr.p_filesz:
                    nhdr = elf.Nhdr.read(file, pos)
                    pos += elf.Nhdr.size
                    # TODO(https://fxbug.dev/42132793) PT_NOTE is expected to be valid
                    # 7-bit ASCII or UTF-8. Remove this when clients no longer
                    # depend on that behavior.
                    name = str(file[pos : pos + nhdr.n_namesz].decode())
                    pos += round_up_to(nhdr.n_namesz)
                    # PT_DESC is not always string-ish, just copy the bytes.
                    if IS_PYTHON3:
                        desc = file[pos : pos + nhdr.n_descsz]
                    else:
                        desc = [ord(b) for b in file[pos : pos + nhdr.n_descsz]]
                    pos += round_up_to(nhdr.n_descsz)
                    yield elf_note(name, nhdr.n_type, desc)

    def gen_sections():
        shdrs = list(gen_shdrs(file, elf, ehdr))
        if not shdrs:
            return
        strtab_shdr = shdrs[ehdr.e_shstrndx]
        for shdr, i in zip(shdrs, range(len(shdrs))):
            if i == 0:
                continue
            assert shdr.sh_name < strtab_shdr.sh_size, (
                "%s: invalid sh_name" % filename
            )
            yield (shdr, extract_C_string(strtab_shdr.sh_offset + shdr.sh_name))

    # Generates '\0'-terminated strings starting at the given offset,
    # until an empty string.
    def gen_strings(start):
        while True:
            end = file.find(b"\0", start)
            assert end >= start, "%s: Unterminated string at %#x" % (
                filename,
                start,
            )
            if start == end:
                break
            yield file[start:end].decode()
            start = end + 1

    def extract_C_string(start):
        for string in gen_strings(start):
            return string
        return ""

    # Returns a string of hex digits (or None).
    def get_build_id():
        build_id = None
        for note in gen_notes():
            # Note that the last build_id note needs to be used due to https://fxbug.dev/42101443.
            possible_build_id = note.build_id_hex()
            if possible_build_id:
                build_id = possible_build_id
        return build_id

    # Returns a list of elf_note objects.
    def get_matching_notes():
        if isinstance(match_notes, bool):
            if match_notes:
                return list(gen_notes())
            else:
                return []
        # If not a bool, it's an iterable of ident pairs.
        return [note for note in gen_notes() if note.ident() in match_notes]

    # Returns a string (without trailing '\0'), or None.
    def get_interp():
        # PT_INTERP points directly to a string in the file.
        for interp in (phdr for phdr in phdrs if phdr.p_type == PT_INTERP):
            interp = file[interp.p_offset : interp.p_offset + interp.p_filesz]
            if interp[-1:] == b"\0":
                interp = interp[:-1]
            return interp.decode()
        return None

    def get_dynamic():
        # PT_DYNAMIC points to the list of ElfNN_Dyn tags.
        for dynamic in (phdr for phdr in phdrs if phdr.p_type == PT_DYNAMIC):
            return [
                elf.Dyn.read(file, dynamic.p_offset + dyn_offset)
                for dyn_offset in range(0, dynamic.p_filesz, elf.Dyn.size)
            ]
        return None

    def dyn_get(dyn, tag):
        for dt in dyn:
            if dt.d_tag == tag:
                return dt.d_val
        return None

    # Returns a string (or None) and a set of strings.
    def get_soname_and_needed(dyn):
        # Each DT_NEEDED or DT_SONAME points to a string in the .dynstr table.
        def GenDTStrings(tag):
            return (
                extract_C_string(strtab_offset + dt.d_val)
                for dt in dyn
                if dt.d_tag == tag
            )

        if dyn is None:
            return None, set()

        # DT_STRTAB points to the string table's vaddr (.dynstr).
        strtab_vaddr = dyn_get(dyn, DT_STRTAB)

        # Find the PT_LOAD containing the vaddr to compute the file offset.
        [strtab_offset] = [
            strtab_vaddr - phdr.p_vaddr + phdr.p_offset
            for phdr in phdrs
            if (
                phdr.p_type == PT_LOAD
                and phdr.p_vaddr <= strtab_vaddr
                and strtab_vaddr - phdr.p_vaddr < phdr.p_filesz
            )
        ]

        soname = None
        for soname in GenDTStrings(DT_SONAME):
            break

        return soname, set(GenDTStrings(DT_NEEDED))

    def get_stripped():
        return all(
            (shdr.sh_flags & SHF_ALLOC) != 0
            or (shdr.sh_type != SHT_SYMTAB and not name.startswith(".debug_"))
            for shdr, name in gen_sections()
        )

    def get_memory_size():
        segments = [phdr for phdr in phdrs if phdr.p_type == PT_LOAD]
        first = segments[0]
        last = segments[-1]
        start = first.p_vaddr & -first.p_align
        last = (last.p_vaddr + last.p_memsz + last.p_align - 1) & -last.p_align
        return last - start

    def get_relro_size():
        return sum(
            phdr.p_memsz for phdr in phdrs if phdr.p_type == PT_GNU_RELRO
        )

    def get_segment_size(phdr, file, mem):
        start = phdr.p_vaddr & -phdr.p_align
        file_end = phdr.p_vaddr + phdr.p_filesz
        mem_end = phdr.p_vaddr + phdr.p_memsz
        file_end = (file_end + phdr.p_align - 1) & -phdr.p_align
        mem_end = (mem_end + phdr.p_align - 1) & -phdr.p_align
        if file and mem:
            return mem_end - start
        if file:
            return file_end - start
        return mem_end - file_end

    def gen_executable_segments():
        return (
            phdr
            for phdr in phdrs
            if phdr.p_type == PT_LOAD and (phdr.p_flags & PF_X) != 0
        )

    def gen_writable_segments():
        return (
            phdr
            for phdr in phdrs
            if phdr.p_type == PT_LOAD and (phdr.p_flags & PF_W) != 0
        )

    def gen_rodata_segments():
        return (
            phdr
            for phdr in phdrs
            if phdr.p_type == PT_LOAD and phdr.p_flags == PF_R
        )

    def get_code_size():
        return sum(
            get_segment_size(phdr, file=True, mem=False)
            for phdr in gen_executable_segments()
        )

    def get_rodata_size():
        return sum(
            get_segment_size(phdr, file=True, mem=False)
            for phdr in gen_rodata_segments()
        )

    def get_data_size():
        return sum(
            get_segment_size(phdr, file=True, mem=False)
            for phdr in gen_writable_segments()
        )

    def get_bss_size():
        return sum(
            get_segment_size(phdr, file=False, mem=True)
            for phdr in gen_writable_segments()
        )

    def get_relsz(dyn, tag, sizetag):
        if dyn is None:
            return 0
        relsz = dyn_get(dyn, sizetag)
        if relsz is None:
            relsz = 0
        if dyn_get(dyn, DT_PLTREL) == tag:
            pltrelsz = dyn_get(dyn, DT_PLTRELSZ)
            if pltrelsz is not None:
                relsz += pltrelsz
        return relsz

    def get_relcount(dyn):
        if dyn is None:
            return 0
        return (dyn_get(dyn, DT_RELCOUNT) or 0) + (
            dyn_get(dyn, DT_RELACOUNT) or 0
        )

    def get_cpu():
        return ELF_MACHINE_TO_CPU.get(ehdr.e_machine)

    def gen_source_files():
        # Given the file position of a CU header (starting with the
        # beginning of the .debug_line section), return the position
        # of the include_directories portion and the position of the
        # next CU header.
        def read_line_header(pos):
            # Decode DWARF .debug_line per-CU header.
            hdr_type = elf.dwarf2_line_header
            hdr = hdr_type.read(file, pos)
            assert hdr.unit_length < 0xFFFFFFF0, "%s: 64-bit DWARF" % filename
            assert hdr.version in [
                2,
                3,
                4,
            ], "%s: DWARF .debug_line version %r" % (filename, hdr.version)
            if hdr.version == 4:
                hdr_type = elf.dwarf4_line_header
                hdr = hdr_type.read(file, pos)
            return (
                pos + hdr_type.size + hdr.opcode_base - 1,
                pos + 4 + hdr.unit_length,
            )

        # Decode include_directories portion of DWARF .debug_line format.
        def read_include_dirs(pos):
            include_dirs = list(gen_strings(pos))
            pos += sum(len(dir) + 1 for dir in include_dirs) + 1
            return pos, include_dirs

        # Decode file_paths portion of DWARF .debug_line format.
        def gen_file_paths(start, limit):
            while start < limit:
                end = file.find(b"\0", start, limit)
                assert end >= start, "%s: Unterminated string at %#x" % (
                    filename,
                    start,
                )
                if start == end:
                    break
                name = file[start:end].decode()
                start = end + 1
                # Decode 3 ULEB128s to advance start, but only use the first.
                for i in range(3):
                    value = 0
                    bits = 0
                    while start < limit:
                        # TODO(https://fxbug.dev/42125859): Remove this single-element slice hack
                        # once Python2 is no longer used in-tree.
                        byte = ord(file[start : start + 1])
                        start += 1
                        value |= (byte & 0x7F) << bits
                        if (byte & 0x80) == 0:
                            break
                        bits += 7
                    if i == 0:
                        include_idx = value
                # Ignore the fake file names the compiler leaks into the DWARF.
                if name not in ["<stdin>", "<command-line>"]:
                    yield name, include_idx

        for shdr, name in gen_sections():
            if name == ".debug_line":
                next = shdr.sh_offset
                while next < shdr.sh_offset + shdr.sh_size:
                    pos, next = read_line_header(next)

                    pos, include_dirs = read_include_dirs(pos)
                    assert pos <= next

                    # 0 means relative to DW_AT_comp_dir, which should be ".".
                    # Indices into the actual table start at 1.
                    include_dirs.insert(0, "")

                    # Decode file_paths and apply include directories.
                    for name, i in gen_file_paths(pos, next):
                        name = os.path.join(include_dirs[i], name)
                        yield os.path.normpath(name)

    # This closure becomes the elf_info object's `get_sources` method.
    def lazy_get_sources():
        # Run the generator and cache its results as a set.
        sources_cache = set(gen_source_files())
        # Replace the method to just return the cached set next time.
        info.get_sources = lambda: sources_cache
        return sources_cache

    # Map in the whole file's contents and use it as a string.
    with mmapper(filename) as mapped:
        fd, file, filesize = mapped
        elf = get_elf_accessor(file)
        if elf is not None:
            # ELF header leads to program headers.
            ehdr = elf.Ehdr.read(file)
            if ehdr.e_type not in (ET_EXEC, ET_DYN):
                # This is an invalid file or an ET_REL file, which don't count
                # as ELF files for our purposes.
                return None
            assert (
                ehdr.e_phentsize == elf.Phdr.size
            ), "%s: invalid e_phentsize %s" % (filename, ehdr.e_phentsize)
            phdrs = list(gen_phdrs(file, elf, ehdr))
            dyn = get_dynamic()
            info = elf_info(
                filename,
                elf_sizes(
                    file=filesize,
                    memory=get_memory_size(),
                    code=get_code_size(),
                    rodata=get_rodata_size(),
                    relro=get_relro_size(),
                    data=get_data_size(),
                    bss=get_bss_size(),
                    rel=get_relsz(dyn, DT_REL, DT_RELSZ),
                    rela=get_relsz(dyn, DT_RELA, DT_RELASZ),
                    relr=get_relsz(dyn, DT_RELR, DT_RELRSZ),
                    relcount=get_relcount(dyn),
                ),
                get_cpu(),
                get_matching_notes(),
                get_build_id(),
                get_stripped(),
                get_interp(),
                *get_soname_and_needed(dyn),
            )
            info.elf = elf
            info.get_sources = lazy_get_sources
            return info

    return None


# Module public API.
__all__ = ["cpu", "elf_info", "elf_note", "get_elf_accessor", "get_elf_info"]


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--strip",
        action="store_true",
        help="Strip each file into FILE.ei-strip",
    )
    parser.add_argument(
        "--build-id", action="store_true", help="Print each build ID"
    )
    parser.add_argument("--bootfs-dir", help="bootfs content", metavar="DIR")
    parser.add_argument("--zbi", help="Read zbi.json", metavar="FILE")
    parser.add_argument("--blobs", help="Read blobs.json", metavar="FILE")
    parser.add_argument("--sizes", help="Write elf_sizes.json", metavar="FILE")
    parser.add_argument("file", help="ELF file", metavar="FILE", nargs="*")
    args = parser.parse_args()

    files = args.file
    if args.zbi:
        if not args.bootfs_dir:
            parser.exit("--zbi and --bootfs-dir must be specified together")
        bootfs_map = {}
        with open(args.zbi) as f:
            zbi = json.load(f)
        for entry in zbi:
            if entry["type"] != "BOOTFS":
                continue
            for item in entry["contents"]:
                filepath = os.path.join(args.bootfs_dir, item["name"])
                files.append(filepath)
                bootfs_map[filepath] = item
    if args.blobs:
        with open(args.blobs) as f:
            blobs = json.load(f)
        files += [blob["source_path"] for blob in blobs]

    if args.sizes:
        if args.blobs:
            blob_map = {blob["source_path"]: blob for blob in blobs}

        def json_size(info):
            sizes = info.sizes._asdict()
            sizes["path"] = info.filename
            sizes["build_id"] = info.build_id
            if args.zbi and info.filename in bootfs_map:
                item = bootfs_map[info.filename]
                assert (
                    info.sizes.file == item["length"]
                ), "%r != %r in %r vs %r" % (
                    info.sizes.file,
                    blob["length"],
                    info,
                    blob,
                )
                sizes["zbi"] = item["size"]
            if args.blobs and info.filename in blob_map:
                blob = blob_map[info.filename]
                assert (
                    info.sizes.file == blob["bytes"]
                ), "%r != %r in %r vs %r" % (
                    info.sizes.file,
                    blob["bytes"],
                    info,
                    blob,
                )
                sizes["blob"] = blob["size"]
            return sizes

        # Sort for stable output.
        sizes = sorted(
            [
                json_size(info)
                for info in (get_elf_info(file) for file in files)
                if info
            ],
            key=lambda info: info["path"],
        )
        totals = {}
        for file in sizes:
            for key, val in file.items():
                if isinstance(val, int):
                    totals[key] = totals.get(key, 0) + val
        with open(args.sizes, "w") as outf:
            json.dump(
                {"files": sizes, "totals": totals},
                outf,
                sort_keys=True,
                indent=1,
            )
    else:
        for file in files:
            info = get_elf_info(file)

            if args.strip:
                stripped_filename = info.filename + ".ei-strip"
                info.strip(stripped_filename)
                print(stripped_filename)
            elif args.build_id:
                print(info.build_id)
            else:
                print(info)
                for source in info.get_sources():
                    print("\t" + source)

    return 0


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