コード例 #1
0
 public void AddSourceInformation(LinkerSymbol baseSymbol, long offset, string information)
 {
     lock (mylock3)
     {
         source.Add(new Tuple <LinkerSymbol, long, string>(baseSymbol, offset, information));
     }
 }
コード例 #2
0
        protected override unsafe void AddVmCalls(IDictionary <string, LinkerSymbol> virtualMachineCalls)
        {
            Trace.WriteLine(@"TestAssemblyLinker adding VM calls:");

            IntPtr allocate = Marshal.GetFunctionPointerForDelegate(allocateArrayHandler);

            const string allocateArrayMethod = @"Mosa.Internal.Runtime.AllocateArray(Ptr methodTable,U4 elementSize,U4 elements)";
            long         virtualAddress      = allocate.ToInt64();

            Trace.WriteLine(String.Format("\t{0} at 0x{1:x08}", allocateArrayMethod, virtualAddress));

            LinkerSymbol symbol = new LinkerSymbol(allocateArrayMethod, SectionKind.Text, virtualAddress);

            symbol.VirtualAddress = new IntPtr(symbol.SectionAddress);

            virtualMachineCalls.Remove(allocateArrayMethod);
            virtualMachineCalls.Add(allocateArrayMethod, symbol);

            IntPtr allocateObject = Marshal.GetFunctionPointerForDelegate(allocateObjectHandler);

            const string allocateObjectMethod = @"Mosa.Internal.Runtime.AllocateObject(Ptr methodTable,U4 classSize)";

            virtualAddress = allocateObject.ToInt64();
            Trace.WriteLine(String.Format("\t{0} at 0x{1:x08}", allocateObjectMethod, virtualAddress));

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

            virtualMachineCalls.Remove(allocateObjectMethod);
            virtualMachineCalls.Add(allocateObjectMethod, symbol);
        }
コード例 #3
0
        protected override void Setup()
        {
            base.Setup();

            symbol    = MethodCompiler.Linker.GetSymbol(MethodCompiler.Method.FullName, SectionKind.Text);
            simLinker = MethodCompiler.Linker as SimLinker;
        }
コード例 #4
0
 public void AddTargetSymbol(LinkerSymbol baseSymbol, int offset, string name)
 {
     lock (mylock1)
     {
         targetSymbols.Add(new Tuple <LinkerSymbol, int, string>(baseSymbol, offset, name));
     }
 }
コード例 #5
0
 public void AddInstruction(LinkerSymbol baseSymbol, long offset, SimInstruction instruction)
 {
     lock (mylock2)
     {
         instructions.Add(new Tuple <LinkerSymbol, long, SimInstruction>(baseSymbol, offset, instruction));
     }
 }
コード例 #6
0
 public void ClearSymbolInformation(LinkerSymbol linkerSymbol)
 {
     lock (symbolData)
     {
         symbolData.Remove(linkerSymbol);
     }
 }
コード例 #7
0
ファイル: ElfLinker.cs プロジェクト: RFN174/MOSA-Project
        private string GetFinalSymboName(LinkerSymbol symbol)
        {
            if (symbol.ExternalSymbolName != null)
            {
                return(symbol.ExternalSymbolName);
            }

            if (symbol.SectionKind != SectionKind.Text)
            {
                return(symbol.Name);
            }

            if (!EmitShortSymbolName)
            {
                return(symbol.Name);
            }

            int pos = symbol.Name.LastIndexOf(") ");

            if (pos < 0)
            {
                return(symbol.Name);
            }

            var shortname = symbol.Name.Substring(0, pos + 1);

            return(shortname);
        }
コード例 #8
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 esp          = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP);
            var multibootEax = Operand.CreateUnmanagedSymbolPointer(TypeSystem, MultibootEAX);
            var multibootEbx = Operand.CreateUnmanagedSymbolPointer(TypeSystem, 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.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, esp, 0), stackTop);
            ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ebp, 0), zero);

            // Place the multiboot address into a static field
            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);
        }
コード例 #9
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");

            Linker.EntryPoint = Linker.GetSymbol(multibootMethod.FullName, SectionKind.Text);
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        protected override void RunPreCompile()
        {
            multibootHeader = Linker.CreateSymbol(MultibootHeaderSymbolName, SectionKind.Text, 1, 0x30);

            multibootMethod = Compiler.CreateLinkerMethod("MultibootInit");

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

            var startUpType   = TypeSystem.GetTypeByName("Mosa.Runtime", "StartUp");
            var startUpMethod = startUpType.FindMethodByName("Stage1");

            Compiler.PlugSystem.CreatePlug(multibootMethod, startUpMethod);
        }
