protected override void Setup()
        {
            base.Setup();

            symbol = MethodCompiler.Linker.GetSymbol(MethodCompiler.Method.FullName, SectionKind.Text);
            simLinker = MethodCompiler.Linker as SimLinker;
        }
Пример #2
0
 public void AddSourceInformation(LinkerSymbol baseSymbol, long offset, string information)
 {
     lock (mylock3)
     {
         source.Add(new Tuple<LinkerSymbol, long, string>(baseSymbol, offset, information));
     }
 }
Пример #3
0
 public void AddInstruction(LinkerSymbol baseSymbol, long offset, SimInstruction instruction)
 {
     lock (mylock2)
     {
         instructions.Add(new Tuple<LinkerSymbol, long, SimInstruction>(baseSymbol, offset, instruction));
     }
 }
 public void ClearSymbolInformation(LinkerSymbol linkerSymbol)
 {
     lock (symbolData)
     {
         symbolData.Remove(linkerSymbol);
     }
 }
Пример #5
0
 public void AddTargetSymbol(LinkerSymbol baseSymbol, int offset, string name)
 {
     lock (mylock1)
     {
         targetSymbols.Add(new Tuple<LinkerSymbol, int, string>(baseSymbol, offset, name));
     }
 }
Пример #6
0
        /// <summary>
        /// Allocates a symbol of the given name in the specified section.
        /// </summary>
        /// <param name="name">The name of the symbol.</param>
        /// <param name="section">The executable section to allocate From.</param>
        /// <param name="size">The number of bytes to allocate. If zero, indicates an unknown amount of memory is required.</param>
        /// <param name="alignment">The alignment. A value of zero indicates the use of a default alignment for the section.</param>
        /// <returns>
        /// A stream, which can be used to populate the section.
        /// </returns>
        public virtual Stream Allocate(string name, SectionKind section, int size, int alignment)
        {
            try
            {
                Stream baseStream = Allocate(section, size, alignment);

                // Create a linker symbol for the name
                LinkerSymbol symbol = new LinkerSymbol(name, section, baseStream.Position);


                // Save the symbol for later use
                if (!symbols.ContainsKey(symbol.Name))
                {
                    symbols.Add(symbol.Name, symbol);
                }

                // Wrap the stream to catch premature disposal
                Stream result = new LinkerStream(symbol, baseStream, size);

                return(result);
            }
            catch (ArgumentException argx)
            {
                throw new LinkerException(String.Format(@"Symbol {0} defined multiple times.", name), argx);
            }
        }
Пример #7
0
 public void Link(LinkType linkType, PatchType patchType, LinkerSymbol patchSymbol, int patchOffset, int relativeBase, LinkerSymbol referenceSymbol, int referenceOffset)
 {
     lock (mylock)
     {
         var linkRequest = new LinkRequest(linkType, patchType, patchSymbol, patchOffset, relativeBase, referenceSymbol, referenceOffset);
         LinkRequests.Add(linkRequest);
     }
 }
Пример #8
0
 internal void SetFirst(LinkerSymbol symbol)
 {
     lock (mylock)
     {
         Symbols.Remove(symbol);
         Symbols.Insert(0, symbol);
     }
 }
Пример #9
0
        internal LinkerSymbol GetSymbol(string name)
        {
            LinkerSymbol symbol = null;

            symbolLookup.TryGetValue(name, out symbol);

            return(symbol);
        }
Пример #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LinkerStream"/> class.
        /// </summary>
        /// <param name="symbol">The linker symbol created by this stream.</param>
        /// <param name="stream">The stream provided by the actual linker instance.</param>
        /// <param name="length">The length of the symbol. Set to zero, if length is unknown.</param>
        public LinkerStream(LinkerSymbol symbol, Stream stream, long length)
        {
            if (symbol == null)
                throw new ArgumentNullException(@"symbol");
            if (stream == null)
                throw new ArgumentNullException(@"stream");

            this.length = length;
            this.start = stream.Position;
            this.symbol = symbol;
            this.stream = stream;
        }
        protected override void Setup()
        {
            base.Setup();

            symbol = MethodCompiler.Linker.GetSymbol(MethodCompiler.Method.FullName, SectionKind.Text);

            stage = MethodCompiler.Compiler.PostCompilePipeline.FindFirst<SimLinkerFinalizationStage>() as SimLinkerFinalizationStage;

            Debug.Assert(stage != null);

            stage.ClearSymbolInformation(symbol);
        }
