예제 #1
0
        /// <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);
            }
        }
예제 #2
0
        /// <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);
                }
            }
        }