static void Main(string[] args)
            {
                bool            is_verbose     = false;
                bool            show_help      = false;
                CLRPH_DEMANGLER demangler_name = CLRPH_DEMANGLER.Default;

                OptionSet opts = new OptionSet()
                {
                    { "v|verbose", "redirect debug traces to console", v => is_verbose = v != null },
                    { "h|help", "show this message and exit", v => show_help = v != null },
                    { "d=|demangler=", "Choose demangler name", v => demangler_name = ParseDemanglerName(v) },
                };

                List <string> eps = opts.Parse(args);

                if (show_help)
                {
                    ShowHelp(opts);
                    return;
                }

                if (is_verbose)
                {
                    // Redirect debug log to the console
                    Debug.Listeners.Add(new TextWriterTraceListener(Console.Out));
                    Debug.AutoFlush = true;
                }

                // always the first call to make
                Phlib.InitializePhLib();
                Demangler demangler;

                switch (args.Length)
                {
                case 0:
                    demangler = new Demangler(CLRPH_DEMANGLER.Microsoft);
                    TestKnownInputs(demangler);
                    break;

                default:
                case 1:
                    demangler = new Demangler(demangler_name);
                    string Filepath = args[1];

                    if (NativeFile.Exists(Filepath))
                    {
                        TestFilepath(Filepath, demangler);
                    }
                    else
                    {
                        string undecoratedName = demangler.UndecorateName(args[1]).Item2;
                        Console.WriteLine(undecoratedName);
                    }

                    break;
                }

                // Force flushing out buffer
                Console.Out.Flush();
            }
Beispiel #2
0
            static bool TestFilepath(string Filepath, Demangler SymPrv)
            {
                PE Pe = new PE(Filepath);

                if (!Pe.Load())
                {
                    Console.Error.WriteLine("[x] Could not load file {0:s} as a PE", Filepath);
                    return(false);
                }

                foreach (PeExport Export in Pe.GetExports())
                {
                    if (Export.Name.Length > 0)
                    {
                        Console.Write("\t Export : {0:s} -> ", Export.Name);
                        Console.Out.Flush();
                        Console.WriteLine("{0:s}", SymPrv.UndecorateName(Export.Name));
                    }
                }

                foreach (PeImportDll DllImport in Pe.GetImports())
                {
                    foreach (PeImport Import in DllImport.ImportList)
                    {
                        if (!Import.ImportByOrdinal)
                        {
                            Console.Write("\t Import from {0:s} : {1:s} -> ", DllImport.Name, Import.Name);
                            Console.Out.Flush();
                            Console.WriteLine("{0:s}", SymPrv.UndecorateName(Import.Name));
                        }
                    }
                }

                return(true);
            }
        private bool AnalyzePointerFromImages(out PointerInfo info, ulong address)
        {
            info = default;

            Image image = GetImage(address, out int imageIndex);

            if (image == null)
            {
                // Value isn't a pointer to a known image...
                return(false);
            }

            info.Offset = address - image.BaseAddress;

            // Try to find what this pointer is referring to
            if (TryGetSubName(image, address, out ElfSymbol symbol))
            {
                info.SubName = symbol.Name;

                // Demangle string if possible
                if (info.SubName.StartsWith("_Z"))
                {
                    info.SubName = Demangler.Parse(info.SubName);
                }
                info.SubOffset = info.Offset - symbol.Value;
            }
            else
            {
                info.SubName = "";
            }

            info.ImageName = GetGuessedNsoNameFromIndex(imageIndex);

            return(true);
        }
Beispiel #4
0
        public void Demangling()
        {
            ITypeDeclaration q;
            bool             isCFun;
            var t = Demangler.Demangle("_D3std5stdio35__T7writelnTC3std6stream4FileTAAyaZ7writelnFC3std6stream4FileAAyaZv", out q, out isCFun);

            Assert.IsFalse(isCFun);
        }