Пример #12
0
        /// <summary>
        /// Initializes a new instance of LinkRequest.
        /// </summary>
        /// <param name="linkType">Type of the link.</param>
        /// <param name="patchType">Type of the patch.</param>
        /// <param name="patchSymbol">The patch symbol.</param>
        /// <param name="patchOffset">The patch offset.</param>
        /// <param name="referenceSymbol">The reference symbol.</param>
        /// <param name="referenceOffset">The reference offset.</param>
        ///
        public LinkRequest(LinkType linkType, PatchType patchType, LinkerSymbol patchSymbol, int patchOffset, LinkerSymbol referenceSymbol, int referenceOffset)
        {
            Debug.Assert(patchSymbol != null);
            Debug.Assert(referenceSymbol != null);

            LinkType = linkType;
            PatchType = patchType;

            PatchSymbol = patchSymbol;
            PatchOffset = patchOffset;

            ReferenceSymbol = referenceSymbol;
            ReferenceOffset = referenceOffset;
        }
Пример #13
0
        /// <summary>
        /// Initializes a new instance of LinkRequest.
        /// </summary>
        /// <param name="linkType">Type of the link.</param>
        /// <param name="patchType">Type of the patch.</param>
        /// <param name="patchSymbol">The patch symbol.</param>
        /// <param name="patchOffset">The patch offset.</param>
        /// <param name="referenceSymbol">The reference symbol.</param>
        /// <param name="referenceOffset">The reference offset.</param>
        ///
        public LinkRequest(LinkType linkType, PatchType patchType, LinkerSymbol patchSymbol, int patchOffset, LinkerSymbol referenceSymbol, int referenceOffset)
        {
            Debug.Assert(patchSymbol != null);
            Debug.Assert(referenceSymbol != null);

            LinkType  = linkType;
            PatchType = patchType;

            PatchSymbol = patchSymbol;
            PatchOffset = patchOffset;

            ReferenceSymbol = referenceSymbol;
            ReferenceOffset = referenceOffset;
        }
Пример #14
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream"/> and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            if (stream != null && symbol != null)
            {
                // Fix the linker symbol size
                symbol.Length = Position;

                // Clear the stream & symbol
                stream = null;
                symbol = null;
            }

            base.Dispose(disposing);
        }
Пример #15
0
        /// <summary>
        /// Initializes a new instance of LinkRequest.
        /// </summary>
        /// <param name="linkType">Type of the link.</param>
        /// <param name="patchType">Type of the patch.</param>
        /// <param name="patchSymbol">The patch symbol.</param>
        /// <param name="patchOffset">The patch offset.</param>
        /// <param name="relativeBase">The relative base.</param>
        /// <param name="referenceSymbol">The reference symbol.</param>
        /// <param name="referenceOffset">The reference offset.</param>
        public LinkRequest(LinkType linkType, PatchType patchType, LinkerSymbol patchSymbol, int patchOffset, int relativeBase, LinkerSymbol referenceSymbol, int referenceOffset)
        {
            Debug.Assert(patchSymbol != null);
            Debug.Assert(referenceSymbol != null);
            Debug.Assert(patchType != null);

            this.LinkType  = linkType;
            this.PatchType = patchType;

            this.PatchSymbol = patchSymbol;
            this.PatchOffset = patchOffset;

            this.RelativeBase    = relativeBase;
            this.ReferenceSymbol = referenceSymbol;
            this.ReferenceOffset = referenceOffset;
        }
