Example #1
0
        /// <summary>
        /// Allocates memory for the static field and initializes it.
        /// </summary>
        /// <param name="field">The field.</param>
        private void CreateStaticField(RuntimeField field)
        {
            Debug.Assert(field != null, "No field given.");

            // Determine the size of the type & alignment requirements
            int size, alignment;

            _architecture.GetTypeRequirements(field.Type, out size, out alignment);

            // Retrieve the linker
            IAssemblyLinker linker = _compiler.Pipeline.Find <IAssemblyLinker> ();
            // The linker section to move this field into
            SectionKind section;

            // Does this field have an RVA?
            if (IntPtr.Zero != field.RVA)
            {
                // FIXME: Move a static field into ROData, if it is read-only and can be initialized
                // using static analysis
                section = SectionKind.Data;
            }
            else
            {
                section = SectionKind.BSS;
            }

            AllocateSpace(linker, field, section, size, alignment);
        }
 /// <summary>
 /// Initializes a new instance of the LinkerFormalSelector class.
 /// </summary>
 public LinkerFormatSelector()
 {
     this.peLinker       = new PortableExecutableLinkerWrapper();
     this.elf32Linker    = new Elf32LinkerWrapper();
     this.elf64Linker    = new Elf64LinkerWrapper();
     this.implementation = null;
 }
Example #3
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);
         }
 }
 /// <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);
     }
 }
        /// <summary>
        /// Performs stage specific processing on the compiler context.
        /// </summary>
        /// <param name="compiler">The compiler context to perform processing in.</param>
        public void Run(AssemblyCompiler compiler)
        {
            _linker = compiler.Pipeline.FindFirst<IAssemblyLinker>();

            CreateISRMethods(compiler);
            CreateIVTMethod(compiler);
        }
Example #6
0
        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            if (_pipeline == null)
            {
                throw new ObjectDisposedException("MethodCompilerBase");
            }

            foreach (IMethodCompilerStage mcs in _pipeline)
            {
                IDisposable d = mcs as IDisposable;
                if (null != d)
                {
                    d.Dispose();
                }
            }

            _pipeline.Clear();
            _pipeline = null;

            _architecture   = null;
            _linker         = null;
            _method         = null;
            _module         = null;
            _type           = null;
            _instructionSet = null;
            _basicBlocks    = null;
        }
 public TestCaseMethodCompiler(IAssemblyLinker linker, IArchitecture architecture, IMetadataModule module, RuntimeType type, RuntimeMethod method)
     : base(linker, architecture, module, type, method)
 {
     // Populate the pipeline
     this.Pipeline.AddRange(new IMethodCompilerStage[] {
         new DecodingStage(),
         new BasicBlockBuilderStage(),
         new OperandDeterminationStage(),
         new InstructionLogger(),
         //new ConstantFoldingStage(),
         new CILTransformationStage(),
         //new InstructionLogger(),
         //InstructionStatisticsStage.Instance,
         //new DominanceCalculationStage(),
         //new EnterSSA(),
         //new ConstantPropagationStage(),
         //new ConstantFoldingStage(),
         //new LeaveSSA(),
         new StackLayoutStage(),
         new PlatformStubStage(),
         new InstructionLogger(),
         //new BlockReductionStage(),
         new LoopAwareBlockOrderStage(),
         //new SimpleTraceBlockOrderStage(),
         //new ReverseBlockOrderStage(),  // reverse all the basic blocks and see if it breaks anything
         //new BasicBlockOrderStage()
         new CodeGenerationStage(),
         //new InstructionLogger(),
     });
 }
        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            if (pipeline == null)
            {
                throw new ObjectDisposedException(@"MethodCompilerBase");
            }

            foreach (IMethodCompilerStage mcs in pipeline)
            {
                IDisposable d = mcs as IDisposable;
                if (null != d)
                {
                    d.Dispose();
                }
            }

            pipeline.Clear();
            pipeline = null;

            architecture   = null;
            linker         = null;
            method         = null;
            type           = null;
            instructionSet = null;
            basicBlocks    = null;
        }
 /// <summary>
 /// Initializes a new instance of the LinkerFormalSelector class.
 /// </summary>
 public LinkerFormatSelector()
 {
     this.peLinker = new PortableExecutableLinkerWrapper();
     this.elf32Linker = new Elf32LinkerWrapper();
     this.elf64Linker = new Elf64LinkerWrapper();
     this.implementation = null;
 }