Beispiel #5
0
        public void PrintGuestStackTrace(CpuThreadState threadState)
        {
            EnsureLoaded();

            StringBuilder trace = new StringBuilder();

            trace.AppendLine("Guest stack trace:");

            void AppendTrace(long address)
            {
                Image image = GetImage(address, out int imageIndex);

                if (image == null || !TryGetSubName(image, address, out string subName))
                {
                    subName = $"Sub{address:x16}";
                }
                else if (subName.StartsWith("_Z"))
                {
                    subName = Demangler.Parse(subName);
                }

                if (image != null)
                {
                    long offset = address - image.BaseAddress;

                    string imageName = GetGuessedNsoNameFromIndex(imageIndex);

                    string imageNameAndOffset = $"[{_owner.Name}] {imageName}:0x{offset:x8}";

                    trace.AppendLine($" {imageNameAndOffset} {subName}");
                }
                else
                {
                    trace.AppendLine($" [{_owner.Name}] ??? {subName}");
                }
            }

            //TODO: ARM32.
            long framePointer = (long)threadState.X29;

            while (framePointer != 0)
            {
                if ((framePointer & 7) != 0 ||
                    !_owner.CpuMemory.IsMapped(framePointer) ||
                    !_owner.CpuMemory.IsMapped(framePointer + 8))
                {
                    break;
                }

                //Note: This is the return address, we need to subtract one instruction
                //worth of bytes to get the branch instruction address.
                AppendTrace(_owner.CpuMemory.ReadInt64(framePointer + 8) - 4);

                framePointer = _owner.CpuMemory.ReadInt64(framePointer);
            }

            Logger.PrintInfo(LogClass.Cpu, trace.ToString());
        }
        public void PrintGuestStackTrace(CpuThreadState ThreadState)
        {
            EnsureLoaded();

            StringBuilder Trace = new StringBuilder();

            Trace.AppendLine("Guest stack trace:");

            void AppendTrace(long Address)
            {
                Image Image = GetImage(Address, out int ImageIndex);

                if (Image == null || !TryGetSubName(Image, Address, out string SubName))
                {
                    SubName = $"Sub{Address:x16}";
                }
                else if (SubName.StartsWith("_Z"))
                {
                    SubName = Demangler.Parse(SubName);
                }

                if (Image != null)
                {
                    long Offset = Address - Image.BaseAddress;

                    string ImageName = GetGuessedNsoNameFromIndex(ImageIndex);

                    string ImageNameAndOffset = $"[{Owner.Name}] {ImageName}:0x{Offset:x8}";

                    Trace.AppendLine($" {ImageNameAndOffset} {SubName}");
                }
                else
                {
                    Trace.AppendLine($" [{Owner.Name}] ??? {SubName}");
                }
            }

            long FramePointer = (long)ThreadState.X29;

            while (FramePointer != 0)
            {
                if ((FramePointer & 7) != 0 ||
                    !Owner.CpuMemory.IsMapped(FramePointer) ||
                    !Owner.CpuMemory.IsMapped(FramePointer + 8))
                {
                    break;
                }

                //Note: This is the return address, we need to subtract one instruction
                //worth of bytes to get the branch instruction address.
                AppendTrace(Owner.CpuMemory.ReadInt64(FramePointer + 8) - 4);

                FramePointer = Owner.CpuMemory.ReadInt64(FramePointer);
            }

            Logger.PrintInfo(LogClass.Cpu, Trace.ToString());
        }
