# Copyright (C) 2009-2024 Free Software Foundation, Inc.
#
# This file is part of GDB.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import gdb
import os.path


class TypeFlag:
    """A class that allows us to store a flag name, its short name,
    and its value.

    In the GDB sources, struct type has a component called instance_flags
    in which the value is the addition of various flags.  These flags are
    defined by the enumerates type_instance_flag_value.  This class helps us
    recreate a list with all these flags that is easy to manipulate and sort.
    Because all flag names start with TYPE_INSTANCE_FLAG_, a short_name
    attribute is provided that strips this prefix.

    ATTRIBUTES
      name:  The enumeration name (eg: "TYPE_INSTANCE_FLAG_CONST").
      value: The associated value.
      short_name: The enumeration name, with the suffix stripped.
    """

    def __init__(self, name, value):
        self.name = name
        self.value = value
        self.short_name = name.replace("TYPE_INSTANCE_FLAG_", "")

    def __lt__(self, other):
        """Sort by value order."""
        return self.value < other.value


# A list of all existing TYPE_INSTANCE_FLAGS_* enumerations,
# stored as TypeFlags objects.  Lazy-initialized.
TYPE_FLAGS = None


class TypeFlagsPrinter:
    """A class that prints a decoded form of an instance_flags value.

    This class uses a global named TYPE_FLAGS, which is a list of
    all defined TypeFlag values.  Using a global allows us to compute
    this list only once.

    This class relies on a couple of enumeration types being defined.
    If not, then printing of the instance_flag is going to be degraded,
    but it's not a fatal error.
    """

    def __init__(self, val):
        self.val = val

    def __str__(self):
        global TYPE_FLAGS
        if TYPE_FLAGS is None:
            self.init_TYPE_FLAGS()
        if not self.val:
            return "0"
        if TYPE_FLAGS:
            flag_list = [
                flag.short_name for flag in TYPE_FLAGS if self.val & flag.value
            ]
        else:
            flag_list = ["???"]
        return "0x%x [%s]" % (self.val, "|".join(flag_list))

    def init_TYPE_FLAGS(self):
        """Initialize the TYPE_FLAGS global as a list of TypeFlag objects.
        This operation requires the search of a couple of enumeration types.
        If not found, a warning is printed on stdout, and TYPE_FLAGS is
        set to the empty list.

        The resulting list is sorted by increasing value, to facilitate
        printing of the list of flags used in an instance_flags value.
        """
        global TYPE_FLAGS
        TYPE_FLAGS = []
        try:
            iflags = gdb.lookup_type("enum type_instance_flag_value")
        except:
            print("Warning: Cannot find enum type_instance_flag_value type.")
            print("         `struct type' pretty-printer will be degraded")
            return
        TYPE_FLAGS = [TypeFlag(field.name, field.enumval) for field in iflags.fields()]
        TYPE_FLAGS.sort()


class StructTypePrettyPrinter:
    """Pretty-print an object of type struct type"""

    def __init__(self, val):
        self.val = val

    def to_string(self):
        fields = []
        fields.append("pointer_type = %s" % self.val["pointer_type"])
        fields.append("reference_type = %s" % self.val["reference_type"])
        fields.append("chain = %s" % self.val["reference_type"])
        fields.append(
            "instance_flags = %s" % TypeFlagsPrinter(self.val["m_instance_flags"])
        )
        fields.append("length = %d" % self.val["m_length"])
        fields.append("main_type = %s" % self.val["main_type"])
        return "\n{" + ",\n ".join(fields) + "}"


