public DbgGeneratedTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, DbgTarget target) : this(debugger, moduleBase, typeId, SymTag.Null, target) { }
} // end GetImplicitThreadLocalStorageForThread() internal DbgModuleInfo(DbgEngDebugger debugger, DEBUG_MODULE_PARAMETERS nativeParams, DbgTarget target) : base(debugger) { if (null == target) { throw new ArgumentNullException("target"); } Target = target; m_params = nativeParams; if (0 == nativeParams.Base) { throw new ArgumentException("Invalid DEBUG_MODULE_PARAMETERS: no base address.", "nativeParams"); } if (UInt64.MaxValue == nativeParams.Base) // (DEBUG_INVALID_OFFSET) { throw new ArgumentException("Invalid DEBUG_MODULE_PARAMETERS: base address indicates the structure is empty. Guess: Don't pass a base address buffer to GetModuleParameters.", "nativeParams"); } // TODO: more validation? } // end constructor
} // end GetNullTypeInfo() protected DbgNullTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, DbgTarget target) : base(debugger, moduleBase, typeId, SymTag.Null, "void", 0, target) { } // end constructor
} // end AggregateMembers() public DbgVirtualBaseClassTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, UdtKind kind, string name, ulong size, uint numChildren, uint classParentId, // could be 0? uint vtableShapeId, // could be 0? bool isVirtBaseClass, bool isIndirectVirtBaseClass, uint baseClassTypeId, uint virtualBaseDispIndex, uint virtualBasePointerOffset, DbgTarget target) : base(debugger, moduleBase, typeId, kind, name, size, numChildren, classParentId, vtableShapeId, isVirtBaseClass, isIndirectVirtBaseClass, baseClassTypeId, target) { VirtualBaseDispIndex = virtualBaseDispIndex; VirtualBasePointerOffset = virtualBasePointerOffset; } // end constructor
protected DbgBaseClassTypeInfoBase(DbgEngDebugger debugger, ulong moduleBase, uint typeId, UdtKind kind, string name, ulong size, uint numChildren, uint classParentId, // could be 0? uint vtableShapeId, // could be 0? bool isVirtBaseClass, bool isIndirectVirtBaseClass, uint baseClassTypeId, DbgTarget target) : base(debugger, moduleBase, typeId, kind, name, size, numChildren, classParentId, vtableShapeId, target) { IsVirtualBaseClass = isVirtBaseClass; IsIndirectVirtualBaseClass = isIndirectVirtBaseClass; BaseClassTypeId = baseClassTypeId; } // end constructor
/// <summary> /// This constructor is used by the modload event. /// </summary> internal DbgModuleInfo(DbgEngDebugger debugger, WDebugSymbols ds, //ulong imageFileHandle, <-- is there any [straightforward] way to get this besides the modload event? Is it useful? ulong baseOffset, uint moduleSize, string moduleName, string imageName, uint checkSum, uint timeDateStamp, DbgTarget target) : base(debugger) { Util.Assert(0 != baseOffset); m_ds = ds; m_baseAddr = baseOffset; m_size = moduleSize; m_name = moduleName; m_imgName = imageName; m_checkSum = checkSum; m_timeDateStamp = timeDateStamp; // We can't always get the current target context--like when we are trying to raise // a "module loaded" event, which happens from a dbgeng callback, where we don't know // the current context. // if( null == target ) // throw new ArgumentNullException( "target" ); Target = target; } // end constructor
} // end GetArrayTypeInfo() public DbgArrayTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, uint arrayTypeId, uint count, ulong size, DbgTarget target) : base(debugger, moduleBase, typeId, SymTag.ArrayType, null, size, target) { m_arrayElemTypeId = arrayTypeId; Count = count; Util.Assert(Size >= (ulong)(ArrayElementType.Size * Count)); if (Size != (ulong)(ArrayElementType.Size * Count)) { // This seems rare, but I've seen it happen. For instance, the // shell32!ObjectMap symbol on 32-bit win7 had a Size of 0x24 and an // element count of 1, but the element size was 0x1c. I thought it might // be some sort of padding (perhaps for alignment), but it seemed like a // strange amount of padding (why pad to 0x24 instead of 0x20??). LogManager.Trace("Warning: strange array type size. The size of the type is 0x{0:x}, but the (ArrayElementType.Size * Count) is (0x{1:x} * {2}) = 0x{3:x}.", Size, ArrayElementType.Size, Count, (ulong)(ArrayElementType.Size * Count)); } } // end constructor
} // end _EnsureIsNamed() public static DbgNamedTypeInfo GetNamedTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, DbgTarget target) { return(_EnsureIsNamed(GetTypeInfo(debugger, moduleBase, typeId, target))); }
} // end _GetModParamsByAddress() internal DbgModuleInfo(DbgEngDebugger debugger, ulong addressInModule, DbgTarget target) : this(debugger, _GetModParamsByAddress(debugger, target.Context, null, addressInModule), target) { }
} // end constructor protected DbgNamedTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, SymTag symTag, DbgTarget target) : this(debugger, moduleBase, typeId, symTag, null, null, target) { } // end constructor
} // end GetVTableTypeInfo() public DbgVTableShapeTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, uint numSlots, DbgTarget target) : base(debugger, moduleBase, typeId, SymTag.VTableShape, target) { NumSlots = numSlots; } // end constructor
// TODO: There is no static factory method. Should I provide one? We'd only need // it if we want to provide a way to get one of these by itself; not via a // FunctionType thing (which already gets the necessary information). public DbgFunctionArgTypeTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, uint argTypeId, DbgTarget target) : base(debugger, moduleBase, typeId, SymTag.FunctionArgType, target) { m_argTypeId = argTypeId; } // end constructor
protected DbgDataMemberTypeInfoBase(DbgEngDebugger debugger, ulong moduleBase, uint typeId, RawDataInfo rdi, DbgTarget target) : base(debugger, moduleBase, typeId, rdi, target) { m_owningTypeId = rdi.ClassParentId; } // end constructor
} // end WireUpChildren() /// <summary> /// Creates a new DbgLocalSymbol object. /// </summary> internal DbgLocalSymbol(DbgSymbolGroup symGroup, uint idx, string name, DEBUG_SYMBOL_PARAMETERS symParams, DEBUG_SYMBOL_ENTRY?dse, DbgTarget target) : base(_GetDebugger(symGroup), name, target) { if (null == symGroup) { throw new ArgumentNullException("symGroup"); } m_symGroup = symGroup; m_idx = idx; m_nativeParams = symParams; m_dse = dse; m_metaDataUnavailable = (null == dse); if (!m_metaDataUnavailable && DbgTypeInfo.IsDbgGeneratedType(m_dse.Value.TypeId)) { // HACK HACKALERT WORKAROUND // // This is a workaround for the fact that we can't get at the type // information that the debugger generates. It tends to do this to create // pointer types, pointing to UDTs (not sure why the pointer types don't // exist in the PDB). // // It of course knows what the pointee type is, but it isn't exposed in // any way. I'd like to add a new IDebugAdvancedN::Request request to grab // it out, but until I get to that, I'll cheat and parse it out of some // string output. // // I don't know how robust this is, because I've rarely seen it (only once // with this code). // _GenerateSyntheticTypeToMatchDbgEngGeneratedType(name, Debugger, m_dse.Value); } // end if( it's a debugger-generated type ) m_pointerAdjustment = 0; if (0 == Util.Strcmp_OI(name, "this")) { try { ulong displacementDontCare; var sym = Debugger.GetSymbolByAddress(symGroup.Frame.InstructionPointer, out displacementDontCare); var ftti = sym.Type as DbgFunctionTypeTypeInfo; Util.Assert(null != ftti); // if we made it this far, we should have the right type m_pointerAdjustment = ftti.ThisAdjust; } catch (DbgEngException dee) { LogManager.Trace("Could not get thisadjust: {0}", Util.GetExceptionMessages(dee)); } } } // end constructor
} // end GetDataTypeInfo() protected DbgDataTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, RawDataInfo rdi, DbgTarget target) : base(debugger, moduleBase, typeId, SymTag.Data, rdi.SymName, target) { DataKind = rdi.DataKind; m_memberTypeId = rdi.TypeId; } // end constructor
public DbgDataStaticMemberTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, RawDataInfo rdi, DbgTarget target) : base(debugger, moduleBase, typeId, rdi, target) { Address = rdi.Address; AddressOffset = rdi.AddressOffset; } // end constructor
} // end GetTypedefTypeInfo() public DbgTypedefTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, uint representedTypeId, string typedefName, DbgTarget target) : base(debugger, moduleBase, typeId, SymTag.Typedef, typedefName, target) { m_representedTypeId = representedTypeId; } // end constructor
public DbgDataMemberTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, RawDataInfo rdi, DbgTarget target) : base(debugger, moduleBase, typeId, rdi, target) { Offset = rdi.Offset; BitfieldLength = rdi.BitfieldLength; BitfieldPosition = rdi.BitPosition; } // end constructor
private DbgNamedTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, SymTag symTag, string name, ulong?pSize, DbgTarget target) : base(debugger, moduleBase, typeId, symTag, target) { m_name = name; m_pSize = pSize; } // end constructor
} // end GetPointerTypeInfo() public DbgPointerTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, uint pointeeTypeId, ulong size, bool isReference, DbgTarget target) : base(debugger, moduleBase, typeId, SymTag.PointerType, size, target) { m_pointeeTypeId = pointeeTypeId; IsReference = isReference; } // end constructor
} // end _LoadTypeInfo() public static DbgTypeInfo GetTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, SymTag symTag, DbgTarget target) { moduleBase = _AdjustModBase(moduleBase, typeId, target); return(GetTypeInfo(debugger, new DbgModuleInfo(debugger, moduleBase, target), typeId, symTag)); }
} // end _AdjustModBase( private static bool _TryGetFromCache(ulong moduleBase, uint typeId, DbgTarget target, out DbgTypeInfo typeInfo) { if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("__DisableTypeCache"))) { typeInfo = null; return(false); } lock ( sm_syncRoot ) { _InitCache(); moduleBase = _AdjustModBase(moduleBase, typeId, target); var perProcModCache = _GetCacheEntryOrCreate(target, sm_typeCache); var perModTypeCache = _GetCacheEntryOrCreate(moduleBase, perProcModCache); bool retVal = perModTypeCache.TryGetValue(typeId, out typeInfo); if (retVal) { // Before deciding if this is actually a hit, check that the type is // still valid (maybe its symbols got reloaded since we cached it). if (!typeInfo._CheckValid()) { retVal = false; typeInfo = null; // If it's not valid for this type, it's not valid for any other // types in the module. perProcModCache.Remove(moduleBase); } } if (retVal) { sm_cacheHits++; } else { sm_cacheMisses++; } // LogManager.Trace( "DbgTypeInfo._TryGetFromCache: modbase {0}, typeId {1}: found? {2}", // Util.FormatQWord( moduleBase ), // typeId, // retVal ); return(retVal); } } // end _TryGetFromCache()
} // end GetVTableTypeInfo() public DbgVTableTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, uint owningTypeId, uint pointerTypeId, uint numChildren, uint offset, DbgTarget target) : base(debugger, moduleBase, typeId, SymTag.VTable, target) { m_owningTypeId = owningTypeId; m_pointerTypeId = pointerTypeId; m_numChildren = numChildren; Offset = offset; } // end constructor
} // end _AddToCache() public static DbgTypeInfo GetTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, DbgTarget target) { DbgTypeInfo typeInfo; moduleBase = _AdjustModBase(moduleBase, typeId, target); if (!_TryGetFromCache(moduleBase, typeId, target, out typeInfo)) { typeInfo = _LoadTypeInfo(debugger, moduleBase, typeId, target); _AddToCache(typeInfo); } return(typeInfo); }
} // end _GetTypeNameForBaseType() public DbgBaseTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, BasicType baseType, ulong size, DbgTarget target) : base(debugger, moduleBase, typeId, SymTag.BaseType, _GetTypeNameForBaseType(debugger, baseType, size), size, target) { BaseType = baseType; } // end constructor
public DbgDataMemberTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, RawDataInfo rdi, DbgTarget target) : base(debugger, moduleBase, typeId, rdi, target) { Offset = rdi.Offset; BitfieldLength = rdi.BitfieldLength; BitfieldPosition = rdi.BitPosition; // Don't know if this is possible, so I'll throw in an assert to help me find // out: Util.Assert(null == rdi.Value, "Oh hey, a non-static data member with a constant value!"); } // end constructor
} // end GetUdtTypeInfo() public DbgFunctionTypeTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, uint returnTypeId, uint classParentId, uint thisAdjust, CallingConvention callingConvention, IReadOnlyList <RawFuncArgTypeInfo> rawArguments, DbgTarget target) : base(debugger, moduleBase, typeId, SymTag.FunctionType, 0, target) { m_returnTypeId = returnTypeId; m_classParentId = classParentId; ThisAdjust = thisAdjust; CallingConvention = callingConvention; m_rawArguments = rawArguments; } // end constructor
} // end GetUdtTypeInfo() public DbgUdtTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, UdtKind kind, string name, ulong size, uint numChildren, uint classParentId, // could be 0 uint vtableShapeId, // could be 0 DbgTarget target) : base(debugger, moduleBase, typeId, SymTag.UDT, name, size, target) { UdtKind = kind; m_classParentId = classParentId; m_vtableShapeId = vtableShapeId; m_numChildren = numChildren; } // end constructor
private DbgEnumTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, string name, DbgBaseTypeInfo baseType, uint numEnumerands, DbgTarget target) : base(debugger, moduleBase, typeId, SymTag.Enum, name, baseType.Size, target) { m_baseType = baseType; m_numEnumerands = numEnumerands; } // end constructor
private static DbgTypeInfo _LoadTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, DbgTarget target) { moduleBase = _AdjustModBase(moduleBase, typeId, target); if (IsDbgNativeType(typeId)) { return(_GetTypeInfoForDbgNativeType(debugger, moduleBase, typeId, target)); } if (0 == moduleBase) { throw new ArgumentException("You must supply a valid module base address.", "moduleBase"); } return(_LoadTypeInfo(debugger, new DbgModuleInfo(debugger, moduleBase, target), typeId)); } // end _LoadTypeInfo()