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(); }
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(); }
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); } }
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()); }
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 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); } }
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); } }
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()); }
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); }
public override void WriteData(ref ObjectDataBuilder builder, NodeFactory factory) { builder.EmitPointerRelocOrIndirectionReference(factory.NecessaryTypeSymbol(TypeFixup)); }
public override void WriteData(ref ObjectDataBuilder builder, NodeFactory factory) { builder.EmitPointerReloc(factory.MethodEntrypoint(MethodFixup)); }
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()); }
public override void WriteData(ref ObjectDataBuilder builder, NodeFactory factory) { builder.EmitPointerRelocOrIndirectionReference(factory.MaximallyConstructableType(TypeFixup)); }
public ObjectDataSignatureBuilder() { _builder = new ObjectDataBuilder(); }
protected abstract void EmitHeaderPrefix(ref ObjectDataBuilder builder);
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()); }
/// <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);
public X64Emitter(NodeFactory factory) { Builder = new ObjectDataBuilder(factory); TargetRegister = new TargetRegisterMap(factory.Target.OperatingSystem); }
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());; }
public override void WriteData(ref ObjectDataBuilder builder, NodeFactory factory) { builder.EmitPointerReloc(factory.ExactCallableAddress(MethodFixup)); }
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(); }
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 }
protected override void EmitHeaderPrefix(ref ObjectDataBuilder builder) { }
private void WriteEmptyDirectoryEntry(ref ObjectDataBuilder builder) { builder.EmitInt(0); builder.EmitInt(0); }
public ARM64Emitter(NodeFactory factory, bool relocsOnly) { Builder = new ObjectDataBuilder(factory, relocsOnly); TargetRegister = new TargetRegisterMap(factory.Target.OperatingSystem); }
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); } }