def _format_type(self, type: gdb.Type, force_name: str = None) -> Tuple[str, str]: if type.code == gdb.TYPE_CODE_PTR: target_pre, target_post = self._format_type(type.target()) return target_pre + "*", target_post elif type.code == gdb.TYPE_CODE_ARRAY: base = type.target() size = int(type.sizeof / base.sizeof) target_pre, target_post = self._format_type(type.target()) return target_pre, target_post + "[" + str(size) + "]" elif type.code == gdb.TYPE_CODE_STRUCT or type.code == gdb.TYPE_CODE_UNION: return self._format_struct(type, force_name) elif type.code == gdb.TYPE_CODE_TYPEDEF: return self._format_type(type.target(), force_name) elif type.code == gdb.TYPE_CODE_FUNC: pre = "".join(self._format_type(type.target())) + "(" arglist = type.fields() arglist_str = ", ".join("".join(self._format_type(x.type)) for x in arglist) return pre, ")(" + arglist_str + ")" else: return str(type), ""
def all_type_tags(gdb_type: gdb.Type, names=None, ops=None, seen=None) -> set: name_list = list(names or []) if isinstance(names, set) else names or [] seen = seen or set([]) ops = ops or [] prev_type = None while prev_type != gdb_type: prev_type = gdb_type gdb_type = gdb_type.unqualified() if str(gdb_type) in seen: break seen.add(str(gdb_type)) if gdb_type.tag is not None: print(" .. : <tag=%s>" % str(gdb_type.tag)) name_list.append(gdb_type.tag) if gdb_type.name is not None: print(" .. : <name=%s>" % str(gdb_type.name)) name_list.append(gdb_type.name) if gdb_type.code in \ (gdb.TYPE_CODE_PTR, gdb.TYPE_CODE_REF, gdb.TYPE_CODE_RVALUE_REF, gdb.TYPE_CODE_ARRAY): print(" .. [%s].target() -> %s" % (str(gdb_type), str(gdb_type.target()))) gdb_type = gdb_type.target() ops.append(gdb.Value.referenced_value) elif gdb_type.code in \ (gdb.TYPE_CODE_UNION, gdb.TYPE_CODE_STRUCT): next_base = next = None for field in gdb_type.fields(): if field.type in (prev_type, gdb_type, None if prev_type is None else prev_type.pointer(), gdb_type.pointer()): continue if field.is_base_class: print( f" [%s].{field.name} ***BASE_CLASS*** {str(field.type)}"\ % (str(field.parent_type))) all_type_tags( field.type, names=name_list, ops=(ops + [(lambda v: v.cast(field.parent_type)[field])]), seen=seen) elif gdb_type.code == gdb.TYPE_CODE_TYPEDEF: print(" [%s] typedef -> %s" % (str(gdb_type), str(gdb_type.strip_typedefs()))) ops.append(lambda v: v.cast(v.type.strip_typedefs())) gdb_type = gdb_type.strip_typedefs() return (set(name_list), ops)
def _is_ast(type_: gdb.Type) -> bool: if type_.code == gdb.TYPE_CODE_PTR: target = type_.target() return target.name == "ast_t" or _is_ast(target) elif type_.code == gdb.TYPE_CODE_TYPEDEF: return type_.name == "ast_ptr_t" return False
def get_basic_type(type: gdb.Type): """ """ if type.code == gdb.TYPE_CODE_REF: # Dereference type type = type.target() # Get unqualified type, strip typedefs type = type.unqualified().strip_typedefs() return type.tag
def get_struct_type(t: gdb.Type) -> Optional[gdb.Type]: """Return the "basic" type of a type. Arguments: type_: The type to reduce to its basic type. Returns: type_ with const/volatile is stripped away, and typedefs/references converted to the underlying type. """ t = t.strip_typedefs() while True: if t.code == gdb.TYPE_CODE_PTR or t.code == gdb.TYPE_CODE_REF or t.code == gdb.TYPE_CODE_RVALUE_REF: t = t.target() elif t.code == gdb.TYPE_CODE_ARRAY: t = t.target() elif t.code == gdb.TYPE_CODE_TYPEDEF: t = t.target() else: break if t.code != gdb.TYPE_CODE_STRUCT and t.code != gdb.TYPE_CODE_UNION: return None else: return t while (type_.code == gdb.TYPE_CODE_REF or type_.code == gdb.TYPE_CODE_RVALUE_REF or type_.code == gdb.TYPE_CODE_TYPEDEF or type_.code == gdb.TYPE_CODE_PTR): if (type_.code == gdb.TYPE_CODE_REF or type_.code == gdb.TYPE_CODE_RVALUE_REF or type_.code == gdb.TYPE_CODE_PTR): type_ = type_.target() else: type_ = type_.strip_typedefs() return type_.unqualified()
def get_basic_type(type_: gdb.Type) -> gdb.Type: """Return the "basic" type of a type. Arguments: type_: The type to reduce to its basic type. Returns: type_ with const/volatile is stripped away, and typedefs/references converted to the underlying type. """ while (type_.code == gdb.TYPE_CODE_REF or type_.code == gdb.TYPE_CODE_RVALUE_REF or type_.code == gdb.TYPE_CODE_TYPEDEF or type_.code == gdb.TYPE_CODE_PTR): if (type_.code == gdb.TYPE_CODE_REF or type_.code == gdb.TYPE_CODE_RVALUE_REF or type_.code == gdb.TYPE_CODE_PTR): type_ = type_.target() else: type_ = type_.strip_typedefs() return type_.unqualified()
def offsetof_type(gdbtype: gdb.Type, member_name: str, error: bool = True) -> Union[Tuple[int, gdb.Type], None]: """ Returns the offset and type of a named member of a structure Args: gdbtype (gdb.Type): The type that contains the specified member, must be a struct or union member_name (str): The member of the member to resolve error (bool, optional, default=True): Whether to consider lookup failures an error Returns: Tuple of: int: The offset of the resolved member gdb.Type: The type of the resolved member Raises: ArgumentTypeError: gdbtype is not of type gdb.Type InvalidComponentError: member_name is not valid for the type """ if not isinstance(gdbtype, gdb.Type): raise ArgumentTypeError('gdbtype', gdbtype, gdb.Type) # We'll be friendly and accept pointers as the initial type if gdbtype.code == gdb.TYPE_CODE_PTR: gdbtype = gdbtype.target() if gdbtype.code != gdb.TYPE_CODE_STRUCT and \ gdbtype.code != gdb.TYPE_CODE_UNION: raise NotStructOrUnionError('gdbtype', gdbtype) try: return __offsetof(gdbtype, member_name, error) except _InvalidComponentBaseError as e: if error: raise InvalidComponentError(gdbtype, member_name, str(e)) from e return None