Ejemplo n.º 1
0
def demangle_ctor_dtor_name(string):
    if string.peek() == "C":
        if string.peek(1) == "1":
            obj = DemangledCTORCompleteObject
        elif string.peek(1) == "2":
            obj = DemangledCTORBaseObject
        elif string.peek(1) == "3":
            obj = DemangledCTORCompleteObjectAllocating
        else:
            raise DemangledException("Unkown char in ctor-dtor-name")

        string.advance(2)

        return obj(string.last_name)
    elif string.peek() == "D":
        if string.peek(1) == "0":
            obj = DemangledDTORDeleting
        elif string.peek(1) == "1":
            obj = DemangledDTORCompleteObject
        elif string.peek(1) == "2":
            obj = DemangledDTORBaseObject
        else:
            raise DemangledException("Unkown char in ctor-dtor-name")

        string.advance(2)

        return obj(string.last_name)
    else:
        raise DemangledException("Unkown char in ctor-dtor-name")
Ejemplo n.º 2
0
def demangle_expr_primary(string):
    if not string.check("L"):
        raise DemangledException("Missing \"L\" in expr-primary")

    if string.peek() == "_":
        ret = demangle_mangled_name(string)
    else:
        type = demangle_type(string)

        obj = DemangledLiteral

        if string.peek() == "n":
            obj = DemangledLiteralNegative
            string.advance()

        count = 0
        while string.peek(count) != "E":
            if string.peek(count) == "":
                raise DemangledException("End of string in expr-primary")

            count += 1

        ret = obj(type, DemangledName(string.get(count)))

    if not string.check("E"):
        raise DemangledException("Missing \"E\" in expr-primary")

    return ret
Ejemplo n.º 3
0
def demangle_special_name(string):
    if string.check("T"):
        char = string.get()
        if char == "V":
            return DemangledVTable(demangle_type(string))
        elif char == "T":
            return DemangledVTT(demangle_type(string))
        elif char == "I":
            return DemangledTypeInfo(demangle_type(string))
        elif char == "S":
            return DemangledTypeInfoName(demangle_type(string))
        elif char == "h":
            demangle_call_offset(string, "h")

            return DemangledThunk(demangle_encoding(string, False))
        elif char == "v":
            demangle_call_offset(string, "v")

            return DemangledVirtualThunk(demangle_encoding(string, False))
        elif char == "c":
            demangle_call_offset(string, "")

            demangle_call_offset(string, "")

            return DemangledCovariantThunk(demangle_encoding(string, False))
        elif char == "C":
            derived = demangle_type(string)
            offset = demangle_number(string)

            if offset < 0:
                raise DemangledException(
                    "Negative offset number in special-name")

            if not string.check() == "_":
                raise DemangledException("Missing \"_\" in special-name")

            base = demangle_type(string)

            return DemangledConstructionVTable(base, derived)
        elif char == "F":
            return DemangledTypeInfoFunction(demangle_type(string))
        else:
            raise DemangledException("Unkown char in special-name")
    elif string.check("G"):
        char = string.get()

        if char == "V":
            return DemangledGuard(demangle_name(string))
        elif char == "R":
            return DemangledRefTemp(demangle_name(string))
        elif char == "A":
            return DemangledHiddenAlias(demangle_encoding(string, False))
        else:
            raise DemangledException("Unkown char in special-name")
    else:
        raise DemangledException("Unkown char in special-name")
Ejemplo n.º 4
0
def demangle_function_type(string):
    if not string.check("F"):
        raise DemangledException("Missing \"F\" in function-type")

    if string.peek() == "Y":
        string.advance()

    ret = demangle_bare_function_type(string, True)

    if not string.check("E"):
        raise DemangledException("Missing \"E\" in function-type")

    return ret
Ejemplo n.º 5
0
def demangle_template_args(string):
    hold_last_name = string.last_name

    if not string.check("I"):
        raise DemangledException("Missing \"I\" in template-args")

    al = None
    pal = None
    while True:
        a = demangle_template_arg(string)

        tmp = DemangledTemplateArgumentList(a, None)

        if al == None:
            al = tmp
            pal = tmp
        else:
            pal.right = tmp
            pal = tmp

        if string.peek() == "E":
            string.advance()
            break

    string.last_name = hold_last_name

    return al
Ejemplo n.º 6
0
def demangle_identifier(string, length):
    ret = string.get(length)

    if len(ret) != length:
        raise DemangledException("Invalid string length in identifier")

    # FIXME: Do stuff with anonymous namespaces here?

    return DemangledName(ret)