コード例 #12
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);
        }
コード例 #13
0
        /// <summary>
        /// Writes the multiboot header.
        /// </summary>
        /// <param name="entryPoint">The virtualAddress of the multiboot compliant entry point.</param>
        protected void WriteMultibootHeader(LinkerSymbol entryPoint)
        {
            // According to the multiboot specification this header must be within the first 8K of the kernel binary.
            Linker.SetFirst(multibootHeader);

            var writer = new BinaryWriter(multibootHeader.Stream, Encoding.ASCII);

            // flags - multiboot flags
            uint flags =
                HEADER_MB_FLAG_MEMORY_INFO_REQUIRED
                | HEADER_MB_FLAG_MODULES_PAGE_ALIGNED
                | (HasVideo ? HEADER_MB_FLAG_VIDEO_MODES_REQUIRED : 0);

            // magic
            writer.Write(HEADER_MB_MAGIC);

            // flags
            writer.Write(flags);

            // checksum
            writer.Write(unchecked (0U - HEADER_MB_MAGIC - flags));

            // header_addr - load address of the multiboot header
            Linker.Link(LinkType.AbsoluteAddress, PatchType.I32, multibootHeader, (int)writer.BaseStream.Position, multibootHeader, 0);
            writer.Write(0);

            // load_addr - address of the binary in memory
            writer.Write(0);

            // load_end_addr - address past the last byte to load from the image
            writer.Write(0);

            // bss_end_addr - address of the last byte to be zeroed out
            writer.Write(0);

            // entry_addr - address of the entry point to invoke
            Linker.Link(LinkType.AbsoluteAddress, PatchType.I32, multibootHeader, (int)writer.BaseStream.Position, entryPoint, 0);
            writer.Write(0);

            // Write video settings if video has been specified, otherwise pad
            writer.Write(0);
            writer.Write(HasVideo ? Width : 0);
            writer.Write(HasVideo ? Height : 0);
            writer.Write(HasVideo ? Depth : 0);
        }
コード例 #14
0
ファイル: TestAssemblyLinker.cs プロジェクト: djlw78/Mosa
        /// <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 override Stream Allocate(string name, SectionKind section, int size, int alignment)
        {
            LinkerStream stream = (LinkerStream)base.Allocate(name, section, size, alignment);

            try
            {
                VirtualMemoryStream vms    = (VirtualMemoryStream)stream.BaseStream;
                LinkerSymbol        symbol = this.GetSymbol(name);
                symbol.VirtualAddress = new IntPtr(vms.Base.ToInt64() + vms.Position);
            }
            catch
            {
                stream.Dispose();
                throw;
            }

            return(stream);
        }
コード例 #15
0
        protected override void RunPreCompile()
        {
            multibootHeader = Linker.DefineSymbol(MultibootHeaderSymbolName, SectionKind.Text, 1, 0x30);

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

            multibootMethod = Compiler.CreateLinkerMethod("MultibootInit");

            Linker.EntryPoint = Linker.GetSymbol(multibootMethod.FullName);

            MethodScanner.MethodInvoked(multibootMethod, multibootMethod);

            var startUpType      = TypeSystem.GetTypeByName("Mosa.Runtime", "StartUp");
            var initializeMethod = startUpType.FindMethodByName("Initialize");

            MethodScanner.MethodInvoked(initializeMethod, multibootMethod);
        }
コード例 #16
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());
            }
        }
コード例 #17
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 override Stream Allocate(string name, SectionKind section, int size, int alignment)
        {
            LinkerStream stream = (LinkerStream)base.Allocate(name, section, size, alignment);

            try
            {
                VirtualMemoryStream vms    = (VirtualMemoryStream)stream.BaseStream;
                LinkerSymbol        symbol = GetSymbol(name);
                symbol.VirtualAddress = new IntPtr(vms.Base.ToInt64() + vms.Position);
                Trace.WriteLine("Symbol " + name + " located at 0x" + symbol.VirtualAddress.ToInt32().ToString("x08"));
            }
            catch
            {
                stream.Dispose();
                throw;
            }

            return(stream);
        }
コード例 #18
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);
        }
