#!/usr/bin/env python3
#
# Copyright (c) 2018 Intel Corporation.
#
# SPDX-License-Identifier: Apache-2.0
#

"""
This script will relocate .text, .rodata, .data and .bss sections from required files
and places it in the required memory region. This memory region and file
are given to this python script in the form of a string.

Example of such a string would be::

   SRAM2:COPY:/home/xyz/zephyr/samples/hello_world/src/main.c,\
   SRAM1:COPY:/home/xyz/zephyr/samples/hello_world/src/main2.c, \
   FLASH2:NOCOPY:/home/xyz/zephyr/samples/hello_world/src/main3.c

One can also specify the program header for a given memory region:

   SRAM2\\ :phdr0:COPY:/home/xyz/zephyr/samples/hello_world/src/main.c

To invoke this script::

   python3 gen_relocate_app.py -i input_string -o generated_linker -c generated_code

Configuration that needs to be sent to the python script.

- If the memory is like SRAM1/SRAM2/CCD/AON then place full object in
  the sections
- If the memory type is appended with _DATA / _TEXT/ _RODATA/ _BSS only the
  selected memory is placed in the required memory region. Others are
  ignored.
- COPY/NOCOPY defines whether the script should generate the relocation code in
  code_relocation.c or not
- NOKEEP will suppress the default behavior of marking every relocated symbol
  with KEEP() in the generated linker script.

Multiple regions can be appended together like SRAM2_DATA_BSS
this will place data and bss inside SRAM2.
"""


import sys
import argparse
import os
import glob
import warnings
from collections import defaultdict
from enum import Enum
from pathlib import Path
from typing import NamedTuple
from typing import NewType
from typing import Tuple

from elftools.elf.elffile import ELFFile
from elftools.elf.sections import SymbolTableSection

MemoryRegion = NewType('MemoryRegion', str)


class SectionKind(Enum):
    TEXT = "text"
    RODATA = "rodata"
    DATA = "data"
    BSS = "bss"
    LITERAL = "literal"

    def __str__(self):
        return self.name

    @classmethod
    def for_section_named(cls, name: str):
        """
        Return the kind of section that includes a section with the given name.

        >>> SectionKind.for_section_with_name(".rodata.str1.4")
        <SectionKind.RODATA: 'rodata'>
        >>> SectionKind.for_section_with_name(".device_deps")
        None
        """
        if ".text." in name:
            return cls.TEXT
        elif ".rodata." in name:
            return cls.RODATA
        elif ".data." in name:
            return cls.DATA
        elif ".bss." in name:
            return cls.BSS
        elif ".literal." in name:
            return cls.LITERAL
        else:
            return None


class OutputSection(NamedTuple):
    obj_file_name: str
    section_name: str
    keep: bool = True


PRINT_TEMPLATE = """
                KEEP(*{obj_file_name}({section_name}))
"""

PRINT_TEMPLATE_NOKEEP = """
                *{obj_file_name}({section_name})
"""

SECTION_LOAD_MEMORY_SEQ = """
        __{0}_{1}_rom_start = LOADADDR(.{0}_{1}_reloc);
"""

LOAD_ADDRESS_LOCATION_FLASH = """
#ifdef CONFIG_XIP
GROUP_DATA_LINK_IN({0}, ROMABLE_REGION)
#else
GROUP_DATA_LINK_IN({0}, {0})
#endif
"""

LOAD_ADDRESS_LOCATION_FLASH_NOCOPY = """
GROUP_LINK_IN({0})
"""

LOAD_ADDRESS_LOCATION_BSS = "GROUP_LINK_IN({0})"

MPU_RO_REGION_START = """

     _{0}_mpu_ro_region_start = ORIGIN({1});

"""

MPU_RO_REGION_END = """

    _{0}_mpu_ro_region_end = .;

"""

# generic section creation format
LINKER_SECTION_SEQ = """

/* Linker section for memory region {2} for  {3} section  */

	SECTION_PROLOGUE(.{0}_{1}_reloc,,)
        {{
                . = ALIGN(4);
                {4}
                . = ALIGN(4);
	}} {5}
        __{0}_{1}_reloc_end = .;
        __{0}_{1}_reloc_start = ADDR(.{0}_{1}_reloc);
        __{0}_{1}_reloc_size = __{0}_{1}_reloc_end - __{0}_{1}_reloc_start;
"""

