コード例 #1
0
ファイル: ModulesSectionNode.cs プロジェクト: schellap/corert
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory);
            objData.RequirePointerAlignment();
            objData.DefinedSymbols.Add(this);
            ObjectAndOffsetSymbolNode startNode = new ObjectAndOffsetSymbolNode(this, 0, "__modules_a");
            ObjectAndOffsetSymbolNode endNode = new ObjectAndOffsetSymbolNode(this, 0, "__modules_z");

            if (factory.Target.OperatingSystem != Internal.TypeSystem.TargetOS.Windows)
            {
                // Temporary work-around for Linux / OSX until CLI is updated
                objData.DefinedSymbols.Add(startNode);
            }

            objData.EmitPointerReloc(factory.ReadyToRunHeader);

            if (factory.Target.OperatingSystem != Internal.TypeSystem.TargetOS.Windows)
            {
                // Temporary work-around for Linux / OSX until CLI is updated
                endNode.SetSymbolOffset(objData.CountBytes);
                objData.DefinedSymbols.Add(endNode);
                objData.EmitZeroPointer();
            }

            return objData.ToObjectData();
        }
コード例 #2
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory);
            objData.RequirePointerAlignment();
            objData.DefinedSymbols.Add(this);
            if (factory.Target.OperatingSystem == Internal.TypeSystem.TargetOS.OSX)
            {
                objData.EmitPointerReloc(factory.JumpThunk((ExternSymbolNode)factory.ExternSymbol("RegisterReadyToRunModule"), factory.ReadyToRunHeader));
            }
            else
            {
                objData.EmitPointerReloc(factory.ReadyToRunHeader);
            }

            return objData.ToObjectData();
        }
コード例 #3
0
        private void WriteFieldRvas(NodeFactory factory, ref ObjectDataBuilder builder, ref BlobReader reader)
        {
            MetadataReader metadataReader = _sourceModule.MetadataReader;
            var            tableIndex     = TableIndex.FieldRva;
            int            rowCount       = metadataReader.GetTableRowCount(tableIndex);

            for (int i = 1; i <= rowCount; i++)
            {
                Debug.Assert(builder.CountBytes == reader.Offset);

                // Rva
                reader.ReadInt32();

                short        fieldToken  = reader.ReadInt16();
                EntityHandle fieldHandle = MetadataTokens.EntityHandle(TableIndex.Field, fieldToken);
                EcmaField    fieldDesc   = (EcmaField)_sourceModule.GetField(fieldHandle);
                Debug.Assert(fieldDesc.HasRva);

                builder.EmitReloc(((ReadyToRunCodegenNodeFactory)factory).CopiedFieldRva(fieldDesc), RelocType.IMAGE_REL_BASED_ADDR32NB);
                builder.EmitShort(fieldToken);
            }
        }
コード例 #4
0
        public unsafe override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialPointerAlignment();
            builder.AddSymbol(this);

            BlobReader metadataBlob   = new BlobReader(_sourceModule.PEReader.GetMetadata().Pointer, _sourceModule.PEReader.GetMetadata().Length);
            var        metadataReader = _sourceModule.MetadataReader;

            //
            // methodDef table
            //

            int methodDefTableOffset = metadataReader.GetTableMetadataOffset(TableIndex.MethodDef);

            builder.EmitBytes(metadataBlob.ReadBytes(methodDefTableOffset));

            WriteMethodTableRvas(factory, ref builder, ref metadataBlob);

            //
            // fieldRva table
            //

            int fieldRvaTableOffset = metadataReader.GetTableMetadataOffset(TableIndex.FieldRva);

            builder.EmitBytes(metadataBlob.ReadBytes(fieldRvaTableOffset - metadataBlob.Offset));

            WriteFieldRvas(factory, ref builder, ref metadataBlob);

            // Copy the rest of the metadata blob
            builder.EmitBytes(metadataBlob.ReadBytes(metadataReader.MetadataLength - metadataBlob.Offset));

            Debug.Assert(builder.CountBytes == metadataBlob.Length);
            Debug.Assert(builder.CountBytes == metadataBlob.Offset);
            Debug.Assert(builder.CountBytes == Size);

            return(builder.ToObjectData());
        }