Beispiel #7
0
        public string GetGuestStackTrace(ARMeilleure.State.ExecutionContext context)
        {
            EnsureLoaded();

            StringBuilder trace = new StringBuilder();

            void AppendTrace(long address)
            {
                Image image = GetImage(address, out int imageIndex);

                if (image == null || !TryGetSubName(image, address, out string subName))
                {
                    subName = $"Sub{address:x16}";
                }
                else if (subName.StartsWith("_Z"))
                {
                    subName = Demangler.Parse(subName);
                }

                if (image != null)
                {
                    long offset = address - image.BaseAddress;

                    string imageName = GetGuessedNsoNameFromIndex(imageIndex);

                    trace.AppendLine($"   {imageName}:0x{offset:x8} {subName}");
                }
                else
                {
                    trace.AppendLine($"   ??? {subName}");
                }
            }

            // TODO: ARM32.
            long framePointer = (long)context.GetX(29);

            trace.AppendLine($"Process: {_owner.Name}, PID: {_owner.Pid}");

            while (framePointer != 0)
            {
                if ((framePointer & 7) != 0 ||
                    !_owner.CpuMemory.IsMapped(framePointer) ||
                    !_owner.CpuMemory.IsMapped(framePointer + 8))
                {
                    break;
                }

                // Note: This is the return address, we need to subtract one instruction
                // worth of bytes to get the branch instruction address.
                AppendTrace(_owner.CpuMemory.ReadInt64(framePointer + 8) - 4);

                framePointer = _owner.CpuMemory.ReadInt64(framePointer);
            }

            return(trace.ToString());
        }
Beispiel #8
0
            static bool TestKnownInputs(Demangler SymPrv)
            {
                Debug.Assert(SymPrv.UndecorateName("??1type_info@@UEAA@XZ") == "public: virtual __cdecl type_info::~type_info(void) __ptr64");
                Debug.Assert(SymPrv.UndecorateName("?setbuf@strstreambuf@@UEAAPEAVstreambuf@@PEADH@Z") == "public: virtual class streambuf * __ptr64 __cdecl strstreambuf::setbuf(char * __ptr64,int) __ptr64");
                Debug.Assert(SymPrv.UndecorateName("?CreateXBaby@XProvider@DirectUI@@UEAAJPEAVIXElementCP@2@PEAUHWND__@@PEAVElement@2@PEAKPEAPEAUIXBaby@2@@Z") == "public: virtual long __cdecl DirectUI::XProvider::CreateXBaby(class DirectUI::IXElementCP * __ptr64,struct HWND__ * __ptr64,class DirectUI::Element * __ptr64,unsigned long * __ptr64,struct DirectUI::IXBaby * __ptr64 * __ptr64) __ptr64");
                Debug.Assert(SymPrv.UndecorateName("??0exception@@QEAA@AEBQEBDH@Z") == "public: __cdecl exception::exception(char const * __ptr64 const & __ptr64,int) __ptr64");
                Debug.Assert(SymPrv.UndecorateName("?what@exception@@UEBAPEBDXZ") == "public: virtual char const * __ptr64 __cdecl exception::what(void)const __ptr64");
                Debug.Assert(SymPrv.UndecorateName("?_Execute_once@std@@YAHAEAUonce_flag@1@P6AHPEAX1PEAPEAX@Z1@Z") == "int __cdecl std::_Execute_once(struct std::once_flag & __ptr64,int (__cdecl*)(void * __ptr64,void * __ptr64,void * __ptr64 * __ptr64),void * __ptr64)");
                Debug.Assert(SymPrv.UndecorateName("?swap@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@IEAAXAEAV12@@Z") == "protected: void __cdecl std::basic_streambuf<wchar_t,struct std::char_traits<wchar_t> >::swap(class std::basic_streambuf<wchar_t,struct std::char_traits<wchar_t> > & __ptr64) __ptr64");

                Console.WriteLine("demangler-test : all known inputs OK");
                return(true);
            }
Beispiel #9
0
        public override void DumpFields(Indenter stream)
        {
            base.DumpFields(stream);

            System.Text.StringBuilder mangled = new System.Text.StringBuilder(64);
            this.Encode(mangled);
            stream.WriteLine("Mangled = {0}", mangled.ToString());
            stream.WriteLine("Demangled = {0}", Demangler.Decode(mangled.ToString()));

            foreach (ParameterDeclaration parameter in _parameters)
            {
                stream.WriteLine("Parameter = {0,4:D4}", parameter.Id);
            }
            stream.WriteLine("Body = {0,4:D4}", (_body == null) ? "null" : _body.Id.ToString("D4"));
        }