LINKER_SECTION_SEQ_MPU = """

/* Linker section for memory region {2} for {3} section  */

	SECTION_PROLOGUE(.{0}_{1}_reloc,,)
        {{
                __{0}_{1}_reloc_start = .;
                {4}
#if {6}
                . = ALIGN({6});
#else
                MPU_ALIGN(__{0}_{1}_reloc_size);
#endif
                __{0}_{1}_reloc_end = .;
	}} {5}
        __{0}_{1}_reloc_size = __{0}_{1}_reloc_end - __{0}_{1}_reloc_start;
"""

SOURCE_CODE_INCLUDES = """
/* Auto generated code. Do not modify.*/
#include <zephyr/kernel.h>
#include <zephyr/linker/linker-defs.h>
#include <zephyr/kernel_structs.h>
#include <kernel_internal.h>
"""

EXTERN_LINKER_VAR_DECLARATION = """
extern char __{0}_{1}_reloc_start[];
extern char __{0}_{1}_rom_start[];
extern char __{0}_{1}_reloc_size[];
"""


DATA_COPY_FUNCTION = """
void data_copy_xip_relocation(void)
{{
{0}
}}
"""

BSS_ZEROING_FUNCTION = """
void bss_zeroing_relocation(void)
{{
{0}
}}
"""

MEMCPY_TEMPLATE = """
	z_early_memcpy(&__{0}_{1}_reloc_start, &__{0}_{1}_rom_start,
		           (size_t) &__{0}_{1}_reloc_size);

"""

MEMSET_TEMPLATE = """
	z_early_memset(&__{0}_bss_reloc_start, 0,
		           (size_t) &__{0}_bss_reloc_size);
"""


def region_is_default_ram(region_name: str) -> bool:
    """
    Test whether a memory region with the given name is the system's default
    RAM region or not.

    This is used to determine whether some items need to be omitted from
    custom regions and instead be placed in the default. In particular, mutable
    data placed in the default RAM section is ignored and is allowed to be
    handled normally by the linker because it is placed in that region anyway.
    """
    return region_name == args.default_ram_region


def find_sections(filename: str) -> 'dict[SectionKind, list[OutputSection]]':
    """
    Locate relocatable sections in the given object file.

    The output value maps categories of sections to the list of actual sections
    located in the object file that fit in that category.
    """
    obj_file_path = Path(filename)

    with open(obj_file_path, 'rb') as obj_file_desc:
        full_lib = ELFFile(obj_file_desc)
        if not full_lib:
            sys.exit("Error parsing file: " + filename)

        sections = [x for x in full_lib.iter_sections()]
        out = defaultdict(list)

        for section in sections:
            section_kind = SectionKind.for_section_named(section.name)
            if section_kind is None:
                continue

            out[section_kind].append(
                OutputSection(obj_file_path.name, section.name)
            )

            # Common variables will be placed in the .bss section
            # only after linking in the final executable. This "if" finds
            # common symbols and warns the user of the problem.
            # The solution to which is simply assigning a 0 to
            # bss variable and it will go to the required place.
            if isinstance(section, SymbolTableSection):
                def is_common_symbol(s):
                    return s.entry["st_shndx"] == "SHN_COMMON"

                for symbol in filter(is_common_symbol, section.iter_symbols()):
                    warnings.warn("Common variable found. Move "+
                                  symbol.name + " to bss by assigning it to 0/NULL")

    return out


def assign_to_correct_mem_region(
    memory_region: str,
    full_list_of_sections: 'dict[SectionKind, list[OutputSection]]'
) -> 'dict[MemoryRegion, dict[SectionKind, list[OutputSection]]]':
    """
    Generate a mapping of memory region to collection of output sections to be
    placed in each region.
    """
    use_section_kinds, memory_region = section_kinds_from_memory_region(memory_region)

    memory_region, _, align_size = memory_region.partition('_')
    if align_size:
        mpu_align[memory_region] = int(align_size)

    keep_sections = '|NOKEEP' not in memory_region
    memory_region = memory_region.replace('|NOKEEP', '')

    output_sections = {}
    for used_kind in use_section_kinds:
        # Pass through section kinds that go into this memory region
        output_sections[used_kind] = [
            section._replace(keep=keep_sections)
            for section in full_list_of_sections[used_kind]
        ]

    return {MemoryRegion(memory_region): output_sections}


