public void EmitMOV(Register regDst, ushort imm16) { Debug.Assert((uint)regDst <= 0x1f); uint instruction = 0xd2800000u | ((uint)imm16 << 5) | (uint)regDst; Builder.EmitUInt(instruction); }
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); } }
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); }
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); }
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); }
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()); }
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()); }
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()); }
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); } }
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); } } }
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()); }
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 }
// Assembly stub creation api. TBD, actually make this general purpose public void EmitBreak() { Builder.EmitUInt(0x002a0005); }