Beispiel #1
0
        public uint GetAddress(uint hereAddress, byte mode, VcdReader addressSection)
        {
            uint address = 0;

            switch (GetMode(mode))
            {
            case AddressMode.Self:
                address = addressSection.ReadInteger();
                break;

            case AddressMode.Here:
                address = hereAddress - addressSection.ReadInteger();
                break;

            case AddressMode.Near:
                address = near[mode - 2] + addressSection.ReadInteger();
                break;

            case AddressMode.Same:
                int index = mode - (2 + NearSlots);
                address = same[index * 256 + addressSection.ReadByte()];
                break;
            }

            Update(address);
            return(address);
        }
Beispiel #2
0
        private Header ReadHeader()
        {
            var header = new Header();

            var fields = (HeaderFields)vcdReader.ReadByte();

            if (fields.Contains(HeaderFields.NotSupported))
            {
                throw new FormatException("unrecognized header indicator bits set");
            }

            header.SecondaryCompressor = SecondaryCompressor.None;
            if (fields.Contains(HeaderFields.SecondaryCompression))
            {
                throw new NotSupportedException("unavailable secondary compressor");
            }

            if (fields.Contains(HeaderFields.CodeTable))
            {
                throw new NotSupportedException("compressed code table not implemented");
            }

            if (fields.Contains(HeaderFields.ApplicationData))
            {
                header.ApplicationData = ReadApplicationData();
            }

            return(header);
        }
Beispiel #3
0
        public uint GetAddress(uint hereAddress, byte mode, VcdReader addressSection)
        {
            uint address = 0;
            switch (GetMode(mode)) {
            case AddressMode.Self:
                address = addressSection.ReadInteger();
                break;

            case AddressMode.Here:
                address = hereAddress - addressSection.ReadInteger();
                break;

            case AddressMode.Near:
                address = near[mode - 2] + addressSection.ReadInteger();
                break;

            case AddressMode.Same:
                int index = mode - (2 + NearSlots);
                address = same[index * 256 + addressSection.ReadByte()];
                break;
            }

            Update(address);
            return address;
        }
        private Window ReadWindow()
        {
            var window = new Window();

            // Get window indicator
            window.Source = (WindowFields)vcdReader.ReadByte();
            if (window.Source.Contains(WindowFields.NotSupported))
            {
                throw new FormatException("unrecognized window indicator bits set");
            }

            if (window.Source.Contains(WindowFields.Source | WindowFields.Target))
            {
                window.SourceSegmentLength = vcdReader.ReadInteger();
                window.SourceSegmentOffset = vcdReader.ReadInteger();
            }

            // Copy offset and copy length may not overflow
            if (window.SourceSegmentOffset.CheckOverflow(window.SourceSegmentLength))
            {
                throw new FormatException("decoder copy window overflows a file offset");
            }

            // Check copy window bounds
            if (window.Source.Contains(WindowFields.Target) &&
                window.SourceSegmentOffset + window.SourceSegmentLength > lastWindowOffset)
            {
                throw new FormatException("VCD_TARGET window out of bounds");
            }

            // Start of Delta Encoding Data
            vcdReader.ReadInteger(); // Length of the delta encoding (following data)

            // Get the length of target window
            window.TargetWindowLength = vcdReader.ReadInteger();
            lastWindowLength          = window.TargetWindowLength;

            // Set the maximum decoder position, beyond which we should not
            // decode any data. This may not exceed the size of a UInt32.
            if (window.SourceSegmentLength.CheckOverflow(window.TargetWindowLength))
            {
                throw new FormatException("decoder target window overflows a UInt32");
            }

            // Check for malicious files
            if (window.TargetWindowLength > HardMaxWindowSize)
            {
                throw new FormatException("Hard window size exceeded");
            }

            // Get compressed / delta fields
            window.CompressedFields = (WindowCompressedFields)vcdReader.ReadByte();
            if (window.CompressedFields.Contains(WindowCompressedFields.Invalid))
            {
                throw new FormatException("unrecognized delta indicator bits set");
            }

            // Compressed fields is only used with secondary compression
            if (window.CompressedFields != WindowCompressedFields.None &&
                header.SecondaryCompressor == SecondaryCompressor.None)
            {
                throw new FormatException("invalid delta indicator bits set");
            }

            // Read section lengths
            var dataLength         = vcdReader.ReadInteger();
            var instructionsLength = vcdReader.ReadInteger();
            var addressesLength    = vcdReader.ReadInteger();

            // Read checksum if so (it's in big-endian-non-integer)
            if (window.Source.Contains(WindowFields.Adler32))
            {
                var checksum = vcdReader.ReadBytes(4);
                window.Checksum = (uint)((checksum[0] << 24) | (checksum[1] << 16) |
                                         (checksum[2] << 8) | checksum[3]);
            }

            // Read sections
            var data         = new MemoryStream(vcdReader.ReadBytes(dataLength));
            var instructions = new MemoryStream(vcdReader.ReadBytes(instructionsLength));
            var addresses    = new MemoryStream(vcdReader.ReadBytes(addressesLength));

            window.Data         = new VcdReader(data);
            window.Instructions = new VcdReader(instructions);
            window.Addresses    = new VcdReader(addresses);

            return(window);
        }