コード例 #5
0
        private void WriteFieldRvas(NodeFactory factory, ref ObjectDataBuilder builder, ref BlobReader reader)
        {
            MetadataReader metadataReader     = _sourceModule.MetadataReader;
            var            tableIndex         = TableIndex.FieldRva;
            int            rowCount           = metadataReader.GetTableRowCount(tableIndex);
            bool           compressedFieldRef = 6 == metadataReader.GetTableRowSize(TableIndex.FieldRva);

            for (int i = 1; i <= rowCount; i++)
            {
                Debug.Assert(builder.CountBytes == reader.Offset);

                // Rva
                reader.ReadInt32();

                int fieldToken;
                if (compressedFieldRef)
                {
                    fieldToken = reader.ReadInt16();
                }
                else
                {
                    fieldToken = reader.ReadInt32();
                }
                EntityHandle fieldHandle = MetadataTokens.EntityHandle(TableIndex.Field, fieldToken);
                EcmaField    fieldDesc   = (EcmaField)_sourceModule.GetField(fieldHandle);
                Debug.Assert(fieldDesc.HasRva);

                builder.EmitReloc(factory.CopiedFieldRva(fieldDesc), RelocType.IMAGE_REL_BASED_ADDR32NB);
                if (compressedFieldRef)
                {
                    builder.EmitUShort((ushort)fieldToken);
                }
                else
                {
                    builder.EmitUInt((uint)fieldToken);
                }
            }
        }
コード例 #6
0
ファイル: ProfileDataNode.cs プロジェクト: zpplus/runtime
        public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
        {
            ProfileDataNode nextElementInList = ((ProfileDataSectionNode)ContainingNode).NextElementToEncode;

            if (nextElementInList != null)
            {
                dataBuilder.EmitPointerReloc(nextElementInList, -OffsetFromStartOfObjectToSymbol);
            }
            else
            {
                dataBuilder.EmitZeroPointer();
            }

            if (relocsOnly)
            {
                return;
            }

            EcmaMethod ecmaMethod  = (EcmaMethod)_methodNode.Method.GetTypicalMethodDefinition();
            int        startOffset = dataBuilder.CountBytes;
            var        reservation = dataBuilder.ReserveInt();

            dataBuilder.EmitInt(0);                                                     // CORBBTPROF_METHOD_HEADER::cDetail
            dataBuilder.EmitInt(ecmaMethod.MetadataReader.GetToken(ecmaMethod.Handle)); // CORBBT_METHOD_INFO::token
            dataBuilder.EmitInt(_ilSize);                                               // CORBBT_METHOD_INFO::ILSize
            dataBuilder.EmitInt(_blockCount);                                           // CORBBT_METHOD_INFO::cBlock
            int sizeOfCORBBTPROF_METHOD_HEADER = dataBuilder.CountBytes - startOffset;

            Debug.Assert(sizeOfCORBBTPROF_METHOD_HEADER == (OffsetFromStartOfObjectToSymbol - _targetDetails.PointerSize));
            dataBuilder.EmitInt(reservation, sizeOfCORBBTPROF_METHOD_HEADER + _profileData.Length);

            dataBuilder.EmitBytes(_profileData);

            while ((dataBuilder.CountBytes & (dataBuilder.TargetPointerSize - 1)) != 0)
            {
                dataBuilder.EmitByte(0);
            }
        }
コード例 #7
0
        public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
        {
            if (!_imports.ShouldSkipEmittingObjectNode(factory))
            {
                dataBuilder.EmitReloc(_imports.StartSymbol, RelocType.IMAGE_REL_BASED_ADDR32NB, 0);
            }
            else
            {
                dataBuilder.EmitUInt(0);
            }

            if (!relocsOnly)
            {
                dataBuilder.EmitInt(_imports.GetData(factory, false).Data.Length);

                dataBuilder.EmitShort((short)_flags);
                dataBuilder.EmitByte((byte)_type);
                dataBuilder.EmitByte(_entrySize);
            }

            if (!_signatures.ShouldSkipEmittingObjectNode(factory))
            {
                dataBuilder.EmitReloc(_signatures.StartSymbol, RelocType.IMAGE_REL_BASED_ADDR32NB, 0);
            }
            else
            {
                dataBuilder.EmitUInt(0);
            }

            if (_emitGCRefMap)
            {
                dataBuilder.EmitReloc(_gcRefMap, RelocType.IMAGE_REL_BASED_ADDR32NB, 0);
            }
            else
            {
                dataBuilder.EmitUInt(0);
            }
        }
コード例 #8
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            if (relocsOnly)
            {
                return(new ObjectData(
                           data: Array.Empty <byte>(),
                           relocs: Array.Empty <Relocation>(),
                           alignment: 1,
                           definedSymbols: new ISymbolDefinitionNode[] { this }));
            }

            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialAlignment(4);
            builder.AddSymbol(this);

            DirectoryEntry resourcesDirectory = _module.PEReader.PEHeaders.CorHeader.ResourcesDirectory;
            PEMemoryBlock  block = _module.PEReader.GetSectionData(resourcesDirectory.RelativeVirtualAddress);

            builder.EmitBytes(block.GetReader().ReadBytes(resourcesDirectory.Size));

            return(builder.ToObjectData());
        }