Пример #16
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LinkerStream"/> class.
        /// </summary>
        /// <param name="symbol">The linker symbol created by this stream.</param>
        /// <param name="stream">The stream provided by the actual linker instance.</param>
        /// <param name="length">The length of the symbol. Set to zero, if length is unknown.</param>
        public LinkerStream(LinkerSymbol symbol, Stream stream, long length)
        {
            if (symbol == null)
            {
                throw new ArgumentNullException(@"symbol");
            }
            if (stream == null)
            {
                throw new ArgumentNullException(@"stream");
            }

            this.length = length;
            this.start  = stream.Position;
            this.symbol = symbol;
            this.stream = stream;
        }
Пример #17
0
        /// <summary>
        /// Initializes a new instance of LinkRequest.
        /// </summary>
        /// <param name="linkType">Type of the link.</param>
        /// <param name="patchType">Type of the patch.</param>
        /// <param name="patchSymbol">The patch symbol.</param>
        /// <param name="patchOffset">The patch offset.</param>
        /// <param name="relativeBase">The relative base.</param>
        /// <param name="referenceSymbol">The reference symbol.</param>
        /// <param name="referenceOffset">The reference offset.</param>
        public LinkRequest(LinkType linkType, PatchType patchType, LinkerSymbol patchSymbol, int patchOffset, int relativeBase, LinkerSymbol referenceSymbol, int referenceOffset)
        {
            Debug.Assert(patchSymbol != null);
            Debug.Assert(referenceSymbol != null);
            Debug.Assert(patchType != null);

            this.LinkType = linkType;
            this.PatchType = patchType;

            this.PatchSymbol = patchSymbol;
            this.PatchOffset = patchOffset;

            this.RelativeBase = relativeBase;
            this.ReferenceSymbol = referenceSymbol;
            this.ReferenceOffset = referenceOffset;
        }
Пример #18
0
        protected LinkerSymbol CreateSymbol(string name, SectionKind kind, uint alignment)
        {
            lock (mylock)
            {
                var section = Sections[(int)kind];

                Debug.Assert(section != null);

                var symbol = section.GetSymbol(name);

                if (symbol == null)
                {
                    symbol = new LinkerSymbol(name, kind, alignment);

                    section.AddLinkerObject(symbol);
                }

                symbol.Alignment = alignment != 0 ? alignment : 0;

                return(symbol);
            }
        }
Пример #19
0
        private SymbolInfo GetSymbolInfo(LinkerSymbol linkerSymbol)
        {
            SymbolInfo symbolInfo = null;

            lock (symbolData)
            {
                if (!symbolData.TryGetValue(linkerSymbol, out symbolInfo))
                {
                    symbolInfo = new SymbolInfo();
                    symbolData.Add(linkerSymbol, symbolInfo);
                }
            }

            return symbolInfo;
        }
Пример #20
0
        public void AddSourceInformation(LinkerSymbol baseSymbol, long offset, string information)
        {
            var symbolInfo = GetSymbolInfo(baseSymbol);

            symbolInfo.source.Add(new Tuple<long, string>(offset, information));
        }
Пример #21
0
        public void AddTargetSymbol(LinkerSymbol baseSymbol, int offset, string name)
        {
            var symbolInfo = GetSymbolInfo(baseSymbol);

            symbolInfo.targetSymbols.Add(new Tuple<int, string>(offset, name));
        }
Пример #22
0
        public void Link(LinkType linkType, PatchType patchType, LinkerSymbol patchSymbol, int patchOffset, int relativeBase, string referenceSymbol, SectionKind patchRelativeBase, int referenceOffset)
        {
            var referenceObject = GetSymbol(referenceSymbol, patchRelativeBase);

            Link(linkType, patchType, patchSymbol, patchOffset, relativeBase, referenceObject, referenceOffset);
        }
