# 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 os.path

import gdb


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.strip_typedefs().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)