コード例 #19
0
ファイル: TestAssemblyLinker.cs プロジェクト: djlw78/Mosa
        /// <summary>
        /// Allocates memory in the specified section.
        /// </summary>
        /// <param name="member">The metadata member to allocate space for.</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 override Stream Allocate(RuntimeMember member, SectionKind section, int size, int alignment)
        {
            string name = CreateSymbolName(member);

            LinkerStream stream = (LinkerStream)base.Allocate(name, section, size, alignment);

            try
            {
                VirtualMemoryStream vms = (VirtualMemoryStream)stream.BaseStream;

                // Save the member address
                member.Address = new IntPtr(vms.Base.ToInt64() + vms.Position);

                LinkerSymbol symbol = this.GetSymbol(name);
                symbol.VirtualAddress = member.Address;
            }
            catch
            {
                stream.Dispose();
                throw;
            }

            return(stream);
        }
コード例 #20
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, writer.Position, Metadata.TypeDefinition + "System.String", 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, writer.Position, Metadata.TypeDefinition + valueType.FullName, 0);
                    writer.WriteZeroBytes(TypeLayout.NativePointerSize);
                }
                else
                {
                    throw new NotSupportedException();
                }

                break;
            }
        }
コード例 #21
0
        /// <summary>
        /// Writes the multiboot header.
        /// </summary>
        /// <param name="entryPoint">The virtualAddress of the multiboot compliant entry point.</param>
        private void WriteMultibootHeader()
        {
            // 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.

            LinkerSymbol entryPoint = Linker.EntryPoint;

            //entryPoint = Linker.GetSymbol(MultibootHeaderSymbolName, SectionKind.Text);

            var stream = multibootHeader.Stream;

            var writer = new BinaryWriter(stream, Encoding.ASCII);

            // flags - multiboot flags
            uint flags = HEADER_MB_FLAG_MEMORY_INFO_REQUIRED | HEADER_MB_FLAG_MODULES_PAGE_ALIGNED;

            if (HasVideo)
            {
                flags |= HEADER_MB_FLAG_VIDEO_MODES_REQUIRED;
            }

            uint load_addr = 0;

            // magic
            writer.Write(HEADER_MB_MAGIC);

            // flags
            writer.Write(flags);

            // checksum
            writer.Write(unchecked (0U - HEADER_MB_MAGIC - flags));

            // header_addr - load address of the multiboot header
            Linker.Link(LinkType.AbsoluteAddress, PatchType.I4, multibootHeader, (int)stream.Position, 0, multibootHeader, 0);
            writer.Write(0);

            // load_addr - address of the binary in memory
            writer.Write(load_addr);

            // load_end_addr - address past the last byte to load from the image
            writer.Write(0);

            // bss_end_addr - address of the last byte to be zeroed out
            writer.Write(0);

            // entry_addr - address of the entry point to invoke
            Linker.Link(LinkType.AbsoluteAddress, PatchType.I4, multibootHeader, (int)stream.Position, 0, entryPoint, 0);
            writer.Write(0);

            // Write video settings if video has been specified, otherwise pad
            if (HasVideo)
            {
                writer.Write(0);                 // Mode, 0 = linear
                writer.Write(Width);             // Width, 1280px
                writer.Write(Height);            // Height, 720px
                writer.Write(Depth);             // Depth, 24px
            }
            else
            {
                writer.Write(0);
                writer.Write(0);
                writer.Write(0);
                writer.Write(0);
            }
        }
