public override ObjectData GetData(NodeFactory factory, bool relocsOnly) { Debug.Assert(MethodHasAssociatedData(factory, _methodNode)); ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly); objData.RequireInitialAlignment(1); objData.AddSymbol(this); AssociatedDataFlags flags = AssociatedDataFlags.None; var flagsReservation = objData.ReserveByte(); ISpecialUnboxThunkNode unboxThunkNode = _methodNode as ISpecialUnboxThunkNode; if (unboxThunkNode != null && unboxThunkNode.IsSpecialUnboxingThunk) { flags |= AssociatedDataFlags.HasUnboxingStubTarget; objData.EmitReloc(unboxThunkNode.GetUnboxingThunkTarget(factory), RelocType.IMAGE_REL_BASED_RELPTR32); } objData.EmitByte(flagsReservation, (byte)flags); 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 ISymbolNode[] { 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); objData.EmitReloc(factory.NecessaryTypeSymbol(_dynamicInvokeMethodContainerType), RelocType.IMAGE_REL_BASED_RELPTR32); 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++) { Debug.Assert(sortedList[i].Value * 4 == objData.CountBytes); var nameAndSig = factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(sortedList[i].Key)); objData.EmitInt(nameAndSig.SavedVertex.VertexOffset); objData.EmitReloc(factory.MethodEntrypoint(sortedList[i].Key), RelocType.IMAGE_REL_BASED_RELPTR32); } _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, relocsOnly); objData.RequireInitialPointerAlignment(); objData.AddSymbol(this); objData.EmitReloc(factory.ThreadStaticsRegion.StartSymbol, RelocType.IMAGE_REL_SECREL); return(objData.ToObjectData()); }
public override void EncodeData(ref ObjectDataBuilder builder, NodeFactory factory, bool relocsOnly) { int gcFieldCount = 0; int startIndex = 0; int numSeries = 0; for (int i = 0; i < _gcMap.Size; i++) { // Skip non-GC fields if (!_gcMap[i]) { continue; } gcFieldCount++; if (i == 0 || !_gcMap[i - 1]) { // The cell starts a new series startIndex = i; } if (i == _gcMap.Size - 1 || !_gcMap[i + 1]) { // The cell ends the current series builder.EmitInt(gcFieldCount); if (_isThreadStatic) { builder.EmitReloc((factory as UtcNodeFactory).TlsStart, RelocType.IMAGE_REL_SECREL, startIndex * factory.Target.PointerSize); } else { builder.EmitReloc(factory.TypeGCStaticsSymbol(_type), RelocType.IMAGE_REL_BASED_RELPTR32, startIndex * factory.Target.PointerSize); } gcFieldCount = 0; numSeries++; } } Debug.Assert(numSeries == NumSeries); }
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 })); } // Zero out the dictionary so that we AV if someone tries to insert after we're done. _insertedSymbolsDictionary = null; var builder = new ObjectDataBuilder(factory, relocsOnly); foreach (SymbolAndDelta symbolAndDelta in _insertedSymbols) { if (factory.Target.Abi == TargetAbi.ProjectN) { int delta = symbolAndDelta.Delta; if (symbolAndDelta.Symbol.RepresentsIndirectionCell) { delta = (int)((uint)delta | IndirectionConstants.RVAPointsToIndirection); } builder.EmitReloc(symbolAndDelta.Symbol, RelocType.IMAGE_REL_BASED_ADDR32NB, delta); } else if (factory.Target.SupportsRelativePointers) { // TODO: set low bit if the linkage of the symbol is IAT_PVALUE. builder.EmitReloc(symbolAndDelta.Symbol, RelocType.IMAGE_REL_BASED_RELPTR32, symbolAndDelta.Delta); } else { builder.EmitPointerReloc(symbolAndDelta.Symbol, symbolAndDelta.Delta); } } _endSymbol.SetSymbolOffset(builder.CountBytes); builder.AddSymbol(this); builder.AddSymbol(_endSymbol); return(builder.ToObjectData()); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly) { ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly); objData.RequireInitialAlignment(4); objData.AddSymbol(this); if (BuildSealedVTableSlots(factory, relocsOnly)) { for (int i = 0; i < _sealedVTableEntries.Count; i++) { MethodDesc canonImplMethod = _sealedVTableEntries[i].GetCanonMethodTarget(CanonicalFormKind.Specific); objData.EmitReloc(factory.MethodEntrypoint(canonImplMethod, _sealedVTableEntries[i].OwningType.IsValueType), RelocType.IMAGE_REL_BASED_RELPTR32); } } 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 ISymbolDefinitionNode[] { this })); } var builder = new ObjectDataBuilder(factory, relocsOnly); builder.RequireInitialPointerAlignment(); builder.AddSymbol(this); // // Entries in the export table need to be sorted by ordinals. When compiling using baseline TOC files, we reuse // the ordinals from the baseline for sorting, otherwise we start assigning new sequential ordinals. Export entries that do // not exist in the baseline will get new sequential ordinals, but for determinism, they are also pre-sorted using the // CompilerComparer logic // ISortableSymbolNode[] symbolNodes = new ISortableSymbolNode[_exportableSymbols.Count]; _exportableSymbols.CopyTo(symbolNodes); Array.Sort(symbolNodes, new CompilerComparer()); builder.EmitInt(1); // Export table version 1 builder.EmitInt(symbolNodes.Length); // Count of exported symbols in this table uint index = GetInitialExportOrdinal == null ? 1 : GetInitialExportOrdinal(); Dictionary <uint, ISortableSymbolNode> symbolsOridnalMap = new Dictionary <uint, ISortableSymbolNode>(); foreach (ISortableSymbolNode symbol in symbolNodes) { uint indexUsed = ReportExportedItem.Invoke(index, (IExportableSymbolNode)symbol); symbolsOridnalMap.Add(indexUsed, symbol); index += (indexUsed == index ? (uint)1 : 0); } foreach (uint ordinal in symbolsOridnalMap.Keys.OrderBy(o => o)) { builder.EmitReloc(symbolsOridnalMap[ordinal], RelocType.IMAGE_REL_BASED_REL32); } return(builder.ToObjectData()); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { // The dependency tracking of this node currently does nothing because the data emission relies // the set of compiled methods which has an incomplete state during dependency tracking. if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this })); } ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly); objData.RequireInitialPointerAlignment(); objData.AddSymbol(this); objData.AddSymbol(_endSymbol); foreach (var mappingEntry in factory.MetadataManager.GetStackTraceMapping(factory)) { objData.EmitReloc(factory.MethodEntrypoint(mappingEntry.Entity), RelocType.IMAGE_REL_BASED_RELPTR32); objData.EmitInt(mappingEntry.MetadataHandle); } _endSymbol.SetSymbolOffset(objData.CountBytes); 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 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 })); } ObjectDataBuilder objDataBuilder = new ObjectDataBuilder(factory, relocsOnly); // Emit number of dictionaries in table objDataBuilder.AddSymbol(this); IReadOnlyCollection <GenericDictionaryNode> dictionariesEmitted = factory.MetadataManager.GetCompiledGenericDictionaries(); objDataBuilder.EmitInt(dictionariesEmitted.Count); DebugInfoBlob signatureData = new DebugInfoBlob(); BlobBuilder signatureBlobBuilder = new BlobBuilder(); BlobBuilder signatureLenBuilder = new BlobBuilder(); ManagedBinaryEmitter pseudoAssembly = factory.WindowsDebugData.DebugPseudoAssemblySection.PseudoAssembly; foreach (GenericDictionaryNode dictionary in dictionariesEmitted) { objDataBuilder.EmitReloc(dictionary, RelocType.IMAGE_REL_BASED_ADDR32NB); objDataBuilder.EmitUInt(signatureData.Size()); signatureBlobBuilder.Clear(); int typeDictLen = dictionary.TypeInstantiation.IsNull ? 0 : dictionary.TypeInstantiation.Length; int methodDictLen = dictionary.MethodInstantiation.IsNull ? 0 : dictionary.MethodInstantiation.Length; signatureBlobBuilder.WriteCompressedInteger(typeDictLen + methodDictLen); if (typeDictLen != 0) { foreach (TypeDesc type in dictionary.TypeInstantiation) { pseudoAssembly.EncodeSignatureForType(type, signatureBlobBuilder); } } if (methodDictLen != 0) { foreach (TypeDesc type in dictionary.MethodInstantiation) { pseudoAssembly.EncodeSignatureForType(type, signatureBlobBuilder); } } int blobSize = signatureBlobBuilder.Count; signatureLenBuilder.Clear(); signatureLenBuilder.WriteCompressedInteger(blobSize); // Prepend the signature data with a length signatureData.WriteBuffer(signatureLenBuilder); // And then attach the actual signature data signatureData.WriteBuffer(signatureBlobBuilder); } // Attach signature information to end after all of the rva/offset pairs objDataBuilder.EmitBytes(signatureData.ToArray()); return(objDataBuilder.ToObjectData()); }
public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly) { dataBuilder.RequireInitialPointerAlignment(); dataBuilder.EmitReloc(Target, RelocType.IMAGE_REL_BASED_ADDR32NB); }
private ObjectNode.ObjectData EncodeEHInfo() { var builder = new ObjectDataBuilder(); builder.Alignment = 1; // TODO: Filter out duplicate clauses builder.EmitCompressedUInt((uint)_ehClauses.Length); for (int i = 0; i < _ehClauses.Length; i++) { var clause = _ehClauses[i]; RhEHClauseKind clauseKind; if (((clause.Flags & CORINFO_EH_CLAUSE_FLAGS.CORINFO_EH_CLAUSE_FAULT) != 0) || ((clause.Flags & CORINFO_EH_CLAUSE_FLAGS.CORINFO_EH_CLAUSE_FINALLY) != 0)) { clauseKind = RhEHClauseKind.RH_EH_CLAUSE_FAULT; } else if ((clause.Flags & CORINFO_EH_CLAUSE_FLAGS.CORINFO_EH_CLAUSE_FILTER) != 0) { clauseKind = RhEHClauseKind.RH_EH_CLAUSE_FILTER; } else { clauseKind = RhEHClauseKind.RH_EH_CLAUSE_TYPED; } builder.EmitCompressedUInt((uint)clause.TryOffset); // clause.TryLength returned by the JIT is actually end offset... // https://github.com/dotnet/coreclr/issues/3585 int tryLength = (int)clause.TryLength - (int)clause.TryOffset; builder.EmitCompressedUInt((uint)((tryLength << 2) | (int)clauseKind)); switch (clauseKind) { case RhEHClauseKind.RH_EH_CLAUSE_TYPED: { builder.EmitCompressedUInt(clause.HandlerOffset); var methodIL = (MethodIL)HandleToObject((IntPtr)_methodScope); var type = (TypeDesc)methodIL.GetObject((int)clause.ClassTokenOrOffset); var typeSymbol = _compilation.NodeFactory.NecessaryTypeSymbol(type); RelocType rel = (_compilation.NodeFactory.Target.IsWindows) ? RelocType.IMAGE_REL_BASED_ABSOLUTE : RelocType.IMAGE_REL_BASED_REL32; builder.EmitReloc(typeSymbol, rel); } break; case RhEHClauseKind.RH_EH_CLAUSE_FAULT: builder.EmitCompressedUInt(clause.HandlerOffset); break; case RhEHClauseKind.RH_EH_CLAUSE_FILTER: builder.EmitCompressedUInt(clause.HandlerOffset); builder.EmitCompressedUInt(clause.ClassTokenOrOffset); break; } } return builder.ToObjectData(); }
public override void EncodeData(ref ObjectDataBuilder builder, NodeFactory factory, bool relocsOnly) { builder.EmitReloc(factory.TypeThreadStaticsSymbol(_type), RelocType.IMAGE_REL_SECREL); }