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

"""
Process ELF file to generate placeholders for kobject
hash table and lookup functions produced by gperf,
since their sizes depend on how many kobjects have
been declared. The output header files will be used
during linking for intermediate output binaries so
that the addresses of these kobjects would remain
the same during later stages of linking.
"""

import sys
import argparse
import os
from distutils.version import LooseVersion

import elftools
from elftools.elf.elffile import ELFFile


if LooseVersion(elftools.__version__) < LooseVersion('0.24'):
    sys.exit("pyelftools is out of date, need version 0.24 or later")


def write_define(out_fp, prefix, name, value):
    """Write the #define to output file"""
    define_name = f"KOBJECT_{prefix}_{name}"
    out_fp.write(f"#ifndef {define_name}\n")
    out_fp.write(f"#define {define_name} {value}\n")
    out_fp.write("#endif\n\n")


def output_simple_header(one_sect):
    """Write the header for kobject section"""

    out_fn = os.path.join(args.outdir,
                          f"linker-kobject-prebuilt-{one_sect['name']}.h")
    out_fp = open(out_fn, "w")

    if one_sect['exists']:
        align = one_sect['align']
        size = one_sect['size']
        prefix = one_sect['define_prefix']

        write_define(out_fp, prefix, 'ALIGN', align)
        write_define(out_fp, prefix, 'SZ', size)

    out_fp.close()


def generate_linker_headers(obj):
    """Generate linker header files to be included by the linker script"""

    # Sections we are interested in
    sections = {
        ".data": {
            "name": "data",
            "define_prefix": "DATA",
            "exists": False,
            "multiplier": int(args.datapct) + 100,
            },
        ".rodata": {
            "name": "rodata",
            "define_prefix": "RODATA",
            "exists": False,
            "extra_bytes": args.rodata,
            },
        ".priv_stacks.noinit": {
            "name": "priv-stacks",
            "define_prefix": "PRIV_STACKS",
            "exists": False,
            },
    }

    for one_sect in obj.iter_sections():
        # REALLY NEED to match exact type as all other sections
        # (symbol, debug, etc.) are descendants where
        # isinstance() would match.
        if type(one_sect) is not elftools.elf.sections.Section: # pylint: disable=unidiomatic-typecheck
            continue

        name = one_sect.name
        if name in sections.keys():
            # Need section alignment and size
            sections[name]['align'] = one_sect['sh_addralign']
            sections[name]['size'] = one_sect['sh_size']
            sections[name]['exists'] = True

            if "multiplier" in sections[name]:
                sections[name]['size'] *= sections[name]['multiplier'] / 100
                sections[name]['size'] = int(sections[name]['size'])

            if "extra_bytes" in sections[name]:
                sections[name]['size'] += int(sections[name]['extra_bytes'])

    for one_sect in sections:
        output_simple_header(sections[one_sect])


def parse_args():
    """Parse command line arguments"""
    global args

    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)

    parser.add_argument("--object", required=True,
                        help="Points to kobject_prebuilt_hash.c.obj")
    parser.add_argument("--outdir", required=True,
                        help="Output directory (<build_dir>/include/generated)")
    parser.add_argument("--datapct", required=True,
                        help="Multipler to the size of reserved space for DATA region")
    parser.add_argument("--rodata", required=True,
                        help="Extra bytes to reserve for RODATA region")
    parser.add_argument("-v", "--verbose", action="store_true",
                        help="Verbose messages")
    args = parser.parse_args()
    if "VERBOSE" in os.environ:
        args.verbose = 1


def main():
    """Main program"""
    parse_args()

    with open(args.object, "rb") as obj_fp:
        obj = ELFFile(obj_fp)

        generate_linker_headers(obj)


if __name__ == "__main__":
    main()
