/// <summary> /// Creates the elf32 file. /// </summary> /// <param name="compiler">The compiler.</param> private void CreateElf32File() { using (FileStream fs = new FileStream(OutputFile, FileMode.Create, FileAccess.Write, FileShare.None)) { Header header = new Header(); header.Type = FileType.Executable; header.Machine = Machine; header.SectionHeaderNumber = (ushort)(Sections.Count + 2); header.SectionHeaderOffset = header.ElfHeaderSize; header.CreateIdent(IdentClass.Class32, IsLittleEndian ? IdentData.Data2LSB : IdentData.Data2MSB, null); // Calculate the concatenated size of all section's data uint offset = 0; foreach (Section section in Sections) { offset += (uint)section.Length; } offset += (uint)nullSection.Length; offset += (uint)stringTableSection.Length; // Calculate offsets header.ProgramHeaderOffset = header.ElfHeaderSize + header.SectionHeaderEntrySize * (uint)header.SectionHeaderNumber + offset; header.ProgramHeaderNumber = 1; header.SectionHeaderStringIndex = 1; EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(fs, IsLittleEndian); // Write the ELF Header header.Write(writer); // Overjump the Section Header Table and write the section's data first long tmp = fs.Position; writer.Seek((int)(tmp + header.SectionHeaderNumber * header.SectionHeaderEntrySize), SeekOrigin.Begin); nullSection.Write(writer); stringTableSection.Write(writer); // Write the _sections foreach (Section section in Sections) section.Write(writer); // Jump back to the Section Header Table writer.Seek((int)tmp, SeekOrigin.Begin); nullSection.WriteHeader(writer); stringTableSection.WriteHeader(writer); // Write the section headers foreach (Section section in Sections) section.WriteHeader(writer); ProgramHeader pheader = new ProgramHeader { Alignment = 0, FileSize = (uint)GetSection(SectionKind.Text).Length }; pheader.MemorySize = pheader.FileSize; pheader.VirtualAddress = 0xFF0000; pheader.Flags = ProgramHeaderFlags.Execute | ProgramHeaderFlags.Read | ProgramHeaderFlags.Write; pheader.Offset = ((Section)GetSection(SectionKind.Text)).Header.Offset; pheader.Type = ProgramHeaderType.Load; writer.Seek((int)header.ProgramHeaderOffset, SeekOrigin.Begin); pheader.Write(writer); } }
/// <summary> /// Creates the final linked file. /// </summary> protected override void CreateFile() { using (FileStream fs = new FileStream(OutputFile, FileMode.Create, FileAccess.Write, FileShare.None)) { Header header = new Header(); header.Type = FileType.Executable; header.Machine = (MachineType)MachineID; header.SectionHeaderNumber = (ushort)(Sections.Length + 2); header.SectionHeaderOffset = header.ElfHeaderSize; header.EntryAddress = (uint)EntryPoint.VirtualAddress; header.CreateIdent(IdentClass.Class32, Endianness == Endianness.Little ? IdentData.Data2LSB : IdentData.Data2MSB, null); // Calculate the concatenated size of all section's data uint offset = 0; ushort programHeaderNumber = 0; foreach (Elf32LinkerSection section in Sections) { offset += (uint)section.Length; if (section.SectionKind != SectionKind.BSS && section.Length > 0) programHeaderNumber++; } offset += (uint)nullSection.Length; offset += (uint)stringTableSection.Length; // Calculate offsets header.ProgramHeaderOffset = header.ElfHeaderSize + header.SectionHeaderEntrySize * (uint)header.SectionHeaderNumber + offset; header.ProgramHeaderNumber = programHeaderNumber; header.SectionHeaderStringIndex = 1; EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(fs, Endianness); // Write the ELF Header header.Write(writer); // Overjump the Section Header Table and write the section's data first long tmp = fs.Position; writer.Seek((int)(tmp + header.SectionHeaderNumber * header.SectionHeaderEntrySize), SeekOrigin.Begin); nullSection.Write(writer); stringTableSection.Write(writer); // Write the _sections foreach (Elf32LinkerSection section in Sections) section.Write(writer); // Jump back to the Section Header Table writer.Seek((int)tmp, SeekOrigin.Begin); nullSection.WriteHeader(writer); stringTableSection.WriteHeader(writer); // Write the section headers foreach (Elf32LinkerSection section in Sections) section.WriteHeader(writer); writer.Seek((int)header.ProgramHeaderOffset, SeekOrigin.Begin); foreach (Elf32LinkerSection section in Sections) { if (section.SectionKind == SectionKind.BSS || section.Length == 0) continue; ProgramHeader pheader = new ProgramHeader { Alignment = 0, FileSize = (uint)section.Length, MemorySize = (uint)section.Length, Offset = section.Header.Offset, VirtualAddress = (uint)section.VirtualAddress, PhysicalAddress = (uint)section.VirtualAddress, Type = ProgramHeaderType.Load, Flags = (section.SectionKind == SectionKind.Text) ? ProgramHeaderFlags.Read | ProgramHeaderFlags.Execute : (section.SectionKind == SectionKind.ROData) ? ProgramHeaderFlags.Read : ProgramHeaderFlags.Read | ProgramHeaderFlags.Write }; pheader.Write(writer); } } }