/// <summary>
 /// Writes the Cil _header.
 /// </summary>
 /// <param name="compiler">The assembly compiler.</param>
 /// <param name="linker">The linker.</param>
 private void WriteCilHeader(AssemblyCompiler compiler, IAssemblyLinker linker)
 {
     using (Stream stream = linker.Allocate(CLI_HEADER.SymbolName, SectionKind.Text, CLI_HEADER.Length, 4))
     using (BinaryWriter bw = new BinaryWriter(stream, Encoding.ASCII)) {
         _cliHeader.Write(bw);
     }
 }
Example #2
0
 /// <summary>
 /// Writes the Cil _header.
 /// </summary>
 /// <param name="compiler">The assembly compiler.</param>
 /// <param name="linker">The linker.</param>
 private void WriteCilHeader(AssemblyCompiler compiler, IAssemblyLinker linker)
 {
     using (Stream stream = linker.Allocate(CLI_HEADER.SymbolName, SectionKind.Text, CLI_HEADER.Length, 4))
         using (BinaryWriter bw = new BinaryWriter(stream, Encoding.ASCII)) {
             _cliHeader.Write(bw);
         }
 }
        private void AskLinkerToCreateMethodTable(string methodTableName, IList <RuntimeMethod> methodTable, IList <string> headerlinks)
        {
            int methodTableSize = ((headerlinks == null ? 0 : headerlinks.Count) + (methodTable == null ? 0 : methodTable.Count)) * typeLayout.NativePointerSize;

            Debug.WriteLine("Method Table: " + methodTableName);

            using (Stream stream = linker.Allocate(methodTableName, SectionKind.Text, methodTableSize, typeLayout.NativePointerAlignment))
            {
                stream.Position = methodTableSize;
            }

            int offset = 0;

            if (headerlinks != null)
            {
                foreach (string link in headerlinks)
                {
                    if (!string.IsNullOrEmpty(link))
                    {
                        Debug.WriteLine("  # " + (offset / typeLayout.NativePointerSize).ToString() + " " + link);
                        linker.Link(LinkType.AbsoluteAddress | LinkType.I4, methodTableName, offset, 0, link, IntPtr.Zero);
                    }
                    else
                    {
                        Debug.WriteLine("  # " + (offset / typeLayout.NativePointerSize).ToString() + " [null]");
                    }
                    offset += typeLayout.NativePointerSize;
                }
            }

            if (methodTable != null)
            {
                foreach (RuntimeMethod method in methodTable)
                {
                    if (!method.IsAbstract)
                    {
                        Debug.WriteLine("  # " + (offset / typeLayout.NativePointerSize).ToString() + " " + method.ToString());
                        linker.Link(LinkType.AbsoluteAddress | LinkType.I4, methodTableName, offset, 0, method.ToString(), IntPtr.Zero);
                    }
                    else
                    {
                        Debug.WriteLine("  # " + (offset / typeLayout.NativePointerSize).ToString() + " [null]");
                    }
                    offset += typeLayout.NativePointerSize;
                }
            }
        }
        /// <summary>
        /// Writes the multiboot _header.
        /// </summary>
        /// <param name="compiler">The assembly compiler.</param>
        /// <param name="linker">The linker.</param>
        /// <param name="entryPoint">The virtualAddress of the multiboot compliant entry point.</param>
        private void WriteMultibootHeader(AssemblyCompiler compiler, IAssemblyLinker linker, IntPtr entryPoint)
        {
            // HACK: According to the multiboot specification this _header must be within the first 8K of the
            // kernel binary. Since the text section is always first, this should take care of the problem.
            using (Stream stream = linker.Allocate(MultibootHeaderSymbolName, SectionKind.Text, 64, 4))
                using (BinaryWriter bw = new BinaryWriter(stream, Encoding.ASCII)) {
                    // flags - multiboot flags
                    uint flags = /*HEADER_MB_FLAG_VIDEO_MODES_REQUIRED | */ HEADER_MB_FLAG_MEMORY_INFO_REQUIRED | HEADER_MB_FLAG_MODULES_PAGE_ALIGNED;
                    // The multiboot _header checksum
                    uint csum = 0;
                    // header_addr is the load virtualAddress of the multiboot _header
                    uint header_addr = 0;
                    // load_addr is the base virtualAddress of the binary in memory
                    uint load_addr = 0;
                    // load_end_addr holds the virtualAddress past the last byte to load From the image
                    uint load_end_addr = 0;
                    // bss_end_addr is the virtualAddress of the last byte to be zeroed out
                    uint bss_end_addr = 0;
                    // entry_point the load virtualAddress of the entry point to invoke
                    uint entry_point = (uint)entryPoint.ToInt32();

                    // Are we linking an ELF binary?
                    if (!(linker is Elf32Linker || linker is Elf64Linker))
                    {
                        // Check the linker layout settings
                        if (linker.LoadSectionAlignment != linker.VirtualSectionAlignment)
                        {
                            throw new LinkerException(@"Load and virtual section alignment must be identical if you are booting non-ELF binaries with a multiboot bootloader.");
                        }

                        // No, special multiboot treatment required
                        flags |= HEADER_MB_FLAG_NON_ELF_BINARY;

                        header_addr   = (uint)(linker.GetSection(SectionKind.Text).VirtualAddress.ToInt64() + linker.GetSymbol(MultibootHeaderSymbolName).SectionAddress);
                        load_addr     = (uint)linker.BaseAddress;
                        load_end_addr = 0;
                        bss_end_addr  = 0;
                    }

                    // Calculate the checksum
                    csum = unchecked (0U - HEADER_MB_MAGIC - flags);

                    bw.Write(HEADER_MB_MAGIC);
                    bw.Write(flags);
                    bw.Write(csum);
                    bw.Write(header_addr);
                    bw.Write(load_addr);
                    bw.Write(load_end_addr);
                    bw.Write(bss_end_addr);

                    // HACK: Symbol has been hacked. What's the correct way to do this?
                    linker.Link(LinkType.AbsoluteAddress | LinkType.I4, MultibootHeaderSymbolName, (int)stream.Position, 0, @"Mosa.Tools.Compiler.LinkerGenerated.<$>MultibootInit()", IntPtr.Zero);

                    bw.Write(videoMode);
                    bw.Write(videoWidth);
                    bw.Write(videoHeight);
                    bw.Write(videoDepth);
                }
        }