Beispiel #10
0
        public void PrintStackTrace(AThreadState ThreadState)
        {
            StringBuilder Trace = new StringBuilder();

            Trace.AppendLine("Guest stack trace:");

            void AppendTrace(long Position)
            {
                Executable Exe = GetExecutable(Position);

                if (Exe == null)
                {
                    return;
                }

                if (!TryGetSubName(Exe, Position, out string SubName))
                {
                    SubName = $"Sub{Position:x16}";
                }
                else if (SubName.StartsWith("_Z"))
                {
                    SubName = Demangler.Parse(SubName);
                }

                long Offset = Position - Exe.ImageBase;

                string ExeNameWithAddr = $"{Exe.Name}:0x{Offset:x8}";

                Trace.AppendLine(" " + ExeNameWithAddr + " " + SubName);
            }

            long FramePointer = (long)ThreadState.X29;

            while (FramePointer != 0)
            {
                AppendTrace(Memory.ReadInt64(FramePointer + 8));

                FramePointer = Memory.ReadInt64(FramePointer);
            }

            Logger.PrintInfo(LogClass.Cpu, Trace.ToString());
        }
Beispiel #11
0
        public static void HandleLdOutput(AbstractDProject prj, BuildResult br, string linkerOutput)
        {
            var ctxt = ResolutionContext.Create(DResolverWrapper.CreateParseCacheView(prj), null, null);

            ctxt.ContextIndependentOptions =
                ResolutionOptions.IgnoreAllProtectionAttributes |
                ResolutionOptions.DontResolveBaseTypes |
                ResolutionOptions.DontResolveBaseClasses |
                ResolutionOptions.DontResolveAliases;

            foreach (Match m in ldErrorRegex.Matches(linkerOutput))
            {
                var error = new BuildError();

                var firstSymbolOccurring = ldMangleRegex.Match(m.Groups["err"].Value);

                if (firstSymbolOccurring.Success)
                {
                    var mangledString    = "_D" + firstSymbolOccurring.Groups["mangle"].Value;
                    var associatedSymbol = DResolver.GetResultMember(Demangler.DemangleAndResolve(mangledString, ctxt));
                    if (associatedSymbol != null)
                    {
                        error.FileName = (associatedSymbol.NodeRoot as DModule).FileName;
                        error.Line     = associatedSymbol.Location.Line;
                        error.Column   = associatedSymbol.Location.Column;
                    }
                }

                error.ErrorText = m.Groups["msg"].Value;
                if (string.IsNullOrWhiteSpace(error.ErrorText))
                {
                    error.ErrorText = m.Groups["err"].Value;
                }

                error.ErrorText = DemangleLdOutput(error.ErrorText);

                br.Append(error);
            }
        }
Beispiel #12
0
            static void Main(string[] args)
            {
                // always the first call to make
                Phlib.InitializePhLib();

                Demangler demangler;

                switch (args.Length)
                {
                case 0:
                    demangler = new Demangler("Microsoft");
                    TestKnownInputs(demangler);
                    break;

                case 1:
                    demangler = new Demangler();
                    TestFilepath(args[0], demangler);

                    break;

                default:
                case 2:
                    string demanglerName = args[0].TrimStart(new char[] { '-' });
                    string Filepath      = args[1];

                    demangler = new Demangler(demanglerName);
                    if (NativeFile.Exists(Filepath))
                    {
                        TestFilepath(Filepath, demangler);
                    }
                    else
                    {
                        Console.WriteLine(demangler.UndecorateName(args[1]));
                    }

                    break;
                }
            }
Beispiel #13
0
        public static string DemangleLdOutput(string output)
        {
            var sb = new StringBuilder();
            int lastInsertionEnd = 0;

            foreach (Match match in ldMangleRegex.Matches(output))
            {
                int hasUnderscore = match.Groups["underscore"].Length;

                var mangleGroup = match.Groups["mangle"];

                var demangledSymbol = Demangler.DemangleQualifier("_D" + mangleGroup.Value).ToString();

                sb.Append(output.Substring(lastInsertionEnd, mangleGroup.Index - lastInsertionEnd - hasUnderscore - 1));
                sb.Append(demangledSymbol);

                lastInsertionEnd = mangleGroup.Index + mangleGroup.Length;
            }

            sb.Append(output.Substring(lastInsertionEnd, output.Length - lastInsertionEnd));

            return(sb.ToString());
        }