Пример #23
0
        /// <summary>
        /// Allocates a symbol of the given name in the specified section.
        /// </summary>
        /// <param name="name">The name of the symbol.</param>
        /// <param name="section">The executable section to allocate from.</param>
        /// <param name="size">The number of bytes to allocate. If zero, indicates an unknown amount of memory is required.</param>
        /// <param name="alignment">The alignment. A value of zero indicates the use of a default alignment for the section.</param>
        /// <returns>
        /// A stream, which can be used to populate the section.
        /// </returns>
        Stream ILinker.Allocate(string name, SectionKind section, int size, int alignment)
        {
            ExtendedLinkerSection linkerSection = (ExtendedLinkerSection)GetSection(section);
            Stream stream = linkerSection.Allocate(size, alignment);

            // Create a linker symbol for the name
            LinkerSymbol symbol = new LinkerSymbol(name, section, stream.Position);

            //symbol.VirtualAddress = linkerSection.VirtualAddress + stream.Position;

            symbols.Add(symbol.Name, symbol);

            return new LinkerStream(symbol, stream, size);
        }
Пример #24
0
        public void Link(LinkType linkType, PatchType patchType, LinkerSymbol patchSymbol, int patchOffset, int relativeBase, string referenceSymbol, SectionKind patchRelativeBase, int referenceOffset)
        {
            var referenceObject = GetSymbol(referenceSymbol, patchRelativeBase);

            Link(linkType, patchType, patchSymbol, patchOffset, relativeBase, referenceObject, referenceOffset);
        }
Пример #25
0
 public SymbolEntry(LinkerSymbol linkerSymbol, bool display32)
 {
     this.LinkerSymbol = linkerSymbol;
     this.display32 = display32;
     this.SectionKind = linkerSymbol.SectionKind.ToString();
 }
Пример #26
0
        protected unsafe void AddVmCall(IDictionary<string, LinkerSymbol> virtualMachineCalls, Delegate handler, string method)
        {
            IntPtr allocate = Marshal.GetFunctionPointerForDelegate(handler);

            long virtualAddress = allocate.ToInt64();
            //Trace.WriteLine(String.Format("\t{0} at 0x{1:x08}", method, virtualAddress));

            LinkerSymbol symbol = new LinkerSymbol(method, SectionKind.Text, virtualAddress);
            symbol.VirtualAddress = new IntPtr(symbol.SectionAddress);

            virtualMachineCalls.Remove(method);
            virtualMachineCalls.Add(method, symbol);
        }
Пример #27
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream"/> and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            if (stream != null && symbol != null)
            {
                // Fix the linker symbol size
                symbol.Length = Position;

                // Clear the stream & symbol
                stream = null;
                symbol = null;
            }

            base.Dispose(disposing);
        }
Пример #28
0
        /// <summary>
        /// Allocates a symbol of the given name in the specified section.
        /// </summary>
        /// <param name="name">The name of the symbol.</param>
        /// <param name="section">The executable section to allocate From.</param>
        /// <param name="size">The number of bytes to allocate. If zero, indicates an unknown amount of memory is required.</param>
        /// <param name="alignment">The alignment. A value of zero indicates the use of a default alignment for the section.</param>
        /// <returns>
        /// A stream, which can be used to populate the section.
        /// </returns>
        public virtual Stream Allocate(string name, SectionKind section, int size, int alignment)
        {
            try
            {
                Stream baseStream = Allocate(section, size, alignment);

                // Create a linker symbol for the name
                LinkerSymbol symbol = new LinkerSymbol(name, section, baseStream.Position);

                // Save the symbol for later use
                symbols.Add(symbol.Name, symbol);

                // Wrap the stream to catch premature disposal
                Stream result = new LinkerStream(symbol, baseStream, size);

                return result;
            }
            catch (ArgumentException argx)
            {
                throw new LinkerException(String.Format(@"Symbol {0} defined multiple times.", name), argx);
            }
        }
