コード例 #1
0
        protected internal static void WriteElf(byte[] ilCode, Stream stream)
        {
            using var writer = new BinaryWriter(stream);

            var file = new ElfFile();

            file.Sections.Add(new ElfSection());
            AddCode(file, ilCode);

            var sectionsStringsIndex = file.AddStringsSection();

            const int headerSize       = 0x34;
            const int segmentsOffset   = headerSize;
            const int segmentEntrySize = 0x20;
            var       dataOffset       = (uint)(segmentsOffset + file.Segments.Count * segmentEntrySize);
            var       sectionsOffset   = dataOffset + file.Data.Length;


            var header = new ElfHeader
            {
                Identification =
                {
                    Magic     = new[] { (char)0x7f, 'E', 'L', 'F' },
                    FileClass = ElfFileClass.Elf32,
                    DataType  = ElfDataType.Lsb,
                    Version   = 1,
                },
                Type                   = ElfType.SharedObject,
                Machine                = 0x0,
                Version                = 1,
                Entry                  = 0x0,
                ProgramHeaderOffset    = segmentsOffset,
                SectionHeaderOffset    = (uint)sectionsOffset,
                Flags                  = 0x84,
                ElfHeaderSize          = headerSize,
                ProgramHeaderEntrySize = segmentEntrySize,
                ProgramHeaderCount     = (ushort)file.Segments.Count,
                SectionHeaderEntrySize = 0x28,
                SectionHeaderCount     = (ushort)file.Sections.Count,
                StringSectionIndex     = (ushort)sectionsStringsIndex
            };

            writer.WriteElf32(header);
            foreach (var segment in file.Segments)
            {
                var cloned = segment;
                cloned.Offset += dataOffset;
                writer.WriteElf32(cloned);
            }
            writer.Write(file.Data.ToArray());
            foreach (var section in file.Sections)
            {
                var cloned = section;
                if (section.Type != ElfSectionType.Null)
                {
                    cloned.Offset += dataOffset;
                }
                writer.WriteElf32(cloned);
            }
        }
コード例 #2
0
        private void AddData(ElfFile file)
        {
            var code = Encoding.UTF8.GetBytes("the big string data; also foo string");

            file.Sections.Add(new ElfSection
            {
                Name    = file.Strings.SaveString(".bss"),
                Type    = ElfSectionType.NoBits,
                Address = 0x800060,
                Flags   = ElfSectionFlags.Alloc | ElfSectionFlags.Writeable,
                Size    = (uint)code.Length,
                Align   = 1,
                Offset  = (uint)file.Data.Position
            });
            file.Segments.Add(new ElfSegment
            {
                Type            = ElfSegmentType.Load,
                Offset          = (uint)file.Data.Position,
                VirtualAddress  = 0x800060,
                PhysicalAddress = 0x800060,
                FileSize        = (uint)code.Length,
                MemorySize      = (uint)code.Length,
                Flags           = ElfSegmentFlags.Writeable | ElfSegmentFlags.Readable,
                Align           = 1,
            });
            file.Data.Write(code, 0, code.Length);
        }
コード例 #3
0
        protected static void AddMetadata(ElfFile file, InsomniaAssemblyMetadata metadata)
        {
            file.Strings.SaveString($".wasm-version::{metadata.Version}");
            file.Strings.SaveString($".wasm-timestamp::{metadata.Timestamp.ToUnixTimeSeconds()}");
            file.Strings.SaveString($".wasm-framework::{metadata.TargetFramework}");
            file.Strings.SaveString($".other-len::{metadata.OtherMeta.Count}");
            var index = 0;

            foreach (var(k, v) in metadata.OtherMeta)
            {
                file.Strings.SaveString($".other-{index++}::{k}\a{v}");
            }
        }
コード例 #4
0
        private static void AddCode(ElfFile file, byte[] il)
        {
            file.Sections.Add(new ElfSection
            {
                Name    = file.Strings.SaveString(".il_code"),
                Type    = ElfSectionType.ProgBits,
                Address = 0,
                Flags   = ElfSectionFlags.Alloc | ElfSectionFlags.Executable,
                Size    = (uint)il.Length,
                Align   = 2,
                Offset  = (uint)file.Data.Position
            });
            file.Segments.Add(new ElfSegment
            {
                Type            = ElfSegmentType.Load,
                Offset          = (uint)file.Data.Position,
                VirtualAddress  = 0,
                PhysicalAddress = 0,
                FileSize        = (uint)il.Length,
                MemorySize      = (uint)il.Length,
                Flags           = ElfSegmentFlags.Executable | ElfSegmentFlags.Readable,
                Align           = 1
            });
            file.Data.Write(il, 0, il.Length);

            var vm_notes = Encoding.ASCII.GetBytes("insomnia");

            file.Sections.Add(new ElfSection
            {
                Name    = file.Strings.SaveString(".note"),
                Type    = ElfSectionType.Note,
                Address = 0,
                Flags   = ElfSectionFlags.Alloc | ElfSectionFlags.Writeable,
                Size    = (uint)vm_notes.Length,
                Align   = 1,
                Offset  = (uint)file.Data.Position
            });
            file.Segments.Add(new ElfSegment
            {
                Type            = ElfSegmentType.Note,
                Offset          = (uint)file.Data.Position,
                VirtualAddress  = 0,
                PhysicalAddress = 0,
                FileSize        = (uint)vm_notes.Length,
                MemorySize      = (uint)vm_notes.Length,
                Flags           = ElfSegmentFlags.Readable,
                Align           = 1
            });
            file.Data.Write(vm_notes, 0, vm_notes.Length);
        }