#
# gdb helper commands and functions for Linux kernel debugging
#
#  module tools
#
# Copyright (c) Siemens AG, 2013
#
# Authors:
#  Jan Kiszka <jan.kiszka@siemens.com>
#
# This work is licensed under the terms of the GNU GPL version 2.
#

import gdb

from linux import cpus, utils


module_type = utils.CachedType("struct module")


def module_list():
    global module_type
    module_ptr_type = module_type.get_type().pointer()
    modules = gdb.parse_and_eval("modules")
    entry = modules['next']
    end_of_list = modules.address

    while entry != end_of_list:
        yield utils.container_of(entry, module_ptr_type, "list")
        entry = entry['next']


def find_module_by_name(name):
    for module in module_list():
        if module['name'].string() == name:
            return module
    return None


class LxModule(gdb.Function):
    """Find module by name and return the module variable.

$lx_module("MODULE"): Given the name MODULE, iterate over all loaded modules
of the target and return that module variable which MODULE matches."""

    def __init__(self):
        super(LxModule, self).__init__("lx_module")

    def invoke(self, mod_name):
        mod_name = mod_name.string()
        module = find_module_by_name(mod_name)
        if module:
            return module.dereference()
        else:
            raise gdb.GdbError("Unable to find MODULE " + mod_name)


LxModule()


class LxLsmod(gdb.Command):
    """List currently loaded modules."""

    _module_use_type = utils.CachedType("struct module_use")

    def __init__(self):
        super(LxLsmod, self).__init__("lx-lsmod", gdb.COMMAND_DATA)

    def invoke(self, arg, from_tty):
        gdb.write(
            "Address{0}    Module                  Size  Used by\n".format(
                "        " if utils.get_long_type().sizeof == 8 else ""))

        for module in module_list():
            gdb.write("{address} {name:<19} {size:>8}  {ref}".format(
                address=str(module['module_core']).split()[0],
                name=module['name'].string(),
                size=str(module['core_size']),
                ref=str(module['refcnt']['counter'])))

            source_list = module['source_list']
            t = self._module_use_type.get_type().pointer()
            entry = source_list['next']
            first = True
            while entry != source_list.address:
                use = utils.container_of(entry, t, "source_list")
                gdb.write("{separator}{name}".format(
                    separator=" " if first else ",",
                    name=use['source']['name'].string()))
                first = False
                entry = entry['next']
            gdb.write("\n")


LxLsmod()