Пример #29
0
        protected override void Run()
        {
            if (multibootMethod == null)
            {
                multibootHeader = Linker.CreateSymbol(MultibootHeaderSymbolName, SectionKind.Text, 1, 0x30);

                multibootMethod = Compiler.CreateLinkerMethod("MultibootInit");

                Linker.EntryPoint = Linker.GetSymbol(multibootMethod.FullName, SectionKind.Text);

                WriteMultibootHeader();

                Linker.CreateSymbol(Multiboot0695Stage.MultibootEAX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize);
                Linker.CreateSymbol(MultibootEBX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize);

                return;
            }

            var typeInitializerSchedulerStage = Compiler.PostCompilePipeline.FindFirst<TypeInitializerSchedulerStage>();

            var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX);
            var ebx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBX);
            var ebp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBP);
            var esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP);

            var MultibootEAX = Operand.CreateUnmanagedSymbolPointer(TypeSystem, Multiboot0695Stage.MultibootEAX);
            var multibootEBX = Operand.CreateUnmanagedSymbolPointer(TypeSystem, Multiboot0695Stage.MultibootEBX);

            var zero = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 0);
            var stackTop = Operand.CreateConstant(TypeSystem.BuiltIn.I4, STACK_ADDRESS);

            var basicBlocks = new BasicBlocks();
            var block = basicBlocks.CreateBlock();
            basicBlocks.AddHeadBlock(block);
            var ctx = new Context(block);

            // Setup the stack and place the sentinel on the stack to indicate the start of the stack
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, esp, zero, stackTop);
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, ebp, zero, zero);

            // Place the multiboot address into a static field
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, MultibootEAX, zero, eax);
            ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, multibootEBX, zero, ebx);

            // call type initializer
            var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializerSchedulerStage.TypeInitializerMethod);
            ctx.AppendInstruction(X86.Call, null, entryPoint);

            // should never get here
            ctx.AppendInstruction(X86.Ret);

            Compiler.CompileMethod(multibootMethod, basicBlocks, 0);
        }
Пример #30
0
 internal void AddLinkerObject(LinkerSymbol symbol)
 {
     Symbols.Add(symbol);
     symbolLookup.Add(symbol.Name, symbol);
 }
Пример #31
0
        private LinkerSymbol CreateTypeDefinition(MosaType type, LinkerSymbol assemblyTableSymbol)
        {
            // Emit type name
            var typeNameSymbol = EmitStringWithLength(type.FullName + Metadata.NameString, type.FullName);

            // Emit type table
            var typeTableSymbol = Linker.CreateSymbol(type.FullName + Metadata.TypeDefinition, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer1 = new EndianAwareBinaryWriter(typeTableSymbol.Stream, Architecture.Endianness);

            // 1. Pointer to Name
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, typeNameSymbol, 0);
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 2. Pointer to Custom Attributes
            if (type.CustomAttributes.Count > 0)
            {
                var customAttributeListSymbol = CreateCustomAttributesTable(type);
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, customAttributeListSymbol, 0);
            }
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 3. Type Code & Attributes
            writer1.Write(((uint)type.TypeCode << 24) + (uint)type.TypeAttributes, TypeLayout.NativePointerSize);

            // 4. Size
            writer1.Write((uint)TypeLayout.GetTypeSize(type), TypeLayout.NativePointerSize);

            // 5. Pointer to Assembly Definition
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, assemblyTableSymbol, 0);
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 6. Pointer to Parent Type
            if (type.BaseType != null)
            {
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, type.BaseType.FullName + Metadata.TypeDefinition, SectionKind.ROData, 0);
            }
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 7. Pointer to Declaring Type
            if (type.DeclaringType != null)
            {
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, type.DeclaringType.FullName + Metadata.TypeDefinition, SectionKind.ROData, 0);
            }
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 8. Pointer to Element Type
            if (type.ElementType != null)
            {
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, type.ElementType.FullName + Metadata.TypeDefinition, SectionKind.ROData, 0);
            }
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 9. Constructor that accepts no parameters, if any, for this type
            foreach (var method in type.Methods)
            {
                if (!method.Name.Equals(".ctor") || !(method.Signature.Parameters.Count == 0) || method.HasOpenGenericParams)
                    continue;

                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, method.FullName + Metadata.MethodDefinition, SectionKind.ROData, 0);
                break;
            }
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 10. Properties (if any)
            if (type.Properties.Count > 0)
            {
                var propertiesSymbol = CreatePropertyDefinitions(type);
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, propertiesSymbol, 0);
            }
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // If the type is not an interface continue, otherwise just pad until the end
            if (!type.IsInterface)
            {
                // 11. Fields (if any)
                if (type.Fields.Count > 0)
                {
                    var fieldsSymbol = CreateFieldDefinitions(type);
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, fieldsSymbol, 0);
                }
                writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

                var interfaces = GetInterfaces(type);

                // If the type doesn't use interfaces then skip 9 and 10
                if (interfaces.Count > 0)
                {
                    // 12. Pointer to Interface Slots
                    var interfaceSlotTableSymbol = CreateInterfaceSlotTable(type, interfaces);
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, interfaceSlotTableSymbol, 0);
                    writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

                    // 13. Pointer to Interface Bitmap
                    var interfaceBitmapSymbol = CreateInterfaceBitmap(type, interfaces);
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, interfaceBitmapSymbol, 0);
                    writer1.WriteZeroBytes(TypeLayout.NativePointerSize);
                }
                else
                {
                    // Fill 12 and 13 with zeros
                    writer1.WriteZeroBytes(TypeLayout.NativePointerSize * 2);
                }

                // For the next part we'll need to get the list of methods from the MosaTypeLayout
                var methodList = TypeLayout.GetMethodTable(type) ?? new List<MosaMethod>();

                // 14. Number of Methods
                writer1.Write(methodList.Count, TypeLayout.NativePointerSize);

                // 15. Pointer to Method Definitions
                foreach (var method in methodList)
                {
                    // Create definition and get the symbol
                    var methodDefinitionSymbol = CreateMethodDefinition(method);

                    // Link
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, methodDefinitionSymbol, 0);
                    writer1.WriteZeroBytes(TypeLayout.NativePointerSize);
                }
            }
            else
            {
                // Fill 11, 12, 13, 14 with zeros, 15 can be left out.
                writer1.WriteZeroBytes(TypeLayout.NativePointerSize * 4);
            }

            // Return typeTableSymbol for linker usage
            return typeTableSymbol;
        }
