#!/usr/bin/env python3
#
# Copyright (c) 2024 Meta Platforms
#
# SPDX-License-Identifier: Apache-2.0

import argparse
import sys
import os
import re

from elftools.elf.elffile import ELFFile
from elftools.elf.descriptions import (
    describe_symbol_type,
)


class gen_symtab_log:

    def __init__(self, debug=False):
        self.__debug = debug

    def debug(self, text):
        """Print debug message if debugging is enabled.

        Note - this function requires config global variable to be initialized.
        """
        if self.__debug:
            sys.stdout.write(os.path.basename(
                sys.argv[0]) + ": " + text + "\n")

    @staticmethod
    def error(text):
        sys.exit(os.path.basename(sys.argv[0]) + ": error: " + text + "\n")

    def set_debug(self, state):
        self.__debug = state


log = gen_symtab_log()


def parse_args():
    parser = argparse.ArgumentParser(description=__doc__,
                                     formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False)

    parser.add_argument("-k", "--kernel", required=True,
                        help="Zephyr kernel image")
    parser.add_argument("-o", "--output", required=True,
                        help="Output source file")
    parser.add_argument("-d", "--debug", action="store_true",
                        help="Print additional debugging information")

    return parser.parse_args()


class symtab_entry:
    def __init__(self, addr, size, offset, name):
        self.addr = addr
        self.size = size
        self.offset = offset
        self.name = name

    def __eq__(self, other):
        return self.addr == other.addr


first_addr = 0
symtab_list = []


def sanitize_func_name(name):
    pattern = r'(^[a-zA-Z_][a-zA-Z0-9_]*)'
    match = re.match(pattern, name)
    if match:
        return match.group(0)
    else:
        log.error(f"Failed to sanitize function name: {name}")

    return name


def main():
    args = parse_args()
    log.set_debug(args.debug)

    with open(args.kernel, "rb") as rf:
        elf = ELFFile(rf)

        # Find the symbol table.
        symtab = elf.get_section_by_name('.symtab')

        i = 1
        for nsym, symbol in enumerate(symtab.iter_symbols()):  # pylint: disable=unused-variable
            symbol_type = describe_symbol_type(symbol['st_info']['type'])
            symbol_addr = symbol['st_value']
            symbol_size = symbol['st_size']

            if symbol_type == 'FUNC' and symbol_addr != 0:
                symbol_name = sanitize_func_name(symbol.name)
                dummy_offset = 0  # offsets will be calculated later after we know the first address
                entry = symtab_entry(
                    symbol_addr, symbol_size, dummy_offset, symbol_name)
                # Prevent entries with duplicated addresses
                if entry not in symtab_list:
                    symtab_list.append(entry)

        # Sort the address in ascending order
        symtab_list.sort(key=lambda x: x.addr, reverse=False)

        # Get the address of the first symbol
        first_addr = symtab_list[0].addr

        for i, entry in enumerate(symtab_list):
            # Offset is calculated here
            entry.offset = entry.addr - first_addr

            # Debug print
            log.debug('%6d: %s %s %.25s' % (
                i,
                hex(entry.addr),
                hex(entry.size),
                entry.name))

    with open(args.output, 'w') as wf:
        print("/* AUTO-GENERATED by gen_symtab.py, do not edit! */", file=wf)
        print("", file=wf)
        print("#include <zephyr/linker/sections.h>", file=wf)
        print("#include <zephyr/debug/symtab.h>", file=wf)
        print("", file=wf)
        print(
            f"const struct z_symtab_entry __symtab_entry z_symtab_entries[{len(symtab_list) + 1}] = {{", file=wf)
        for i, entry in enumerate(symtab_list):
            print(
                f"\t/* ADDR: {hex(entry.addr)} SIZE: {hex(entry.size)} */", file=wf)
            print(
                f"\t[{i}] = {{.offset = {hex(entry.offset)}, .name = \"{entry.name}\"}},", file=wf)

        # Append a dummy entry at the end to facilitate the binary search
        if symtab_list[-1].size == 0:
            dummy_offset = f"{hex(symtab_list[-1].offset)} + sizeof(uintptr_t)"
        else:
            dummy_offset = f"{hex(symtab_list[-1].offset + symtab_list[-1].size)}"
        print("\t/* dummy entry */", file=wf)
        print(
            f"\t[{len(symtab_list)}] = {{.offset = {dummy_offset}, .name = \"?\"}},", file=wf)
        print(f"}};\n", file=wf)

        print(f"const struct symtab_info __symtab_info z_symtab = {{", file=wf)
        print(f"\t.first_addr = {hex(first_addr)},", file=wf)
        print(f"\t.length = {len(symtab_list)},", file=wf)
        print(f"\t.entries = z_symtab_entries,", file=wf)
        print(f"}};\n", file=wf)


if __name__ == "__main__":
    main()
