Beispiel #1
0
class VectorCursorPrinter(PrettyPrinter):
    """Pretty-print Ada.Containers.Vectors.Cursor values."""

    name = 'Vector_Cursor'

    type_pattern = Match.TypeName(
        suffix='.cursor',
        pattern=Match.Struct(
            Match.Field('container',
                        Match.Pointer(VectorPrinter.type_pattern)),
            Match.Field('index', Match.Integer()),
        ))

    def to_string(self):
        if self.value['container']:
            vector = VectorPrinter(self.value['container'])
            index = self.value['index']
            try:
                element = str(vector.element(index))
            except gdb.MemoryError:
                return 'Cursor ([Invalid])'
            assoc = '{} => {}'.format(index, element)
        else:
            assoc = 'No_Element'
        return 'Cursor ({})'.format(assoc)
Beispiel #2
0
class VectorCursorPrinter(PrettyPrinter):
    """Pretty-print Ada.Containers.Vectors.Cursor values."""

    name = "Vector_Cursor"

    type_pattern = Match.TypeName(
        suffix=".cursor",
        pattern=Match.Struct(
            Match.Field("container",
                        Match.Pointer(VectorPrinter.type_pattern)),
            Match.Field("index", Match.Integer()),
        ),
    )

    def to_string(self):
        if self.value["container"]:
            vector = VectorPrinter(self.value["container"])
            index = self.value["index"]
            try:
                element = str(vector.element(index))
            except gdb.MemoryError:
                return "Cursor ([Invalid])"
            assoc = "{} => {}".format(index, element)
        else:
            assoc = "No_Element"
        return "Cursor ({})".format(assoc)
def get_rbtree_pattern(node_pattern):
    """
    Return the type pattern for red-black trees used in GNAT's implementation
    of standard containers for nodes that match the given `node_pattern`.
    """
    node_access_pattern = Match.Pointer(node_pattern)
    return Match.Struct(
        Match.Field("_tag"),
        Match.Field("first", node_access_pattern),
        Match.Field("last", node_access_pattern),
        Match.Field("root", node_access_pattern),
        Match.Field("length", Match.Integer()),
        Match.Field("tc"),
    )
Beispiel #4
0
class DoublyLinkedListPrinter(PrettyPrinter):
    """Pretty-print Ada.Containers.Doubly_Linked_Lists values."""

    name = "Doubly_Linked_List"

    node_pattern = Match.TypeName(
        suffix=".node_type",
        pattern=Match.Struct(
            Match.Field("element"),
            Match.Field("next", Match.Pointer()),
            Match.Field("prev", Match.Pointer()),
        ),
    )

    type_pattern = Match.TypeName(
        suffix=".list",
        pattern=Match.Struct(
            Match.Field("_parent"),
            Match.Field("first", Match.Pointer(node_pattern)),
            Match.Field("last", Match.Pointer(node_pattern)),
            Match.Field("length", Match.Integer()),
            Match.Field("tc"),
        ),
    )

    def display_hint(self):
        return "array"

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

    def children(self):
        if self.value["first"]:
            node = self.value["first"]
            for i in range(self.length):
                yield ("[{}]".format(i), node["element"])
                node = node["next"]
            if node:
                raise gdb.MemoryError("The linked list seems invalid")

    def to_string(self):
        return "{} of length {}".format(
            pretty_typename(self.value.type),
            self.length,
        )
Beispiel #5
0
class DoublyLinkedListPrinter(PrettyPrinter):
    """Pretty-print Ada.Containers.Doubly_Linked_Lists values."""

    name = 'Doubly_Linked_List'

    node_pattern = Match.TypeName(suffix='.node_type',
                                  pattern=Match.Struct(
                                      Match.Field('element'),
                                      Match.Field('next', Match.Pointer()),
                                      Match.Field('prev', Match.Pointer()),
                                  ))

    type_pattern = Match.TypeName(suffix='.list',
                                  pattern=Match.Struct(
                                      Match.Field('_parent'),
                                      Match.Field('first',
                                                  Match.Pointer(node_pattern)),
                                      Match.Field('last',
                                                  Match.Pointer(node_pattern)),
                                      Match.Field('length', Match.Integer()),
                                      Match.Field('tc'),
                                  ))

    def display_hint(self):
        return 'array'

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

    def children(self):
        if self.value['first']:
            node = self.value['first']
            for i in range(self.length):
                yield ('[{}]'.format(i), node['element'])
                node = node['next']
            if node:
                raise gdb.MemoryError('The linked list seems invalid')

    def to_string(self):
        return '{} of length {}'.format(
            pretty_typename(self.value.type),
            self.length,
        )
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'),
    )
