# SPDX-License-Identifier: GPL-2.0+
# Copyright (c) 2016 Google, Inc
# Written by Simon Glass <sjg@chromium.org>
#
# Handle various things related to ELF images
#

from collections import namedtuple, OrderedDict
import io
import os
import re
import shutil
import struct
import tempfile

from patman import command
from patman import tools
from patman import tout

ELF_TOOLS = True
try:
    from elftools.elf.elffile import ELFFile
    from elftools.elf.elffile import ELFError
    from elftools.elf.sections import SymbolTableSection
except:  # pragma: no cover
    ELF_TOOLS = False

# Information about an EFL symbol:
# section (str): Name of the section containing this symbol
# address (int): Address of the symbol (its value)
# size (int): Size of the symbol in bytes
# weak (bool): True if the symbol is weak
# offset (int or None): Offset of the symbol's data in the ELF file, or None if
#   not known
Symbol = namedtuple('Symbol', ['section', 'address', 'size', 'weak', 'offset'])

# Information about an ELF file:
#    data: Extracted program contents of ELF file (this would be loaded by an
#           ELF loader when reading this file
#    load: Load address of code
#    entry: Entry address of code
#    memsize: Number of bytes in memory occupied by loading this ELF file
ElfInfo = namedtuple('ElfInfo', ['data', 'load', 'entry', 'memsize'])


def GetSymbols(fname, patterns):
    """Get the symbols from an ELF file

    Args:
        fname: Filename of the ELF file to read
        patterns: List of regex patterns to search for, each a string

    Returns:
        None, if the file does not exist, or Dict:
          key: Name of symbol
          value: Hex value of symbol
    """
    stdout = tools.run('objdump', '-t', fname)
    lines = stdout.splitlines()
    if patterns:
        re_syms = re.compile('|'.join(patterns))
    else:
        re_syms = None
    syms = {}
    syms_started = False
    for line in lines:
        if not line or not syms_started:
            if 'SYMBOL TABLE' in line:
                syms_started = True
            line = None  # Otherwise code coverage complains about 'continue'
            continue
        if re_syms and not re_syms.search(line):
            continue

        space_pos = line.find(' ')
        value, rest = line[:space_pos], line[space_pos + 1:]
        flags = rest[:7]
        parts = rest[7:].split()
        section, size =  parts[:2]
        if len(parts) > 2:
            name = parts[2] if parts[2] != '.hidden' else parts[3]
            syms[name] = Symbol(section, int(value, 16), int(size, 16),
                                flags[1] == 'w', None)

    # Sort dict by address
    return OrderedDict(sorted(syms.items(), key=lambda x: x[1].address))

def GetSymbolFileOffset(fname, patterns):
    """Get the symbols from an ELF file

    Args:
        fname: Filename of the ELF file to read
        patterns: List of regex patterns to search for, each a string

    Returns:
        None, if the file does not exist, or Dict:
          key: Name of symbol
          value: Hex value of symbol
    """
    def _GetFileOffset(elf, addr):
        for seg in elf.iter_segments():
            seg_end = seg['p_vaddr'] + seg['p_filesz']
            if seg.header['p_type'] == 'PT_LOAD':
                if addr >= seg['p_vaddr'] and addr < seg_end:
                    return addr - seg['p_vaddr'] + seg['p_offset']

    if not ELF_TOOLS:
        raise ValueError('Python elftools package is not available')

    syms = {}
    with open(fname, 'rb') as fd:
        elf = ELFFile(fd)

        re_syms = re.compile('|'.join(patterns))
        for section in elf.iter_sections():
            if isinstance(section, SymbolTableSection):
                for symbol in section.iter_symbols():
                    if not re_syms or re_syms.search(symbol.name):
                        addr = symbol.entry['st_value']
                        syms[symbol.name] = Symbol(
                            section.name, addr, symbol.entry['st_size'],
                            symbol.entry['st_info']['bind'] == 'STB_WEAK',
                            _GetFileOffset(elf, addr))

    # Sort dict by address
    return OrderedDict(sorted(syms.items(), key=lambda x: x[1].address))

def GetSymbolAddress(fname, sym_name):
    """Get a value of a symbol from an ELF file

    Args:
        fname: Filename of the ELF file to read
        patterns: List of regex patterns to search for, each a string

    Returns:
        Symbol value (as an integer) or None if not found
    """
    syms = GetSymbols(fname, [sym_name])
    sym = syms.get(sym_name)
    if not sym:
        return None
    return sym.address

