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)
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)
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)
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)