コード例 #9
0
ファイル: PreInitFieldInfo.cs プロジェクト: dnbllglm/corert
        public void WriteData(ref ObjectDataBuilder builder, NodeFactory factory)
        {
            int offset = Offset;

            if (FixupInfos != null)
            {
                int startOffset = builder.CountBytes;

                for (int i = 0; i < FixupInfos.Count; ++i)
                {
                    var fixupInfo = FixupInfos[i];

                    // do we have overlapping fixups?
                    if (fixupInfo.Offset < offset)
                    {
                        throw new BadImageFormatException();
                    }

                    // emit bytes before fixup
                    builder.EmitBytes(Data, offset, fixupInfo.Offset - offset);

                    // write the fixup
                    FixupInfos[i].WriteData(ref builder, factory);

                    // move pointer past the fixup
                    offset = Offset + builder.CountBytes - startOffset;
                }
            }

            if (offset > Data.Length)
            {
                throw new BadImageFormatException();
            }

            // Emit remaining bytes
            builder.EmitBytes(Data, offset, Data.Length - offset);
        }
コード例 #10
0
 public override void WriteData(ref ObjectDataBuilder builder, NodeFactory factory)
 {
     builder.EmitPointerRelocOrIndirectionReference(factory.NecessaryTypeSymbol(TypeFixup));
 }
コード例 #11
0
ファイル: PreInitFieldInfo.cs プロジェクト: mskvortsov/corert
 public override void WriteData(ref ObjectDataBuilder builder, NodeFactory factory)
 {
     builder.EmitPointerReloc(factory.MethodEntrypoint(MethodFixup));
 }
コード例 #12
0
 public static ObjectDataBuilder.Reservation Write(ref ObjectDataBuilder dataBuilder, ushort id)
 {
     dataBuilder.EmitInt(id);
     return(dataBuilder.ReserveInt());
 }
コード例 #13
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialPointerAlignment();
            builder.AddSymbol(this);

            BlobReader reader = _module.PEReader.GetEntireImage().GetReader();

            reader.Offset = _module.PEReader.PEHeaders.CorHeaderStartOffset;

            // Header Size
            int headerSize = reader.ReadInt32();

            builder.EmitInt(headerSize);

            // Runtime major, minor version
            builder.EmitUShort(reader.ReadUInt16());
            builder.EmitUShort(reader.ReadUInt16());

            // Metadata Directory
            ReadDirectoryEntry(ref reader);
            var metadataBlob = factory.CopiedMetadataBlob(_module);

            builder.EmitReloc(metadataBlob, RelocType.IMAGE_REL_BASED_ADDR32NB);
            builder.EmitInt(metadataBlob.Size);

            // Flags
            builder.EmitUInt((uint)(((CorFlags)reader.ReadUInt32() & ~CorFlags.ILOnly) | CorFlags.ILLibrary));

            // Entrypoint
            builder.EmitInt(reader.ReadInt32());

            // Resources Directory
            if (ReadDirectoryEntry(ref reader).Size > 0)
            {
                var managedResources = factory.CopiedManagedResources(_module);
                builder.EmitReloc(managedResources, RelocType.IMAGE_REL_BASED_ADDR32NB);
                builder.EmitInt(managedResources.Size);
            }
            else
            {
                WriteEmptyDirectoryEntry(ref builder);
            }

            // Strong Name Signature Directory
            if (ReadDirectoryEntry(ref reader).Size > 0)
            {
                var strongNameSignature = factory.CopiedStrongNameSignature(_module);
                builder.EmitReloc(strongNameSignature, RelocType.IMAGE_REL_BASED_ADDR32NB);
                builder.EmitInt(strongNameSignature.Size);
            }
            else
            {
                WriteEmptyDirectoryEntry(ref builder);
            }


            // Code Manager Table Directory
            ReadDirectoryEntry(ref reader);
            WriteEmptyDirectoryEntry(ref builder);

            // VTable Fixups Directory
            ReadDirectoryEntry(ref reader);
            WriteEmptyDirectoryEntry(ref builder);

            // Export Address Table Jumps Directory
            ReadDirectoryEntry(ref reader);
            WriteEmptyDirectoryEntry(ref builder);

            // Managed Native (ReadyToRun) Header Directory
            ReadDirectoryEntry(ref reader);
            builder.EmitReloc(factory.Header, RelocType.IMAGE_REL_BASED_ADDR32NB);
            builder.EmitReloc(factory.Header, RelocType.IMAGE_REL_SYMBOL_SIZE);

            // Did we fully read the header?
            Debug.Assert(reader.Offset - headerSize == _module.PEReader.PEHeaders.CorHeaderStartOffset);
            Debug.Assert(builder.CountBytes == headerSize);
            Debug.Assert(headerSize == Size);

            return(builder.ToObjectData());
        }
