Пример #1
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();
        }