Example #10
0
        /// <summary>
        /// Lays out the sections in order of appearance.
        /// </summary>
        /// <param name="linker">The linker.</param>
        protected virtual void LayoutSections(IAssemblyLinker linker)
        {
            long fileAlignment    = linker.LoadSectionAlignment;
            long sectionAlignment = linker.VirtualSectionAlignment;

            // Reset the size of the image
            long virtualSizeOfImage = sectionAlignment;
            long fileSizeOfImage    = fileAlignment;

            // Move all sections to their right positions
            foreach (LinkerSection ls in linker.Sections)
            {
                // Only use a section with something inside
                if (ls.Length > 0)
                {
                    // Set the section virtualAddress
                    ls.VirtualAddress = new IntPtr(linker.BaseAddress + virtualSizeOfImage);
                    ls.Offset         = fileSizeOfImage;

                    // Update the file size
                    fileSizeOfImage += ls.Length;
                    fileSizeOfImage  = AlignValue(fileSizeOfImage, fileAlignment);

                    // Update the virtual size
                    virtualSizeOfImage += ls.Length;
                    virtualSizeOfImage  = AlignValue(virtualSizeOfImage, sectionAlignment);
                }
            }
        }
        /// <summary>
        /// Lays out the sections in order of appearance.
        /// </summary>
        /// <param name="linker">The linker.</param>
        protected virtual void LayoutSections(IAssemblyLinker linker)
        {
            long fileAlignment = linker.LoadSectionAlignment;
            long sectionAlignment = linker.VirtualSectionAlignment;

            // Reset the size of the image
            long virtualSizeOfImage = sectionAlignment;
            long fileSizeOfImage = fileAlignment;

            // Move all sections to their right positions
            foreach (LinkerSection ls in linker.Sections) {
                // Only use a section with something inside
                if (ls.Length > 0) {
                    // Set the section virtualAddress
                    ls.VirtualAddress = new IntPtr(linker.BaseAddress + virtualSizeOfImage);
                    ls.Offset = fileSizeOfImage;

                    // Update the file size
                    fileSizeOfImage += ls.Length;
                    fileSizeOfImage = AlignValue(fileSizeOfImage, fileAlignment);

                    // Update the virtual size
                    virtualSizeOfImage += ls.Length;
                    virtualSizeOfImage = AlignValue(virtualSizeOfImage, sectionAlignment);
                }
            }
        }
Example #12
0
 public TestCaseMethodCompiler(IAssemblyLinker linker, IArchitecture architecture, IMetadataModule module, RuntimeType type, RuntimeMethod method) :
     base(linker, architecture, module, type, method)
 {
     // Populate the pipeline
     this.Pipeline.AddRange(new IMethodCompilerStage[] {
         new DecodingStage(),
         new BasicBlockBuilderStage(),
         new OperandDeterminationStage(),
         new InstructionLogger(typeof(OperandDeterminationStage)),
         //new ConstantFoldingStage(),
         new CILTransformationStage(),
         //new InstructionLogger(typeof(CILTransformationStage)),
         //InstructionStatisticsStage.Instance,
         //new DominanceCalculationStage(),
         //new EnterSSA(),
         //new ConstantPropagationStage(),
         //new ConstantFoldingStage(),
         //new LeaveSSA(),
         new StackLayoutStage(),
         new InstructionLogger(typeof(StackLayoutStage)),
         //new BlockReductionStage(),
         new LoopAwareBlockOrderStage(),
         //new SimpleTraceBlockOrderStage(),
         //new ReverseBlockOrderStage(),  // reverse all the basic blocks and see if it breaks anything
         //new BasicBlockOrderStage()
         new CodeGenerationStage(),
         //new InstructionLogger(typeof(CodeGenerationStage)),
         // new InstructionLogger(typeof(CodeGenerationStage)),
     });
 }
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);
                }
        }
Example #14
0
 /// <summary>
 /// Emits all the section created in the binary file.
 /// </summary>
 /// <param name="linker">The assembly linker.</param>
 private void EmitSections(IAssemblyLinker linker)
 {
     _writer.WriteLine("Offset           Virtual          Length           Name                             Class");
     foreach (LinkerSection section in linker.Sections)
     {
         _writer.WriteLine("{0:x16} {1:x16} {2:x16} {3} {4}", section.Offset, section.VirtualAddress.ToInt64(), section.Length, section.Name.PadRight(32), section.SectionKind);
     }
 }
Example #15
0
        public MethodCompiler(IAssemblyLinker linker, IArchitecture architecture, IMetadataModule module, RuntimeType type, RuntimeMethod method, Stream codeStream)
            : base(linker, architecture, module, type, method)
        {
            if (null == codeStream)
                throw new ArgumentNullException(@"codeStream");

            _codeStream = codeStream;
        }
 /// <summary>
 /// Lays the symbols out according to their offset in the section.
 /// </summary>
 /// <param name="linker">The linker.</param>
 protected virtual void LayoutSymbols(IAssemblyLinker linker)
 {
     // Adjust the symbol addresses
     foreach (LinkerSymbol symbol in linker.Symbols) {
         LinkerSection ls = linker.GetSection(symbol.Section);
         symbol.Offset = ls.Offset + symbol.SectionAddress;
         symbol.VirtualAddress = new IntPtr(ls.VirtualAddress.ToInt64() + symbol.SectionAddress);
     }
 }
