Пример #1
0
        private void ProcessJumpTable(uint jtOffset)
        {
            var         j  = new JumpTable();
            ImageReader ir = new BeImageReader(image, jtOffset);

            j.AboveA5Size     = ir.ReadBeUInt32();
            j.BelowA5Size     = ir.ReadBeUInt32();
            j.JumpTableSize   = ir.ReadBeUInt32();
            j.JumpTableOffset = ir.ReadBeUInt32();
            uint size = j.JumpTableSize;

            while (size > 0)
            {
                JumpTableEntry jte = new JumpTableEntry();
                jte.RoutineOffsetFromSegmentStart = ir.ReadBeUInt16();
                jte.Instruction       = ir.ReadBeUInt32();
                jte.LoadSegTrapNumber = ir.ReadBeUInt16();
                Debug.WriteLine(string.Format("Jump table entry: {0:x2} {1:X4} {2:X2}", jte.RoutineOffsetFromSegmentStart, jte.Instruction, jte.LoadSegTrapNumber));
                size -= 8;
            }
        }
Пример #2
0
        public void ParseExt(Action <Hunk> h)
        {
            var hunk = new ExtHunk();

            h(hunk);
            var ext_def    = new List <ExtObject>();
            var ext_ref    = new List <ExtObject>();
            var ext_common = new List <ExtObject>();

            hunk.ext_def    = ext_def;
            hunk.ext_ref    = ext_ref;
            hunk.ext_common = ext_common;
            var ext_size = 1;

            while (ext_size > 0)
            {
                // ext type | size
                var ext_type_size = this.read_long();
                var ext_type      = (ExtType)(byte)(ext_type_size >> (int)ExtType.EXT_TYPE_SHIFT);
                ext_size = ext_type_size & (int)ExtType.EXT_TYPE_SIZE_MASK;
                if (ext_size < 0)
                {
                    throw new BadImageFormatException(string.Format("{0} has invalid size.", hunk.HunkType));
                }
                // ext name
                string ext_name = this.ReadSizedString(ext_size);
                if (ext_name == null)
                {
                    throw new BadImageFormatException(string.Format("{0} has invalid name.", hunk.HunkType));
                }
                else if (ext_name.Length == 0)
                {
                    break;
                }

                // create local ext object
                var ext = new ExtObject {
                    type = ext_type, name = ext_name
                };

                // check and setup type name
                if (!ext_names.ContainsKey(ext_type))
                {
                    throw new BadImageFormatException(string.Format("{0} has unspported ext entry {1}.", hunk.HunkType, ext_type));
                }
                // ext common
                if (ext_type == ExtType.EXT_ABSCOMMON || ext_type == ExtType.EXT_RELCOMMON)
                {
                    ext.common_size = (uint)this.read_long();
                    ext_common.Add(ext);
                    // ext def
                }
                else if (ext_type == ExtType.EXT_DEF || ext_type == ExtType.EXT_ABS || ext_type == ExtType.EXT_RES)
                {
                    ext.def = f.ReadBeUInt32();
                    ext_def.Add(ext);
                }
                else
                {
                    // ext ref
                    var num_refs = this.read_long();
                    if (num_refs == 0)
                    {
                        num_refs = 1;
                    }
                    var refs = new List <uint>();
                    for (int a = 0; a < num_refs; ++a)
                    {
                        var @ref = f.ReadBeUInt32();
                        refs.Add(@ref);
                    }
                    ext.refs = refs;
                    ext_ref.Add(ext);
                }
            }
        }
Пример #3
0
        public void Relocate()
        {
            var  memA5          = (ByteMemoryArea)platform.A5World.MemoryArea;
            var  a5belowWriter  = new BeImageWriter(memA5, 0);
            var  a5belowReader  = new BeImageReader(memA5, 0);
            uint a5globalOffset = platform.A5Offset - a5dbelow;

            var a5WorldAddress = (UInt32)((platform.A5World.Address.Offset + platform.A5Offset) & 0xFFFFFFFF);

            // set Repeat count = 1, reset after each completed copy cycle
            // byte token lower 4 bits number of words to copy from compressed data
            // byte token upper 4 bits number of words to skip in global application data space
            // if either value is 0 then get run length value which is in bytes.
            // if the new run length value for copy is 0 then it's the end of compression data.

            for (;;)
            {
                int a5repeat = 1;
                // Skip is number of 16-bit words to skip
                uint a5globalSkip = a5dr.ReadByte();
                if (a5globalSkip == 0)
                {
                    a5globalSkip = a5dr.ReadByte();
                    if (a5globalSkip == 0)
                    {
                        break;
                    }
                    if (a5globalSkip > 0x7F)
                    {
                        a5globalSkip = ((a5globalSkip & 0x7F) << 8) + a5dr.ReadByte();
                        a5globalSkip = (a5globalSkip << 16) + a5dr.ReadBeUInt16();
                    }
                    else
                    {
                        a5repeat = ResourceFork.GetRunLengthValue(a5dr, ref a5repeat);
                        //$BUG: a5repeat could return the value 0. The do-while below will
                        // decrement a5repeat before testing. This will lead to an effective
                        // repeat count of 2^32; likely not wanted.
                    }
                }
                else
                {
                    if ((a5globalSkip & 0x80) == 0x80)
                    {
                        a5globalSkip = ((a5globalSkip & 0x7F) << 8) + a5dr.ReadByte();
                    }
                }
                a5globalSkip = a5globalSkip * 2;
                do
                {
                    a5globalOffset += a5globalSkip;
                    a5belowReader.Seek(a5globalOffset, SeekOrigin.Begin);
                    uint a5ptrOffset = a5belowReader.ReadBeUInt32();
                    a5belowWriter.Position = (int)a5globalOffset;

                    // write relocated A5World pointers to absolute address in A5World segment
                    // Possible register/mark as Global pointer references to strings

                    a5belowWriter.WriteBeUInt32((a5WorldAddress + a5ptrOffset) & 0xFFFFFFFF);
                    --a5repeat;
                } while (a5repeat > 0);
            }
        }