def _format_struct(self, type: gdb.Type, force_name: str = None) -> Tuple[str, str]: if utils.get_type_name_or_tag(type) is not None and force_name is None: # Named types are not expanded since they are declared before this type return self.get_type_name(utils.get_type_name_or_tag(type)), "" else: if force_name is not None: # Named types are always written as structs since they need to be subclassable out = "struct" else: if type.code == gdb.TYPE_CODE_UNION: out = "union" else: out = "struct" if force_name is not None: out += " " + force_name out += " {\n" for f in type.fields(): pre, post = self._format_type(f.type) out += "\n".join(" " + x for x in pre.splitlines()) out += (" " + f.name if f.name is not None else "") + post + ";\n" out += "}" return out, ""
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 _extract_type(type_: gdb.Type) -> Type: """ Extract a gdb.Type """ fields = [extract_field(f) for f in type_.fields()] template_arguments = [] try: i = 0 while True: arg = type_.template_argument(i) if isinstance(arg, gdb.Value): arg = _extract_value(arg) elif isinstance(arg, gdb.Type): arg = _extract_type(arg) else: raise ValueError("Template argument is not a gdb.Value or gdb.Type?") template_arguments.append(arg) i += 1 except gdb.error: pass return Type(type_code=type_.code, name=type_.name, size=type_.sizeof, tag=type_.tag, fields=fields, template_arguments=template_arguments )
def setup_pageflags(cls, gdbtype: gdb.Type) -> None: for field in gdbtype.fields(): cls.pageflags[field.name] = field.enumval cls.setup_pageflags_done = True if cls.setup_page_type_done and not cls.setup_pageflags_finish_done: cls.setup_pageflags_finish() cls.PG_slab = 1 << cls.pageflags['PG_slab'] cls.PG_lru = 1 << cls.pageflags['PG_lru']
def __populate_names(cls, enum_type: gdb.Type, items_name: str) -> Tuple[int, List[str]]: nr_items = enum_type[items_name].enumval names = ["__UNKNOWN__"] * nr_items for field in enum_type.fields(): if field.enumval < nr_items: names[field.enumval] = field.name return (nr_items, names)
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 setup_pageflags(cls, gdbtype: gdb.Type) -> None: for field in gdbtype.fields(): cls.pageflags[field.name] = field.enumval cls.setup_pageflags_done = True if cls.setup_page_type_done and not cls.setup_pageflags_finish_done: cls.setup_pageflags_finish() cls.PG_slab = 1 << cls.pageflags['PG_slab'] cls.PG_lru = 1 << cls.pageflags['PG_lru'] cls.PG_head = 1 << cls.pageflags['PG_head'] cls.PG_swapbacked = 1 << cls.pageflags['PG_swapbacked'] flags_check = 0 for flagname in _PAGE_FLAGS_CHECK_AT_FREE: flags_check |= 1 << cls.pageflags[flagname] cls.PAGE_FLAGS_CHECK_AT_FREE = flags_check cls.NR_PAGEFLAGS = cls.pageflags["__NR_PAGEFLAGS"] cls.PAGE_FLAGS_CHECK_AT_PREP = (1 << cls.NR_PAGEFLAGS) - 1
def _process_type_fields(self, parent_type: TypeWrapper, t: gdb.Type, agg: TypeAggregator): for f in t.fields(): field_t: gdb.Type = f.type self._process_type(parent_type, field_t, agg, f.name is None)
def setup_page_ext_flags(cls, gdbtype: gdb.Type) -> None: for field in gdbtype.fields(): cls.page_ext_flags[field.name] = field.enumval