Beispiel #14
0
        public void PrintStackTrace(AThreadState ThreadState)
        {
            long[] Positions = ThreadState.GetCallStack();

            StringBuilder Trace = new StringBuilder();

            Trace.AppendLine("Guest stack trace:");

            foreach (long Position in Positions)
            {
                if (!SymbolTable.TryGetValue(Position, out string SubName))
                {
                    SubName = $"Sub{Position:x16}";
                }
                else if (SubName.StartsWith("_Z"))
                {
                    SubName = Demangler.Parse(SubName);
                }

                Trace.AppendLine(" " + SubName + " (" + GetNsoNameAndAddress(Position) + ")");
            }

            Device.Log.PrintInfo(LogClass.Cpu, Trace.ToString());
        }
Beispiel #15
0
        public static void HandleOptLinkOutput(AbstractDProject Project, BuildResult br, string linkerOutput)
        {
            var ctxt = ResolutionContext.Create(DResolverWrapper.CreateParseCacheView(Project), null, null);

            ctxt.ContextIndependentOptions =
                ResolutionOptions.IgnoreAllProtectionAttributes |
                ResolutionOptions.DontResolveBaseTypes |
                ResolutionOptions.DontResolveBaseClasses |
                ResolutionOptions.DontResolveAliases;

            foreach (Match match in optlinkRegex.Matches(linkerOutput))
            {
                var error = new BuildError();

                // Get associated D source file
                if (match.Groups["obj"].Success)
                {
                    var obj = Project.GetAbsoluteChildPath(new FilePath(match.Groups["obj"].Value)).ChangeExtension(".d");

                    foreach (var pf in Project.Files)
                    {
                        if (pf.FilePath == obj)
                        {
                            error.FileName = pf.FilePath;
                            break;
                        }
                    }
                }

                var msg = match.Groups["message"].Value;

                var symUndefMatch = symbolUndefRegex.Match(msg);

                if (symUndefMatch.Success && symUndefMatch.Groups["mangle"].Success)
                {
                    var mangledSymbol = symUndefMatch.Groups["mangle"].Value;
                    ITypeDeclaration qualifier;
                    try
                    {
                        var resSym = Demangler.DemangleAndResolve(mangledSymbol, ctxt, out qualifier);
                        if (resSym is DSymbol)
                        {
                            var ds  = resSym as DSymbol;
                            var ast = ds.Definition.NodeRoot as DModule;
                            if (ast != null)
                            {
                                error.FileName = ast.FileName;
                            }
                            error.Line   = ds.Definition.Location.Line;
                            error.Column = ds.Definition.Location.Column;
                            msg          = ds.Definition.ToString(false, true);
                        }
                        else
                        {
                            msg = qualifier.ToString();
                        }
                    }
                    catch (Exception ex)
                    {
                        msg = "<log analysis error> " + ex.Message;
                    }
                    error.ErrorText = msg + " could not be resolved - library reference missing?";
                }
                else
                {
                    error.ErrorText = "Linker error " + match.Groups["code"].Value + " - " + msg;
                }

                br.Append(error);
            }
        }