class StructMainTypePrettyPrinter:
    """Pretty-print an objet of type main_type"""

    def __init__(self, val):
        self.val = val

    def flags_to_string(self):
        """struct main_type contains a series of components that
        are one-bit ints whose name start with "flag_".  For instance:
        flag_unsigned, flag_stub, etc.  In essence, these components are
        really boolean flags, and this method prints a short synthetic
        version of the value of all these flags.  For instance, if
        flag_unsigned and flag_static are the only components set to 1,
        this function will return "unsigned|static".
        """
        fields = [
            field.name.replace("flag_", "")
            for field in self.val.type.fields()
            if field.name.startswith("flag_") and self.val[field.name]
        ]
        return "|".join(fields)

    def owner_to_string(self):
        """Return an image of component "owner"."""
        if self.val["m_flag_objfile_owned"] != 0:
            return "%s (objfile)" % self.val["m_owner"]["objfile"]
        else:
            return "%s (gdbarch)" % self.val["m_owner"]["gdbarch"]

    def struct_field_location_img(self, field_val):
        """Return an image of the loc component inside the given field
        gdb.Value.
        """
        loc_val = field_val["m_loc"]
        loc_kind = str(field_val["m_loc_kind"])
        if loc_kind == "FIELD_LOC_KIND_BITPOS":
            return "bitpos = %d" % loc_val["bitpos"]
        elif loc_kind == "FIELD_LOC_KIND_ENUMVAL":
            return "enumval = %d" % loc_val["enumval"]
        elif loc_kind == "FIELD_LOC_KIND_PHYSADDR":
            return "physaddr = 0x%x" % loc_val["physaddr"]
        elif loc_kind == "FIELD_LOC_KIND_PHYSNAME":
            return "physname = %s" % loc_val["physname"]
        elif loc_kind == "FIELD_LOC_KIND_DWARF_BLOCK":
            return "dwarf_block = %s" % loc_val["dwarf_block"]
        else:
            return "m_loc = ??? (unsupported m_loc_kind value)"

    def struct_field_img(self, fieldno):
        """Return an image of the main_type field number FIELDNO."""
        f = self.val["flds_bnds"]["fields"][fieldno]
        label = "flds_bnds.fields[%d]:" % fieldno
        if f["m_artificial"]:
            label += " (artificial)"
        fields = []
        fields.append("m_name = %s" % f["m_name"])
        fields.append("m_type = %s" % f["m_type"])
        fields.append("m_loc_kind = %s" % f["m_loc_kind"])
        fields.append("bitsize = %d" % f["m_bitsize"])
        fields.append(self.struct_field_location_img(f))
        return label + "\n" + "  {" + ",\n   ".join(fields) + "}"

    def bound_img(self, bound_name):
        """Return an image of the given main_type's bound."""
        bounds = self.val["flds_bnds"]["bounds"].dereference()
        b = bounds[bound_name]
        bnd_kind = str(b["m_kind"])
        if bnd_kind == "PROP_CONST":
            return str(b["m_data"]["const_val"])
        elif bnd_kind == "PROP_UNDEFINED":
            return "(undefined)"
        else:
            info = [bnd_kind]
            if bound_name == "high" and bounds["flag_upper_bound_is_count"]:
                info.append("upper_bound_is_count")
            return "{} ({})".format(str(b["m_data"]["baton"]), ",".join(info))

    def bounds_img(self):
        """Return an image of the main_type bounds."""
        b = self.val["flds_bnds"]["bounds"].dereference()
        low = self.bound_img("low")
        high = self.bound_img("high")

        img = "flds_bnds.bounds = {%s, %s}" % (low, high)
        if b["flag_bound_evaluated"]:
            img += " [evaluated]"
        return img

    def type_specific_img(self):
        """Return a string image of the main_type type_specific union.
        Only the relevant component of that union is printed (based on
        the value of the type_specific_kind field.
        """
        type_specific_kind = str(self.val["type_specific_field"])
        type_specific = self.val["type_specific"]
        if type_specific_kind == "TYPE_SPECIFIC_NONE":
            img = "type_specific_field = %s" % type_specific_kind
        elif type_specific_kind == "TYPE_SPECIFIC_CPLUS_STUFF":
            img = "cplus_stuff = %s" % type_specific["cplus_stuff"]
        elif type_specific_kind == "TYPE_SPECIFIC_GNAT_STUFF":
            img = (
                "gnat_stuff = {descriptive_type = %s}"
                % type_specific["gnat_stuff"]["descriptive_type"]
            )
        elif type_specific_kind == "TYPE_SPECIFIC_FLOATFORMAT":
            img = "floatformat[0..1] = %s" % type_specific["floatformat"]
        elif type_specific_kind == "TYPE_SPECIFIC_FUNC":
            img = (
                "calling_convention = %d"
                % type_specific["func_stuff"]["calling_convention"]
            )
            # tail_call_list is not printed.
        elif type_specific_kind == "TYPE_SPECIFIC_SELF_TYPE":
            img = "self_type = %s" % type_specific["self_type"]
        elif type_specific_kind == "TYPE_SPECIFIC_FIXED_POINT":
            # The scaling factor is an opaque structure, so we cannot
            # decode its value from Python (not without insider knowledge).
            img = (
                "scaling_factor: <opaque> (call __gmpz_dump with "
                " _mp_num and _mp_den fields if needed)"
            )
        elif type_specific_kind == "TYPE_SPECIFIC_INT":
            img = "int_stuff = { bit_size = %d, bit_offset = %d }" % (
                type_specific["int_stuff"]["bit_size"],
                type_specific["int_stuff"]["bit_offset"],
            )
        else:
            img = (
                "type_specific = ??? (unknown type_specific_kind: %s)"
                % type_specific_kind
            )
        return img

    def to_string(self):
        """Return a pretty-printed image of our main_type."""
        fields = []
        fields.append("name = %s" % self.val["name"])
        fields.append("code = %s" % self.val["code"])
        fields.append("flags = [%s]" % self.flags_to_string())
        fields.append("owner = %s" % self.owner_to_string())
        fields.append("target_type = %s" % self.val["m_target_type"])
        if self.val["m_nfields"] > 0:
            for fieldno in range(self.val["m_nfields"]):
                fields.append(self.struct_field_img(fieldno))
        if self.val["code"] == gdb.TYPE_CODE_RANGE:
            fields.append(self.bounds_img())
        fields.append(self.type_specific_img())

        return "\n{" + ",\n ".join(fields) + "}"