def section_kinds_from_memory_region(memory_region: str) -> 'Tuple[set[SectionKind], str]':
    """
    Get the section kinds requested by the given memory region name.

    Region names can be like RAM_RODATA_TEXT or just RAM; a section kind may
    follow the region name. If no kinds are specified all are assumed.

    In addition to the parsed kinds, the input region minus specifiers for those
    kinds is returned.

    >>> section_kinds_from_memory_region('SRAM2_TEXT')
    ({<SectionKind.TEXT: 'text'>}, 'SRAM2')
    """
    out = set()
    for kind in SectionKind:
        specifier = f"_{kind}"
        if specifier in memory_region:
            out.add(kind)
            memory_region = memory_region.replace(specifier, "")
    if not out:
        # No listed kinds implies all of the kinds
        out = set(SectionKind)
    return (out, memory_region)


def print_linker_sections(list_sections: 'list[OutputSection]'):
    out = ''
    for section in sorted(list_sections):
        template = PRINT_TEMPLATE if section.keep else PRINT_TEMPLATE_NOKEEP
        out += template.format(obj_file_name=section.obj_file_name,
                               section_name=section.section_name)
    return out

def add_phdr(memory_type, phdrs):
    return f'{memory_type} {phdrs[memory_type] if memory_type in phdrs else ""}'


def string_create_helper(
    kind: SectionKind,
    memory_type,
    full_list_of_sections: 'dict[SectionKind, list[OutputSection]]',
    load_address_in_flash,
    is_copy,
    phdrs
):
    linker_string = ''
    if load_address_in_flash:
        if is_copy:
            load_address_string = LOAD_ADDRESS_LOCATION_FLASH.format(add_phdr(memory_type, phdrs))
        else:
            load_address_string = LOAD_ADDRESS_LOCATION_FLASH_NOCOPY.format(add_phdr(memory_type, phdrs))
    else:
        load_address_string = LOAD_ADDRESS_LOCATION_BSS.format(add_phdr(memory_type, phdrs))
    if full_list_of_sections[kind]:
        # Create a complete list of funcs/ variables that goes in for this
        # memory type
        tmp = print_linker_sections(full_list_of_sections[kind])
        if region_is_default_ram(memory_type) and kind in (SectionKind.DATA, SectionKind.BSS):
            linker_string += tmp
        else:
            if not region_is_default_ram(memory_type) and kind is SectionKind.RODATA:
                align_size = 0
                if memory_type in mpu_align:
                    align_size = mpu_align[memory_type]

                linker_string += LINKER_SECTION_SEQ_MPU.format(memory_type.lower(), kind.value, memory_type.upper(),
                                                               kind, tmp, load_address_string, align_size)
            else:
                if region_is_default_ram(memory_type) and kind in (SectionKind.TEXT, SectionKind.LITERAL):
                    align_size = 0
                    linker_string += LINKER_SECTION_SEQ_MPU.format(memory_type.lower(), kind.value, memory_type.upper(),
                                                                   kind, tmp, load_address_string, align_size)
                else:
                    linker_string += LINKER_SECTION_SEQ.format(memory_type.lower(), kind.value, memory_type.upper(),
                                                               kind, tmp, load_address_string)
            if load_address_in_flash:
                linker_string += SECTION_LOAD_MEMORY_SEQ.format(memory_type.lower(), kind.value, memory_type.upper(),
                                                                kind)
    return linker_string