Example #17
0
        public void Run()
        {
            this.linker = this.methodCompiler.Linker;

            if (this.methodCompiler.Method.Name == @".cctor")
            {
                this.AttemptToStaticallyAllocateObjects();
            }
        }
        public void Run()
        {
            this.linker = this.MethodCompiler.Linker;

            if (this.MethodCompiler.Method.Name == @".cctor")
            {
                this.AttemptToStaticallyAllocateObjects();
            }
        }
Example #19
0
 /// <summary>
 /// Lays the symbols out according to their offset in the section.
 /// </summary>
 /// <param name="linker">The linker.</param>
 protected virtual void LayoutSymbols(IAssemblyLinker linker)
 {
     // Adjust the symbol addresses
     foreach (LinkerSymbol symbol in linker.Symbols)
     {
         LinkerSection ls = linker.GetSection(symbol.Section);
         symbol.Offset         = ls.Offset + symbol.SectionAddress;
         symbol.VirtualAddress = new IntPtr(ls.VirtualAddress.ToInt64() + symbol.SectionAddress);
     }
 }
Example #20
0
        public MethodCompiler(IAssemblyLinker linker, IArchitecture architecture, IMetadataModule module, RuntimeType type, RuntimeMethod method, Stream codeStream) :
            base(linker, architecture, module, type, method)
        {
            if (null == codeStream)
            {
                throw new ArgumentNullException(@"codeStream");
            }

            _codeStream = codeStream;
        }
        /// <summary>
        /// Retrieves the assembly linker from compiler.
        /// </summary>
        /// <returns>The retrieved assembly linker.</returns>
        protected IAssemblyLinker RetrieveAssemblyLinkerFromCompiler()
        {
            IAssemblyLinker linker = compiler.Pipeline.FindFirst <IAssemblyLinker>();

            if (linker == null)
            {
                throw new InvalidOperationException(@"A linker is required.");
            }

            return(linker);
        }
        void IAssemblyCompilerStage.Setup(AssemblyCompiler compiler)
        {
            base.Setup(compiler);

            typeInitializerSchedulerStage = compiler.Pipeline.FindFirst<ITypeInitializerSchedulerStage>();

            if (typeInitializerSchedulerStage == null)
                throw new InvalidOperationException(@"AssemblyCompilationStage needs a ITypeInitializerSchedulerStage.");

            linker = RetrieveAssemblyLinkerFromCompiler();
        }
Example #23
0
        /// <summary>
        /// Performs stage specific processing on the compiler context.
        /// </summary>
        /// <param name="compiler">The compiler context to perform processing in.</param>
        public void Run(AssemblyCompiler compiler)
        {
            IAssemblyLinker linker = compiler.Pipeline.Find <IAssemblyLinker> ();

            if (linker == null)
            {
                throw new InvalidOperationException("ObjectFileLayoutStage needs a linker.");
            }

            LayoutSections(linker);
            LayoutSymbols(linker);
        }
        void IAssemblyCompilerStage.Setup(AssemblyCompiler compiler)
        {
            base.Setup(compiler);

            typeInitializerSchedulerStage = compiler.Pipeline.FindFirst <ITypeInitializerSchedulerStage>();

            if (typeInitializerSchedulerStage == null)
            {
                throw new InvalidOperationException(@"AssemblyCompilationStage needs a ITypeInitializerSchedulerStage.");
            }

            linker = RetrieveAssemblyLinkerFromCompiler();
        }
 public AotAssemblyCompiler(IArchitecture architecture, IMetadataModule assembly, ITypeInitializerSchedulerStage typeInitializerSchedulerStage, IAssemblyLinker linker)
     : base(architecture, assembly)
 {
     this.Pipeline.AddRange(
             new IAssemblyCompilerStage[]
             {
                 new TypeLayoutStage(),
                 new AssemblyMemberCompilationSchedulerStage(),
                 new MethodCompilerSchedulerStage(),
                 new TypeInitializerSchedulerStageProxy(typeInitializerSchedulerStage),
                 new LinkerProxy(linker)
             });
 }
Example #26
0
        /// <summary>
        /// Initializes the metadata builder stage using the given assembly compiler.
        /// </summary>
        /// <param name="compiler">The assembly compiler.</param>
        private void Initialize(AssemblyCompiler compiler)
        {
            IAssemblyLinker linker = RetrieveAssemblyLinkerFromCompiler(compiler);

            if (linker == null)
            {
                throw new InvalidOperationException(@"Can't build metadata without a linker.");
            }

            _metadataStream = AllocateMetadataStream(linker);
            _metadataWriter = new BinaryWriter(_metadataStream, Encoding.UTF8);
            _metadataSource = compiler.Metadata;
        }