Example #5
0
 private void AllocateSpace(IAssemblyLinker linker, RuntimeField field, SectionKind section, int size, int alignment)
 {
     using (Stream stream = linker.Allocate(field, section, size, alignment))
     {
         if (IntPtr.Zero != field.RVA)
         {
             InitializeStaticValueFromRVA(stream, size, field);
         }
         else
         {
             WriteDummyBytes(stream, size);
         }
     }
 }
Example #6
0
        /// <summary>
        /// Exports the CIL metadata.
        /// </summary>
        /// <param name="module">The module.</param>
        /// <param name="linker">The linker.</param>
        private void ExportCilMetadata(IMetadataModule module, IAssemblyLinker linker)
        {
            /*
             * FIXME:
             * - Obtain CIL & MOSA metadata tables
             * - Write metadata root
             * - Write the CIL tables (modified)
             * - Write the MOSA tables (new)
             * - Write the strings, guid and blob heap (unchanged From original module)
             */

            // Metadata is in the .text section in order to make it relocatable everywhere.
            using (Stream stream = linker.Allocate(Runtime.Metadata.Symbol.Name, SectionKind.Text, module.Metadata.Metadata.Length, 0))

                using (BinaryWriter bw = new BinaryWriter(stream, Encoding.ASCII)) {
                    bw.Write(module.Metadata.Metadata);
                }
        }
        /// <summary>
        /// Exports the CIL metadata.
        /// </summary>
        /// <param name="module">The module.</param>
        /// <param name="linker">The linker.</param>
        private void ExportCilMetadata(IMetadataModule module, IAssemblyLinker linker)
        {
            /*
             * FIXME:
             * - Obtain CIL & MOSA metadata tables
             * - Write metadata root
             * - Write the CIL tables (modified)
             * - Write the MOSA tables (new)
             * - Write the strings, guid and blob heap (unchanged From original module)
             */

            // Metadata is in the .text section in order to make it relocatable everywhere.
            using (Stream stream = linker.Allocate(Runtime.Metadata.Symbol.Name, SectionKind.Text, module.Metadata.Metadata.Length, 0))

            using (BinaryWriter bw = new BinaryWriter(stream, Encoding.ASCII)) {
                bw.Write(module.Metadata.Metadata);
            }
        }
Example #8
0
 /// <summary>
 /// Allocates the metadata stream in the output assembly.
 /// </summary>
 /// <param name="linker">The linker to allocate the metadata stream in.</param>
 /// <returns>The allocated metadata stream.</returns>
 private static Stream AllocateMetadataStream(IAssemblyLinker linker)
 {
     return(linker.Allocate(Symbol.Name, SectionKind.Text, 0, 0));
 }