Пример #32
0
        protected override void Run()
        {
            if (multibootMethod == null)
            {
                multibootHeader = Linker.CreateSymbol(MultibootHeaderSymbolName, SectionKind.Text, 1, 0x30);

                multibootMethod = Compiler.CreateLinkerMethod("MultibootInit");

                Linker.EntryPoint = Linker.GetSymbol(multibootMethod.FullName, SectionKind.Text);

                WriteMultibootHeader();

                return;
            }

            var typeInitializerSchedulerStage = Compiler.Pipeline.FindFirst<TypeInitializerSchedulerStage>();

            var ecx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ECX);
            var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX);
            var ebx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBX);
            var ebp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBP);

            var basicBlocks = new BasicBlocks();
            var instructionSet = new InstructionSet(25);

            var ctx = instructionSet.CreateNewBlock(basicBlocks);
            basicBlocks.AddHeaderBlock(ctx.BasicBlock);

            // set sentinal on the stack to indicate the start of the stack
            var zero = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 0);
            ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ebp, 0), zero);

            // store multiboot registers eax and ebx at 0x200000 and 0x200004 respectively
            ctx.AppendInstruction(X86.Mov, ecx, Operand.CreateConstantSignedInt(TypeSystem, 0x200000));
            ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), eax);
            ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 4), ebx);

            // call type initializer
            var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializerSchedulerStage.TypeInitializerMethod);
            ctx.AppendInstruction(X86.Call, null, entryPoint);

            // should never get here
            ctx.AppendInstruction(X86.Ret);

            Compiler.CompileMethod(multibootMethod, basicBlocks, instructionSet);
        }
Пример #33
0
 internal void AddLinkerObject(LinkerSymbol symbol)
 {
     Symbols.Add(symbol);
     symbolLookup.Add(symbol.Name, symbol);
 }