Ejemplo n.º 7
0
def demangle_discriminator(string):
    if string.peek() != "_":
        return

    string.advance()
    discrim = demangle_number(string)

    if discrim < 0:
        raise DemangledException("Negative number in discriminator")
Ejemplo n.º 8
0
def demangle_call_offset(string, c):
    if c == "":
        c = string.get()

    if c == "h":
        demangle_number(string)
    elif c == "v":
        demangle_number(string)

        if not string.check("_"):
            raise DemangledException("Missing \"_\" in call-offset")

        demangle_number(string)
    else:
        raise DemangledException("Not a call-offset")

    if not string.check("_"):
        raise DemangledException("Missing \"_\" in call-offset")
Ejemplo n.º 9
0
def demangle_template_param(string):
    if not string.check("T"):
        raise DemangledException("Missing \"T\" in template-param")
        return None

    if string.peek() == "_":
        param = 0
    else:
        param = demangle_number(string)

        if param < 0:
            raise DemangledException("Negative param in template-param")

        param += 1

    if not string.check("_"):
        raise DemangledException("Missing \"_\" in template-param")

    return DemangledTemplateParam(param)
Ejemplo n.º 10
0
def demangle_array_type(string):
    if not string.check("A"):
        raise DemangledException("Missing \"A\" in array-type")

    if string.peek() == "_":
        dim = None
    elif string.peek().isdigit():
        count = 0
        while string.peek(count) != None and string.peek(count).isdigit():
            count += 1

        dim = DemangledName(string.get(count))
    else:
        dim = demangle_expression(string)

    if not string.check("_"):
        raise DemangledException("Missing \"_\" in array-type")

    return DemangledArrayType(dim, demangle_type(string))
Ejemplo n.º 11
0
def demangle_source_name(string):
    length = demangle_number(string)

    if length <= 0:
        raise DemangledException("0 length number in source-name")

    ret = demangle_identifier(string, length)
    string.last_name = ret.name

    return ret
Ejemplo n.º 12
0
def demangle_nested_name(string):
    if not string.check("N"):
        raise DemangledException("Missing \"N\" in nested-name")

    (start, end) = demangle_CV_qualifiers(string, True)

    tmp = demangle_prefix(string)

    # Two cases: we can have no CV-qualifiers in which case start and end are
    # None and we just want to return tmp, otherwise tmp needs to be put into
    # the left part of end.  This is so much simpler with real pointers...
    if start == None:
        start = tmp
    else:
        end.left = tmp

    if not string.check("E"):
        raise DemangledException("Missing \"E\" in nested-name")

    return start
Ejemplo n.º 13
0
def demangle_local_name(string):
    if not string.check("Z"):
        raise DemangledException("Missing \"Z\" in local-name")

    function = demangle_encoding(string, False)

    if not string.check("E"):
        raise DemangledException("Missing \"E\" in local-name")

    if string.peek() == "s":
        string.advance()

        demangle_discriminator(string)

        return DemangledLocalName(function, DemangledName("string literal"))
    else:
        name = demangle_name(string)

        demangle_discriminator(string)

        return DemangledLocalName(function, name)
Ejemplo n.º 14
0
def demangle_template_arg(string):
    if string.peek() == "X":
        string.advance()
        ret = demangle_expression(string)

        if not string.check("E"):
            raise DemangledException("Missing \"E\" in template-arg")

        return ret
    elif string.peek() == "L":
        return demangle_expr_primary(string)
    else:
        return demangle_type(string)
Ejemplo n.º 15
0
def demangle_pointer_to_member_type(string):
    if not string.check("M"):
        raise DemangledException("Missing \"M\" in pointer-to-member-type")

    cl = demangle_type(string)

    (start, end) = demangle_CV_qualifiers(string, True)

    end.left = demangle_type(string)

    if start != end and not isinstance(end.left, DemangledFunctionType):
        add_substitution(string, start)

    return DemangledPointerMemoryType(cl, start)
Ejemplo n.º 16
0
def demangle_prefix(string):
    ret = None

    while True:
        peek = string.peek()

        if string.peek() == "":
            raise DemangledException("End of string in prefix")

        obj = DemangledQualifiedName

        if string.peek().isdigit() or string.peek().islower() or \
                string.peek() in ("C", "D", "L"):
            demangled = demangle_unqualified_name(string)
        elif string.peek() == "S":
            demangled = demangle_substitution(string, True)
        elif string.peek() == "I":
            if ret == None:
                raise DemangledException(
                    "No return type for template in prefix")

            obj = DemangledTemplate
            demangled = demangle_template_args(string)
        elif string.peek() == "T":
            demangled = demangle_template_param(string)
        elif string.peek() == "E":
            return ret
        else:
            raise DemangledException("Unkown char in prefix")

        if ret == None:
            ret = demangled
        else:
            ret = obj(ret, demangled)

        if peek != "S" and string.peek() != "E":
            add_substitution(string, ret)
