示例#1
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);
            }
        }
        private void EmitImmediate(int immediate, int size)
        {
            switch (size)
            {
            case 0:
                break;

            case 1:
                Builder.EmitByte((byte)immediate);
                break;

            case 2:
                Builder.EmitShort((short)immediate);
                break;

            case 4:
                Builder.EmitInt(immediate);
                break;

            default:
                throw new NotImplementedException();
            }
        }
示例#3
0
 // add reg, immediate
 public void EmitADD(Register reg, byte immediate)
 {
     Builder.EmitInt((int)(0x91 << 24) | (immediate << 10) | ((byte)reg << 5) | (byte)reg);
 }
        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());
        }
示例#5
0
 public static ObjectDataBuilder.Reservation Write(ref ObjectDataBuilder dataBuilder, ushort id)
 {
     dataBuilder.EmitInt(id);
     return(dataBuilder.ReserveInt());
 }
示例#6
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());
        }
示例#7
0
 private void WriteEmptyDirectoryEntry(ref ObjectDataBuilder builder)
 {
     builder.EmitInt(0);
     builder.EmitInt(0);
 }
示例#8
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
        }