Example #27
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 #28
0
        /// <summary>
        /// Performs stage specific processing on the compiler context.
        /// </summary>
        /// <param name="compiler">The compiler context to perform processing in.</param>
        public void Run(AssemblyCompiler compiler)
        {
            IAssemblyLinker linker = compiler.Pipeline.Find <IAssemblyLinker>();

            if (linker == null)
            {
                throw new InvalidOperationException(@"Can't run without a linker.");
            }

            // FIXME: Retrieve the compilation target assembly
            // HACK: Using Metadata From source assembly, rather than re-create it From scratch From the target assembly
            IMetadataModule module = compiler.Assembly;

            ExportCilMetadata(module, linker);
        }
Example #29
0
        /// <summary>
        /// Writes the multiboot entry point.
        /// </summary>
        /// <param name="linker">The linker.</param>
        /// <returns>The virtualAddress of the real entry point.</returns>
        private IntPtr WriteMultibootEntryPoint(IAssemblyLinker linker)
        {
            /*
             * FIXME:
             *
             * We can't use the standard entry point of the module. Instead
             * we write a multiboot compliant entry point here, which populates
             * the boot structure - so that it can be retrieved later.
             *
             * Unfortunately this means, we need to define the boot structure
             * in the kernel to be able to access it later.
             *
             */

            return(IntPtr.Zero);
        }
Example #30
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);
                }
        }
Example #31
0
        /// <summary>
        /// Emits all symbols emitted in the binary file.
        /// </summary>
        /// <param name="linker">The assembly linker.</param>
        private void EmitSymbols(IAssemblyLinker linker)
        {
            _writer.WriteLine("Offset           Virtual          Length           Symbol");
            foreach (LinkerSymbol symbol in linker.Symbols)
            {
                _writer.WriteLine("{0:x16} {1:x16} {2:x16} {3}", symbol.Offset, symbol.VirtualAddress.ToInt64(), symbol.Length, symbol.Name);
            }

            LinkerSymbol entryPoint = linker.EntryPoint;

            if (entryPoint != null)
            {
                _writer.WriteLine();
                _writer.WriteLine("Entry point is {0}", entryPoint.Name);
                _writer.WriteLine("\tat offset {0:x16}", entryPoint.Offset);
                _writer.WriteLine("\tat virtual address {0:x16}", entryPoint.VirtualAddress.ToInt64());
            }
        }
Example #32
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>
        /// Adds the additional options for the parsing process to the given OptionSet.
        /// </summary>
        /// <param name="optionSet">A given OptionSet to add the options to.</param>
        public void AddOptions(OptionSet optionSet)
        {
            IHasOptions options;

            optionSet.Add(
                "f|format=",
                "Select the format of the binary file to create [{ELF32|ELF64|PE}].",
                delegate(string format)
            {
                this.implementation = SelectImplementation(format);
            }
                );

            optionSet.Add(
                "o|out=",
                "The name of the output {file}.",
                delegate(string file)
            {
                this.outputFile =
                    peLinker.Wrapped.OutputFile            =
                        elf32Linker.Wrapped.OutputFile     =
                            elf64Linker.Wrapped.OutputFile =
                                file;
            }
                );

            options = peLinker as IHasOptions;
            if (options != null)
            {
                options.AddOptions(optionSet);
            }

            options = elf32Linker as IHasOptions;
            if (options != null)
            {
                options.AddOptions(optionSet);
            }

            options = elf64Linker as IHasOptions;
            if (options != null)
            {
                options.AddOptions(optionSet);
            }
        }