コード例 #14
0
 public override void WriteData(ref ObjectDataBuilder builder, NodeFactory factory)
 {
     builder.EmitPointerRelocOrIndirectionReference(factory.MaximallyConstructableType(TypeFixup));
 }
コード例 #15
0
ファイル: SignatureBuilder.cs プロジェクト: krishvoor/runtime
 public ObjectDataSignatureBuilder()
 {
     _builder = new ObjectDataBuilder();
 }
コード例 #16
0
 protected abstract void EmitHeaderPrefix(ref ObjectDataBuilder builder);
コード例 #17
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialPointerAlignment();
            builder.AddSymbol(this);

            ImmutableArray <DebugDirectoryEntry> entries = default(ImmutableArray <DebugDirectoryEntry>);

            if (_module != null)
            {
                entries = _module.PEReader.ReadDebugDirectory();
            }

            int numEntries = GetNumDebugDirectoryEntriesInModule();

            // First, write the native debug directory entry
            {
                var entry = _nativeEntry;

                builder.EmitUInt(0 /* Characteristics */);
                if (numEntries > 0)
                {
                    builder.EmitUInt(entries[0].Stamp);
                    builder.EmitUShort(entries[0].MajorVersion);
                }
                else
                {
                    builder.EmitUInt(0);
                    builder.EmitUShort(0);
                }
                // Make sure the "is portable pdb" indicator (MinorVersion == 0x504d) is clear
                // for the NGen debug directory entry since this debug directory can be copied
                // from an existing entry which could be a portable pdb.
                builder.EmitUShort(0 /* MinorVersion */);
                builder.EmitInt((int)DebugDirectoryEntryType.CodeView);
                builder.EmitInt(entry.Size);
                builder.EmitReloc(entry, RelocType.IMAGE_REL_BASED_ADDR32NB);
                builder.EmitReloc(entry, RelocType.IMAGE_REL_FILE_ABSOLUTE);
            }

            // If generating a composite image, emit the deterministic marker
            if (_insertDeterministicEntry)
            {
                builder.EmitUInt(0 /* Characteristics */);
                builder.EmitUInt(0);
                builder.EmitUShort(0);
                builder.EmitUShort(0);
                builder.EmitInt((int)DebugDirectoryEntryType.Reproducible);
                builder.EmitInt(0);
                builder.EmitUInt(0);
                builder.EmitUInt(0);
            }

            // Second, copy existing entries from input module
            for (int i = 0; i < numEntries; i++)
            {
                builder.EmitUInt(0 /* Characteristics */);
                builder.EmitUInt(entries[i].Stamp);
                builder.EmitUShort(entries[i].MajorVersion);
                builder.EmitUShort(entries[i].MinorVersion);
                builder.EmitInt((int)entries[i].Type);
                builder.EmitInt(entries[i].DataSize);
                if (entries[i].DataSize == 0)
                {
                    builder.EmitUInt(0);
                    builder.EmitUInt(0);
                }
                else
                {
                    builder.EmitReloc(factory.DebugDirectoryEntry(_module, i), RelocType.IMAGE_REL_BASED_ADDR32NB);
                    builder.EmitReloc(factory.DebugDirectoryEntry(_module, i), RelocType.IMAGE_REL_FILE_ABSOLUTE);
                }
            }

            Debug.Assert(builder.CountBytes == Size);

            return(builder.ToObjectData());
        }
コード例 #18
0
 /// <summary>
 /// Writes fixup data into current ObjectDataBuilder. Caller needs to make sure ObjectDataBuilder is
 /// at correct offset before writing.
 /// </summary>
 public abstract void WriteData(ref ObjectDataBuilder builder, NodeFactory factory);
コード例 #19
0
ファイル: X64Emitter.cs プロジェクト: tijoytom/corert
 public X64Emitter(NodeFactory factory)
 {
     Builder = new ObjectDataBuilder(factory);
     TargetRegister = new TargetRegisterMap(factory.Target.OperatingSystem);
 }
コード例 #20
0
 public X64Emitter(NodeFactory factory)
 {
     Builder        = new ObjectDataBuilder(factory);
     TargetRegister = new TargetRegisterMap(factory.Target.OperatingSystem);
 }
