/// <summary> /// Builds the MacOS A5World, based on the contents of the jump table in CODE#0. /// </summary> /// <param name="jt"></param> /// <param name="addr"></param> /// <param name="codeSegs"></param> /// <returns></returns> public ImageSegment LoadA5World( JumpTable jt, Address addr, Dictionary <int, ImageSegment> codeSegs, SortedList <Address, ImageSymbol> symbols) { var size = jt.BelowA5Size + jt.AboveA5Size; var mem = new MemoryArea(addr, new byte[size]); var w = new BeImageWriter(mem, jt.BelowA5Size + jt.JumpTableOffset); int i = 0; foreach (var entry in jt.Entries) { w.WriteBeUInt16(entry.RoutineOffsetFromSegmentStart); int iSeg = (ushort)entry.Instruction; var targetSeg = codeSegs[iSeg]; var addrDst = targetSeg.Address + entry.RoutineOffsetFromSegmentStart; if (!symbols.ContainsKey(addrDst)) { symbols.Add(addrDst, ImageSymbol.Procedure(arch, addrDst)); } w.WriteBeUInt16(0x4EF9); // jmp (xxxxxxxxx).L w.WriteBeUInt32(addrDst.ToUInt32()); ++i; } return(new ImageSegment("A5World", mem, AccessMode.ReadWriteExecute)); }
public static byte[] OctalStringToBytes(string octalBytes) { var w = new BeImageWriter(); int h = 0; int nDigits = 0; for (int i = 0; i < octalBytes.Length; ++i) { var digit = octalBytes[i] - '0'; if (0 <= digit && digit <= 9) { ++nDigits; h = h * 8 + digit; if (nDigits == 6) { w.WriteBeUInt16((ushort)h); h = 0; nDigits = 0; } } } var aOut = new byte[w.Position]; Array.Copy(w.Bytes, aOut, aOut.Length); return(aOut); }
private void Rewrite(params ushort[] opcodes) { byte[] bytes = new byte[opcodes.Length * 2]; var writer = new BeImageWriter(bytes); foreach (ushort opcode in opcodes) { writer.WriteBeUInt16(opcode); } mem = new MemoryArea(addrBase, bytes); }
private byte[] FlattenSymbolTable() { var syms = new BeImageWriter(); foreach (var sym in symbols) { syms.WriteBeUInt32(sym.st_name); syms.WriteBeUInt32(sym.st_value); syms.WriteBeUInt32(sym.st_size); syms.WriteByte(sym.st_info); syms.WriteByte(sym.st_other); syms.WriteBeUInt16(sym.st_shndx); } return(syms.ToArray()); }
public void MacOS_ResolveIndirectCall() { var macOS = new MacOSClassic(null, new M68kArchitecture("m68k")); var a5 = new Identifier(Registers.a5.Name, Registers.a5.DataType, Registers.a5); var a5world = new MemoryArea(Address.Ptr32(0x00100000), new byte[0x0300]); macOS.A5World = new ImageSegment("A5World", a5world, AccessMode.ReadWrite); macOS.A5Offset = 0x0100u; const int jumpTableOffset = 0x0032; const uint uAddrDirect = 0x00123400u; var w = new BeImageWriter(a5world, macOS.A5Offset + jumpTableOffset); w.WriteBeUInt16(0x4EF9); // jmp... (not really necessary for the test but hey....); w.WriteBeUInt32(uAddrDirect); var m = new RtlEmitter(null); var instr = new RtlCall(m.IAdd(a5, jumpTableOffset), 4, RtlClass.Call); var addr = macOS.ResolveIndirectCall(instr); Assert.AreEqual(uAddrDirect, addr.ToUInt32()); }
private byte[] ParseOctPattern(string octalBytes) { var w = new BeImageWriter(); int h = 0; for (int i = 0; i < octalBytes.Length; ++i) { var digit = octalBytes[i] - '0'; if (0 <= digit && digit <= 9) { h = h * 8 + digit; if ((i + 1) % 6 == 0) { w.WriteBeUInt16((ushort)h); h = 0; } } else { break; } } return(w.Bytes); }
private void Given_Link(int amount) { // Emit a LINK instruction reservice `amount` bytes of space. w.WriteBeUInt16(MacsBugSymbolScanner.LINK); w.WriteBeUInt16((ushort)amount); }
protected void BuildObjectFile32() { // Add symbol table if (symbols.Count > 0) { Given_Section(".symtab", SectionHeaderType.SHT_SYMTAB, ElfLoader.SHF_ALLOC, FlattenSymbolTable()); var os = objectSections[objectSections.Count - 1]; os.ElementSize = Elf32_Sym.Size; os.Link = (ushort)objectSections.Count; Given_Section(".strtab", SectionHeaderType.SHT_STRTAB, ElfLoader.SHF_ALLOC, symbolStringtab.ToArray()); } var bin = new BeImageWriter(); bin.WriteByte(0x7F); bin.WriteBytes(new byte[] { 0x45, 0x4C, 0x46 }); bin.WriteByte(1); // 32-bit bin.WriteByte(2); // big-endian bin.WriteByte(1); // ELF version bin.WriteByte(0); // OS ABI bin.WriteByte(0); // OS version bin.WriteBytes(0, 7); // pad // ELF header bin.WriteBeUInt16(1); // relocatable bin.WriteBeUInt16((ushort)ElfMachine.EM_SPARC); bin.WriteBeUInt32(1); // version bin.WriteBeUInt32(0); // entry point (none in reloc file) bin.WriteBeUInt32(0); // program segment table offset (none in reloc file) bin.WriteBeUInt32((uint)bin.Position + 20); // point to section table. bin.WriteBeUInt32(0); // e_flags; bin.WriteBeUInt16(0); // e_ehsize; bin.WriteBeUInt16((ushort)Elf32_PHdr.Size); // e_phentsize; bin.WriteBeUInt16((ushort)progHeaders.Count); // e_phnum; bin.WriteBeUInt16(0); // e_shentsize; bin.WriteBeUInt16((ushort)objectSections.Count); // e_shnum; bin.WriteBeUInt16(1); // e_shstrndx; // Build string table. var strtab = new MemoryStream(); var mpOsToiName = new Dictionary <ObjectSection, int>(); foreach (var os in this.objectSections) { mpOsToiName[os] = (int)strtab.Position; var bytes = Encoding.ASCII.GetBytes(os.Name); strtab.Write(bytes, 0, bytes.Length); strtab.WriteByte(0); } // Reserve space for program header table and // section table. var iProgHdrTable = (uint)bin.Position; var iShTable = (uint)bin.Position + (uint)(progHeaders.Count * Elf32_PHdr.Size); var iStrTable = iShTable + (uint)(40 * objectSections.Count); // Write string table var aStrtable = strtab.ToArray(); objectSections[1].Content = aStrtable; var iContent = iStrTable; // Place remaining sections. foreach (var section in objectSections.Skip(1)) { section.Offset = iContent; iContent = Align((uint)(iContent + section.Content.Length)); } // Write the program header table foreach (var ph in this.progHeaders) { bin.WriteBeUInt32((uint)ph.Type); bin.WriteBeUInt32(ph.Offset); bin.WriteBeUInt32(ph.VirtualAddress); bin.WriteBeUInt32(0); bin.WriteBeUInt32((uint)ph.Content.Length); bin.WriteBeUInt32(ph.AllocateSize); bin.WriteBeUInt32(ph.Flags); bin.WriteBeUInt32(ph.Alignment); } // Write the section table. foreach (var os in this.objectSections) { bin.WriteBeUInt32((uint)mpOsToiName[os]); bin.WriteBeUInt32((uint)os.Type); bin.WriteBeUInt32(os.Flags); bin.WriteBeUInt32(0); bin.WriteBeUInt32(os.Offset); bin.WriteBeUInt32(os.Content != null ? (uint)os.Content.Length : 0u); bin.WriteBeUInt32(os.Link); bin.WriteBeUInt32(0); bin.WriteBeUInt32(0); bin.WriteBeUInt32(os.ElementSize); } // write the non-null sections. foreach (var section in objectSections.Skip(1)) { bin.WriteBytes(section.Content); Align(bin); } this.rawBytes = bin.ToArray(); }