/// <summary> /// Initializes data based on the <see cref="ModifierRecord"/>. /// </summary> private void Initialize(ModifierRecord record) { PdbSymbol symbol = PdbModule.GetSymbol(record.ModifiedType); symbol.LinkSymbols(this); Tag = symbol.Tag; BasicType = symbol.BasicType; Offset = symbol.Offset; Size = symbol.Size; IsVirtualInheritance = symbol.IsVirtualInheritance; IsForwardReference = symbol.IsForwardReference; UniqueName = symbol.UniqueName; Name = symbol.Name; if ((record.Modifiers & ModifierOptions.Unaligned) != ModifierOptions.None) { Name = "unaligned " + Name; } if ((record.Modifiers & ModifierOptions.Volatile) != ModifierOptions.None) { Name = "volatile " + Name; } if ((record.Modifiers & ModifierOptions.Const) != ModifierOptions.None) { Name = "const " + Name; } }
/// <summary> /// Initializes a new instance of the <see cref="PdbSymbolField"/> class. /// </summary> /// <param name="parentType">The parent type.</param> /// <param name="record">Static data member type record.</param> public PdbSymbolField(PdbSymbol parentType, StaticDataMemberRecord record) : base(parentType) { Name = record.Name; LocationType = DIA.LocationType.Static; DataKind = DIA.DataKind.StaticMember; Type = parentType.PdbModule.GetSymbol(record.Type); Size = Type.Size; // Try native constant ConstantSymbol constant; string nativeConstant = $"{parentType.Name}::{Name}"; if (!parentType.PdbModule.Constants.TryGetValue(nativeConstant, out constant)) { // Try managed constant string managedConstant = $"{parentType.Name}.{Name}"; if (!parentType.PdbModule.Constants.TryGetValue(managedConstant, out constant)) { constant = null; } } if (constant != null && record.Type == constant.TypeIndex) { LocationType = DIA.LocationType.Constant; Value = constant.Value; } }
/// <summary> /// Gets defined symbol (follows forward references by unique name). /// </summary> /// <param name="index">Type index.</param> /// <returns>Symbol definition if exists or forward reference.</returns> private PdbSymbol GetDefinedSymbol(int index) { PdbSymbol symbol = allSymbolsCache[index]; if (string.IsNullOrEmpty(symbol.UniqueName)) { return(symbol); } PdbSymbol definedSymbol; if (!symbolsByUniqueName.TryGetValue(symbol.UniqueName, out definedSymbol)) { return(symbol); } return(definedSymbol); }
/// <summary> /// Initializes a new instance of the <see cref="PdbSymbolField"/> class. /// </summary> /// <param name="parentType">The parent type.</param> /// <param name="record">Data member type record.</param> public PdbSymbolField(PdbSymbol parentType, DataMemberRecord record) : base(parentType) { Name = record.Name; DataKind = DIA.DataKind.Member; Offset = (int)record.FieldOffset; TypeRecord typeRecord = !record.Type.IsSimple ? parentType.PdbModule.PdbFile.TpiStream[record.Type] : null; if (typeRecord is BitFieldRecord bitFieldRecord) { LocationType = DIA.LocationType.BitField; BitPosition = bitFieldRecord.BitOffset; BitSize = bitFieldRecord.BitSize; Type = parentType.PdbModule.GetSymbol(bitFieldRecord.Type); } else { LocationType = DIA.LocationType.ThisRel; Type = parentType.PdbModule.GetSymbol(record.Type); Size = Type.Size; } }
/// <summary> /// Gets all types defined in the symbol. /// </summary> public override IEnumerable <Symbol> GetAllTypes() { TypeLeafKind[] kinds = new TypeLeafKind[] { TypeLeafKind.LF_CLASS, TypeLeafKind.LF_STRUCTURE, TypeLeafKind.LF_INTERFACE, TypeLeafKind.LF_UNION, TypeLeafKind.LF_ENUM }; List <Symbol> selectedSymbols = new List <Symbol>(); // Find all symbols that will be returned and populate symbolsByUniqueName. symbolsByUniqueName = new Dictionary <string, PdbSymbol>(); foreach (TypeLeafKind kind in kinds) { foreach (TypeIndex typeIndex in PdbFile.TpiStream.GetIndexes(kind)) { PdbSymbol symbol = allSymbolsCache[(int)typeIndex.ArrayIndex] = CreateSymbol((int)typeIndex.ArrayIndex), oldSymbol; if (string.IsNullOrEmpty(symbol.UniqueName)) { selectedSymbols.Add(symbol); } else if (!symbolsByUniqueName.TryGetValue(symbol.UniqueName, out oldSymbol)) { symbolsByUniqueName.Add(symbol.UniqueName, symbol); } else if (oldSymbol.IsForwardReference && !symbol.IsForwardReference) { symbolsByUniqueName[symbol.UniqueName] = symbol; } } } selectedSymbols.AddRange(symbolsByUniqueName.Values); // Now that we have symbolsByUniqueName, we can search for defined symbols. symbolsByName = new Dictionary <string, PdbSymbol>(); foreach (TypeLeafKind kind in kinds) { foreach (TypeIndex typeIndex in PdbFile.TpiStream.GetIndexes(kind)) { PdbSymbol symbol = definedSymbolsCache[(int)typeIndex.ArrayIndex]; if (!string.IsNullOrEmpty(symbol.Name) && !symbolsByName.ContainsKey(symbol.Name)) { symbolsByName.Add(symbol.Name, symbol); } } } // Add all known built-in types into symbolsByName foreach (TypeIndex typeIndex in TypeIndex.BuiltinTypes) { PdbSymbol symbol = builtinSymbolsCache[typeIndex]; if (!string.IsNullOrEmpty(symbol.Name) && !symbolsByName.ContainsKey(symbol.Name)) { symbolsByName.Add(symbol.Name, symbol); } } // Add pointer to all known built-in types into symbolsByName foreach (TypeIndex t in TypeIndex.BuiltinTypes) { TypeIndex typeIndex = new TypeIndex(t.SimpleKind, SimpleTypeMode.NearPointer); PdbSymbol symbol = builtinSymbolsCache[typeIndex]; if (!string.IsNullOrEmpty(symbol.Name) && !symbolsByName.ContainsKey(symbol.Name)) { symbolsByName.Add(symbol.Name, symbol); } } return(selectedSymbols); }