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; } }
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); } } }
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); } }