#!/usr/bin/env python3.8
# 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
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(fxbug.dev/55190) 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 fxbug.dev/26967.
            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(fxbug.dev/48946): 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)
            assert ehdr.e_phentsize == elf.Phdr.size, (
                "%s: invalid e_phentsize" % filename)
            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())
