示例#1
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)
示例#2
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)
示例#3
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)
示例#4
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)
示例#5
0
import re

from gnatdbg.generics import Match


s = gdb.parse_and_eval('s')
char_type = s.type.target()

# Only arrays can match
assert not Match.Array().match(s.type.target())
assert Match.Array().match(s.type)

# The element type must match
assert not Match.Array(element=Match.Array()).match(s.type)
assert Match.Array(element=Match.Char()).match(s.type)

# The first bound must match
assert not Match.Array(first=2).match(s.type)
assert Match.Array(first=1).match(s.type)

# The last bound must match
assert not Match.Array(last=1).match(s.type)
assert Match.Array(last=2).match(s.type)