def LookupAndWriteSymbols(elf_fname, entry, section):
    """Replace all symbols in an entry with their correct values

    The entry contents is updated so that values for referenced symbols will be
    visible at run time. This is done by finding out the symbols offsets in the
    entry (using the ELF file) and replacing them with values from binman's data
    structures.

    Args:
        elf_fname: Filename of ELF image containing the symbol information for
            entry
        entry: Entry to process
        section: Section which can be used to lookup symbol values
    """
    fname = tools.get_input_filename(elf_fname)
    syms = GetSymbols(fname, ['image', 'binman'])
    if not syms:
        return
    base = syms.get('__image_copy_start')
    if not base:
        return
    for name, sym in syms.items():
        if name.startswith('_binman'):
            msg = ("Section '%s': Symbol '%s'\n   in entry '%s'" %
                   (section.GetPath(), name, entry.GetPath()))
            offset = sym.address - base.address
            if offset < 0 or offset + sym.size > entry.contents_size:
                raise ValueError('%s has offset %x (size %x) but the contents '
                                 'size is %x' % (entry.GetPath(), offset,
                                                 sym.size, entry.contents_size))
            if sym.size == 4:
                pack_string = '<I'
            elif sym.size == 8:
                pack_string = '<Q'
            else:
                raise ValueError('%s has size %d: only 4 and 8 are supported' %
                                 (msg, sym.size))

            # Look up the symbol in our entry tables.
            value = section.GetImage().LookupImageSymbol(name, sym.weak, msg,
                                                         base.address)
            if value is None:
                value = -1
                pack_string = pack_string.lower()
            value_bytes = struct.pack(pack_string, value)
            tout.debug('%s:\n   insert %s, offset %x, value %x, length %d' %
                       (msg, name, offset, value, len(value_bytes)))
            entry.data = (entry.data[:offset] + value_bytes +
                        entry.data[offset + sym.size:])

def MakeElf(elf_fname, text, data):
    """Make an elf file with the given data in a single section

    The output file has a several section including '.text' and '.data',
    containing the info provided in arguments.

    Args:
        elf_fname: Output filename
        text: Text (code) to put in the file's .text section
        data: Data to put in the file's .data section
    """
    outdir = tempfile.mkdtemp(prefix='binman.elf.')
    s_file = os.path.join(outdir, 'elf.S')

    # Spilt the text into two parts so that we can make the entry point two
    # bytes after the start of the text section
    text_bytes1 = ['\t.byte\t%#x' % byte for byte in text[:2]]
    text_bytes2 = ['\t.byte\t%#x' % byte for byte in text[2:]]
    data_bytes = ['\t.byte\t%#x' % byte for byte in data]
    with open(s_file, 'w') as fd:
        print('''/* Auto-generated C program to produce an ELF file for testing */

.section .text
.code32
.globl _start
.type _start, @function
%s
_start:
%s
.ident "comment"

.comm fred,8,4

.section .empty
.globl _empty
_empty:
.byte 1

.globl ernie
.data
.type ernie, @object
.size ernie, 4
ernie:
%s
''' % ('\n'.join(text_bytes1), '\n'.join(text_bytes2), '\n'.join(data_bytes)),
        file=fd)
    lds_file = os.path.join(outdir, 'elf.lds')

    # Use a linker script to set the alignment and text address.
    with open(lds_file, 'w') as fd:
        print('''/* Auto-generated linker script to produce an ELF file for testing */

PHDRS
{
    text PT_LOAD ;
    data PT_LOAD ;
    empty PT_LOAD FLAGS ( 6 ) ;
    note PT_NOTE ;
}

SECTIONS
{
    . = 0xfef20000;
    ENTRY(_start)
    .text . : SUBALIGN(0)
    {
        *(.text)
    } :text
    .data : {
        *(.data)
    } :data
    _bss_start = .;
    .empty : {
        *(.empty)
    } :empty
    /DISCARD/ : {
        *(.note.gnu.property)
    }
    .note : {
        *(.comment)
    } :note
    .bss _bss_start  (OVERLAY) : {
        *(.bss)
    }
}
''', file=fd)
    # -static: Avoid requiring any shared libraries
    # -nostdlib: Don't link with C library
    # -Wl,--build-id=none: Don't generate a build ID, so that we just get the
    #   text section at the start
    # -m32: Build for 32-bit x86
    # -T...: Specifies the link script, which sets the start address
    cc, args = tools.get_target_compile_tool('cc')
    args += ['-static', '-nostdlib', '-Wl,--build-id=none', '-m32', '-T',
            lds_file, '-o', elf_fname, s_file]
    stdout = command.output(cc, *args)
    shutil.rmtree(outdir)