def generate_linker_script(linker_file, sram_data_linker_file, sram_bss_linker_file,
                           complete_list_of_sections, phdrs):
    gen_string = ''
    gen_string_sram_data = ''
    gen_string_sram_bss = ''

    for memory_type, full_list_of_sections in \
            sorted(complete_list_of_sections.items()):

        is_copy = bool("|COPY" in memory_type)
        memory_type = memory_type.split("|", 1)[0]

        if region_is_default_ram(memory_type) and is_copy:
            gen_string += MPU_RO_REGION_START.format(memory_type.lower(), memory_type.upper())

        gen_string += string_create_helper(SectionKind.LITERAL, memory_type, full_list_of_sections, 1, is_copy, phdrs)
        gen_string += string_create_helper(SectionKind.TEXT, memory_type, full_list_of_sections, 1, is_copy, phdrs)
        gen_string += string_create_helper(SectionKind.RODATA, memory_type, full_list_of_sections, 1, is_copy, phdrs)

        if region_is_default_ram(memory_type) and is_copy:
            gen_string += MPU_RO_REGION_END.format(memory_type.lower())

        if region_is_default_ram(memory_type):
            gen_string_sram_data += string_create_helper(SectionKind.DATA, memory_type, full_list_of_sections, 1, 1, phdrs)
            gen_string_sram_bss += string_create_helper(SectionKind.BSS, memory_type, full_list_of_sections, 0, 1, phdrs)
        else:
            gen_string += string_create_helper(SectionKind.DATA, memory_type, full_list_of_sections, 1, 1, phdrs)
            gen_string += string_create_helper(SectionKind.BSS, memory_type, full_list_of_sections, 0, 1, phdrs)

    # finally writing to the linker file
    with open(linker_file, "w") as file_desc:
        file_desc.write(gen_string)

    with open(sram_data_linker_file, "w") as file_desc:
        file_desc.write(gen_string_sram_data)

    with open(sram_bss_linker_file, "w") as file_desc:
        file_desc.write(gen_string_sram_bss)


def generate_memcpy_code(memory_type, full_list_of_sections, code_generation):
    generate_sections, memory_type = section_kinds_from_memory_region(memory_type)

    # Non-BSS sections get copied to the destination memory, except data in
    # main memory which gets copied automatically.
    for kind in (SectionKind.TEXT, SectionKind.RODATA, SectionKind.DATA):
        if region_is_default_ram(memory_type) and kind is SectionKind.DATA:
            continue

        if kind in generate_sections and full_list_of_sections[kind]:
            code_generation["copy_code"] += MEMCPY_TEMPLATE.format(memory_type.lower(), kind.value)
            code_generation["extern"] += EXTERN_LINKER_VAR_DECLARATION.format(
                memory_type.lower(), kind.value)

    # BSS sections in main memory are automatically zeroed; others need to have
    # zeroing code generated.
    if (SectionKind.BSS in generate_sections
        and full_list_of_sections[SectionKind.BSS]
        and not region_is_default_ram(memory_type)
    ):
        code_generation["zero_code"] += MEMSET_TEMPLATE.format(memory_type.lower())
        code_generation["extern"] += EXTERN_LINKER_VAR_DECLARATION.format(
            memory_type.lower(), SectionKind.BSS.value)

    return code_generation


def dump_header_file(header_file, code_generation):
    code_string = ''
    # create a dummy void function if there is no code to generate for
    # bss/data/text regions

    code_string += code_generation["extern"]

    if code_generation["copy_code"]:
        code_string += DATA_COPY_FUNCTION.format(code_generation["copy_code"])
    else:
        code_string += DATA_COPY_FUNCTION.format("return;")
    if code_generation["zero_code"]:
        code_string += BSS_ZEROING_FUNCTION.format(code_generation["zero_code"])
    else:
        code_string += BSS_ZEROING_FUNCTION.format("return;")

    with open(header_file, "w") as header_file_desc:
        header_file_desc.write(SOURCE_CODE_INCLUDES)
        header_file_desc.write(code_string)


def parse_args():
    global args
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False)
    parser.add_argument("-d", "--directory", required=True,
                        help="obj file's directory")
    parser.add_argument("-i", "--input_rel_dict", required=True, type=argparse.FileType('r'),
                        help="input file with dict src:memory type(sram2 or ccm or aon etc)")
    parser.add_argument("-o", "--output", required=False, help="Output ld file")
    parser.add_argument("-s", "--output_sram_data", required=False,
                        help="Output sram data ld file")
    parser.add_argument("-b", "--output_sram_bss", required=False,
                        help="Output sram bss ld file")
    parser.add_argument("-c", "--output_code", required=False,
                        help="Output relocation code header file")
    parser.add_argument("-R", "--default_ram_region", default='SRAM',
                        help="Name of default RAM memory region for system")
    parser.add_argument("-v", "--verbose", action="count", default=0,
                        help="Verbose Output")
    args = parser.parse_args()


# return the absolute path for the object file.
def get_obj_filename(searchpath, filename):
    # get the object file name which is almost always pended with .obj
    obj_filename = filename.split("/")[-1] + ".obj"

    for dirpath, _, files in os.walk(searchpath):
        for filename1 in files:
            if filename1 == obj_filename:
                if filename.split("/")[-2] in dirpath.split("/")[-1]:
                    fullname = os.path.join(dirpath, filename1)
                    return fullname


