public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { ObjectDataBuilder builder = new ObjectDataBuilder(factory); builder.DefinedSymbols.Add(this); // // Emit a MethodFixupCell struct // // Address (to be fixed up at runtime) builder.EmitZeroPointer(); // Entry point name if (factory.Target.IsWindows && _entryPointName.StartsWith("#", StringComparison.OrdinalIgnoreCase)) { // Windows-specific ordinal import // CLR-compatible behavior: Strings that can't be parsed as a signed integer are treated as zero. int entrypointOrdinal; if (!int.TryParse(_entryPointName.Substring(1), out entrypointOrdinal)) entrypointOrdinal = 0; // CLR-compatible behavior: Ordinal imports are 16-bit on Windows. Discard rest of the bits. builder.EmitNaturalInt((ushort)entrypointOrdinal); } else { // Import by name builder.EmitPointerReloc(factory.ConstantUtf8String(_entryPointName)); } // Module fixup cell builder.EmitPointerReloc(factory.PInvokeModuleFixup(_moduleName)); return builder.ToObjectData(); }
public override void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation) { ThreadStaticsNode targetNode = (ThreadStaticsNode)GetTarget(factory, typeInstantiation, methodInstantiation); int typeTlsIndex = factory.ThreadStaticsRegion.IndexOfEmbeddedObject(targetNode); builder.EmitNaturalInt(typeTlsIndex); }
public override void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation, GenericDictionaryNode dictionary) { FieldDesc instantiatedField = _field.InstantiateSignature(typeInstantiation, methodInstantiation); int offset = instantiatedField.Offset.AsInt; builder.EmitNaturalInt(offset); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly) { ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly); builder.RequireInitialPointerAlignment(); builder.AddSymbol(this); builder.AddSymbol(StartSymbol); builder.EmitInt(1); builder.EmitInt(_importNodes.Count); builder.EmitPointerReloc(factory.ExternSymbol(ExportTableToImportSymbol)); if (!relocsOnly) { FinalizeOffsets(); foreach (MrtImportNode node in _importNodes) { Debug.Assert(((ISymbolDefinitionNode)node).Offset == builder.CountBytes); builder.AddSymbol(node); builder.EmitNaturalInt(node.Ordinal); } } EndSymbol.SetSymbolOffset(builder.CountBytes); builder.AddSymbol(EndSymbol); ObjectData objData = builder.ToObjectData(); return(objData); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this })); } Debug.Assert(_dynamicInvokeMethodContainerType != null); // Ensure the native layout blob has been saved factory.MetadataManager.NativeLayoutInfo.SaveNativeLayoutInfoWriter(factory); ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly); objData.RequireInitialPointerAlignment(); objData.AddSymbol(this); if (factory.Target.SupportsRelativePointers) { objData.EmitReloc(factory.NecessaryTypeSymbol(_dynamicInvokeMethodContainerType), RelocType.IMAGE_REL_BASED_RELPTR32); } else { objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_dynamicInvokeMethodContainerType)); } List <KeyValuePair <MethodDesc, int> > sortedList = new List <KeyValuePair <MethodDesc, int> >(_methodToTemplateIndex); sortedList.Sort((firstEntry, secondEntry) => firstEntry.Value.CompareTo(secondEntry.Value)); for (int i = 0; i < sortedList.Count; i++) { var nameAndSig = factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(sortedList[i].Key)); if (factory.Target.SupportsRelativePointers) { objData.EmitInt(nameAndSig.SavedVertex.VertexOffset); objData.EmitReloc(factory.MethodEntrypoint(sortedList[i].Key), RelocType.IMAGE_REL_BASED_RELPTR32); } else { objData.EmitNaturalInt(nameAndSig.SavedVertex.VertexOffset); objData.EmitPointerReloc(factory.MethodEntrypoint(sortedList[i].Key)); } } _endSymbol.SetSymbolOffset(objData.CountBytes); objData.AddSymbol(_endSymbol); // Prevent further adds now we're done writing #if DEBUG if (!relocsOnly) { _dataEmitted = true; } #endif return(objData.ToObjectData()); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { ObjectDataBuilder objData = new ObjectDataBuilder(factory); // The interface dispatch cell has an alignment requirement of 2 * [Pointer size] as part of the // synchronization mechanism of the two values in the runtime. objData.RequireInitialAlignment(_targetMethod.Context.Target.PointerSize * 2); objData.AddSymbol(this); if (factory.Target.Architecture == TargetArchitecture.ARM) { objData.EmitPointerReloc(factory.InitialInterfaceDispatchStub); } else { objData.EmitPointerReloc(factory.ExternSymbol("RhpInitialDynamicInterfaceDispatch")); } if (factory.Target.Abi == TargetAbi.CoreRT) { // TODO: Enable Indirect Pointer for Interface Dispatch Cell. See https://github.com/dotnet/corert/issues/2542 objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_targetMethod.OwningType), (int)InterfaceDispatchCellCachePointerFlags.CachePointerIsInterfacePointerOrMetadataToken); } else { if (factory.CompilationModuleGroup.ContainsType(_targetMethod.OwningType)) { objData.EmitReloc(factory.NecessaryTypeSymbol(_targetMethod.OwningType), RelocType.IMAGE_REL_BASED_RELPTR32, (int)InterfaceDispatchCellCachePointerFlags.CachePointerIsInterfaceRelativePointer); } else { objData.EmitReloc(factory.NecessaryTypeSymbol(_targetMethod.OwningType), RelocType.IMAGE_REL_BASED_RELPTR32, (int)InterfaceDispatchCellCachePointerFlags.CachePointerIsIndirectedInterfaceRelativePointer); } if (objData.TargetPointerSize == 8) { // IMAGE_REL_BASED_RELPTR is a 32-bit relocation. However, the cell needs a full pointer // width there since a pointer to the cache will be written into the cell. Emit additional // 32 bits on targets whose pointer size is 64 bit. objData.EmitInt(0); } } // End the run of dispatch cells objData.EmitZeroPointer(); // Avoid consulting VTable slots until they're guaranteed complete during final data emission if (!relocsOnly) { objData.EmitNaturalInt(VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, _targetMethod)); } return(objData.ToObjectData()); }
public override void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation, GenericDictionaryNode dictionary) { TypeDesc instantiatedType = _type.InstantiateSignature(typeInstantiation, methodInstantiation); int typeSize; if (_type.IsDefType) { typeSize = ((DefType)_type).InstanceFieldSize.AsInt; } else { typeSize = factory.TypeSystemContext.Target.PointerSize; } builder.EmitNaturalInt(typeSize); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly); builder.RequireInitialPointerAlignment(); builder.AddSymbol(this); // // Emit a MethodFixupCell struct // // Address (to be fixed up at runtime) builder.EmitZeroPointer(); // Entry point name string entryPointName = _pInvokeMethodData.EntryPointName; if (factory.Target.IsWindows && entryPointName.StartsWith("#", StringComparison.OrdinalIgnoreCase)) { // Windows-specific ordinal import // CLR-compatible behavior: Strings that can't be parsed as a signed integer are treated as zero. int entrypointOrdinal; if (!int.TryParse(entryPointName.Substring(1), out entrypointOrdinal)) { entrypointOrdinal = 0; } // CLR-compatible behavior: Ordinal imports are 16-bit on Windows. Discard rest of the bits. builder.EmitNaturalInt((ushort)entrypointOrdinal); } else { // Import by name builder.EmitPointerReloc(factory.ConstantUtf8String(entryPointName)); } // Module fixup cell builder.EmitPointerReloc(factory.PInvokeModuleFixup(_pInvokeMethodData.ModuleData)); builder.EmitInt((int)_pInvokeMethodData.CharSetMangling); return(builder.ToObjectData()); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly); objData.RequireInitialPointerAlignment(); objData.AddSymbol(this); int typeTlsIndex = 0; if (!relocsOnly) { var node = factory.TypeThreadStaticsSymbol(_type); typeTlsIndex = ((ThreadStaticsNode)node).IndexFromBeginningOfArray; } objData.EmitPointerReloc(factory.TypeManagerIndirection); objData.EmitNaturalInt(typeTlsIndex); return(objData.ToObjectData()); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { ObjectDataBuilder objData = new ObjectDataBuilder(factory); objData.Alignment = objData.TargetPointerSize; objData.DefinedSymbols.Add(this); int typeTlsIndex = 0; if (!relocsOnly) { var node = factory.TypeThreadStaticsSymbol(_type); typeTlsIndex = factory.ThreadStaticsRegion.IndexOfEmbeddedObject(node); } objData.EmitPointerReloc(factory.TypeManagerIndirection); objData.EmitNaturalInt(typeTlsIndex); return(objData.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 ISymbolNode[] { this })); } // Ensure native layout is saved to get valid Vertex offsets factory.MetadataManager.NativeLayoutInfo.SaveNativeLayoutInfoWriter(factory); ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly); objData.RequireInitialPointerAlignment(); objData.AddSymbol(this); objData.EmitPointerReloc(factory.TypeManagerIndirection); objData.EmitNaturalInt(_nativeSignature.SavedVertex.VertexOffset); return(objData.ToObjectData()); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this })); } // Ensure the native layout blob has been saved factory.MetadataManager.NativeLayoutInfo.SaveNativeLayoutInfoWriter(factory); ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly); objData.RequireInitialPointerAlignment(); objData.AddSymbol(this); if (_methodToTemplateIndex == null) { BuildMethodToIdMap(factory); } TypeDesc containerType = null; foreach (var method in _methodToTemplateIndex.Keys) { Debug.Assert(containerType == null || containerType == method.OwningType); containerType = method.OwningType; #if !DEBUG break; #endif } if (factory.Target.SupportsRelativePointers) { objData.EmitReloc(factory.NecessaryTypeSymbol(containerType), RelocType.IMAGE_REL_BASED_RELPTR32); } else { objData.EmitPointerReloc(factory.NecessaryTypeSymbol(containerType)); } List <KeyValuePair <MethodDesc, int> > sortedList = new List <KeyValuePair <MethodDesc, int> >(_methodToTemplateIndex); sortedList.Sort((firstEntry, secondEntry) => firstEntry.Value.CompareTo(secondEntry.Value)); for (int i = 0; i < sortedList.Count; i++) { var nameAndSig = factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(sortedList[i].Key)); if (factory.Target.SupportsRelativePointers) { objData.EmitInt(nameAndSig.SavedVertex.VertexOffset); objData.EmitReloc(factory.MethodEntrypoint(sortedList[i].Key), RelocType.IMAGE_REL_BASED_RELPTR32); } else { objData.EmitNaturalInt(nameAndSig.SavedVertex.VertexOffset); objData.EmitPointerReloc(factory.MethodEntrypoint(sortedList[i].Key)); } } _endSymbol.SetSymbolOffset(objData.CountBytes); objData.AddSymbol(_endSymbol); return(objData.ToObjectData()); }
public override void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation, GenericDictionaryNode dictionary) { Debug.Assert(false, "CallingConventionConverterLookupResult contents should only be generated into generic dictionaries at runtime"); builder.EmitNaturalInt(0); }
protected override void GetElementDataForNodes(ref ObjectDataBuilder builder, NodeFactory factory, bool relocsOnly) { if (relocsOnly) { return; } // The interface dispatch cell has an alignment requirement of 2 * [Pointer size] as part of the // synchronization mechanism of the two values in the runtime. builder.RequireInitialAlignment(factory.Target.PointerSize * 2); // This number chosen to be high enough that the cost of recording slot numbers is cheap. const int InterfaceDispatchCellRunLength = 32; const int NoSlot = -1; // // We emit the individual dispatch cells in groups. The purpose of the grouping is to save // us the number of slots we need to emit. The grouping looks like this: // // DispatchCell1 // DispatchCell2 // ... // DispatchCellN // Null // Slot of the above dispatch cells // int runLength = 0; int currentSlot = NoSlot; foreach (InterfaceDispatchCellNode node in NodesList) { MethodDesc targetMethod = node.TargetMethod; int targetSlot = VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, targetMethod, targetMethod.OwningType); if (currentSlot == NoSlot) { // This is the first dispatch cell we're emitting currentSlot = targetSlot; } else if (currentSlot != targetSlot || runLength == InterfaceDispatchCellRunLength) { // Make sure we are sorted Debug.Assert(targetSlot >= currentSlot); // End the run of dispatch cells builder.EmitZeroPointer(); builder.EmitNaturalInt(currentSlot); currentSlot = targetSlot; runLength = 0; } node.InitializeOffsetFromBeginningOfArray(builder.CountBytes); node.EncodeData(ref builder, factory, relocsOnly); builder.AddSymbol(node); runLength++; } if (runLength > 0) { // End the run of dispatch cells builder.EmitZeroPointer(); builder.EmitNaturalInt(currentSlot); } }