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(); } }
// 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()); }
public static ObjectDataBuilder.Reservation Write(ref ObjectDataBuilder dataBuilder, ushort id) { dataBuilder.EmitInt(id); return(dataBuilder.ReserveInt()); }
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()); }
private void WriteEmptyDirectoryEntry(ref ObjectDataBuilder builder) { builder.EmitInt(0); builder.EmitInt(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 }