/// <summary> /// Writes the elf header /// </summary> /// <param name="writer">The writer.</param> protected void Write64(EndianAwareBinaryWriter writer) { writer.Seek(0, SeekOrigin.Begin); writer.Write(Ident); // ident writer.Write((ushort)Type); // type writer.Write((ushort)Machine); // machine writer.Write((uint)Version); // version writer.Write(EntryAddress); // entry writer.Write((ulong)ProgramHeaderOffset); // phoff writer.Write((ulong)SectionHeaderOffset); // shoff writer.Write(Flags); // flags writer.Write(ElfHeaderSize64); // ehsize writer.Write(ProgramHeader.EntrySize64); // phentsize writer.Write(ProgramHeaderNumber); // phnum writer.Write(SectionHeaderEntry.EntrySize64); // shentsize writer.Write((ushort)SectionHeaderNumber); // shnum writer.Write((ushort)SectionHeaderStringIndex); // shstrndx }
/// <summary> /// Writes the specified fs. /// </summary> /// <param name="writer">The writer.</param> public void Write(EndianAwareBinaryWriter writer) { writer.Seek(0, SeekOrigin.Begin); writer.Write(Ident); writer.Write((ushort)Type); writer.Write((ushort)Machine); writer.Write((uint)Version); writer.Write(EntryAddress); writer.Write(ProgramHeaderOffset); writer.Write(SectionHeaderOffset); writer.Write(Flags); writer.Write(ElfHeaderSize); writer.Write(ProgramHeaderEntrySize); writer.Write(ProgramHeaderNumber); writer.Write(SectionHeaderEntrySize); writer.Write(SectionHeaderNumber); SectionHeaderStringIndex = 1; writer.Write(SectionHeaderStringIndex); }
/// <summary> /// Creates the elf32 file. /// </summary> private void CreateElf64File() { using (FileStream fs = new FileStream(this.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.Class64, IdentData.Data2LSB, 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 = (uint)header.ElfHeaderSize + (uint)header.SectionHeaderEntrySize * (uint)header.SectionHeaderNumber + offset; header.SectionHeaderStringIndex = (ushort)((ushort)header.ProgramHeaderOffset + (ushort)header.ProgramHeaderNumber * (ushort)header.ProgramHeaderEntrySize); 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); } }
/// <summary> /// Writes the specified fs. /// </summary> /// <param name="writer">The writer.</param> public void Write(EndianAwareBinaryWriter writer) { writer.Seek(0, SeekOrigin.Begin); writer.Write(Ident); writer.Write((ushort)Type); writer.Write((ushort)Machine); writer.Write((uint)Version); writer.Write(EntryAddress); writer.Write(ProgramHeaderOffset); writer.Write(SectionHeaderOffset); writer.Write(Flags); writer.Write(ElfHeaderSize); writer.Write(ProgramHeaderEntrySize); writer.Write(ProgramHeaderNumber); writer.Write(SectionHeaderEntrySize); writer.Write(SectionHeaderNumber); SectionHeaderStringIndex = 1; writer.Write(SectionHeaderStringIndex); }
/// <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); } } }
/// <summary> /// Writes the elf header /// </summary> /// <param name="writer">The writer.</param> protected void Write64(EndianAwareBinaryWriter writer) { writer.Seek(0, SeekOrigin.Begin); writer.Write(Ident); // ident writer.Write((ushort)Type); // type writer.Write((ushort)Machine); // machine writer.Write((uint)Version); // version writer.Write(EntryAddress); // entry writer.Write((ulong)ProgramHeaderOffset); // phoff writer.Write((ulong)SectionHeaderOffset); // shoff writer.Write(Flags); // flags writer.Write(ElfHeaderSize64); // ehsize writer.Write(ProgramHeader.EntrySize64); // phentsize writer.Write(ProgramHeaderNumber); // phnum writer.Write(SectionHeaderEntry.EntrySize64); // shentsize writer.Write((ushort)SectionHeaderNumber); // shnum writer.Write((ushort)SectionHeaderStringIndex); // shstrndx }