Example #34
0
        /// <summary>
        /// Performs stage specific processing on the compiler context.
        /// </summary>
        /// <param name="compiler">The compiler context to perform processing in.</param>
        public void Run(AssemblyCompiler compiler)
        {
            if (compiler == null)
            {
                throw new ArgumentNullException(@"compiler");
            }

            IAssemblyLinker linker = compiler.Pipeline.Find <IAssemblyLinker>();

            Debug.Assert(linker != null, @"No linker??");

            if (!secondStage)
            {
                IntPtr entryPoint = WriteMultibootEntryPoint(linker);
                WriteMultibootHeader(compiler, linker, entryPoint);
                secondStage = true;
            }
            else
            {
                TypeInitializerSchedulerStage typeInitializerSchedulerStage = compiler.Pipeline.Find <TypeInitializerSchedulerStage>();

                SigType I4 = new SigType(CilElementType.I4);

                RegisterOperand ecx = new RegisterOperand(I4, GeneralPurposeRegister.ECX);
                RegisterOperand eax = new RegisterOperand(I4, GeneralPurposeRegister.EAX);
                RegisterOperand ebx = new RegisterOperand(I4, GeneralPurposeRegister.EBX);

                InstructionSet instructionSet = new InstructionSet(16);
                Context        ctx            = new Context(instructionSet, -1);

                ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, ecx, new ConstantOperand(I4, 0x200000));
                ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, new MemoryOperand(I4, ecx.Register, new IntPtr(0x0)), eax);
                ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, new MemoryOperand(I4, ecx.Register, new IntPtr(0x4)), ebx);
                ctx.AppendInstruction(IR.Instruction.CallInstruction);
                ctx.InvokeTarget = typeInitializerSchedulerStage.Method;
                ctx.AppendInstruction(CPUx86.Instruction.NopInstruction);
                ctx.AppendInstruction(CPUx86.Instruction.NopInstruction);
                ctx.AppendInstruction(CPUx86.Instruction.RetInstruction);

                CompilerGeneratedMethod method = LinkTimeCodeGenerator.Compile(compiler, @"MultibootInit", instructionSet);
                linker.EntryPoint = linker.GetSymbol(method);
            }
        }
Example #35
0
        /// <summary>
        /// Performs stage specific processing on the compiler context.
        /// </summary>
        /// <param name="compiler">The compiler context to perform processing in.</param>
        public void Run(AssemblyCompiler compiler)
        {
            // Retrieve the linker
            IAssemblyLinker linker = compiler.Pipeline.Find <IAssemblyLinker> ();

            // Emit map file _header
            this.writer.WriteLine(linker.OutputFile);
            this.writer.WriteLine();
            this.writer.WriteLine("Timestamp is {0}", linker.TimeStamp);
            this.writer.WriteLine();
            this.writer.WriteLine("Preferred load address is {0:x16}", linker.BaseAddress);
            this.writer.WriteLine();

            // Emit the sections
            EmitSections(linker);
            this.writer.WriteLine();

            // Emit all symbols
            EmitSymbols(linker);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="BaseMethodCompiler"/> class.
        /// </summary>
        /// <param name="linker">The _linker.</param>
        /// <param name="architecture">The target compilation Architecture.</param>
        /// <param name="type">The type, which owns the method to compile.</param>
        /// <param name="method">The method to compile by this instance.</param>
        protected BaseMethodCompiler(
            IAssemblyLinker linker,
            IArchitecture architecture,
            ICompilationSchedulerStage compilationScheduler,
            RuntimeType type,
            RuntimeMethod method,
            ITypeSystem typeSystem,
            ITypeLayout typeLayout)
        {
            if (architecture == null)
            {
                throw new ArgumentNullException(@"architecture");
            }

            if (linker == null)
            {
                throw new ArgumentNullException(@"linker");
            }

            if (compilationScheduler == null)
            {
                throw new ArgumentNullException(@"compilationScheduler");
            }

            this.linker       = linker;
            this.architecture = architecture;
            this.method       = method;
            this.type         = type;

            parameters     = new List <Operand>(new Operand[method.Parameters.Count]);
            nextStackSlot  = 0;
            basicBlocks    = new List <BasicBlock>();
            instructionSet = null;             // this will be set later

            pipeline = new CompilerPipeline();

            this.compilationScheduler = compilationScheduler;
            this.moduleTypeSystem     = method.Module;
            this.typeSystem           = typeSystem;
            this.typeLayout           = typeLayout;
        }
        /// <summary>
        /// Initializes a new instance of <see cref="MachineCodeEmitter"/>.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        /// <param name="codeStream">The stream the machine code is written to.</param>
        /// <param name="linker">The linker used to resolve external addresses.</param>
        void ICodeEmitter.Initialize(IMethodCompiler compiler, Stream codeStream, IAssemblyLinker linker)
        {
            Debug.Assert(null != compiler, @"MachineCodeEmitter needs a method compiler.");
            if (compiler == null)
            {
                throw new ArgumentNullException(@"compiler");
            }
            Debug.Assert(null != codeStream, @"MachineCodeEmitter needs a code stream.");
            if (codeStream == null)
            {
                throw new ArgumentNullException(@"codeStream");
            }
            Debug.Assert(null != linker, @"MachineCodeEmitter needs a linker.");
            if (linker == null)
            {
                throw new ArgumentNullException(@"linker");
            }

            _compiler               = compiler;
            _codeStream             = codeStream;
            _codeStreamBasePosition = codeStream.Position;
            _linker = linker;
        }
Example #38
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MethodCompilerBase"/> class.
        /// </summary>
        /// <param name="linker">The _linker.</param>
        /// <param name="architecture">The target compilation Architecture.</param>
        /// <param name="module">The metadata module, that contains the type.</param>
        /// <param name="type">The type, which owns the _method to compile.</param>
        /// <param name="method">The method to compile by this instance.</param>
        protected MethodCompilerBase(IAssemblyLinker linker, IArchitecture architecture, IMetadataModule module, RuntimeType type, RuntimeMethod method)
        {
            if (architecture == null)
            {
                throw new ArgumentNullException("architecture");
            }

            if (linker == null)
            {
                throw new ArgumentNullException("linker");
            }

            _architecture   = architecture;
            _linker         = linker;
            _method         = method;
            _module         = module;
            _parameters     = new List <Operand> (new Operand[_method.Parameters.Count]);
            _type           = type;
            _nextStackSlot  = 0;
            _basicBlocks    = new List <BasicBlock> ();
            _instructionSet = null;
            // this will be set later
        }
Example #39
0
        /// <summary>
        /// Performs stage specific processing on the compiler context.
        /// </summary>
        /// <param name="compiler">The compiler context to perform processing in.</param>
        public void Run(AssemblyCompiler compiler)
        {
            if (compiler == null)
            {
                throw new ArgumentNullException(@"compiler");
            }

            IAssemblyLinker linker = compiler.Pipeline.Find <IAssemblyLinker>();

            Debug.Assert(linker != null, @"No linker??");

            _cliHeader.Cb = 0x48;
            _cliHeader.MajorRuntimeVersion = 2;
            _cliHeader.MinorRuntimeVersion = 0;
            _cliHeader.Flags           = RuntimeImageFlags.ILOnly;
            _cliHeader.EntryPointToken = 0x06000001;             // FIXME: ??

            LinkerSymbol metadata = linker.GetSymbol(Mosa.Runtime.Metadata.Symbol.Name);

            _cliHeader.Metadata.VirtualAddress = (uint)(linker.GetSection(SectionKind.Text).VirtualAddress.ToInt64() + metadata.SectionAddress);
            _cliHeader.Metadata.Size           = (int)metadata.Length;

            WriteCilHeader(compiler, linker);
        }
        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            if (pipeline == null)
                throw new ObjectDisposedException(@"MethodCompilerBase");

            foreach (IMethodCompilerStage mcs in pipeline)
            {
                IDisposable d = mcs as IDisposable;
                if (d != null)
                    d.Dispose();
            }

            pipeline = null;
            architecture = null;
            linker = null;
            method = null;
            type = null;
            instructionSet = null;
            basicBlocks = null;
            stackLayout = null;
            locals = null;
        }
        void IAssemblyCompilerStage.Setup(AssemblyCompiler compiler)
        {
            base.Setup(compiler);
            linker = RetrieveAssemblyLinkerFromCompiler();

            if (compiler.CompilerOptions.Multiboot.VideoDepth.HasValue)
                this.VideoDepth = compiler.CompilerOptions.Multiboot.VideoDepth.Value;
            if (compiler.CompilerOptions.Multiboot.VideoHeight.HasValue)
                this.VideoHeight = compiler.CompilerOptions.Multiboot.VideoHeight.Value;
            if (compiler.CompilerOptions.Multiboot.VideoMode.HasValue)
                this.VideoMode = compiler.CompilerOptions.Multiboot.VideoMode.Value;
            if (compiler.CompilerOptions.Multiboot.VideoWidth.HasValue)
                this.VideoWidth = compiler.CompilerOptions.Multiboot.VideoWidth.Value;
        }