class CoreAddrPrettyPrinter:
    """Print CORE_ADDR values as hex."""

    def __init__(self, val):
        self._val = val

    def to_string(self):
        return hex(int(self._val))


class IntrusiveListPrinter:
    """Print a struct intrusive_list."""

    def __init__(self, val):
        self._val = val

        # Type of linked items.
        self._item_type = self._val.type.template_argument(0)
        self._node_ptr_type = gdb.lookup_type(
            "intrusive_list_node<{}>".format(self._item_type.tag)
        ).pointer()

        # Type of value -> node converter.
        self._conv_type = self._val.type.template_argument(1)

        if self._uses_member_node():
            # The second template argument of intrusive_member_node is a member
            # pointer value.  Its value is the offset of the node member in the
            # enclosing type.
            member_node_ptr = self._conv_type.template_argument(1)
            member_node_ptr = member_node_ptr.cast(gdb.lookup_type("int"))
            self._member_node_offset = int(member_node_ptr)

            # This is only needed in _as_node_ptr if using a member node.  Look it
            # up here so we only do it once.
            self._char_ptr_type = gdb.lookup_type("char").pointer()

    def display_hint(self):
        return "array"

    def _uses_member_node(self):
        """Return True if the list items use a node as a member, False if
        they use a node as a base class.
        """

        if self._conv_type.name.startswith("intrusive_member_node<"):
            return True
        elif self._conv_type.name.startswith("intrusive_base_node<"):
            return False
        else:
            raise RuntimeError(
                "Unexpected intrusive_list value -> node converter type: {}".format(
                    self._conv_type.name
                )
            )

    def to_string(self):
        s = "intrusive list of {}".format(self._item_type)

        if self._uses_member_node():
            node_member = self._conv_type.template_argument(1)
            s += ", linked through {}".format(node_member)

        return s

    def _as_node_ptr(self, elem_ptr):
        """Given ELEM_PTR, a pointer to a list element, return a pointer to the
        corresponding intrusive_list_node.
        """

        assert elem_ptr.type.code == gdb.TYPE_CODE_PTR

        if self._uses_member_node():
            # Node as a member: add the member node offset from to the element's
            # address to get the member node's address.
            elem_char_ptr = elem_ptr.cast(self._char_ptr_type)
            node_char_ptr = elem_char_ptr + self._member_node_offset
            return node_char_ptr.cast(self._node_ptr_type)
        else:
            # Node as a base: just casting from node pointer to item pointer
            # will adjust the pointer value.
            return elem_ptr.cast(self._node_ptr_type)

    def _children_generator(self):
        """Generator that yields one tuple per list item."""

        elem_ptr = self._val["m_front"]
        idx = 0
        while elem_ptr != 0:
            yield (str(idx), elem_ptr.dereference())
            node_ptr = self._as_node_ptr(elem_ptr)
            elem_ptr = node_ptr["next"]
            idx += 1

    def children(self):
        return self._children_generator()


class HtabPrinter:
    """Pretty-printer for htab_t hash tables."""

    def __init__(self, val):
        self._val = val

    def display_hint(self):
        return "array"

    def to_string(self):
        n = int(self._val["n_elements"]) - int(self._val["n_deleted"])
        return "htab_t with {} elements".format(n)

    def children(self):
        size = int(self._val["size"])
        entries = self._val["entries"]

        child_i = 0
        for entries_i in range(size):
            entry = entries[entries_i]
            # 0 (NULL pointer) means there's nothing, 1 (HTAB_DELETED_ENTRY)
            # means there was something, but is now deleted.
            if int(entry) in (0, 1):
                continue

            yield (str(child_i), entry)
            child_i += 1


def type_lookup_function(val):
    """A routine that returns the correct pretty printer for VAL
    if appropriate.  Returns None otherwise.
    """
    tag = val.type.tag
    name = val.type.name
    if tag == "type":
        return StructTypePrettyPrinter(val)
    elif tag == "main_type":
        return StructMainTypePrettyPrinter(val)
    elif name == "CORE_ADDR":
        return CoreAddrPrettyPrinter(val)
    elif tag is not None and tag.startswith("intrusive_list<"):
        return IntrusiveListPrinter(val)
    elif name == "htab_t":
        return HtabPrinter(val)
    return None


def register_pretty_printer(objfile):
    """A routine to register a pretty-printer against the given OBJFILE."""
    objfile.pretty_printers.append(type_lookup_function)


if __name__ == "__main__":
    if gdb.current_objfile() is not None:
        # This is the case where this script is being "auto-loaded"
        # for a given objfile.  Register the pretty-printer for that
        # objfile.
        register_pretty_printer(gdb.current_objfile())
    else:
        # We need to locate the objfile corresponding to the GDB
        # executable, and register the pretty-printer for that objfile.
        # FIXME: The condition used to match the objfile is too simplistic
        # and will not work on Windows.
        for objfile in gdb.objfiles():
            if os.path.basename(objfile.filename) == "gdb":
                objfile.pretty_printers.append(type_lookup_function)
