예제 #1
0
        public void EmitMOV(Register regDst, ushort imm16)
        {
            Debug.Assert((uint)regDst <= 0x1f);
            uint instruction = 0xd2800000u | ((uint)imm16 << 5) | (uint)regDst;

            Builder.EmitUInt(instruction);
        }
예제 #2
0
        public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
        {
            if (!relocsOnly && _imports.ShouldSkipEmittingObjectNode(factory))
            {
                // Don't emit import section node at all if there are no entries in it
                return;
            }

            dataBuilder.EmitReloc(_imports.StartSymbol, RelocType.IMAGE_REL_BASED_ADDR32NB, 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);
            }
        }
예제 #3
0
 public static void Write(ref ObjectDataBuilder builder, ushort namedEntries, ushort idEntries)
 {
     builder.EmitUInt(0);   // Characteristics
     builder.EmitUInt(0);   // TimeDateStamp
     builder.EmitUShort(4); // MajorVersion
     builder.EmitUShort(0); // MinorVersion
     builder.EmitUShort(namedEntries);
     builder.EmitUShort(idEntries);
 }
예제 #4
0
 internal static void EmitHeader(ref ObjectDataBuilder builder)
 {
     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);
 }
예제 #5
0
 internal void EmitHeader(ref ObjectDataBuilder builder)
 {
     builder.EmitUInt(0);        /* Characteristics */
     builder.EmitUInt(0);        /* Stamp */
     builder.EmitUShort(1);      /* Major */
     builder.EmitUShort(0);      /* Minor */
     builder.EmitInt((int)PerfMapEntryType);
     builder.EmitInt(Size);
     builder.EmitReloc(this, RelocType.IMAGE_REL_BASED_ADDR32NB);
     builder.EmitReloc(this, RelocType.IMAGE_REL_FILE_ABSOLUTE);
 }
예제 #6
0
 internal void EmitHeader(ref ObjectDataBuilder builder, uint stamp, ushort majorVersion)
 {
     builder.EmitUInt(0);        /* Characteristics */
     builder.EmitUInt(stamp);
     builder.EmitUShort(majorVersion);
     // Make sure the "is portable pdb" indicator (MinorVersion == 0x504d) is clear.
     // The NI PDB generated currently is a full PDB.
     builder.EmitUShort(0 /* MinorVersion */);
     builder.EmitInt((int)DebugDirectoryEntryType.CodeView);
     builder.EmitInt(Size);
     builder.EmitReloc(this, RelocType.IMAGE_REL_BASED_ADDR32NB);
     builder.EmitReloc(this, RelocType.IMAGE_REL_FILE_ABSOLUTE);
 }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            LayoutMethodsWithEHInfo();

            ObjectDataBuilder exceptionInfoLookupBuilder = new ObjectDataBuilder(factory, relocsOnly);

            exceptionInfoLookupBuilder.RequireInitialAlignment(2 * sizeof(uint));

            // Add the symbol representing this object node
            exceptionInfoLookupBuilder.AddSymbol(this);

            // First, emit the actual EH records in sequence and store map from methods to the EH record symbols
            for (int index = 0; index < _methodNodes.Count; index++)
            {
                exceptionInfoLookupBuilder.EmitReloc(_methodNodes[index], RelocType.IMAGE_REL_BASED_ADDR32NB);
                exceptionInfoLookupBuilder.EmitReloc(_ehInfoNode, RelocType.IMAGE_REL_BASED_ADDR32NB, _ehInfoOffsets[index]);
            }

            // Sentinel record - method RVA = -1, EH info offset = end of the EH info block
            exceptionInfoLookupBuilder.EmitUInt(~0u);
            exceptionInfoLookupBuilder.EmitReloc(_ehInfoNode, RelocType.IMAGE_REL_BASED_ADDR32NB, _ehInfoNode.Count);

            return(exceptionInfoLookupBuilder.ToObjectData());
        }
예제 #8
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

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

            ImmutableArray <DebugDirectoryEntry> entries = _module.PEReader.ReadDebugDirectory();
            int numEntries = GetNumDebugDirectoryEntriesInModule();

            // First, write the native debug directory entry
            {
                var entry = (NativeDebugDirectoryEntryNode)factory.DebugDirectoryEntry(_module, -1);

                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);
            }

            // 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());
        }
예제 #9
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 }));
            }

            if (_methodNodes == null)
            {
                LayoutRuntimeFunctions();
            }

            ObjectDataBuilder runtimeFunctionsBuilder = new ObjectDataBuilder(factory, relocsOnly);

            runtimeFunctionsBuilder.RequireInitialAlignment(4);

            // Add the symbol representing this object node
            runtimeFunctionsBuilder.AddSymbol(this);

            foreach (MethodWithGCInfo method in _methodNodes)
            {
                int[] funcletOffsets = method.GCInfoNode.CalculateFuncletOffsets(factory);

                for (int frameIndex = 0; frameIndex < method.FrameInfos.Length; frameIndex++)
                {
                    FrameInfo frameInfo = method.FrameInfos[frameIndex];

                    // StartOffset of the runtime function
                    int codeDelta = 0;
                    if (Target.Architecture == TargetArchitecture.ARM)
                    {
                        // THUMB_CODE
                        codeDelta = 1;
                    }
                    runtimeFunctionsBuilder.EmitReloc(method, RelocType.IMAGE_REL_BASED_ADDR32NB, delta: frameInfo.StartOffset + codeDelta);
                    if (!relocsOnly && Target.Architecture == TargetArchitecture.X64)
                    {
                        // On Amd64, the 2nd word contains the EndOffset of the runtime function
                        runtimeFunctionsBuilder.EmitReloc(method, RelocType.IMAGE_REL_BASED_ADDR32NB, delta: frameInfo.EndOffset);
                    }
                    runtimeFunctionsBuilder.EmitReloc(factory.RuntimeFunctionsGCInfo.StartSymbol, RelocType.IMAGE_REL_BASED_ADDR32NB, funcletOffsets[frameIndex]);
                }
            }

            // Emit sentinel entry
            runtimeFunctionsBuilder.EmitUInt(~0u);

            _tableSize = runtimeFunctionsBuilder.CountBytes;
            return(runtimeFunctionsBuilder.ToObjectData());
        }
예제 #10
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.EmitReloc(_imports.StartSymbol, RelocType.IMAGE_REL_SYMBOL_SIZE);
                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);
            }
        }
예제 #11
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);
                }
            }
        }
예제 #12
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());
        }
예제 #13
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
        }
예제 #14
0
        // Assembly stub creation api. TBD, actually make this general purpose

        public void EmitBreak()
        {
            Builder.EmitUInt(0x002a0005);
        }