Ejemplo n.º 17
0
def demangle_unqualified_name(string):
    peek = string.peek()

    if string.peek().isdigit():
        return demangle_source_name(string)
    elif string.peek().islower():
        return demangle_operator_name(string)
    elif string.peek() in ("C", "D"):
        return demangle_ctor_dtor_name(string)
    elif string.peek() == "L":
        string.advance()
        ret = demangle_source_name(string)

        demangle_discriminator(string)

        return ret
    else:
        raise DemangledException("Invalid char in unqualified-name")
Ejemplo n.º 18
0
def demangle_bare_function_type(string, has_return_type):
    if string.peek() == "J":
        string.advance()
        has_return_type = True

    return_type = None
    tl = None
    ptl = None

    while True:
        if string.peek() in ("", "E"):
            break

        type = demangle_type(string)

        if has_return_type:
            return_type = type
            has_return_type = False
        else:
            tmp = DemangledArgumentList(type, None)

            if tl == None:
                tl = tmp
                ptl = tmp
            else:
                ptl.right = tmp
                ptl = ptl.right

    if tl == None:
        raise DemangledException("Invalid bare-function-type")

    if tl.right == None and isinstance(tl.left, DemangledBuiltinType) and \
            tl.left.display == PrintType.void:
        tl = None

    return DemangledFunctionType(return_type, tl)
Ejemplo n.º 19
0
def demangle_type(string):
    # <builin type short name>:(<type representation>, <type printing>)
    builtin_dict = {
        "a": ("signed char", PrintType.default),
        "b": ("bool", PrintType.bool),
        "c": ("char", PrintType.default),
        "d": ("double", PrintType.float),
        "e": ("long double", PrintType.float),
        "f": ("float", PrintType.float),
        "g": ("__float128", PrintType.float),
        "h": ("unsigned char", PrintType.default),
        "i": ("int", PrintType.int),
        "j": ("unsigned int", PrintType.unsigned),
        "k": ("", PrintType.default),
        "l": ("long", PrintType.long),
        "m": ("unsigned long", PrintType.unsigned_long),
        "n": ("__int128", PrintType.default),
        "o": ("unsigned __int128", PrintType.default),
        "p": ("", PrintType.default),
        "q": ("", PrintType.default),
        "r": ("", PrintType.default),
        "s": ("short", PrintType.default),
        "t": ("unsigned short", PrintType.default),
        "u": ("", PrintType.default),
        "v": ("void", PrintType.void),
        "w": ("wchar_t", PrintType.default),
        "x": ("long long", PrintType.long_long),
        "y": ("unsigned long long", PrintType.unsigned_long_long),
        "z": ("...", PrintType.default)
    }

    peek = string.peek()

    if peek in ("r", "V", "K"):
        (start, end) = demangle_CV_qualifiers(string, False)

        end.left = demangle_type(string)

        add_substitution(string, start)

        return start

    can_subst = True

    if builtin_dict.has_key(peek):
        ret = DemangledBuiltinType(builtin_dict[peek])

        string.advance()
        can_subst = False
    elif peek == "u":
        string.advance()
        ret = DemangledVendorType(demangle_source_name(string))
    elif peek == "F":
        ret = demangle_function_type(string)
    elif peek in ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "N", "Z"):
        ret = demangle_class_enum_type(string)
    elif peek == "A":
        ret = demangle_array_type(string)
    elif peek == "M":
        ret = demangle_pointer_to_member_type(string)
    elif peek == "T":
        ret = demangle_template_param(string)

        if string.peek() == "I":
            add_substitution(ret)

            ret = DemangledTemplate(ret, demangle_template_args(string))
    elif peek == "S":
        peek_next = string.peek(1)
        if peek_next.isdigit() or peek_next == "_" or peek_next.isupper():
            ret = demangle_substitution(string, False)

            if string.peek() == "I":
                ret = DemangledTemplate(ret, demangle_template_args(string))
            else:
                can_subst = False
        else:
            ret = demangle_class_enum_type(string)

            if isinstance(ret, DemangledSubstitution):
                can_subst = False
    elif peek == "P":
        string.advance()

        ret = DemangledPointer(demangle_type(string))
    elif peek == "R":
        string.advance()

        ret = DemangledReference(demangle_type(string))
    elif peek == "C":
        string.advance()

        ret = DemangledComplex(demangle_type(string))
    elif peek == "G":
        string.advance()

        ret = DemangledImaginary(demangle_type(string))
    elif peek == "U":
        string.advance()

        ret = demangle_source_name(string)
        ret = DemangledVendorTypeQualified(demangle_type(string), ret)
    else:
        raise DemangledException("Unkown char in type")

    if can_subst:
        add_substitution(string, ret)

    return ret