Beispiel #16
0
        public string GetGuestStackTrace(ARMeilleure.State.ExecutionContext context)
        {
            EnsureLoaded();

            StringBuilder trace = new StringBuilder();

            void AppendTrace(ulong address)
            {
                Image image = GetImage(address, out int imageIndex);

                if (image == null || !TryGetSubName(image, address, out string subName))
                {
                    subName = $"Sub{address:x16}";
                }
                else if (subName.StartsWith("_Z"))
                {
                    subName = Demangler.Parse(subName);
                }

                if (image != null)
                {
                    ulong offset = address - image.BaseAddress;

                    string imageName = GetGuessedNsoNameFromIndex(imageIndex);

                    trace.AppendLine($"   {imageName}:0x{offset:x8} {subName}");
                }
                else
                {
                    trace.AppendLine($"   ??? {subName}");
                }
            }

            trace.AppendLine($"Process: {_owner.Name}, PID: {_owner.Pid}");

            if (context.IsAarch32)
            {
                ulong framePointer = context.GetX(11);

                while (framePointer != 0)
                {
                    if ((framePointer & 3) != 0 ||
                        !_owner.CpuMemory.IsMapped(framePointer) ||
                        !_owner.CpuMemory.IsMapped(framePointer + 4))
                    {
                        break;
                    }

                    AppendTrace(_owner.CpuMemory.Read <uint>(framePointer + 4));

                    framePointer = _owner.CpuMemory.Read <uint>(framePointer);
                }
            }
            else
            {
                ulong framePointer = context.GetX(29);

                while (framePointer != 0)
                {
                    if ((framePointer & 7) != 0 ||
                        !_owner.CpuMemory.IsMapped(framePointer) ||
                        !_owner.CpuMemory.IsMapped(framePointer + 8))
                    {
                        break;
                    }

                    AppendTrace(_owner.CpuMemory.Read <ulong>(framePointer + 8));

                    framePointer = _owner.CpuMemory.Read <ulong>(framePointer);
                }
            }

            return(trace.ToString());
        }
Beispiel #17
0
        public static DNode ExamTraceSymbol(string symName, ResolutionContext ctxt, out bool mightBeLegalUnresolvableSymbol)
        {
            DSymbol ds = null;

            mightBeLegalUnresolvableSymbol = false;

            if (string.IsNullOrWhiteSpace(symName))
            {
                return(null);
            }

            // Try to handle a probably mangled string or C function.
            if (symName.StartsWith("_"))
            {
                try{
                    ds = Demangler.DemangleAndResolve(symName, ctxt) as DSymbol;
                }catch {}
            }

            // Stuff like void std.stdio.File.LockingTextWriter.put!(immutable(char)[]).put(immutable(char)[])
            if (ds == null && Lexer.IsIdentifierPart((int)symName[0]))
            {
                mightBeLegalUnresolvableSymbol = true;
                ITypeDeclaration q;
                var method = DParser.ParseMethodDeclarationHeader(symName, out q);
                q = Demangler.RemoveNestedTemplateRefsFromQualifier(q);

                AbstractType[] overloads = null;
                D_Parser.Completion.CodeCompletion.DoTimeoutableCompletionTask(null, ctxt, () => {
                    try {
                        overloads = AmbiguousType.TryDissolve(LooseResolution.LookupIdRawly(ctxt.ParseCache, q, ctxt.ScopedBlock.NodeRoot as DModule)).ToArray();
                    }
                    catch (Exception ex) { MonoDevelop.Core.LoggingService.LogWarning("Error during trace.log symbol resolution of " + q.ToString(), ex); }
                });

                if (overloads == null || overloads.Length == 0)
                {
                    return(null);
                }
                else if (overloads.Length == 1)
                {
                    ds = overloads[0] as DSymbol;
                }
                else
                {
                    method.Type = Demangler.RemoveNestedTemplateRefsFromQualifier(method.Type);
                    var methodType = TypeDeclarationResolver.GetMethodReturnType(method, ctxt);

                    var methodParameters = new List <AbstractType>();
                    D_Parser.Completion.CodeCompletion.DoTimeoutableCompletionTask(null, ctxt, () => {
                        if (method.Parameters != null && method.Parameters.Count != 0)
                        {
                            foreach (var parm in method.Parameters)
                            {
                                methodParameters.Add(TypeDeclarationResolver.ResolveSingle(Demangler.RemoveNestedTemplateRefsFromQualifier(parm.Type), ctxt));
                            }
                        }
                    });

                    foreach (var o in overloads)
                    {
                        ds = o as DSymbol;
                        if (ds == null || !(ds.Definition is DMethod))
                        {
                            continue;
                        }

                        var dm = ds.Definition as DMethod;
                        // Compare return types
                        if (dm.Type != null)
                        {
                            if (methodType == null || ds.Base == null || !ResultComparer.IsEqual(methodType, ds.Base))
                            {
                                continue;
                            }
                        }
                        else if (dm.Type == null && methodType != null)
                        {
                            return(null);
                        }

                        // Compare parameters
                        if (methodParameters.Count != dm.Parameters.Count)
                        {
                            continue;
                        }

                        for (int i = 0; i < methodParameters.Count; i++)
                        {
                            if (!ResultComparer.IsImplicitlyConvertible(methodParameters[i], TypeDeclarationResolver.ResolveSingle(Demangler.RemoveNestedTemplateRefsFromQualifier(dm.Parameters[i].Type), ctxt)))
                            {
                                continue;
                            }
                        }
                    }
                }
            }

            return(ds != null ? ds.Definition : null);
        }