Example #42
0
 public AotAssemblyCompiler(IArchitecture architecture, IAssemblyLinker linker, ITypeSystem typeSystem, ITypeLayout typeLayout, IInternalTrace internalTrace, CompilerOptions compilerOptions)
     : base(architecture, typeSystem, typeLayout, internalTrace, compilerOptions)
 {
 }
 void IAssemblyCompilerStage.Setup(AssemblyCompiler compiler)
 {
     base.Setup(compiler);
     this.linker = RetrieveAssemblyLinkerFromCompiler();
 }
Example #44
0
        void IAssemblyCompilerStage.Setup(AssemblyCompiler compiler)
        {
            base.Setup(compiler);

            linker = RetrieveAssemblyLinkerFromCompiler();
        }
Example #45
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 #46
0
        void IAssemblyCompilerStage.Setup(AssemblyCompiler compiler)
        {
            base.Setup(compiler);
            this.linker = RetrieveAssemblyLinkerFromCompiler();

            plugTypeAttribute = typeSystem.GetType("Mosa.Internal.Plug", "Mosa.Internal.Plug", "PlugTypeAttribute");
            plugMethodAttribute = typeSystem.GetType("Mosa.Internal.Plug", "Mosa.Internal.Plug", "PlugMethodAttribute");
        }
 public void Setup(AssemblyCompiler compiler)
 {
     this.compiler = compiler;
     this.linker = compiler.Pipeline.FindFirst<IAssemblyLinker>();
 }
