Exemple #1
0
    def print_stats(obj: drgn.Object) -> None:
        names = [
            memb.name for memb in sdb.get_type('struct arc_stats').members
        ]

        for name in names:
            print("{:32} = {}".format(name, int(obj.member_(name).value.ui64)))
Exemple #2
0
def enum_lookup(enum_type_name: str, value: int) -> str:
    """return a string which is the short name of the enum value
    (truncating off the common prefix) """
    fields = sdb.get_type(enum_type_name).type.enumerators
    enum_string: str = fields[value].name
    prefix = os.path.commonprefix([f[0] for f in fields])
    return enum_string[prefix.rfind("_") + 1:]
Exemple #3
0
 def from_range_tree(self, rt: drgn.Object) -> Iterable[drgn.Object]:
     enum_dict = dict(sdb.get_type('enum range_seg_type').enumerators)
     range_seg_type_to_type = {
         enum_dict['RANGE_SEG32']: 'range_seg32_t*',
         enum_dict['RANGE_SEG64']: 'range_seg64_t*',
         enum_dict['RANGE_SEG_GAP']: 'range_seg_gap_t*',
     }
     seg_type_name = range_seg_type_to_type[int(rt.rt_type)]
     yield from sdb.execute_pipeline([rt.rt_root.address_of_()],
                                     [Btree(), Cast(seg_type_name)])
Exemple #4
0
def get_valid_type_by_name(cmd: sdb.Command, tname: str) -> drgn.Type:
    """
    Given a type name in string form (`tname`) without any C keyword
    prefixes (e.g. 'struct', 'enum', 'class', 'union'), return the
    corresponding drgn.Type object.

    This function is used primarily by commands that accept a type
    name as an argument and exist only to save keystrokes for the
    user.
    """
    if tname in ['struct', 'enum', 'union', 'class']:
        #
        # Note: We have to do this because currently in drgn
        # prog.type('struct') returns a different error than
        # prog.type('bogus'). The former returns a SyntaxError
        # "null identifier" while the latter returns LookupError
        # "could not find typedef bogus". The former is not
        # user-friendly and thus we just avoid that situation
        # by instructing the user to skip such keywords.
        #
        raise sdb.CommandError(
            cmd.name,
            f"skip keyword '{tname}' or quote your type \"{tname} <typename>\"")

    try:
        type_ = sdb.get_type(tname)
        if type_.kind == drgn.TypeKind.TYPEDEF and type_.type_name(
        ) == sdb.type_canonical_name(type_):
            #
            # In some C codebases there are typedefs like this:
            #
            #     typedef union GCObject GCObject; // taken from LUA repo
            #
            # The point of the above is to avoid typing the word
            # 'union' every time we declare a variable of that type.
            # For the purposes of SDB, passing around a drng.Type
            # describing the typedef above isn't particularly
            # useful. Using such an object with the `ptype` command
            # (one of the consumers of this function) would yield
            # the following:
            #
            #     sdb> ptype GCObject
            #     typedef union GCObject GCObject
            #
            # Resolving the typedef's explicitly in those cases
            # is more useful and this is why this if-clause exists.
            #
            #     sdb> ptype GCObject
            #     union GCObject {
            #             GCheader gch;
            #             union TString ts;
            #             ...
            #     }
            #
            return sdb.type_canonicalize(type_)
        return type_
    except LookupError:
        #
        # We couldn't find a type with that name. Check if
        # it is a structure, an enum, or a union.
        #
        pass
    for prefix in ["struct ", "enum ", "union "]:
        try:
            return sdb.get_type(f"{prefix}{tname}")
        except LookupError:
            pass
    raise sdb.CommandError(
        cmd.name,
        f"couldn't find typedef, struct, enum, nor union named '{tname}'")
Exemple #5
0
def get_valid_type_by_name(cmd: sdb.Command, tname: str) -> drgn.Type:
    """
    Given a type name in string form (`tname`) without any C keyword
    prefixes (e.g. 'struct', 'enum', 'class', 'union'), return the
    corresponding drgn.Type object. If `tname` starts with a C keyword
    we just return the type as is.

    This function is used primarily by commands that accept a type
    name as an argument and exist only to save keystrokes for the
    user.
    """
    TYPE_KEYWORDS = ['struct', 'enum', 'union', 'class']

    tokens = tname.split()
    if len(tokens) > 2:
        #
        # drgn fails in all kinds of ways when we pass it an
        # invalid type that consists of more than 2 text tokens.
        #
        raise sdb.CommandError(cmd.name,
                               f"input '{tname}' is not a valid type name")

    if len(tokens) == 2:
        if tokens[0] not in TYPE_KEYWORDS or tokens[1] in TYPE_KEYWORDS:
            #
            # For the same reason mentioned in the above comment
            # we also ensure that someone may not invalid two-token
            # input that has the following errors:
            # 1] Doesn't start with a type keyword - e.g "bogus type"
            # 2] Has a type keyword as its type name (also see
            #    comment below) - e.g. struct struct
            #
            raise sdb.CommandError(
                cmd.name, f"input '{tname}' is not a valid type name")
        try:
            return sdb.get_type(tname)
        except LookupError as err:
            raise sdb.CommandError(cmd.name,
                                   f"couldn't find type '{tname}'") from err
        except SyntaxError as err:
            raise sdb.CommandError(
                cmd.name, f"input '{tname}' is not a valid type name") from err

    if tname in TYPE_KEYWORDS:
        #
        # Note: We have to do this because currently in drgn
        # prog.type('struct') returns a different error than
        # prog.type('bogus'). The former returns a SyntaxError
        # "null identifier" while the latter returns LookupError
        # "could not find typedef bogus". The former is not
        # user-friendly and thus we just avoid that situation
        # by instructing the user to skip such keywords.
        #
        raise sdb.CommandError(
            cmd.name,
            f"skip keyword '{tname}' or quote your type \"{tname} <typename>\""
        )

    try:
        type_ = sdb.get_type(tname)
        if type_.kind == drgn.TypeKind.TYPEDEF and type_.type_name(
        ) == sdb.type_canonical_name(type_):
            #
            # In some C codebases there are typedefs like this:
            #
            #     typedef union GCObject GCObject; // taken from LUA repo
            #
            # The point of the above is to avoid typing the word
            # 'union' every time we declare a variable of that type.
            # For the purposes of SDB, passing around a drng.Type
            # describing the typedef above isn't particularly
            # useful. Using such an object with the `ptype` command
            # (one of the consumers of this function) would yield
            # the following:
            #
            #     sdb> ptype GCObject
            #     typedef union GCObject GCObject
            #
            # Resolving the typedef's explicitly in those cases
            # is more useful and this is why this if-clause exists.
            #
            #     sdb> ptype GCObject
            #     union GCObject {
            #             GCheader gch;
            #             union TString ts;
            #             ...
            #     }
            #
            return sdb.type_canonicalize(type_)
        return type_
    except LookupError:
        #
        # We couldn't find a type with that name. Check if
        # it is a structure, an enum, or a union.
        #
        pass
    except SyntaxError as err:
        raise sdb.CommandError(
            cmd.name, f"input '{tname}' is not a valid type name") from err
    for prefix in TYPE_KEYWORDS:
        try:
            return sdb.get_type(f"{prefix} {tname}")
        except LookupError:
            pass
    raise sdb.CommandError(
        cmd.name,
        f"couldn't find typedef, struct, enum, nor union named '{tname}'")