コード例 #22
0
        private LinkerSymbol CreateTypeDefinition(MosaType type, LinkerSymbol assemblyTableSymbol)
        {
            // Emit type table
            var typeNameSymbol  = EmitStringWithLength(Metadata.NameString + type.FullName, type.FullName);
            var typeTableSymbol = Linker.DefineSymbol(Metadata.TypeDefinition + type.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer          = new EndianAwareBinaryWriter(typeTableSymbol.Stream, Architecture.Endianness);

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

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

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

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

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

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

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

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

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

                var targetMethodData = GetTargetMethodData(method);

                if (targetMethodData.HasCode)
                {
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.Position, Metadata.MethodDefinition + targetMethodData.Method.FullName, 0);
                }

                break;
            }
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 10. Properties (if any)
            if (type.Properties.Count > 0)
            {
                var propertiesSymbol = CreatePropertyDefinitions(type);
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.Position, propertiesSymbol, 0);
            }
            writer.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, writer.Position, fieldsSymbol, 0);
                }
                writer.WriteZeroBytes(TypeLayout.NativePointerSize);

                var interfaces = type.HasOpenGenericParams ? null : GetInterfaces(type);

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

                    // 13. Pointer to Interface Bitmap
                    var interfaceBitmapSymbol = CreateInterfaceBitmap(type, interfaces);
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.Position, interfaceBitmapSymbol, 0);
                    writer.WriteZeroBytes(TypeLayout.NativePointerSize);
                }
                else
                {
                    // Fill 12 and 13 with zeros
                    writer.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
                writer.Write(methodList.Count, TypeLayout.NativePointerSize);

                // 15. Pointer to Methods
                foreach (var method in methodList)
                {
                    var targetMethodData = GetTargetMethodData(method);

                    if (targetMethodData.HasCode)
                    {
                        Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, writer.Position, targetMethodData.Method.FullName, 0);
                    }
                    writer.WriteZeroBytes(TypeLayout.NativePointerSize);
                }

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

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

            return(typeTableSymbol);
        }
コード例 #23
0
ファイル: MetadataStage.cs プロジェクト: jwoff78/MOSA-Project
        private LinkerSymbol CreateTypeDefinition(MosaType type, LinkerSymbol assemblyTableSymbol)
        {
            // Emit type table
            var typeNameSymbol       = EmitStringWithLength(Metadata.NameString + type.FullName, type.FullName);
            var typeDefinitionSymbol = Linker.DefineSymbol(Metadata.TypeDefinition + type.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer = new BinaryWriter(typeDefinitionSymbol.Stream);

            // 1. Pointer to Name
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeDefinitionSymbol, writer.GetPosition(), typeNameSymbol, (int)Compiler.ObjectHeaderSize);
            writer.WriteZeroBytes(NativePointerSize);

            // 2. Pointer to Custom Attributes
            if (type.CustomAttributes.Count > 0)
            {
                var customAttributeListSymbol = CreateCustomAttributesTable(type);
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeDefinitionSymbol, writer.GetPosition(), customAttributeListSymbol, 0);
            }
            writer.WriteZeroBytes(NativePointerSize);

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

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

            // 5. Pointer to Assembly Definition
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeDefinitionSymbol, writer.GetPosition(), assemblyTableSymbol, 0);
            writer.WriteZeroBytes(NativePointerSize);

            // 6. Pointer to Base Type
            if (type.BaseType != null)
            {
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeDefinitionSymbol, writer.GetPosition(), Metadata.TypeDefinition + type.BaseType.FullName, 0);
            }
            writer.WriteZeroBytes(NativePointerSize);

            // 7. Pointer to Declaring Type
            if (type.DeclaringType != null)
            {
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeDefinitionSymbol, writer.GetPosition(), Metadata.TypeDefinition + type.DeclaringType.FullName, 0);
            }
            writer.WriteZeroBytes(NativePointerSize);

            // 8. Pointer to Element Type
            if (type.ElementType != null)
            {
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeDefinitionSymbol, writer.GetPosition(), Metadata.TypeDefinition + type.ElementType.FullName, 0);
            }
            writer.WriteZeroBytes(NativePointerSize);

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

                var targetMethodData = GetTargetMethodData(method);

                if (targetMethodData.HasCode)
                {
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeDefinitionSymbol, writer.GetPosition(), Metadata.MethodDefinition + targetMethodData.Method.FullName, 0);
                }

                break;
            }
            writer.WriteZeroBytes(NativePointerSize);

            // 10. Properties (if any)
            if (type.Properties.Count > 0)
            {
                var propertiesSymbol = CreatePropertyDefinitions(type);
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeDefinitionSymbol, writer.GetPosition(), propertiesSymbol, 0);
            }
            writer.WriteZeroBytes(NativePointerSize);

            LinkerSymbol interfaceSlotTableSymbol = null;

            // 11. Fields Definitions
            if (!type.IsInterface && type.Fields.Count > 0)
            {
                var fieldsSymbol = CreateFieldDefinitions(type);
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeDefinitionSymbol, writer.GetPosition(), fieldsSymbol, 0);
            }
            writer.WriteZeroBytes(NativePointerSize);

            var interfaces = type.IsInterface || type.HasOpenGenericParams ? null : GetInterfaces(type);

            if (interfaces != null && interfaces.Count == 0)
            {
                interfaces = null;
            }

            // 12. Pointer to Interface Slots
            if (interfaces != null)
            {
                interfaceSlotTableSymbol = CreateInterfaceSlotTable(type, interfaces);
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeDefinitionSymbol, writer.GetPosition(), interfaceSlotTableSymbol, 0);
            }
            writer.WriteZeroBytes(NativePointerSize);

            // 13. Pointer to Interface Bitmap
            if (interfaces != null)
            {
                var interfaceBitmapSymbol = CreateInterfaceBitmap(type, interfaces);
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeDefinitionSymbol, writer.GetPosition(), interfaceBitmapSymbol, 0);
            }
            writer.WriteZeroBytes(NativePointerSize);

            var methodList = TypeLayout.GetMethodTable(type);

            // 14. Number of Methods
            writer.Write(methodList == null ? 0 : methodList.Count, NativePointerSize);

            // 15. Method Table
            if (methodList != null)
            {
                foreach (var method in methodList)
                {
                    var targetMethodData = GetTargetMethodData(method);

                    if (targetMethodData.HasCode)
                    {
                        Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeDefinitionSymbol, writer.GetPosition(), targetMethodData.Method.FullName, 0);
                    }
                    writer.WriteZeroBytes(NativePointerSize);
                }
            }

            // 16. Method Definition Table
            if (!type.IsInterface && methodList != null)
            {
                foreach (var method in methodList)
                {
                    // Create definition and get the symbol
                    var methodDefinitionSymbol = CreateMethodDefinition(method);

                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeDefinitionSymbol, writer.GetPosition(), methodDefinitionSymbol, 0);
                    writer.WriteZeroBytes(NativePointerSize);
                }
            }

            return(typeDefinitionSymbol);
        }
