Example #1
0
        private void EmitFields()
        {
            writer.WriteLine("[Fields]");
            writer.WriteLine("TypeID\tIndex\tFullName\tName\tFieldTypeID\tAddress\tAttributes\tOffset\tDataLength\tDataAddress");

            foreach (var type in TypeSystem.AllTypes)
            {
                if (type.IsModule)
                {
                    continue;
                }

                int index = 0;

                foreach (var field in type.Fields)
                {
                    var symbolName = Metadata.FieldDefinition + field.FullName;

                    if (!Linker.IsSymbolDefined(symbolName))
                    {
                        continue;
                    }

                    var symbol = Linker.GetSymbol(symbolName);

                    //var datasection = (field.Data != null) ? SectionKind.ROData : SectionKind.BSS; // not used yet

                    writer.WriteLine(
                        "{0}\t{1}\t{2}\t{3}\t{4}\t{5:x8}\t{6}\t{7}\t{8}\t{9:x8}",
                        type.ID,
                        index++,
                        field.FullName,
                        field.Name,
                        field.FieldType.ID,
                        symbol?.VirtualAddress ?? 0,
                        (int)field.FieldAttributes,
                        field.IsStatic && !field.IsLiteral ? 0 : TypeLayout.GetFieldOffset(field), // todo: missing first offset
                        field.Data?.Length ?? 0,
                        0                                                                          // todo: DataAddress
                        );
                }
            }
        }
Example #2
0
        private LinkerSymbol CreateFieldDefinitions(MosaType type)
        {
            // Emit fields table
            var fieldsTableSymbol = Linker.DefineSymbol(Metadata.FieldsTable + type.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer1           = new EndianAwareBinaryWriter(fieldsTableSymbol.Stream, Architecture.Endianness);

            // 1. Number of Fields
            writer1.Write((uint)type.Fields.Count, TypeLayout.NativePointerSize);

            // 2. Pointers to Field Definitions
            foreach (var field in type.Fields)
            {
                // Emit field name
                var fieldNameSymbol = EmitStringWithLength(Metadata.NameString + field.FullName, field.Name);

                // Emit field definition
                var fieldDefSymbol = Linker.DefineSymbol(Metadata.FieldDefinition + field.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
                var writer2        = new EndianAwareBinaryWriter(fieldDefSymbol.Stream, Architecture.Endianness);

                // 1. Name
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, writer2.Position, fieldNameSymbol, 0);
                writer2.WriteZeroBytes(TypeLayout.NativePointerSize);

                // 2. Pointer to Custom Attributes
                if (field.CustomAttributes.Count > 0)
                {
                    var customAttributesTableSymbol = CreateCustomAttributesTable(field);
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, writer2.Position, customAttributesTableSymbol, 0);
                }
                writer2.WriteZeroBytes(TypeLayout.NativePointerSize);

                // 3. Attributes
                writer2.Write((uint)field.FieldAttributes, TypeLayout.NativePointerSize);

                // 4. Pointer to Field Type
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, writer2.Position, Metadata.TypeDefinition + field.FieldType.FullName, 0);
                writer2.WriteZeroBytes(TypeLayout.NativePointerSize);

                // 5 & 6. Offset / Address + Size
                if (field.IsStatic && !field.IsLiteral && !type.HasOpenGenericParams)
                {
                    if (Compiler.MethodScanner.IsFieldAccessed(field))
                    {
                        Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, writer2.Position, field.FullName, 0);
                    }
                    writer2.WriteZeroBytes(TypeLayout.NativePointerSize);
                    writer2.Write(field.Data?.Length ?? 0, TypeLayout.NativePointerSize);
                }
                else
                {
                    writer2.WriteZeroBytes(TypeLayout.NativePointerSize);
                    writer2.Write(TypeLayout.GetFieldOffset(field), TypeLayout.NativePointerSize);
                }

                // Add pointer to field list
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldsTableSymbol, writer1.Position, fieldDefSymbol, 0);
                writer1.WriteZeroBytes(TypeLayout.NativePointerSize);
            }

            return(fieldsTableSymbol);
        }
Example #3
0
        private LinkerSymbol CreateFieldDefinitions(MosaType type)
        {
            // Emit fields table
            var fieldsTableSymbol = Linker.CreateSymbol(type.FullName + Metadata.FieldsTable, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer1           = new EndianAwareBinaryWriter(fieldsTableSymbol.Stream, Architecture.Endianness);

            // 1. Number of Fields
            writer1.Write((uint)type.Fields.Count, TypeLayout.NativePointerSize);

            // 2. Pointers to Field Definitions
            foreach (MosaField field in type.Fields)
            {
                // Emit field name
                var fieldNameSymbol = EmitStringWithLength(field.FullName + Metadata.NameString, field.Name);

                // Emit field definition
                var fieldDefSymbol = Linker.CreateSymbol(field.FullName + Metadata.FieldDefinition, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
                var writer2        = new EndianAwareBinaryWriter(fieldDefSymbol.Stream, Architecture.Endianness);

                // 1. Name
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, (int)writer2.Position, 0, fieldNameSymbol, 0);
                writer2.WriteZeroBytes(TypeLayout.NativePointerSize);

                // 2. Pointer to Custom Attributes
                if (field.CustomAttributes.Count > 0)
                {
                    var customAttributesTableSymbol = CreateCustomAttributesTable(field);
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, (int)writer2.Position, 0, customAttributesTableSymbol, 0);
                }
                writer2.WriteZeroBytes(TypeLayout.NativePointerSize);

                // 3. Attributes
                writer2.Write((uint)field.FieldAttributes, TypeLayout.NativePointerSize);

                // 4. Pointer to Field Type
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, (int)writer2.Position, 0, field.FieldType.FullName + Metadata.TypeDefinition, SectionKind.ROData, 0);
                writer2.WriteZeroBytes(TypeLayout.NativePointerSize);

                // 5 & 6. Offset / Address + Size
                if (field.IsStatic && !field.IsLiteral)
                {
                    var section = (field.Data != null) ? SectionKind.ROData : SectionKind.BSS;
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, (int)writer2.Position, 0, field.FullName, section, 0);
                    writer2.WriteZeroBytes(TypeLayout.NativePointerSize);
                    writer2.Write((field.Data != null) ? field.Data.Length : 0, TypeLayout.NativePointerSize);
                }
                else
                {
                    writer2.WriteZeroBytes(TypeLayout.NativePointerSize);
                    writer2.Write(TypeLayout.GetFieldOffset(field), TypeLayout.NativePointerSize);
                }

                // Create another symbol with field data if any
                if (field.IsStatic)
                {
                    // Assign a memory slot to the static & initialize it, if there's initial data set
                    // Determine the size of the type & alignment requirements
                    int size, alignment;
                    Architecture.GetTypeRequirements(TypeLayout, field.FieldType, out size, out alignment);

                    size = TypeLayout.GetFieldSize(field);

                    // The linker section to move this field into
                    SectionKind section = field.Data != null ? section = SectionKind.ROData : section = SectionKind.BSS;

                    var symbol = Compiler.Linker.CreateSymbol(field.FullName, section, alignment, size);

                    if (field.Data != null)
                    {
                        symbol.Stream.Write(field.Data, 0, size);
                    }
                }

                // Add pointer to field list
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldsTableSymbol, (int)writer1.Position, 0, fieldDefSymbol, 0);
                writer1.WriteZeroBytes(TypeLayout.NativePointerSize);
            }

            // Return fieldsTableSymbol for linker usage
            return(fieldsTableSymbol);
        }