public async Task <SSymbolNameAndDisplacement> LookupSymbolName(ulong pointer) { try { SModule module = await this.debuggerEngine.GetModuleForAddress(pointer); Dia2Lib.IDiaSession session = await this.debuggerEngine.DiaLoader.LoadDiaSession(module.Name); if (session != null) { // We have a DIA session; use it. Dia2Lib.IDiaSymbol symbol; ulong rva = pointer - module.BaseAddress; session.findSymbolByRVA((uint)rva, Dia2Lib.SymTagEnum.SymTagNull, out symbol); // Blocks don't have names. Walk up to the nearest non-block parent. while ((Dia2Lib.SymTagEnum)symbol.symTag == Dia2Lib.SymTagEnum.SymTagBlock) { symbol = symbol.lexicalParent; } SymTagEnum symTag = (SymTagEnum)symbol.symTag; string name; if (symTag == SymTagEnum.SymTagPublicSymbol || symTag == SymTagEnum.SymTagThunk) { // Public symbols have decorated names that need to be undecorated (see dbghelp!diaFillSymbolInfo). symbol.get_undecoratedNameEx(0x1000, out name); } else { name = symbol.name; } return(new SSymbolNameAndDisplacement() { Module = module.Name, Name = name, Displacement = (ulong)(rva - symbol.relativeVirtualAddress) }); } else { return(await this.debuggerEngine.LookupSymbolName(pointer)); } } catch { throw new DebuggerException(String.Format("Invalid symbol address: 0x{0:x8}", pointer)); } }
public async Task <IEnumerable <SNamedSymbol> > GetSymbolsInStackFrame(ulong instructionAddress, ulong stackAddress, ulong frameAddress) { List <SNamedSymbol> results = new List <SNamedSymbol>(); SModule module = await this.debuggerEngine.GetModuleForAddress(instructionAddress); Dia2Lib.IDiaSession session = await this.debuggerEngine.DiaLoader.LoadDiaSession(module.Name); if (session == null) { throw new DebuggerException("Loading stack frame symbols directly from the debugger is not supported."); } Dia2Lib.IDiaSymbol symbol; uint rva = (uint)(instructionAddress - module.BaseAddress); try { session.findSymbolByRVA(rva, Dia2Lib.SymTagEnum.SymTagNull, out symbol); } catch { throw new DebuggerException(string.Format("Invalid symbol address: 0x:{0:x8}", instructionAddress)); } if ((SymTagEnum)symbol.symTag == SymTagEnum.SymTagFunction || (SymTagEnum)symbol.symTag == SymTagEnum.SymTagBlock) { do { IDiaEnumSymbols symbols = null; symbol.findChildrenExByRVA(SymTagEnum.SymTagData, null, (uint)DiaHelpers.NameSearchOptions.nsNone, rva, out symbols); foreach (IDiaSymbol localSymbol in symbols) { DiaHelpers.LocationType location = (DiaHelpers.LocationType)localSymbol.locationType; if (location == DiaHelpers.LocationType.LocIsRegRel) { // Check if the offset is from the stack address or frame address. DiaHelpers.CV_HREG_e register = (DiaHelpers.CV_HREG_e)localSymbol.registerId; ulong relativeAddress = 0; switch (register) { case DiaHelpers.CV_HREG_e.CV_AMD64_RSP: case DiaHelpers.CV_HREG_e.CV_AMD64_ESP: // Also CV_REG_ESP relativeAddress = stackAddress; break; case DiaHelpers.CV_HREG_e.CV_AMD64_RBP: case DiaHelpers.CV_HREG_e.CV_AMD64_EBP: // Also CV_REG_EBP case DiaHelpers.CV_HREG_e.CV_ALLREG_VFRAME: relativeAddress = frameAddress; break; default: // Relative to a register that's not the frame pointer or stack pointer. We don't have support for this yet. continue; } int pointerAdjustment = 0; if (localSymbol.name == "this") { pointerAdjustment = symbol.type.thisAdjust; } results.Add(new SNamedSymbol() { Symbol = new SSymbolResult() { Module = module.Name, Pointer = (ulong)((long)relativeAddress + localSymbol.offset), Type = DiaHelpers.GetTypeName(localSymbol.type, pointerAdjustment) }, Name = localSymbol.name }); } } // If the symbol wasn't a function (e.g. it was a block) keep going until we reach containing function. } while ((SymTagEnum)symbol.symTag != SymTagEnum.SymTagFunction && ((symbol = symbol.lexicalParent) != null)); } return(results); }