コード例 #24
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);
            }
        }
コード例 #25
0
        protected unsafe override void AddVmCalls(IDictionary<string, LinkerSymbol> virtualMachineCalls)
        {
            Trace.WriteLine(@"TestAssemblyLinker adding VM calls:");

            IntPtr allocate = Marshal.GetFunctionPointerForDelegate(allocateArrayHandler);

            const string allocateArrayMethod = @"Mosa.Internal.Runtime.AllocateArray(Ptr methodTable,U4 elementSize,U4 elements)";
            long virtualAddress = allocate.ToInt64();
            Trace.WriteLine(String.Format("\t{0} at 0x{1:x08}", allocateArrayMethod, virtualAddress));

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

            virtualMachineCalls.Remove(allocateArrayMethod);
            virtualMachineCalls.Add(allocateArrayMethod, symbol);

            IntPtr allocateObject = Marshal.GetFunctionPointerForDelegate(allocateObjectHandler);

            const string allocateObjectMethod = @"Mosa.Internal.Runtime.AllocateObject(Ptr methodTable,U4 classSize)";
            virtualAddress = allocateObject.ToInt64();
            Trace.WriteLine(String.Format("\t{0} at 0x{1:x08}", allocateObjectMethod, virtualAddress));

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

            virtualMachineCalls.Remove(allocateObjectMethod);
            virtualMachineCalls.Add(allocateObjectMethod, symbol);
        }
コード例 #26
0
ファイル: SymbolView.cs プロジェクト: mwoodruff1/MOSA-Project
 public SymbolEntry(LinkerSymbol linkerSymbol, bool display32)
 {
     LinkerSymbol   = linkerSymbol;
     this.display32 = display32;
     SectionKind    = linkerSymbol.SectionKind.ToString();
 }
コード例 #27
0
        public void AddTargetSymbol(LinkerSymbol baseSymbol, int offset, string name)
        {
            var symbolInfo = GetSymbolInfo(baseSymbol);

            symbolInfo.targetSymbols.Add(new Tuple <int, string>(offset, name));
        }
コード例 #28
0
        public void AddInstruction(LinkerSymbol baseSymbol, long offset, SimInstruction instruction)
        {
            var symbolInfo = GetSymbolInfo(baseSymbol);

            symbolInfo.instructions.Add(new Tuple <long, SimInstruction>(offset, instruction));
        }
コード例 #29
0
        public void AddSourceInformation(LinkerSymbol baseSymbol, long offset, string information)
        {
            var symbolInfo = GetSymbolInfo(baseSymbol);

            symbolInfo.source.Add(new Tuple <long, string>(offset, information));
        }