protected override void RunPostCompile() { foreach (var type in TypeSystem.AllTypes) { foreach (var field in type.Fields) { if (!field.IsStatic) { continue; } if (!Compiler.MethodScanner.IsFieldAccessed(field)) { continue; } var section = field.Data != null ? SectionKind.ROData : SectionKind.BSS; int size = TypeLayout.GetFieldSize(field); var symbol = Compiler.Linker.DefineSymbol(field.FullName, section, Architecture.NativeAlignment, size); if (field.Data != null) { symbol.Stream.Write(field.Data, 0, size); } } } }
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); }