Пример #34
0
        protected override void Run()
        {
            if (multibootMethod == null)
            {
                multibootHeader = Linker.CreateSymbol(MultibootHeaderSymbolName, SectionKind.Text, 1, 0x30);

                multibootMethod = Compiler.CreateLinkerMethod("MultibootInit");

                Linker.EntryPoint = Linker.GetSymbol(multibootMethod.FullName, SectionKind.Text);

                WriteMultibootHeader();

                Linker.CreateSymbol(MultibootEAX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize);
                Linker.CreateSymbol(MultibootEBX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize);

                return;
            }

            var typeInitializerSchedulerStage = Compiler.PostCompilePipeline.FindFirst<TypeInitializerSchedulerStage>();

            var ecx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ECX);
            var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX);
            var ebx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBX);
            var ebp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBP);
            var multibootEax = Operand.CreateUnmanagedSymbolPointer(TypeSystem, MultibootEAX);
            var multibootEbx = Operand.CreateUnmanagedSymbolPointer(TypeSystem, MultibootEBX);

            var basicBlocks = new BasicBlocks();
            var block = basicBlocks.CreateBlock();
            basicBlocks.AddHeaderBlock(block);
            var ctx = new Context(block);

            // set sentinel on the stack to indicate the start of the stack
            var zero = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 0);
            ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ebp, 0), zero);

            ctx.AppendInstruction(X86.Mov, ecx, multibootEax);
            ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), eax);
            ctx.AppendInstruction(X86.Mov, ecx, multibootEbx);
            ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), ebx);

            // call type initializer
            var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializerSchedulerStage.TypeInitializerMethod);
            ctx.AppendInstruction(X86.Call, null, entryPoint);

            // should never get here
            ctx.AppendInstruction(X86.Ret);

            Compiler.CompileMethod(multibootMethod, basicBlocks, 0);
        }
Пример #35
0
 public void Link(LinkType linkType, PatchType patchType, LinkerSymbol patchSymbol, int patchOffset, int relativeBase, LinkerSymbol referenceSymbol, int referenceOffset)
 {
     lock (mylock)
     {
         var linkRequest = new LinkRequest(linkType, patchType, patchSymbol, patchOffset, relativeBase, referenceSymbol, referenceOffset);
         //LinkRequests.Add(linkRequest);
         patchSymbol.AddPatch(linkRequest);
     }
 }
Пример #36
0
        public void Link(LinkType linkType, PatchType patchType, string patchSymbolName, SectionKind patchKind, int patchOffset, int relativeBase, LinkerSymbol referenceSymbol, int referenceOffset)
        {
            var patchObject = GetSymbol(patchSymbolName, patchKind);

            Link(linkType, patchType, patchObject, patchOffset, relativeBase, referenceSymbol, referenceOffset);
        }
Пример #37
0
        protected LinkerSymbol CreateSymbol(string name, SectionKind kind, uint alignment)
        {
            lock (mylock)
            {
                var section = Sections[(int)kind];

                Debug.Assert(section != null);

                var symbol = section.GetSymbol(name);

                if (symbol == null)
                {
                    symbol = new LinkerSymbol(name, kind, alignment);

                    section.AddLinkerObject(symbol);
                }

                symbol.Alignment = alignment != 0 ? alignment : 0;

                return symbol;
            }
        }
Пример #38
0
        public void Link(LinkType linkType, PatchType patchType, string patchSymbolName, SectionKind patchKind, int patchOffset, int relativeBase, LinkerSymbol referenceSymbol, int referenceOffset)
        {
            var patchObject = GetSymbol(patchSymbolName, patchKind);

            Link(linkType, patchType, patchObject, patchOffset, relativeBase, referenceSymbol, referenceOffset);
        }
Пример #39
0
        protected override void RunPreCompile()
        {
            multibootHeader = Linker.CreateSymbol(MultibootHeaderSymbolName, SectionKind.Text, 1, 0x30);

            Linker.CreateSymbol(MultibootEAX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize);
            Linker.CreateSymbol(MultibootEBX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize);

            multibootMethod = Compiler.CreateLinkerMethod("MultibootInit");

            var multibootSymbol = Linker.GetSymbol(multibootMethod.FullName, SectionKind.Text);

            Linker.EntryPoint = multibootSymbol;
        }
