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(); }
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); }
public void Demangling() { ITypeDeclaration q; bool isCFun; var t = Demangler.Demangle("_D3std5stdio35__T7writelnTC3std6stream4FileTAAyaZ7writelnFC3std6stream4FileAAyaZv", out q, out isCFun); Assert.IsFalse(isCFun); }
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()); }
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()); }
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); }
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")); }
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()); }
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); } }
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; } }
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()); }
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()); }
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); } }
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()); }
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); }
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); }