Example #48
0
 public LinkerProxy(IAssemblyLinker linker)
 {
     this.linker = linker;
 }
        /// <summary>
        /// Adds the additional options for the parsing process to the given OptionSet.
        /// </summary>
        /// <param name="optionSet">A given OptionSet to add the options to.</param>
        public void AddOptions(OptionSet optionSet)
        {
            IHasOptions options;

            optionSet.Add(
                "f|format=",
                "Select the format of the binary file to create [{ELF32|ELF64|PE}].",
                delegate(string format)
                {
                    this.implementation = SelectImplementation(format);
                }
            );

            optionSet.Add(
                "o|out=",
                "The name of the output {file}.",
                delegate(string file)
                {
                    this.outputFile =
                        peLinker.Wrapped.OutputFile =
                        elf32Linker.Wrapped.OutputFile =
                        elf64Linker.Wrapped.OutputFile =
                            file;
                }
            );

            options = peLinker as IHasOptions;
            if (options != null)
                options.AddOptions(optionSet);

            options = elf32Linker as IHasOptions;
            if (options != null)
                options.AddOptions(optionSet);

            options = elf64Linker as IHasOptions;
            if (options != null)
                options.AddOptions(optionSet);
        }
Example #50
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));
 }
        public void Setup(AssemblyCompiler compiler)
        {
            this.compiler = compiler;

            this.linker = RetrieveAssemblyLinkerFromCompiler();
            if (this.linker == null)
            {
                throw new InvalidOperationException(@"Can't build metadata without a linker.");
            }
        }
Example #52
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);
     }
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="BaseMethodCompiler"/> class.
        /// </summary>
        /// <param name="assemblyCompiler">The assembly compiler.</param>
        /// <param name="type">The type, which owns the method to compile.</param>
        /// <param name="method">The method to compile by this instance.</param>
        /// <param name="instructionSet">The instruction set.</param>
        /// <param name="compilationScheduler">The compilation scheduler.</param>
        protected BaseMethodCompiler(AssemblyCompiler assemblyCompiler, RuntimeType type, RuntimeMethod method, InstructionSet instructionSet, ICompilationSchedulerStage compilationScheduler)
        {
            if (compilationScheduler == null)
                throw new ArgumentNullException(@"compilationScheduler");

            this.assemblyCompiler = assemblyCompiler;
            this.method = method;
            this.type = type;
            this.compilationScheduler = compilationScheduler;
            this.moduleTypeSystem = method.Module;

            this.architecture = assemblyCompiler.Architecture;
            this.typeSystem = assemblyCompiler.TypeSystem;
            this.typeLayout = AssemblyCompiler.TypeLayout;
            this.internalTrace = AssemblyCompiler.InternalTrace;

            this.linker = assemblyCompiler.Pipeline.FindFirst<IAssemblyLinker>();
            this.plugSystem = assemblyCompiler.Pipeline.FindFirst<IPlugSystem>();

            this.parameters = new List<Operand>(new Operand[method.Parameters.Count]);
            this.basicBlocks = new BasicBlocks();

            this.instructionSet = instructionSet ?? new InstructionSet(256);

            this.pipeline = new CompilerPipeline();

            this.stackLayout = new StackLayout(architecture, method.Parameters.Count + (method.Signature.HasThis || method.Signature.HasExplicitThis ? 1 : 0));

            this.virtualRegisterLayout = new VirtualRegisterLayout(architecture, stackLayout);

            EvaluateParameterOperands();
        }
Example #54
0
        /// <summary>
        /// Emits all symbols emitted in the binary file.
        /// </summary>
        /// <param name="linker">The assembly linker.</param>
        private void EmitSymbols(IAssemblyLinker linker)
        {
            this.writer.WriteLine ("Offset           Virtual          Length           Symbol");
            foreach (LinkerSymbol symbol in linker.Symbols)
            {
                this.writer.WriteLine ("{0:x16} {1:x16} {2:x16} {3}", symbol.Offset, symbol.VirtualAddress.ToInt64 (), symbol.Length, symbol.Name);
            }

            LinkerSymbol entryPoint = linker.EntryPoint;
            if (null != entryPoint)
            {
                this.writer.WriteLine ();
                this.writer.WriteLine ("Entry point is {0}", entryPoint.Name);
                this.writer.WriteLine ("\tat offset {0:x16}", entryPoint.Offset);
                this.writer.WriteLine ("\tat virtual address {0:x16}", entryPoint.VirtualAddress.ToInt64 ());
            }
        }