コード例 #21
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            List <CustomAttributeEntry> customAttributeEntries = GetCustomAttributeEntries();
            int countOfEntries = customAttributeEntries.Count;

            if (countOfEntries == 0)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            // Buckets have 8 entries
            uint minTableBucketCount = (uint)(countOfEntries / 8) + 1;
            uint bucketCount         = 1;

            // Bucket count must be power of two
            while (bucketCount < minTableBucketCount)
            {
                bucketCount *= 2;
            }

            // Resize the array.
            bool tryAgainWithBiggerTable = false;
            int  countOfRetries          = 0;

            ushort[] pTable;
            do
            {
                tryAgainWithBiggerTable = false;
                uint actualSizeOfTable = bucketCount * 8; // Buckets have 8 entries in them
                pTable = new ushort[actualSizeOfTable];
                uint[] state = new uint[] { 729055690, 833774698, 218408041, 493449127 };
                // Attempt to fill table
                foreach (var customAttributeEntry in customAttributeEntries)
                {
                    string name = customAttributeEntry.TypeNamespace + "." + customAttributeEntry.TypeName;
                    // This hashing algorithm MUST match exactly the logic in NativeCuckooFilter
                    int    hashOfAttribute = ReadyToRunHashCode.NameHashCode(name);
                    uint   hash            = unchecked ((uint)ReadyToRunHashCode.CombineTwoValuesIntoHash((uint)hashOfAttribute, (uint)customAttributeEntry.Parent));
                    ushort fingerprint     = (ushort)(hash >> 16);
                    if (fingerprint == 0)
                    {
                        fingerprint = 1;
                    }
                    uint bucketAIndex    = hash % bucketCount;
                    uint fingerprintHash = (uint)fingerprint;
                    uint bucketBIndex    = (bucketAIndex ^ (fingerprintHash % bucketCount));
                    Debug.Assert(bucketAIndex == (bucketBIndex ^ (fingerprintHash % bucketCount)));
                    if ((XorShift128(state) & 1) != 0) // Randomly choose which bucket to attempt to fill first
                    {
                        uint temp = bucketAIndex;
                        bucketAIndex = bucketBIndex;
                        bucketBIndex = temp;
                    }
                    Func <uint, ushort, bool> hasEntryInBucket = (uint bucketIndex, ushort fprint) =>
                    {
                        for (int i = 0; i < 8; i++)
                        {
                            if (pTable[(bucketIndex * 8) + i] == fprint)
                            {
                                return(true);
                            }
                        }
                        return(false);
                    };
                    Func <uint, bool> isEmptyEntryInBucket = (uint bucketIndex) =>
                    {
                        for (int i = 0; i < 8; i++)
                        {
                            if (pTable[(bucketIndex * 8) + i] == 0)
                            {
                                return(true);
                            }
                        }
                        return(false);
                    };
                    Action <uint, ushort> fillEmptyEntryInBucket = (uint bucketIndex, ushort fprint) =>
                    {
                        for (int i = 0; i < 8; i++)
                        {
                            if (pTable[(bucketIndex * 8) + i] == 0)
                            {
                                pTable[(bucketIndex * 8) + i] = fprint;
                                return;
                            }
                        }
                        Debug.Assert(false, "Not possible to reach here");
                    };
                    // Scan for pre-existing fingerprint entry in buckets
                    if (hasEntryInBucket(bucketAIndex, fingerprint) || hasEntryInBucket(bucketBIndex, fingerprint))
                    {
                        continue;
                    }

                    // Determine if there is space in a bucket to add a new entry
                    if (isEmptyEntryInBucket(bucketAIndex))
                    {
                        fillEmptyEntryInBucket(bucketAIndex, fingerprint);
                        continue;
                    }

                    if (isEmptyEntryInBucket(bucketBIndex))
                    {
                        fillEmptyEntryInBucket(bucketBIndex, fingerprint);
                        continue;
                    }

                    bool success     = false;
                    int  MaxNumKicks = 256;
                    // Note, that bucketAIndex itself was chosen randomly above.
                    for (int n = 0; !success && n < MaxNumKicks; n++)
                    {
                        // Randomly swap an entry in bucket bucketAIndex with fingerprint
                        uint   entryIndexInBucket = XorShift128(state) & 0x7;
                        ushort temp = fingerprint;
                        fingerprint = pTable[(bucketAIndex * 8) + entryIndexInBucket];
                        pTable[(bucketAIndex * 8) + entryIndexInBucket] = temp;

                        // Find other bucket
                        fingerprintHash = (uint)fingerprint;
                        bucketAIndex    = bucketAIndex ^ (fingerprintHash % bucketCount);
                        if (isEmptyEntryInBucket(bucketAIndex))
                        {
                            fillEmptyEntryInBucket(bucketAIndex, fingerprint);
                            success = true;
                        }
                    }

                    if (success)
                    {
                        continue;
                    }

                    tryAgainWithBiggerTable = true;
                }

                if (tryAgainWithBiggerTable)
                {
                    // bucket entry kicking path requires bucket counts to be power of two in size due to use of xor to retrieve second hash
                    bucketCount *= 2;
                }
            }while(tryAgainWithBiggerTable && ((countOfRetries++) < 2));

            byte[] result;
            if (tryAgainWithBiggerTable)
            {
                result = Array.Empty <byte>();
            }
            else
            {
                result = new byte[pTable.Length * 2];
                for (int i = 0; i < pTable.Length; i++)
                {
                    result[i * 2]     = (byte)(pTable[i] % 256);
                    result[i * 2 + 1] = (byte)(pTable[i] >> 8);
                }
            }

            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialAlignment(16);
            builder.AddSymbol(this);
            builder.EmitBytes(result);

            return(builder.ToObjectData());;
        }