Ejemplo n.º 20
0
def demangle_operator_name(string):
    # <operator short name>:(<operator representation>, <argument count>)
    op_dict = {
        "aN": ("&=", 2),
        "aS": ("=", 2),
        "aa": ("&&", 2),
        "ad": ("&", 1),
        "an": ("&", 2),
        "cl": ("()", 0),
        "cm": (",", 2),
        "co": ("~", 1),
        "dV": ("/=", 2),
        "da": ("delete[]", 1),
        "de": ("*", 1),
        "dl": ("delete", 1),
        "dv": ("/", 2),
        "eO": ("^=", 2),
        "eo": ("^", 2),
        "eq": ("==", 2),
        "ge": (">=", 2),
        "gt": (">", 2),
        "ix": ("[]", 2),
        "lS": ("<<=", 2),
        "le": ("<=", 2),
        "ls": ("<<", 2),
        "lt": ("<", 2),
        "mI": ("-=", 2),
        "mL": ("*=", 2),
        "mi": ("-", 2),
        "ml": ("*", 2),
        "mm": ("--", 1),
        "na": ("new[]", 1),
        "ne": ("!=", 2),
        "ng": ("-", 1),
        "nt": ("!", 1),
        "nw": ("new", 1),
        "oR": ("|=", 2),
        "oo": ("||", 2),
        "or": ("|", 2),
        "pL": ("+=", 2),
        "pl": ("+", 2),
        "pm": ("->*", 2),
        "pp": ("++", 1),
        "ps": ("+", 1),
        "pt": ("->", 2),
        "qu": ("?", 3),
        "rM": ("%=", 2),
        "rS": (">>=", 2),
        "rm": ("%", 2),
        "rs": (">>", 2),
        "st": ("sizeof ", 1),
        "sz": ("sizeof ", 1)
    }

    if string.peek() == "v" and string.peek(1).isdigit():
        string.advance()
        vendor_id = int(string.get())

        return DemangledExtendedOperator(vendor_id, \
                demangle_source_name(string))
    elif string.peek(length=2) == "cv":
        string.advance(2)

        return DemangledCast(demangle_type(string), None)
    else:
        op_id = string.peek(length=2)

        if op_dict.has_key(op_id):
            (name, args) = op_dict[op_id]
            string.advance(2)

            return DemangledOperator(name, args)
        else:
            raise DemangledException("Invalid operator-name")
Ejemplo n.º 21
0
def demangle_mangled_name(string, top_level):
    if not string.get(2) == "_Z":
        raise DemangledException("Missing \"_Z\" in mangled-name")

    return demangle_encoding(string, top_level)
Ejemplo n.º 22
0
def demangle_substitution(string, prefix):
    subs_dict = {
        "t": ("std", "std", None),
        "a": ("std::allocator", "std::allocator", "allocator"),
        "b": ("std::basic_string", "std::basic_string", "basic_string"),
        "s":
        ("std::string",
         "std::basic_string<char, std::char_traits<char>, std::allocator<char> >",
         "basic_string"),
        "i":
        ("std::istream", "std::basic_istream<char, std::char_traits<char> >",
         "basic_istream"),
        "o":
        ("std::ostream", "std::basic_ostream<char, std::char_traits<char> >",
         "basic_ostream"),
        "d":
        ("std::iostream", "std::basic_iostream<char, std::char_traits<char> >",
         "basic_iostream")
    }

    if not string.check("S"):
        raise DemangledException("Missing \"S\" in substitution")

    c = string.get()

    if c == "_" or c.isdigit() or c.isupper():
        id = 0

        if c != "_":
            while True:
                if c != "":
                    id = id * 36 + int(c, 36)
                else:
                    raise DemangledException("Out of digits in substitution")

                c = string.get()

                if c == "_":
                    break

            id += 1

        if id >= len(string.subs):
            raise DemangledException("Id out of range of subs in substitution")

        return string.subs[id]
    else:
        # FIXME: by default c++filt has verbose on
        # This probably should be a config variable?
        verbose = True

        if prefix:
            peek = string.peek()

            if peek in ("C", "D"):
                verbose = True

        if subs_dict.has_key(c):
            std_sub = subs_dict[c]

            if std_sub[2] != None:
                string.last_name = std_sub[2]

            if verbose:
                s = std_sub[1]
            else:
                s = std_sub[0]

            return DemangledSubstitution(s)
        else:
            raise DemangledException("Unkown char in substitution")