# Extracts all possible components for the input string:
# <mem_region>[\ :program_header]:<flag_1>[;<flag_2>...]:<file_1>[;<file_2>...]
# Returns a 4-tuple with them: (mem_region, program_header, flags, files)
# If no `program_header` is defined, returns an empty string
def parse_input_string(line):
    # Be careful when splitting by : to avoid breaking absolute paths on Windows
    mem_region, rest = line.split(':', 1)

    phdr = ''
    if mem_region.endswith(' '):
        mem_region = mem_region.rstrip()
        phdr, rest = rest.split(':', 1)

    # Split lists by semicolons, in part to support generator expressions
    flag_list, file_list = (lst.split(';') for lst in rest.split(':', 1))

    return mem_region, phdr, flag_list, file_list


# Create a dict with key as memory type and files as a list of values.
# Also, return another dict with program headers for memory regions
def create_dict_wrt_mem():
    # need to support wild card *
    rel_dict = dict()
    phdrs = dict()

    input_rel_dict = args.input_rel_dict.read()
    if input_rel_dict == '':
        sys.exit("Disable CONFIG_CODE_DATA_RELOCATION if no file needs relocation")
    for line in input_rel_dict.split('|'):
        if ':' not in line:
            continue

        mem_region, phdr, flag_list, file_list = parse_input_string(line)

        # Handle any program header
        if phdr != '':
            phdrs[mem_region] = f':{phdr}'

        file_name_list = []
        # Use glob matching on each file in the list
        for file_glob in file_list:
            glob_results = glob.glob(file_glob)
            if not glob_results:
                warnings.warn("File: "+file_glob+" Not found")
                continue
            elif len(glob_results) > 1:
                warnings.warn("Regex in file lists is deprecated, please use file(GLOB) instead")
            file_name_list.extend(glob_results)
        if len(file_name_list) == 0:
            continue
        if mem_region == '':
            continue
        if args.verbose:
            print("Memory region ", mem_region, " Selected for files:", file_name_list)

        mem_region = "|".join((mem_region, *flag_list))

        if mem_region in rel_dict:
            rel_dict[mem_region].extend(file_name_list)
        else:
            rel_dict[mem_region] = file_name_list

    return rel_dict, phdrs


def main():
    global mpu_align
    mpu_align = {}
    parse_args()
    searchpath = args.directory
    linker_file = args.output
    sram_data_linker_file = args.output_sram_data
    sram_bss_linker_file = args.output_sram_bss
    rel_dict, phdrs = create_dict_wrt_mem()
    complete_list_of_sections: 'dict[MemoryRegion, dict[SectionKind, list[OutputSection]]]' \
        = defaultdict(lambda: defaultdict(list))

    # Create/or truncate file contents if it already exists
    # raw = open(linker_file, "w")

    # for each memory_type, create text/rodata/data/bss sections for all obj files
    for memory_type, files in rel_dict.items():
        full_list_of_sections: 'dict[SectionKind, list[OutputSection]]' = defaultdict(list)

        for filename in files:
            obj_filename = get_obj_filename(searchpath, filename)
            # the obj file wasn't found. Probably not compiled.
            if not obj_filename:
                continue

            file_sections = find_sections(obj_filename)
            # Merge sections from file into collection of sections for all files
            for category, sections in file_sections.items():
                full_list_of_sections[category].extend(sections)

        # cleanup and attach the sections to the memory type after cleanup.
        sections_by_category = assign_to_correct_mem_region(memory_type, full_list_of_sections)
        for (region, section_category_map) in sections_by_category.items():
            for (category, sections) in section_category_map.items():
                complete_list_of_sections[region][category].extend(sections)

    generate_linker_script(linker_file, sram_data_linker_file,
                           sram_bss_linker_file, complete_list_of_sections, phdrs)

    code_generation = {"copy_code": '', "zero_code": '', "extern": ''}
    for mem_type, list_of_sections in sorted(complete_list_of_sections.items()):

        if "|COPY" in mem_type:
            mem_type = mem_type.split("|", 1)[0]
            code_generation = generate_memcpy_code(mem_type,
                                               list_of_sections, code_generation)

    dump_header_file(args.output_code, code_generation)


if __name__ == '__main__':
    main()