コード例 #22
0
 public override void WriteData(ref ObjectDataBuilder builder, NodeFactory factory)
 {
     builder.EmitPointerReloc(factory.ExactCallableAddress(MethodFixup));
 }
コード例 #23
0
ファイル: StringImport.cs プロジェクト: zwei222/coreclr
 public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
 {
     // This needs to be an empty target pointer since it will be filled in with the string pointer
     // when loaded by CoreCLR
     dataBuilder.EmitZeroPointer();
 }
コード例 #24
0
        public void WriteResources(ISymbolNode nodeAssociatedWithDataBuilder, ref ObjectDataBuilder dataBuilder)
        {
            Debug.Assert(dataBuilder.CountBytes == 0);

            SortedDictionary <string, List <ObjectDataBuilder.Reservation> > nameTable = new SortedDictionary <string, List <ObjectDataBuilder.Reservation> >();
            Dictionary <ResLanguage, int> dataEntryTable = new Dictionary <ResLanguage, int>();
            List <Tuple <ResType, ObjectDataBuilder.Reservation> >     resTypes     = new List <Tuple <ResType, ObjectDataBuilder.Reservation> >();
            List <Tuple <ResName, ObjectDataBuilder.Reservation> >     resNames     = new List <Tuple <ResName, ObjectDataBuilder.Reservation> >();
            List <Tuple <ResLanguage, ObjectDataBuilder.Reservation> > resLanguages = new List <Tuple <ResLanguage, ObjectDataBuilder.Reservation> >();

            IMAGE_RESOURCE_DIRECTORY.Write(ref dataBuilder, checked ((ushort)_resTypeHeadName.Count), checked ((ushort)_resTypeHeadID.Count));
            foreach (KeyValuePair <string, ResType> res in _resTypeHeadName)
            {
                resTypes.Add(new Tuple <ResType, ObjectDataBuilder.Reservation>(res.Value, IMAGE_RESOURCE_DIRECTORY_ENTRY.Write(ref dataBuilder, res.Key, nameTable)));
            }
            foreach (KeyValuePair <ushort, ResType> res in _resTypeHeadID)
            {
                resTypes.Add(new Tuple <ResType, ObjectDataBuilder.Reservation>(res.Value, IMAGE_RESOURCE_DIRECTORY_ENTRY.Write(ref dataBuilder, res.Key)));
            }

            foreach (Tuple <ResType, ObjectDataBuilder.Reservation> type in resTypes)
            {
                dataBuilder.EmitUInt(type.Item2, (uint)dataBuilder.CountBytes | 0x80000000);
                IMAGE_RESOURCE_DIRECTORY.Write(ref dataBuilder, checked ((ushort)type.Item1.NameHeadName.Count), checked ((ushort)type.Item1.NameHeadID.Count));

                foreach (KeyValuePair <string, ResName> res in type.Item1.NameHeadName)
                {
                    resNames.Add(new Tuple <ResName, ObjectDataBuilder.Reservation>(res.Value, IMAGE_RESOURCE_DIRECTORY_ENTRY.Write(ref dataBuilder, res.Key, nameTable)));
                }
                foreach (KeyValuePair <ushort, ResName> res in type.Item1.NameHeadID)
                {
                    resNames.Add(new Tuple <ResName, ObjectDataBuilder.Reservation>(res.Value, IMAGE_RESOURCE_DIRECTORY_ENTRY.Write(ref dataBuilder, res.Key)));
                }
            }

            foreach (Tuple <ResName, ObjectDataBuilder.Reservation> type in resNames)
            {
                dataBuilder.EmitUInt(type.Item2, (uint)dataBuilder.CountBytes | 0x80000000);
                IMAGE_RESOURCE_DIRECTORY.Write(ref dataBuilder, 0, checked ((ushort)type.Item1.Languages.Count));
                foreach (KeyValuePair <ushort, ResLanguage> res in type.Item1.Languages)
                {
                    resLanguages.Add(new Tuple <ResLanguage, ObjectDataBuilder.Reservation>(res.Value, IMAGE_RESOURCE_DIRECTORY_ENTRY.Write(ref dataBuilder, res.Key)));
                }
            }

            // Emit name table
            dataBuilder.PadAlignment(2); // name table is 2 byte aligned
            foreach (KeyValuePair <string, List <ObjectDataBuilder.Reservation> > name in nameTable)
            {
                foreach (ObjectDataBuilder.Reservation reservation in name.Value)
                {
                    dataBuilder.EmitUInt(reservation, (uint)dataBuilder.CountBytes | 0x80000000);
                }

                dataBuilder.EmitUShort(checked ((ushort)name.Key.Length));
                foreach (char c in name.Key)
                {
                    dataBuilder.EmitUShort((ushort)c);
                }
            }

            // Emit byte arrays of resource data, capture the offsets
            foreach (Tuple <ResLanguage, ObjectDataBuilder.Reservation> language in resLanguages)
            {
                dataBuilder.PadAlignment(4); // Data in resource files is 4 byte aligned
                dataEntryTable.Add(language.Item1, dataBuilder.CountBytes);
                dataBuilder.EmitBytes(language.Item1.DataEntry);
            }

            dataBuilder.PadAlignment(4); // resource data entries are 4 byte aligned
            foreach (Tuple <ResLanguage, ObjectDataBuilder.Reservation> language in resLanguages)
            {
                dataBuilder.EmitInt(language.Item2, dataBuilder.CountBytes);
                IMAGE_RESOURCE_DATA_ENTRY.Write(ref dataBuilder, nodeAssociatedWithDataBuilder, dataEntryTable[language.Item1], language.Item1.DataEntry.Length);
            }
            dataBuilder.PadAlignment(4); // resource data entries are 4 byte aligned
        }