Example #9
0
 /// <summary>
 /// Requests a stream to emit native instructions to.
 /// </summary>
 /// <returns>A stream object, which can be used to store emitted instructions.</returns>
 public virtual Stream RequestCodeStream()
 {
     return(_linker.Allocate(_method, SectionKind.Text, 0, 0));
 }
Example #10
0
 private void AllocateSpace(IAssemblyLinker linker, RuntimeField field, SectionKind section, int size, int alignment)
 {
     using (Stream stream = linker.Allocate (field, section, size, alignment))
     {
         if (IntPtr.Zero != field.RVA)
             InitializeStaticValueFromRVA (stream, size, field);
         else
             WriteDummyBytes (stream, size);
     }
 }
Example #11
0
 /// <summary>
 /// Allocates the metadata stream in the output assembly.
 /// </summary>
 /// <param name="linker">The linker to allocate the metadata stream in.</param>
 /// <returns>The allocated metadata stream.</returns>
 private static Stream AllocateMetadataStream(IAssemblyLinker linker)
 {
     return linker.Allocate(Symbol.Name, SectionKind.Text, 0, 0);
 }
 /// <summary>
 /// Requests a stream to emit native instructions to.
 /// </summary>
 /// <returns>A stream object, which can be used to store emitted instructions.</returns>
 public virtual Stream RequestCodeStream()
 {
     return(linker.Allocate(method.ToString(), SectionKind.Text, 0, 0));
 }
Example #13
0
        /// <summary>
        /// Writes the multiboot _header.
        /// </summary>
        /// <param name="compiler">The assembly compiler.</param>
        /// <param name="linker">The linker.</param>
        /// <param name="entryPoint">The virtualAddress of the multiboot compliant entry point.</param>
        private void WriteMultibootHeader(AssemblyCompiler compiler, IAssemblyLinker linker, IntPtr entryPoint)
        {
            // HACK: According to the multiboot specification this _header must be within the first 8K of the
            // kernel binary. Since the text section is always first, this should take care of the problem.
            using (Stream stream = linker.Allocate(MultibootHeaderSymbolName, SectionKind.Text, 64, 4))
            using (BinaryWriter bw = new BinaryWriter(stream, Encoding.ASCII)) {
                // flags - multiboot flags
                uint flags = /*HEADER_MB_FLAG_VIDEO_MODES_REQUIRED | */HEADER_MB_FLAG_MEMORY_INFO_REQUIRED | HEADER_MB_FLAG_MODULES_PAGE_ALIGNED;
                // The multiboot _header checksum
                uint csum = 0;
                // header_addr is the load virtualAddress of the multiboot _header
                uint header_addr = 0;
                // load_addr is the base virtualAddress of the binary in memory
                uint load_addr = 0;
                // load_end_addr holds the virtualAddress past the last byte to load From the image
                uint load_end_addr = 0;
                // bss_end_addr is the virtualAddress of the last byte to be zeroed out
                uint bss_end_addr = 0;
                // entry_point the load virtualAddress of the entry point to invoke
                uint entry_point = (uint)entryPoint.ToInt32();

                // Are we linking an ELF binary?
                if (!(linker is Elf32Linker || linker is Elf64Linker)) {
                    // Check the linker layout settings
                    if (linker.LoadSectionAlignment != linker.VirtualSectionAlignment)
                        throw new LinkerException(@"Load and virtual section alignment must be identical if you are booting non-ELF binaries with a multiboot bootloader.");

                    // No, special multiboot treatment required
                    flags |= HEADER_MB_FLAG_NON_ELF_BINARY;

                    header_addr = (uint)(linker.GetSection(SectionKind.Text).VirtualAddress.ToInt64() + linker.GetSymbol(MultibootHeaderSymbolName).SectionAddress);
                    load_addr = (uint)linker.BaseAddress;
                    load_end_addr = 0;
                    bss_end_addr = 0;
                }

                // Calculate the checksum
                csum = unchecked(0U - HEADER_MB_MAGIC - flags);

                bw.Write(HEADER_MB_MAGIC);
                bw.Write(flags);
                bw.Write(csum);
                bw.Write(header_addr);
                bw.Write(load_addr);
                bw.Write(load_end_addr);
                bw.Write(bss_end_addr);

                // HACK: Symbol has been hacked. What's the correct way to do this?
                linker.Link(LinkType.AbsoluteAddress | LinkType.I4, MultibootHeaderSymbolName, (int)stream.Position, 0, @"Mosa.Tools.Compiler.LinkerGenerated.<$>MultibootInit()", IntPtr.Zero);

                bw.Write(videoMode);
                bw.Write(videoWidth);
                bw.Write(videoHeight);
                bw.Write(videoDepth);
            }
        }