def DecodeElf(data, location):
    """Decode an ELF file and return information about it

    Args:
        data: Data from ELF file
        location: Start address of data to return

    Returns:
        ElfInfo object containing information about the decoded ELF file
    """
    file_size = len(data)
    with io.BytesIO(data) as fd:
        elf = ELFFile(fd)
        data_start = 0xffffffff;
        data_end = 0;
        mem_end = 0;
        virt_to_phys = 0;

        for i in range(elf.num_segments()):
            segment = elf.get_segment(i)
            if segment['p_type'] != 'PT_LOAD' or not segment['p_memsz']:
                skipped = 1  # To make code-coverage see this line
                continue
            start = segment['p_paddr']
            mend = start + segment['p_memsz']
            rend = start + segment['p_filesz']
            data_start = min(data_start, start)
            data_end = max(data_end, rend)
            mem_end = max(mem_end, mend)
            if not virt_to_phys:
                virt_to_phys = segment['p_paddr'] - segment['p_vaddr']

        output = bytearray(data_end - data_start)
        for i in range(elf.num_segments()):
            segment = elf.get_segment(i)
            if segment['p_type'] != 'PT_LOAD' or not segment['p_memsz']:
                skipped = 1  # To make code-coverage see this line
                continue
            start = segment['p_paddr']
            offset = 0
            if start < location:
                offset = location - start
                start = location
            # A legal ELF file can have a program header with non-zero length
            # but zero-length file size and a non-zero offset which, added
            # together, are greater than input->size (i.e. the total file size).
            #  So we need to not even test in the case that p_filesz is zero.
            # Note: All of this code is commented out since we don't have a test
            # case for it.
            size = segment['p_filesz']
            #if not size:
                #continue
            #end = segment['p_offset'] + segment['p_filesz']
            #if end > file_size:
                #raise ValueError('Underflow copying out the segment. File has %#x bytes left, segment end is %#x\n',
                                 #file_size, end)
            output[start - data_start:start - data_start + size] = (
                segment.data()[offset:])
    return ElfInfo(output, data_start, elf.header['e_entry'] + virt_to_phys,
                   mem_end - data_start)

def UpdateFile(infile, outfile, start_sym, end_sym, insert):
    tout.notice("Creating file '%s' with data length %#x (%d) between symbols '%s' and '%s'" %
                (outfile, len(insert), len(insert), start_sym, end_sym))
    syms = GetSymbolFileOffset(infile, [start_sym, end_sym])
    if len(syms) != 2:
        raise ValueError("Expected two symbols '%s' and '%s': got %d: %s" %
                         (start_sym, end_sym, len(syms),
                          ','.join(syms.keys())))

    size = syms[end_sym].offset - syms[start_sym].offset
    if len(insert) > size:
        raise ValueError("Not enough space in '%s' for data length %#x (%d); size is %#x (%d)" %
                         (infile, len(insert), len(insert), size, size))

    data = tools.read_file(infile)
    newdata = data[:syms[start_sym].offset]
    newdata += insert + tools.get_bytes(0, size - len(insert))
    newdata += data[syms[end_sym].offset:]
    tools.write_file(outfile, newdata)
    tout.info('Written to offset %#x' % syms[start_sym].offset)

def read_segments(data):
    """Read segments from an ELF file

    Args:
        data (bytes): Contents of file

    Returns:
        tuple:
            list of segments, each:
                int: Segment number (0 = first)
                int: Start address of segment in memory
                bytes: Contents of segment
            int: entry address for image

    Raises:
        ValueError: elftools is not available
    """
    if not ELF_TOOLS:
        raise ValueError('Python elftools package is not available')
    with io.BytesIO(data) as inf:
        try:
            elf = ELFFile(inf)
        except ELFError as err:
            raise ValueError(err)
        entry = elf.header['e_entry']
        segments = []
        for i in range(elf.num_segments()):
            segment = elf.get_segment(i)
            if segment['p_type'] != 'PT_LOAD' or not segment['p_memsz']:
                skipped = 1  # To make code-coverage see this line
                continue
            start = segment['p_offset']
            rend = start + segment['p_filesz']
            segments.append((i, segment['p_paddr'], data[start:rend]))
    return segments, entry
