public void A5Relocator_Skip_Repeat() { Given_Relocator(); var w = new BeImageWriter(mem.Bytes, 0); w.WriteByte(0x00); // Skip 2 halfwords. w.WriteByte(0x02); w.WriteByte(0x03); // Repeat 3 w = new BeImageWriter(mem.Bytes, 1024); w.WriteBeUInt32(0xFFFF0000u); w.WriteBeUInt32(0x00010000); w.WriteBeUInt32(0x00010004); w.WriteBeUInt32(0x00010008); w.WriteBeUInt32(0xFFFF0000u); relocator.Relocate(); var r = mem.CreateBeReader(1024); Assert.AreEqual(0xFFFF0000u, r.ReadBeUInt32()); Assert.AreEqual(0x00110800u, r.ReadBeUInt32()); Assert.AreEqual(0x00110804u, r.ReadBeUInt32()); Assert.AreEqual(0x00110808u, r.ReadBeUInt32()); Assert.AreEqual(0xFFFF0000u, r.ReadBeUInt32()); }
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 A5Relocator_One() { Given_Relocator(); var w = new BeImageWriter(mem.Bytes, 0); w.WriteByte(0x80); // Skip 0. w.WriteByte(0x00); w = new BeImageWriter(mem.Bytes, 1024); w.WriteBeUInt32(0x00123400); relocator.Relocate(); var r = mem.CreateBeReader(1024); var uRelocated = r.ReadBeUInt32(); Assert.AreEqual(0x00223C00u, uRelocated); }
private static void WriteString(string s, BeImageWriter w) { if (s.Length <= 0) { w.WriteBeUInt32(0); return; } byte[] ab = enc.GetBytes(s); int padLength = (ab.Length + 3) & ~3; w.WriteBeUInt32((uint)padLength / 4); w.WriteBytes(ab); int cPad = padLength - ab.Length; while (--cPad >= 0) { w.WriteByte(0); } }
private void Given_Variable_Length_Symbol(string str) { var ab = Encoding.ASCII.GetBytes(str); if (ab.Length < 0x20) { w.WriteByte((byte)(0x80 + ab.Length)); } else { w.WriteByte(0x80); w.WriteByte((byte)ab.Length); } w.WriteBytes(ab); if ((w.Position & 1) == 1) { w.WriteByte(0x00); } }
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(); }
private void A5Expand(BeImageReader a5dr, UInt32 a5dbelow) { var a5belowWriter = new BeImageWriter(platform.A5World.MemoryArea, platform.A5Offset - a5dbelow); int a5RunLengthToken = 0; int a5RunLengthCopySize = 0; int a5globalSkip = 0; int a5repeat = 0; var a5copylength = 0; bool a5dataEnd = false; // Compressed data // 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. do { a5repeat = 1; // Token value - upper nibble is words to skip, lower nibble is words to copy a5RunLengthToken = a5dr.ReadByte(); a5globalSkip = a5RunLengthToken; a5RunLengthCopySize = a5RunLengthToken & 0x0F; if (a5RunLengthCopySize == 0) { a5RunLengthCopySize = GetRunLengthValue(a5dr, ref a5repeat); if (a5RunLengthCopySize == 0) { a5dataEnd = true; } } else { a5RunLengthCopySize = a5RunLengthCopySize * 2; } if (!a5dataEnd) { a5globalSkip = a5globalSkip & 0xF0; if (a5globalSkip == 0) { a5globalSkip = GetRunLengthValue(a5dr, ref a5repeat); } else { // convert value 0x01 - 0x0F number of words to skip in upper nibble to number of bytes to skip a5globalSkip = a5globalSkip >> 3; } do { a5belowWriter.Position = a5belowWriter.Position + a5globalSkip; a5copylength = a5RunLengthCopySize; do { a5belowWriter.WriteByte(a5dr.ReadByte()); a5copylength -= 1; } while (a5copylength > 0); a5repeat -= 1; } while (a5repeat > 0); } } while (!a5dataEnd); }