Example #1
0
 /// <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;
 }
Example #2
0
        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]);
        }
Example #4
0
        /// <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;
 }
Example #8
0
        /// <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);
            });
        }
Example #9
0
        /// <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
            }
        }