protected static void Align(ImageWriter strtab) { while (strtab.Position % 4 != 0) { strtab.WriteByte(0); } }
protected void BuildObjectFile32(bool big_endian) { // Add symbol table if (symbols.Count > 0) { Given_Section(".symtab", SectionHeaderType.SHT_SYMTAB, ElfLoader.SHF_ALLOC, FlattenSymbolTable(big_endian)); 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()); } ImageWriter bin = big_endian ? new BeImageWriter() : (ImageWriter) new LeImageWriter(); bin.WriteByte(0x7F); bin.WriteBytes(new byte[] { 0x45, 0x4C, 0x46 }); bin.WriteByte(1); // 32-bit bin.WriteByte(big_endian ? ElfLoader.ELFDATA2MSB : ElfLoader.ELFDATA2LSB); bin.WriteByte(1); // ELF version bin.WriteByte(0); // OS ABI bin.WriteByte(0); // OS version bin.WriteBytes(0, 7); // pad // ELF header bin.WriteUInt16(1); // relocatable bin.WriteUInt16((ushort)ElfMachine.EM_SPARC); bin.WriteUInt32(1); // version bin.WriteUInt32(0); // entry point (none in reloc file) bin.WriteUInt32(0); // program segment table offset (none in reloc file) bin.WriteUInt32((uint)bin.Position + 20); // point to section table. bin.WriteUInt32(0); // e_flags; bin.WriteUInt16(0); // e_ehsize; bin.WriteUInt16((ushort)Elf32_PHdr.Size); // e_phentsize; bin.WriteUInt16((ushort)progHeaders.Count); // e_phnum; bin.WriteUInt16(0); // e_shentsize; bin.WriteUInt16((ushort)objectSections.Count); // e_shnum; bin.WriteUInt16(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.WriteUInt32((uint)ph.Type); bin.WriteUInt32(ph.Offset); bin.WriteUInt32(ph.VirtualAddress); bin.WriteUInt32(0); bin.WriteUInt32((uint)ph.Content.Length); bin.WriteUInt32(ph.AllocateSize); bin.WriteUInt32(ph.Flags); bin.WriteUInt32(ph.Alignment); } // Write the section table. foreach (var os in this.objectSections) { bin.WriteUInt32((uint)mpOsToiName[os]); bin.WriteUInt32((uint)os.Type); bin.WriteUInt32(os.Flags); bin.WriteUInt32(0); bin.WriteUInt32(os.Offset); bin.WriteUInt32(os.Content != null ? (uint)os.Content.Length : 0u); bin.WriteUInt32(os.Link); bin.WriteUInt32(0); bin.WriteUInt32(0); bin.WriteUInt32(os.ElementSize); } // write the non-null sections. foreach (var section in objectSections.Skip(1)) { bin.WriteBytes(section.Content); Align(bin); } this.rawBytes = bin.ToArray(); }