/// <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; }
/// <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); }
/// <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; }
/// <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); } } }
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)), }); }
/// <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); } }
/// <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); } }
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); } }
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(); } }
/// <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); } }
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(); }
/// <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) }); }
/// <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; }
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> /// 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); }
/// <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); }
/// <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> /// 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()); } }
/// <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); } }
/// <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); } }
/// <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; }
/// <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 }
/// <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; }
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(); }
void IAssemblyCompilerStage.Setup(AssemblyCompiler compiler) { base.Setup(compiler); linker = RetrieveAssemblyLinkerFromCompiler(); }
/// <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); }
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>(); }
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); }
/// <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."); } }
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(); }
/// <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 ()); } }
/// <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; }
/// <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>(); }