Пример #40
0
        public void AddInstruction(LinkerSymbol baseSymbol, long offset, SimInstruction instruction)
        {
            var symbolInfo = GetSymbolInfo(baseSymbol);

            symbolInfo.instructions.Add(new Tuple<long, SimInstruction>(offset, instruction));
        }
Пример #41
0
        public void Link(LinkType linkType, PatchType patchType, LinkerSymbol patchSymbol, int patchOffset, SectionKind referenceKind, string referenceSymbolName, int referenceOffset)
        {
            var referenceObject = GetSymbol(referenceSymbolName, referenceKind);

            Link(linkType, patchType, patchSymbol, patchOffset, referenceObject, referenceOffset);
        }
Пример #42
0
 internal void SetFirst(LinkerSymbol symbol)
 {
     lock (mylock)
     {
         Symbols.Remove(symbol);
         Symbols.Insert(0, symbol);
     }
 }
Пример #43
0
        private void WriteArgument(EndianAwareBinaryWriter writer, LinkerSymbol symbol, MosaType type, object value)
        {
            if (type.IsEnum)
                type = type.GetEnumUnderlyingType();
            switch (type.TypeCode)
            {
                // 1 byte
                case MosaTypeCode.Boolean:
                    writer.Write((bool)value);
                    break;

                case MosaTypeCode.U1:
                    writer.Write((byte)value);
                    break;

                case MosaTypeCode.I1:
                    writer.Write((sbyte)value);
                    break;

                // 2 bytes
                case MosaTypeCode.Char:
                    writer.Write((char)value);
                    break;

                case MosaTypeCode.U2:
                    writer.Write((ushort)value);
                    break;

                case MosaTypeCode.I2:
                    writer.Write((short)value);
                    break;

                // 4 bytes
                case MosaTypeCode.U4:
                    writer.Write((uint)value);
                    break;

                case MosaTypeCode.I4:
                    writer.Write((int)value);
                    break;

                case MosaTypeCode.R4:
                    writer.Write((float)value);
                    break;

                // 8 bytes
                case MosaTypeCode.U8:
                    writer.Write((ulong)value);
                    break;

                case MosaTypeCode.I8:
                    writer.Write((long)value);
                    break;

                case MosaTypeCode.R8:
                    writer.Write((double)value);
                    break;

                // SZArray
                case MosaTypeCode.SZArray:
                    Debug.Assert(value is MosaCustomAttribute.Argument[]);
                    var arr = (MosaCustomAttribute.Argument[])value;
                    writer.Write(arr.Length, TypeLayout.NativePointerSize);
                    foreach (var elem in arr)
                        WriteArgument(writer, symbol, elem.Type, elem.Value);
                    break;

                // String
                case MosaTypeCode.String:

                    // Since strings are immutable, make it an object that we can just use
                    var str = (string)value;
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, symbol, (int)writer.Position, 0, "System.String" + Metadata.TypeDefinition, SectionKind.ROData, 0);
                    writer.WriteZeroBytes(TypeLayout.NativePointerSize * 2);
                    writer.Write(str.Length, TypeLayout.NativePointerSize);
                    writer.Write(System.Text.Encoding.Unicode.GetBytes(str));
                    break;

                default:
                    if (type.FullName == "System.Type")
                    {
                        var valueType = (MosaType)value;
                        Linker.Link(LinkType.AbsoluteAddress, NativePatchType, symbol, (int)writer.Position, 0, valueType.FullName + Metadata.TypeDefinition, SectionKind.ROData, 0);
                        writer.WriteZeroBytes(TypeLayout.NativePointerSize);
                    }
                    else
                        throw new NotSupportedException();
                    break;
            }
        }
Пример #44
0
        public void SetFirst(LinkerSymbol symbol)
        {
            var section = LinkerSections[(int)symbol.SectionKind];

            section.SetFirst(symbol);
        }