Beispiel #18
0
        public static DNode ExamTraceSymbol(string symName, ResolutionContext ctxt, out bool mightBeLegalUnresolvableSymbol)
        {
            DSymbol ds = null;

            mightBeLegalUnresolvableSymbol = false;

            if (string.IsNullOrWhiteSpace(symName))
            {
                return(null);
            }

            // Try to handle a probably mangled string or C function.
            if (symName.StartsWith("_"))
            {
                try{
                    ds = Demangler.DemangleAndResolve(symName, ctxt) as DSymbol;
                }catch {}
            }

            // Stuff like void std.stdio.File.LockingTextWriter.put!(immutable(char)[]).put(immutable(char)[])
            if (ds == null && Lexer.IsIdentifierPart((int)symName[0]))
            {
                mightBeLegalUnresolvableSymbol = true;
                ITypeDeclaration q;
                var method = DParser.ParseMethodDeclarationHeader(symName, out q);
                q           = Demangler.RemoveNestedTemplateRefsFromQualifier(q);
                method.Type = Demangler.RemoveNestedTemplateRefsFromQualifier(method.Type);
                var methodType       = TypeDeclarationResolver.GetMethodReturnType(method, ctxt);
                var methodParameters = new List <AbstractType>();

                if (method.Parameters != null && method.Parameters.Count != 0)
                {
                    foreach (var parm in method.Parameters)
                    {
                        methodParameters.Add(TypeDeclarationResolver.ResolveSingle(Demangler.RemoveNestedTemplateRefsFromQualifier(parm.Type), ctxt));
                    }
                }

                ctxt.ContextIndependentOptions |= ResolutionOptions.IgnoreAllProtectionAttributes;
                var overloads = TypeDeclarationResolver.Resolve(q, ctxt);


                if (overloads == null || overloads.Length == 0)
                {
                    return(null);
                }
                else if (overloads.Length == 1)
                {
                    ds = overloads[0] as DSymbol;
                }
                else
                {
                    foreach (var o in overloads)
                    {
                        ds = o as DSymbol;
                        if (ds == null || !(ds.Definition is DMethod))
                        {
                            continue;
                        }

                        var dm = ds.Definition as DMethod;
                        // Compare return types
                        if (dm.Type != null)
                        {
                            if (methodType == null || ds.Base == null || !ResultComparer.IsEqual(methodType, ds.Base))
                            {
                                continue;
                            }
                        }
                        else if (dm.Type == null && methodType != null)
                        {
                            return(null);
                        }

                        // Compare parameters
                        if (methodParameters.Count != dm.Parameters.Count)
                        {
                            continue;
                        }

                        for (int i = 0; i < methodParameters.Count; i++)
                        {
                            if (!ResultComparer.IsImplicitlyConvertible(methodParameters[i], TypeDeclarationResolver.ResolveSingle(Demangler.RemoveNestedTemplateRefsFromQualifier(dm.Parameters[i].Type), ctxt)))
                            {
                                continue;
                            }
                        }
                    }
                }
            }

            if (ds != null)
            {
                return(ds.Definition);
            }
            return(null);
        }