示例#1
0
class OrderedSetPrinter(BaseSetPrinter):
    """Pretty-print Ada.Containers.Ordered_Sets.Set values."""

    name = 'Ordered_Set'

    type_pattern = Match.TypeName(
        suffix='.set',
        pattern=Match.Struct(
            Match.Field('_parent'),
            Match.Field(
                'tree',
                get_rbtree_pattern(
                    Match.Struct(
                        Match.Field('parent', Match.Typedef(Match.Pointer())),
                        Match.Field('left', Match.Typedef(Match.Pointer())),
                        Match.Field('right', Match.Typedef(Match.Pointer())),
                        Match.Field('color', Match.Enum()),
                        Match.Field('element'),
                    ))),
        ))

    @property
    def length(self):
        return self.value['tree']['length']

    def get_node_iterator(self):
        return dfs(self.value['tree'])
示例#2
0
class OrderedSetPrinter(BaseSetPrinter):
    """Pretty-print Ada.Containers.Ordered_Sets.Set values."""

    name = "Ordered_Set"

    type_pattern = Match.TypeName(
        suffix=".set",
        pattern=Match.Struct(
            Match.Field("_parent"),
            Match.Field(
                "tree",
                get_rbtree_pattern(
                    Match.Struct(
                        Match.Field("parent", Match.Typedef(Match.Pointer())),
                        Match.Field("left", Match.Typedef(Match.Pointer())),
                        Match.Field("right", Match.Typedef(Match.Pointer())),
                        Match.Field("color", Match.Enum()),
                        Match.Field("element"),
                    )),
            ),
        ),
    )

    @property
    def length(self):
        return self.value["tree"]["length"]

    def get_node_iterator(self):
        return dfs(self.value["tree"])
示例#3
0
class HashedSetPrinter(BaseSetPrinter):
    """Pretty-print Ada.Containers.Hashed_Sets.Set values."""

    name = "Hashed_Set"

    type_pattern = Match.TypeName(
        suffix=".set",
        pattern=Match.Struct(
            Match.Field("_parent"),
            Match.Field(
                "ht",
                get_htable_pattern(
                    Match.Struct(
                        Match.Field("element"),
                        Match.Field("next", Match.Typedef(Match.Pointer())),
                    )),
            ),
        ),
    )

    @property
    def length(self):
        return self.value["ht"]["length"]

    def get_node_iterator(self):
        return iterate(self.value["ht"])
示例#4
0
class StringAccess(object):
    """
    Helper class to inspect String accesses.
    """

    type_pattern = Match.Typedef(
        Match.Struct(
            Match.Field('P_ARRAY',
                        Match.Pointer(Match.Array(element=Match.Char(), ))),
            Match.Field('P_BOUNDS'),
        ))

    default_encodings = {
        1: None,
        2: 'utf-16',
        4: 'utf-32',
    }

    def __init__(self, value):
        if not self.matches(value):
            raise TypeError('Input is not an access to string')
        self.value = value

    @classmethod
    def matches(cls, value):
        """
        Return whether `value` is a string access.

        :param gdb.Value value: Value to test.
        :rtype: bool
        """
        return cls.type_pattern.match(value.type)

    @property
    def bounds(self):
        """
        Return the bounds of the accessed string.

        :rtype: (int, int)
        """
        struct = self.value['P_BOUNDS']
        return (int(struct['LB0']), int(struct['UB0']))

    @property
    def length(self):
        lb, ub = self.bounds
        return 0 if lb > ub else (ub - lb + 1)

    def get_string(self, encoding=None, errors=None):
        """
        Return the accessed string.

        :rtype: str
        """
        return _fetch_string(self.value['P_ARRAY'], self.length, encoding,
                             errors)
示例#5
0
def get_htable_pattern(node_pattern):
    """
    Return the type pattern for hash tables used in GNAT's implementation of
    standard containers for nodes that match the given `node_pattern`.
    """
    # TODO: unfortunately, due to the current state of DWARF/GDB, it is not
    # possible to reach `node_pattern` through hash table's value type.
    return Match.Struct(
        Match.Field('_tag'),
        # See below for the type of `buckets`.
        Match.Field(
            'buckets',
            Match.Typedef(
                Match.Struct(
                    Match.Field('P_ARRAY', Match.Pointer()),
                    Match.Field('P_BOUNDS', Match.Pointer()),
                ))),
        Match.Field('length', Match.Integer()),
        Match.Field('tc'),
    )
示例#6
0
class HashedSetPrinter(BaseSetPrinter):
    """Pretty-print Ada.Containers.Hashed_Sets.Set values."""

    name = 'Hashed_Set'

    type_pattern = Match.TypeName(
        suffix='.set',
        pattern=Match.Struct(
            Match.Field('_parent'),
            Match.Field(
                'ht',
                get_htable_pattern(
                    Match.Struct(
                        Match.Field('element'),
                        Match.Field('next', Match.Typedef(Match.Pointer())),
                    ))),
        ))

    @property
    def length(self):
        return self.value['ht']['length']

    def get_node_iterator(self):
        return iterate(self.value['ht'])
示例#7
0
class StringAccess(object):
    """
    Helper class to inspect String accesses.
    """

    type_pattern = Match.Typedef(
        Match.Struct(
            Match.Field(
                "P_ARRAY",
                Match.Pointer(
                    Match.Array(
                        element=Match.Char(),
                    )
                ),
            ),
            Match.Field("P_BOUNDS"),
        )
    )

    def __init__(self, value):
        if not self.matches(value):
            raise TypeError("Input is not an access to string")
        self.value = value

    @classmethod
    def matches(cls, value):
        """
        Return whether `value` is a string access.

        :param gdb.Value value: Value to test.
        :rtype: bool
        """
        return cls.type_pattern.match(value.type)

    @property
    def bounds(self):
        """
        Return the bounds of the accessed string.

        :rtype: (int, int)
        """
        struct = self.value["P_BOUNDS"]
        return (int(struct["LB0"]), int(struct["UB0"]))

    @property
    def length(self):
        lb, ub = self.bounds
        return 0 if lb > ub else (ub - lb + 1)

    def _ptr(self):
        """Return the string pointer for this value."""
        access = self.value["P_ARRAY"]
        ptr_to_elt_type = access.type.target().target().pointer()
        return access.cast(ptr_to_elt_type)

    @property
    def is_valid(self):
        """Return True if the string is valid (has non-zero address)."""
        return self._ptr() != 0

    def get_string(self):
        """
        Return the accessed string.

        :rtype: str
        """
        return self._ptr().lazy_string(length=self.length)