コード例 #25
0
 protected override void EmitHeaderPrefix(ref ObjectDataBuilder builder)
 {
 }
コード例 #26
0
 private void WriteEmptyDirectoryEntry(ref ObjectDataBuilder builder)
 {
     builder.EmitInt(0);
     builder.EmitInt(0);
 }
コード例 #27
0
 public ARM64Emitter(NodeFactory factory, bool relocsOnly)
 {
     Builder        = new ObjectDataBuilder(factory, relocsOnly);
     TargetRegister = new TargetRegisterMap(factory.Target.OperatingSystem);
 }
コード例 #28
0
        private void ComputeDependencyNodeDependencies(List <DependencyNodeCore <NodeFactory> > obj)
        {
            foreach (MethodCodeNode methodCodeNodeNeedingCode in obj)
            {
                MethodDesc method     = methodCodeNodeNeedingCode.Method;
                string     methodName = method.ToString();
                Log.WriteLine("Compiling " + methodName);

                var methodIL = _ilProvider.GetMethodIL(method);
                if (methodIL == null)
                {
                    return;
                }

                MethodCode methodCode;
                try
                {
                    if (_skipJitList.Contains(new TypeAndMethod(method.OwningType.Name, method.Name)))
                    {
                        throw new NotImplementedException("SkipJIT");
                    }

                    methodCode = _corInfo.CompileMethod(method);

                    if (methodCode.Relocs != null)
                    {
                        if (methodCode.Relocs.Any(r => r.Target is FieldDesc))
                        {
                            // We only support FieldDesc for InitializeArray intrinsic right now.
                            throw new NotImplementedException("RuntimeFieldHandle is not implemented");
                        }
                    }
                }
                catch (Exception e)
                {
                    Log.WriteLine("*** " + e.Message + " (" + method + ")");

                    // Call the __not_yet_implemented method
                    DependencyAnalysis.X64.X64Emitter emit = new DependencyAnalysis.X64.X64Emitter(_nodeFactory);
                    emit.Builder.RequireAlignment(_nodeFactory.Target.MinimumFunctionAlignment);
                    emit.Builder.DefinedSymbols.Add(methodCodeNodeNeedingCode);

                    emit.EmitLEAQ(emit.TargetRegister.Arg0, _nodeFactory.StringIndirection(method.ToString()));
                    DependencyAnalysis.X64.AddrMode loadFromArg0 =
                        new DependencyAnalysis.X64.AddrMode(emit.TargetRegister.Arg0, null, 0, 0, DependencyAnalysis.X64.AddrModeSize.Int64);
                    emit.EmitMOV(emit.TargetRegister.Arg0, ref loadFromArg0);
                    emit.EmitMOV(emit.TargetRegister.Arg0, ref loadFromArg0);

                    emit.EmitLEAQ(emit.TargetRegister.Arg1, _nodeFactory.StringIndirection(e.Message));
                    DependencyAnalysis.X64.AddrMode loadFromArg1 =
                        new DependencyAnalysis.X64.AddrMode(emit.TargetRegister.Arg1, null, 0, 0, DependencyAnalysis.X64.AddrModeSize.Int64);
                    emit.EmitMOV(emit.TargetRegister.Arg1, ref loadFromArg1);
                    emit.EmitMOV(emit.TargetRegister.Arg1, ref loadFromArg1);

                    emit.EmitJMP(_nodeFactory.ExternSymbol("__not_yet_implemented"));
                    methodCodeNodeNeedingCode.SetCode(emit.Builder.ToObjectData());
                    continue;
                }

                ObjectDataBuilder objData = new ObjectDataBuilder();
                objData.Alignment = _nodeFactory.Target.MinimumFunctionAlignment;
                objData.EmitBytes(methodCode.Code);
                objData.DefinedSymbols.Add(methodCodeNodeNeedingCode);

                BlobNode readOnlyDataBlob = null;
                if (methodCode.ROData != null)
                {
                    readOnlyDataBlob = _nodeFactory.ReadOnlyDataBlob(
                        "__readonlydata_" + _nameMangler.GetMangledMethodName(method),
                        methodCode.ROData, methodCode.RODataAlignment);
                }

                if (methodCode.Relocs != null)
                {
                    for (int i = 0; i < methodCode.Relocs.Length; i++)
                    {
                        // TODO: Arbitrary relocs
                        if (methodCode.Relocs[i].Block != BlockType.Code)
                        {
                            throw new NotImplementedException();
                        }

                        int         offset    = methodCode.Relocs[i].Offset;
                        int         delta     = methodCode.Relocs[i].Delta;
                        RelocType   relocType = (RelocType)methodCode.Relocs[i].RelocType;
                        ISymbolNode targetNode;

                        object target = methodCode.Relocs[i].Target;
                        if (target is MethodDesc)
                        {
                            targetNode = _nodeFactory.MethodEntrypoint((MethodDesc)target);
                        }
                        else if (target is ReadyToRunHelper)
                        {
                            targetNode = _nodeFactory.ReadyToRunHelper((ReadyToRunHelper)target);
                        }
                        else if (target is JitHelper)
                        {
                            targetNode = _nodeFactory.ExternSymbol(((JitHelper)target).MangledName);
                        }
                        else if (target is string)
                        {
                            targetNode = _nodeFactory.StringIndirection((string)target);
                        }
                        else if (target is TypeDesc)
                        {
                            targetNode = _nodeFactory.NecessaryTypeSymbol((TypeDesc)target);
                        }
                        else if (target is RvaFieldData)
                        {
                            var rvaFieldData = (RvaFieldData)target;
                            targetNode = _nodeFactory.ReadOnlyDataBlob(rvaFieldData.MangledName,
                                                                       rvaFieldData.Data, _typeSystemContext.Target.PointerSize);
                        }
                        else if (target is BlockRelativeTarget)
                        {
                            var blockRelativeTarget = (BlockRelativeTarget)target;
                            // TODO: Arbitrary block relative relocs
                            if (blockRelativeTarget.Block != BlockType.ROData)
                            {
                                throw new NotImplementedException();
                            }
                            targetNode = readOnlyDataBlob;
                        }
                        else
                        {
                            // TODO:
                            throw new NotImplementedException();
                        }

                        objData.AddRelocAtOffset(targetNode, relocType, offset, delta);
                    }
                }
                // TODO: ColdCode
                if (methodCode.ColdCode != null)
                {
                    throw new NotImplementedException();
                }

                methodCodeNodeNeedingCode.SetCode(objData.ToObjectData());

                methodCodeNodeNeedingCode.InitializeFrameInfos(methodCode.FrameInfos);
                methodCodeNodeNeedingCode.InitializeDebugLocInfos(methodCode.DebugLocInfos);
            }
        }