public async Task <SSymbolResult> LookupGlobalSymbol(string moduleName, string symbolName) { SSymbolResult result = new SSymbolResult(); Dia2Lib.IDiaSession session = await this.debuggerEngine.DiaLoader.LoadDiaSession(moduleName); if (session != null) { // We have a DIA session, use that. try { Dia2Lib.IDiaEnumSymbols symbols; session.globalScope.findChildren(Dia2Lib.SymTagEnum.SymTagNull, symbolName, (uint)DiaHelpers.NameSearchOptions.nsCaseSensitive, out symbols); foreach (Dia2Lib.IDiaSymbol diaSymbol in symbols) { if (((DiaHelpers.LocationType)diaSymbol.locationType) == DiaHelpers.LocationType.LocIsTLS) { // For TLS-relative symbols, fall back to the debugger. return(await this.debuggerEngine.LookupGlobalSymbol(moduleName, symbolName)); } result.Module = moduleName; result.Pointer = (await this.debuggerEngine.GetModuleForName(moduleName)).BaseAddress + diaSymbol.relativeVirtualAddress; result.Type = DiaHelpers.GetTypeName(diaSymbol.type); return(result); } } catch { } throw new DebuggerException(String.Format("Invalid symbol: {0}!{1}", moduleName, symbolName)); } else { return(await this.debuggerEngine.LookupGlobalSymbol(moduleName, symbolName)); } }
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); }
private async Task <Type> LoadTypeFromDiaSession(IDiaSession diaSession, string module, string typename, DiaHelpers.NameSearchOptions options) { IDiaEnumSymbols symbols; diaSession.findChildren(diaSession.globalScope, SymTagEnum.SymTagNull, typename, (uint)options, out symbols); foreach (IDiaSymbol iterationSymbol in symbols) { IDiaSymbol symbol = iterationSymbol; while ((SymTagEnum)symbol.symTag == SymTagEnum.SymTagTypedef) { symbol = symbol.type; } SymTagEnum symTag = (SymTagEnum)symbol.symTag; if (symTag == SymTagEnum.SymTagUDT || symTag == SymTagEnum.SymTagBaseType || symTag == SymTagEnum.SymTagEnum) { // Get the fields for this class. IDiaEnumSymbols dataSymbols; symbol.findChildren(SymTagEnum.SymTagData, null, 0, out dataSymbols); uint typeSize = (uint)symbol.length; Dictionary <string, SField> fields = new Dictionary <string, SField>(); Dictionary <string, ulong> constants = new Dictionary <string, ulong>(); foreach (IDiaSymbol dataSymbol in dataSymbols) { DiaHelpers.LocationType location = (DiaHelpers.LocationType)dataSymbol.locationType; if (location == DiaHelpers.LocationType.LocIsBitField) { byte bitOffset = (byte)dataSymbol.bitPosition; byte bitCount = (byte)dataSymbol.length; fields.Add(dataSymbol.name, new SField((uint)dataSymbol.offset, (uint)dataSymbol.type.length, module, DiaHelpers.GetTypeName(dataSymbol.type), bitOffset, bitCount)); } else if (location == DiaHelpers.LocationType.LocIsThisRel) { fields.Add(dataSymbol.name, new SField((uint)dataSymbol.offset, (uint)dataSymbol.type.length, module, DiaHelpers.GetTypeName(dataSymbol.type), 0, 0)); } else if (location == DiaHelpers.LocationType.LocIsConstant) { try { constants.Add(dataSymbol.name, (ulong)dataSymbol.value); } catch { // If the cast failed, just ignore the constant for now. } } } IDiaEnumSymbols enumSymbols; symbol.findChildren(SymTagEnum.SymTagEnum, null, 0, out enumSymbols); List <string> names = new List <string>(); foreach (IDiaSymbol enumSymbol in enumSymbols) { if (enumSymbol.name.IndexOf("<unnamed-enum") == 0) { // Anonymous enum. Include the constants in the outer type. IDiaEnumSymbols anonymousEnumDataSymbols; enumSymbol.findChildren(SymTagEnum.SymTagData, null, 0, out anonymousEnumDataSymbols); foreach (IDiaSymbol dataSymbol in anonymousEnumDataSymbols) { DiaHelpers.LocationType location = (DiaHelpers.LocationType)dataSymbol.locationType; if (location == DiaHelpers.LocationType.LocIsConstant) { try { constants.Add(dataSymbol.name, (ulong)dataSymbol.value); } catch { // If the cast failed, just ignore the constant for now. } } } } } // Get the base types. List <SBaseType> baseTypes = new List <SBaseType>(); IDiaEnumSymbols baseClassSymbols; symbol.findChildren(SymTagEnum.SymTagBaseClass, null, 0, out baseClassSymbols); foreach (IDiaSymbol baseClassSymbol in baseClassSymbols) { string baseTypename = DiaHelpers.GetTypeName(baseClassSymbol.type); Type baseType; try { baseType = await this.LoadType(module, baseTypename); } catch (DebuggerException) { // Sometimes types will refer to a base type that doesn't resolve; just ignore that type. baseType = null; } if (baseType != null) { baseTypes.Add(new SBaseType(baseType, baseClassSymbol.offset)); } else { System.Diagnostics.Debug.WriteLine("Unable to retrieve base type: {0}", baseTypename); } } // Construct the type. Type type = new Type(module, typename, typeSize, symTag == SymTagEnum.SymTagEnum, fields, constants, baseTypes); return(type); } } return(null); }