예제 #1
0
        /// <summary>
        /// Reads LDA data blocks
        /// </summary>
        /// <remarks>
        /// The format of LDA blocks is:
        /// +------+
        /// | 0001 | - word16 - Magic
        /// |------|
        /// | BC   | - word16 - Count
        /// |------|
        /// | ADDR | - word16 - Absolute load address
        /// |------|
        /// | Data | - byte[] - Data (`Count` bytes, including the first 6 bytes)
        ///   ...  
        /// |------|
        /// | Chk  | - byte - Checksum
        /// +------+
        /// </remarks>
        /// <param name="rdr"></param>
        /// <returns></returns>
        public Tuple<ushort, byte[]> ReadDataBlock(LeImageReader rdr)
        {
            ushort count;
            ushort uAddr;
            byte b;

            // Eat bytes until 1 followed by 0.
            do
            {
                while (rdr.TryReadByte(out b) && b != 1)
                    ;
                if (b != 1)
                    return null;    // invalid file
                if (!rdr.TryReadByte(out b))
                    return null;
            } while (b != 0);

            if (!rdr.TryReadLeUInt16(out count))
                return null;
            if (!rdr.TryReadLeUInt16(out uAddr))
                return null;

            if (count == 6)
                return new Tuple<ushort, byte[]>(uAddr, null);
            var data = rdr.ReadBytes(count - 6);
            if (data == null || data.Length < count - 6)
                return null;
            if (!rdr.TryReadByte(out b))  // read (and ignore) checksum
                return null;

            Debug.Print("Data block: {0:X4} {1:X4}", uAddr, count);
            return Tuple.Create(uAddr, data);
        }
예제 #2
0
        /// <summary>
        /// Reads LDA data blocks
        /// </summary>
        /// <remarks>
        /// The format of LDA blocks is:
        /// +------+
        /// | 0001 | - word16 - Magic
        /// |------|
        /// | BC   | - word16 - Count
        /// |------|
        /// | ADDR | - word16 - Absolute load address
        /// |------|
        /// | Data | - byte[] - Data (`Count` bytes, including the first 6 bytes)
        ///   ...
        /// |------|
        /// | Chk  | - byte - Checksum
        /// +------+
        /// </remarks>
        /// <param name="rdr"></param>
        /// <returns></returns>
        public (ushort, byte[]?) ReadDataBlock(LeImageReader rdr)
        {
            ushort count;
            ushort uAddr;
            byte   b;

            // Eat bytes until 1 followed by 0.
            do
            {
                while (rdr.TryReadByte(out b) && b != 1)
                {
                    ;
                }
                if (b != 1)
                {
                    return(0, null);     // invalid file
                }
                if (!rdr.TryReadByte(out b))
                {
                    return(0, null);
                }
            } while (b != 0);

            if (!rdr.TryReadLeUInt16(out count))
            {
                return(0, null);
            }
            if (!rdr.TryReadLeUInt16(out uAddr))
            {
                return(0, null);
            }

            if (count == 6)
            {
                return(uAddr, null);
            }
            var data = rdr.ReadBytes(count - 6);

            if (data == null || data.Length < count - 6)
            {
                return(0, null);
            }
            if (!rdr.TryReadByte(out b))  // read (and ignore) checksum
            {
                return(0, null);
            }

            Debug.Print("Data block: {0:X4} {1:X4}", uAddr, count);
            return(uAddr, data);
        }
예제 #3
0
        /// <summary>
        /// Reads LDA data blocks
        /// </summary>
        /// <remarks>
        /// The format of LDA blocks is:
        /// +------+
        /// | 0001 | - word16 - Magic
        /// |------|
        /// | BC   | - word16 - Count
        /// |------|
        /// | ADDR | - word16 - Absolute load address
        /// |------|
        /// | Data | - byte[] - Data (`Count` bytes)
        ///   ...
        /// |------|
        /// | Chk  | - byte - Checksum
        /// +------+
        /// </remarks>
        /// <param name="rdr"></param>
        /// <returns></returns>
        public ImageSegment ReadDataBlock(LeImageReader rdr)
        {
            ushort w;
            ushort count;
            ushort uAddr;
            byte   b;

            if (!rdr.TryReadLeUInt16(out w) || w != 0x0001)
            {
                return(null);
            }
            if (!rdr.TryReadLeUInt16(out count))
            {
                return(null);
            }
            if (!rdr.TryReadLeUInt16(out uAddr))
            {
                return(null);
            }
            var data = rdr.ReadBytes(count);

            if (data == null || data.Length < count)
            {
                return(null);
            }
            if (!rdr.TryReadByte(out b))
            {
                return(null);
            }

            Debug.Print("Data block: {0:X4} {1:X4}", uAddr, count);
            return(new ImageSegment(
                       string.Format("seg{0:X4}", uAddr),
                       new MemoryArea(Address.Ptr16(uAddr), data),
                       AccessMode.ReadWriteExecute));
        }
예제 #4
0
파일: OmfLoader.cs 프로젝트: qcyb/reko
        public override TypeLibrary Load(IPlatform platform, TypeLibrary dstLib)
        {
            var loader = new TypeLibraryDeserializer(platform, true, dstLib);
            var rdr    = new LeImageReader(rawImage);

            var(type, _) = ReadRecord(rdr);
            if (type != RecordType.LibraryHeader)
            {
                return(dstLib);
            }

            (type, _) = ReadRecord(rdr);
            if (type != RecordType.THEADR)
            {
                return(dstLib);
            }
            for (; ;)
            {
                byte[] data;
                (type, data) = ReadRecord(rdr);
                if (data == null)
                {
                    break;
                }
                switch (type)
                {
                default: throw new NotImplementedException($"OMF record type {type} ({(int) type:X} has not been implemented yet.");

                case RecordType.THEADR:
                    // Can't seem to do anything useful with THEADRs
                    break;

                case RecordType.COMENT:
                    var rdrComent = new LeImageReader(data);
                    if (!rdrComent.TryReadByte(out byte _)) // Ignore the comment type
                    {
                        break;
                    }
                    if (!rdrComent.TryReadByte(out byte cmtClass))
                    {
                        break;
                    }
                    if ((CommentClass)cmtClass != CommentClass.Extensions)
                    {
                        break;
                    }
                    if (!rdrComent.TryReadByte(out byte cmtExt))
                    {
                        break;
                    }
                    if ((CommentExtension)cmtExt == CommentExtension.IMPDEF)
                    {
                        ReadImpdef(rdrComent, loader);
                    }
                    else
                    {
                        throw new NotImplementedException($"OMF COMENT extension {(CommentExtension) cmtExt} (0x{cmtExt:X}) is not implemented yet.");
                    }
                    break;

                case RecordType.MODEND:
                    // Modend's seem to be followed by padding to a 16-byte boundary.
                    while ((rdr.Offset & 0xF) != 0 && rdr.TryReadByte(out _))
                    {
                        ;
                    }
                    break;

                case RecordType.LibraryEnd:
                    return(dstLib);
                }
            }
            return(dstLib);
        }