Example #55
0
        /// <summary>
        /// Initializes a new instance of <see cref="BaseCodeEmitter"/>.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        /// <param name="codeStream">The stream the machine code is written to.</param>
        /// <param name="linker">The linker used to resolve external addresses.</param>
        void ICodeEmitter.Initialize(IMethodCompiler compiler, Stream codeStream, IAssemblyLinker linker)
        {
            Debug.Assert(null != compiler, @"MachineCodeEmitter needs a method compiler.");
            if (compiler == null)
                throw new ArgumentNullException(@"compiler");
            Debug.Assert(null != codeStream, @"MachineCodeEmitter needs a code stream.");
            if (codeStream == null)
                throw new ArgumentNullException(@"codeStream");
            Debug.Assert(null != linker, @"MachineCodeEmitter needs a linker.");
            if (linker == null)
                throw new ArgumentNullException(@"linker");

            this.compiler = compiler;
            this.codeStream = codeStream;
            this.codeStreamBasePosition = codeStream.Position;
            this.linker = linker;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="MethodCompilerBase"/> class.
        /// </summary>
        /// <param name="linker">The _linker.</param>
        /// <param name="architecture">The target compilation Architecture.</param>
        /// <param name="module">The metadata module, that contains the type.</param>
        /// <param name="type">The type, which owns the _method to compile.</param>
        /// <param name="method">The method to compile by this instance.</param>
        protected MethodCompilerBase(
			IAssemblyLinker linker,
			IArchitecture architecture,
		    ICompilationSchedulerStage compilationScheduler,
			IMetadataModule module,
			RuntimeType type,
			RuntimeMethod method)
        {
            if (architecture == null)
                throw new ArgumentNullException(@"architecture");

            if (linker == null)
                throw new ArgumentNullException(@"linker");

            if (compilationScheduler == null)
                throw new ArgumentNullException(@"compilationScheduler");

            _linker = linker;
            _architecture = architecture;
            this.compilationScheduler = compilationScheduler;
            _method = method;
            _module = module;
            _parameters = new List<Operand>(new Operand[_method.Parameters.Count]);
            _type = type;
            _nextStackSlot = 0;
            _basicBlocks = new List<BasicBlock>();
            _instructionSet = null; // this will be set later
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="BaseMethodCompiler"/> class.
        /// </summary>
        /// <param name="linker">The _linker.</param>
        /// <param name="architecture">The target compilation Architecture.</param>
        /// <param name="type">The type, which owns the method to compile.</param>
        /// <param name="method">The method to compile by this instance.</param>
        protected BaseMethodCompiler(
			IAssemblyLinker linker,
			IArchitecture architecture,
			ICompilationSchedulerStage compilationScheduler,
			RuntimeType type,
			RuntimeMethod method,
			ITypeSystem typeSystem,
			ITypeLayout typeLayout)
        {
            if (architecture == null)
                throw new ArgumentNullException(@"architecture");

            if (linker == null)
                throw new ArgumentNullException(@"linker");

            if (compilationScheduler == null)
                throw new ArgumentNullException(@"compilationScheduler");

            this.linker = linker;
            this.architecture = architecture;
            this.method = method;
            this.type = type;

            parameters = new List<Operand>(new Operand[method.Parameters.Count]);
            nextStackSlot = 0;
            basicBlocks = new List<BasicBlock>();
            instructionSet = null; // this will be set later

            pipeline = new CompilerPipeline();

            this.compilationScheduler = compilationScheduler;
            this.moduleTypeSystem = method.Module;
            this.typeSystem = typeSystem;
            this.typeLayout = typeLayout;
        }
        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            if (_pipeline == null)
                throw new ObjectDisposedException(@"MethodCompilerBase");

            foreach (IMethodCompilerStage mcs in _pipeline) {
                IDisposable d = mcs as IDisposable;
                if (null != d)
                    d.Dispose();
            }

            _pipeline.Clear();
            _pipeline = null;

            _architecture = null;
            _linker = null;
            _method = null;
            _module = null;
            _type = null;
            _instructionSet = null;
            _basicBlocks = null;
        }
Example #59
0
 /// <summary>
 /// Emits all the section created in the binary file.
 /// </summary>
 /// <param name="linker">The assembly linker.</param>
 private void EmitSections(IAssemblyLinker linker)
 {
     this.writer.WriteLine ("Offset           Virtual          Length           Name                             Class");
     foreach (LinkerSection section in linker.Sections)
     {
         this.writer.WriteLine ("{0:x16} {1:x16} {2:x16} {3} {4}", section.Offset, section.VirtualAddress.ToInt64 (), section.Length, section.Name.PadRight (32), section.SectionKind);
     }
 }
 public void Setup(AssemblyCompiler compiler)
 {
     this.outputAssemblyCompiler = compiler;
     this.typeInitializerSchedulerStage = compiler.Pipeline.FindFirst<ITypeInitializerSchedulerStage>();
     this.linker = compiler.Pipeline.FindFirst<IAssemblyLinker>();
 }