/// <summary> /// Initializes a new instance of the <see cref="PdbSymbolField"/> class. /// </summary> /// <param name="parentType">The parent type.</param> /// <param name="constant">Constant symbol record.</param> public PdbSymbolField(PdbGlobalScope parentType, ConstantSymbol constant) : base(parentType) { Name = constant.Name; LocationType = DIA.LocationType.Constant; DataKind = DIA.DataKind.StaticMember; Type = parentType.PdbModule.GetSymbol(constant.TypeIndex); Size = Type.Size; Value = constant.Value; }
public static string GetClassTagName(string class_name) { string tag = "_" + class_name + "_" + "tag"; var c_syms = new ConstantSymbol(); if (class_name == c_syms.Bool.str_ || class_name == c_syms.Int.str_ || class_name == c_syms.Str.str_) { tag = tag.ToLower(); } return(tag); }
public void CanDeclareConstant() { var interpreter = new LineInterpreter(); interpreter.ParseAndExecute("glob is I"); var globSymbol = new ConstantSymbol("glob"); var iSymbol = new RomanSymbol("I"); Assert.IsTrue(interpreter.Processor.ConstantsTable.ContainsKey(globSymbol)); Assert.AreEqual(iSymbol, interpreter.Processor.ConstantsTable[globSymbol]); }
/// <summary> /// Reads symbol record from symbol references for the specified index. /// </summary> /// <param name="index">Index of the symbol record.</param> private SymbolRecord GetSymbol(int index) { // Since DictionaryCache is allowing only single thread to call this function, we don't need to lock reader here. SymbolReference reference = references[index]; Reader.Position = reference.DataOffset; switch (reference.Kind) { case SymbolRecordKind.S_GPROC32: case SymbolRecordKind.S_LPROC32: case SymbolRecordKind.S_GPROC32_ID: case SymbolRecordKind.S_LPROC32_ID: case SymbolRecordKind.S_LPROC32_DPC: case SymbolRecordKind.S_LPROC32_DPC_ID: return(ProcedureSymbol.Read(Reader, reference.Kind)); case SymbolRecordKind.S_PUB32: return(Public32Symbol.Read(Reader, reference.Kind)); case SymbolRecordKind.S_CONSTANT: case SymbolRecordKind.S_MANCONSTANT: return(ConstantSymbol.Read(Reader, reference.Kind)); case SymbolRecordKind.S_LDATA32: case SymbolRecordKind.S_GDATA32: case SymbolRecordKind.S_LMANDATA: case SymbolRecordKind.S_GMANDATA: return(DataSymbol.Read(Reader, reference.Kind)); case SymbolRecordKind.S_PROCREF: case SymbolRecordKind.S_LPROCREF: return(ProcedureReferenceSymbol.Read(Reader, reference.Kind)); case SymbolRecordKind.S_UDT: case SymbolRecordKind.S_COBOLUDT: return(UdtSymbol.Read(Reader, reference.Kind)); case SymbolRecordKind.S_LTHREAD32: case SymbolRecordKind.S_GTHREAD32: return(ThreadLocalDataSymbol.Read(Reader, reference.Kind)); default: throw new NotImplementedException(); } }
/// <summary> /// Creates a list of static fields based on <see cref="TagRecord"/>.<see cref="TagRecord.FieldList"/>. /// </summary> private List <PdbTypeStaticField> EnumerateStaticFields() { List <PdbTypeStaticField> fields = new List <PdbTypeStaticField>(); foreach (TypeRecord field in EnumerateFieldList()) { if (field is StaticDataMemberRecord staticDataMemberRecord) { // Check if static field is constant string fullName = Name + "::" + staticDataMemberRecord.Name; var globals = Pdb.PdbFile.GlobalsStream; ConstantSymbol constant = null; ThreadLocalDataSymbol threadLocalData = null; DataSymbol data = null; if (globals.HashBuckets != null) { uint hash = HashTable.HashStringV1(fullName); var bucket = globals.HashBuckets[hash % (uint)globals.HashBuckets.Length]; for (int i = bucket.Start; i < bucket.End; i++) { SymbolRecord record = globals.Symbols[i]; if (record is ConstantSymbol c && c.Name.String == fullName) { constant = c; break; } else if (record is ThreadLocalDataSymbol tls && tls.Name.String == fullName) { threadLocalData = tls; break; } else if (record is DataSymbol ds && ds.Name.String == fullName) { data = ds; break; } // TODO: bucket items are ordered by byte value. Is it comparable by string.CompareTo? } }
/// <summary> /// Initializes a new instance of the <see cref="PdbTypeConstant"/> class. /// </summary> /// <param name="containerType">Type that contains this field.</param> /// <param name="staticDataMemberRecord">The static data member record.</param> /// <param name="constant">The constant symbol.</param> internal PdbTypeConstant(PdbUserDefinedType containerType, StaticDataMemberRecord staticDataMemberRecord, ConstantSymbol constant) : base(containerType, staticDataMemberRecord) { Constant = constant; }
/// <summary> /// Initializes a new instance of the <see cref="PdbLocalConstant"/> class. /// </summary> /// <param name="localScope">Local scope where this contanst is defined.</param> /// <param name="constant">Constant symbol read from PDB.</param> internal PdbLocalConstant(PdbLocalScope localScope, ConstantSymbol constant) { LocalScope = localScope; Constant = constant; }
/// <summary> /// Initializes a new instance of the <see cref="GlobalsStream"/> class. /// </summary> /// <param name="file">PDB file containing this stream.</param> /// <param name="reader">Binary stream reader.</param> public GlobalsStream(PdbFile file, IBinaryReader reader) { File = file; // Read header Header = GlobalsStreamHeader.Read(reader); if (Header.Signature != GlobalsStreamHeader.ExpectedSignature) { throw new Exception($"GSIHashHeader signature (0x{GlobalsStreamHeader.ExpectedSignature:X}) not found."); } if (Header.Version != GlobalsStreamHeader.ExpectedVersion) { throw new Exception("Encountered unsupported globals stream version."); } // Read hash records if (Header.HashRecordsSubstreamSize % GlobalsStreamHashRecord.Size != 0) { throw new Exception("Invalid hash record array size."); } if (reader.BytesRemaining < Header.HashRecordsSubstreamSize) { throw new Exception("Error reading hash records."); } GlobalsStreamHashRecord[] hashRecords = new GlobalsStreamHashRecord[Header.HashRecordsSubstreamSize / GlobalsStreamHashRecord.Size]; for (int i = 0; i < hashRecords.Length; i++) { hashRecords[i] = GlobalsStreamHashRecord.Read(reader); } HashRecords = hashRecords; // Read hash buckets if (Header.HashBucketsSubstreamSize > 0) { const uint IPHR_HASH = 4096; const uint SizeOfHROffsetCalc = 12; ulong bitmapSizeInBits = (IPHR_HASH / 32 + 1) * 32; int bitmapEntriesCount = (int)(bitmapSizeInBits / 8); if (reader.BytesRemaining < bitmapEntriesCount) { throw new Exception("Could not read a bitmap."); } byte[] hashBitmap = reader.ReadByteArray(bitmapEntriesCount); int nonEmptyBucketsCount = 0; for (int i = 0; i < hashBitmap.Length; i++) { nonEmptyBucketsCount += bitCount[hashBitmap[i]]; } if (reader.BytesRemaining < nonEmptyBucketsCount * 4) // 4 = sizeof(uint) { throw new Exception("Could not read a bitmap."); } uint[] nonEmptyBucketOffsets = reader.ReadUintArray(nonEmptyBucketsCount); GlobalsStreamHashBucket[] hashBuckets = new GlobalsStreamHashBucket[IPHR_HASH]; for (int i = 0, j = 0; i < IPHR_HASH; i++) { int byteIndex = i / 8; int bitIndex = i % 8; if ((hashBitmap[byteIndex] & (1 << bitIndex)) != 0) { uint start = nonEmptyBucketOffsets[j++] / SizeOfHROffsetCalc; uint end = j < nonEmptyBucketOffsets.Length ? nonEmptyBucketOffsets[j] / SizeOfHROffsetCalc : (uint)HashRecords.Length; hashBuckets[i] = new GlobalsStreamHashBucket { Start = (int)start, End = (int)end, }; } else { hashBuckets[i] = new GlobalsStreamHashBucket { Start = -1, End = -1, } }; } HashBuckets = hashBuckets; } Symbols = new ArrayCache <SymbolRecord>(HashRecords.Length, index => File.PdbSymbolStream.GetSymbolRecordByOffset(HashRecords[index].Offset - 1)); constantsCache = SimpleCache.CreateStruct(() => { List <ConstantSymbol> constants = new List <ConstantSymbol>(); for (int i = 0; i < Symbols.Count; i++) { ConstantSymbol constant = Symbols[i] as ConstantSymbol; if (constant != null) { constants.Add(constant); } } return(constants); }); threadLocalDataCache = SimpleCache.CreateStruct(() => { List <ThreadLocalDataSymbol> threadLocalData = new List <ThreadLocalDataSymbol>(); for (int i = 0; i < Symbols.Count; i++) { ThreadLocalDataSymbol tls = Symbols[i] as ThreadLocalDataSymbol; if (tls != null) { threadLocalData.Add(tls); } } return(threadLocalData); }); dataCache = SimpleCache.CreateStruct(() => { List <DataSymbol> data = new List <DataSymbol>(); for (int i = 0; i < Symbols.Count; i++) { DataSymbol d = Symbols[i] as DataSymbol; if (d != null) { data.Add(d); } } return(data); }); }
/// <summary> /// Reads symbol record from symbol references for the specified index. /// </summary> /// <param name="index">Index of the symbol record.</param> private SymbolRecord GetSymbol(int index) { // Since DictionaryCache is allowing only single thread to call this function, we don't need to lock reader here. SymbolRecordReference reference = references[index]; Reader.Position = reference.DataOffset; switch (reference.Kind) { case SymbolRecordKind.S_GPROC32: case SymbolRecordKind.S_LPROC32: case SymbolRecordKind.S_GPROC32_ID: case SymbolRecordKind.S_LPROC32_ID: case SymbolRecordKind.S_LPROC32_DPC: case SymbolRecordKind.S_LPROC32_DPC_ID: return(ProcedureSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_PUB32: return(Public32Symbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_CONSTANT: case SymbolRecordKind.S_MANCONSTANT: return(ConstantSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_LDATA32: case SymbolRecordKind.S_GDATA32: case SymbolRecordKind.S_LMANDATA: case SymbolRecordKind.S_GMANDATA: return(DataSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_PROCREF: case SymbolRecordKind.S_LPROCREF: return(ProcedureReferenceSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_TOKENREF: return(TokenReferenceSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_UDT: case SymbolRecordKind.S_COBOLUDT: return(UdtSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_LTHREAD32: case SymbolRecordKind.S_GTHREAD32: return(ThreadLocalDataSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_GMANPROC: case SymbolRecordKind.S_LMANPROC: return(ManagedProcedureSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_BLOCK32: return(BlockSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_OEM: return(OemSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen)); case SymbolRecordKind.S_UNAMESPACE: return(NamespaceSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_MANSLOT: return(AttributeSlotSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_END: case SymbolRecordKind.S_INLINESITE_END: return(EndSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_ANNOTATION: return(AnnotationSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_ANNOTATIONREF: return(AnnotationReferenceSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_REGREL32: return(RegisterRelativeSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_OBJNAME: return(ObjectNameSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_COMPILE2: return(Compile2Symbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_COMPILE3: return(Compile3Symbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_ENVBLOCK: return(EnvironmentBlockSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_BUILDINFO: return(BuildInfoSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_FRAMEPROC: return(FrameProcedureSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_LABEL32: return(LabelSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_HEAPALLOCSITE: return(HeapAllocationSiteSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_CALLSITEINFO: return(CallSiteInfoSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_FRAMECOOKIE: return(FrameCookieSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_THUNK32: return(Thunk32Symbol.Read(Reader, this, index, reference.Kind, reference.DataLen)); case SymbolRecordKind.S_LOCAL: return(LocalSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_DEFRANGE_REGISTER: return(DefRangeRegisterSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen)); case SymbolRecordKind.S_DEFRANGE_REGISTER_REL: return(DefRangeRegisterRelativeSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen)); case SymbolRecordKind.S_DEFRANGE_SUBFIELD_REGISTER: return(DefRangeSubfieldRegisterSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen)); case SymbolRecordKind.S_DEFRANGE_FRAMEPOINTER_REL: return(DefRangeFramePointerRelativeSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen)); case SymbolRecordKind.S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE: return(DefRangeFramePointerRelativeFullScopeSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_CALLEES: case SymbolRecordKind.S_CALLERS: return(FunctionListSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen)); case SymbolRecordKind.S_FILESTATIC: return(FileStaticSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_TRAMPOLINE: return(TrampolineSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_SECTION: return(SectionSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_COFFGROUP: return(CoffGroupSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_EXPORT: return(ExportSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_INLINESITE: return(InlineSiteSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen)); default: #if DEBUG throw new NotImplementedException($"Unknown reference kind: {reference.Kind}"); #else return(null); #endif } }