Beispiel #7
0
class VectorPrinter(PrettyPrinter):
    """Pretty-print Ada.Containers.Vectors.Vector values."""

    name = "Vector"

    type_pattern = Match.TypeName(
        suffix=".vector",
        pattern=Match.Struct(
            Match.Field("_parent"),
            Match.Field(
                "elements",
                Match.Pointer(
                    Match.Struct(
                        Match.Field("last", Match.Integer()),
                        Match.Field("ea", Match.Array()),
                    )),
            ),
            Match.Field("last", Match.Integer()),
            Match.Field("tc"),
        ),
    )

    def display_hint(self):
        return "array"

    @property
    def array_bounds(self):
        elements = self.value["elements"]
        if not elements:
            return (1, 0)
        array_type = elements["ea"].type
        first_index, _ = array_type.range()
        last_index = int(self.value["last"])
        return (first_index, last_index)

    @property
    def length(self):
        first, last = self.array_bounds
        if first <= last:
            return last - first + 1
        else:
            return 0

    @property
    def array_elements(self):
        first, last = self.array_bounds
        if first <= last:
            base_value = self.value["elements"]["ea"]
            return base_value.cast(base_value.type.target().array(first, last))
        else:
            return None

    def element(self, index):
        first, last = self.array_bounds
        if first <= index and index <= last:
            return self.array_elements[index]
        else:
            raise gdb.MemoryError(
                "Out of bound vector access ({} not in {} ..  {})".format(
                    index, first, last))

    def children(self):
        elements = self.array_elements
        if elements:
            first_index, last_index = elements.type.range()
            for i in range(first_index, last_index + 1):
                elt = elements[i]
                elt.fetch_lazy()
                yield ("[{}]".format(i), elt)

    def to_string(self):
        return "{} of length {}".format(pretty_typename(self.value.type),
                                        self.length)
Beispiel #8
0
class VectorPrinter(PrettyPrinter):
    """Pretty-print Ada.Containers.Vectors.Vector values."""

    name = 'Vector'

    type_pattern = Match.TypeName(
        suffix='.vector',
        pattern=Match.Struct(
            Match.Field('_parent'),
            Match.Field(
                'elements',
                Match.Pointer(
                    Match.Struct(
                        Match.Field('last', Match.Integer()),
                        Match.Field('ea', Match.Array()),
                    ))),
            Match.Field('last', Match.Integer()),
            Match.Field('tc'),
        ))

    def display_hint(self):
        return 'array'

    @property
    def array_bounds(self):
        elements = self.value['elements']
        if not elements:
            return (1, 0)
        array_type = elements['ea'].type
        first_index, _ = array_type.range()
        last_index = int(self.value['last'])
        return (first_index, last_index)

    @property
    def length(self):
        first, last = self.array_bounds
        if first <= last:
            return last - first + 1
        else:
            return 0

    @property
    def array_elements(self):
        first, last = self.array_bounds
        if first <= last:
            base_value = self.value['elements']['ea']
            return base_value.cast(base_value.type.target().array(first, last))
        else:
            return None

    def element(self, index):
        first, last = self.array_bounds
        if first <= index and index <= last:
            return self.array_elements[index]
        else:
            raise gdb.MemoryError(
                'Out of bound vector access ({} not in {} ..  {})'.format(
                    index, first, last))

    def children(self):
        elements = self.array_elements
        if elements:
            first_index, last_index = elements.type.range()
            for i in range(first_index, last_index + 1):
                elt = elements[i]
                elt.fetch_lazy()
                yield ('[{}]'.format(i), elt)

    def to_string(self):
        return '{} of length {}'.format(pretty_typename(self.value.type),
                                        self.length)
Beispiel #9
0
import re

from gnatdbg.generics import Match

nr = gdb.parse_and_eval('nr')
r = gdb.parse_and_eval('r')
i = gdb.parse_and_eval('i')

# Only structs can match
assert not Match.Struct().match(i.type)
assert Match.Struct().match(nr.type)

# The number of fields must match
assert not Match.Struct(Match.Field('i')).match(nr.type)
assert Match.Struct(Match.Field('i')).match(r.type)

# The field names must match
assert not Match.Struct(Match.Field('o')).match(r.type)
assert Match.Struct(Match.Field('i')).match(r.type)

# The field types must match
assert not Match.Struct(Match.Field('i', Match.Char())).match(r.type)
assert Match.Struct(Match.Field('i', Match.Integer())).match(r.type)