public static ObjectData GetDataForPreInitDataField( ISymbolDefinitionNode node, MetadataType _type, List <PreInitFieldInfo> sortedPreInitFields, int startOffset, NodeFactory factory, bool relocsOnly = false) { ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly); builder.RequireInitialAlignment(_type.GCStaticFieldAlignment.AsInt); int staticOffset = startOffset; int staticOffsetEnd = _type.GCStaticFieldSize.AsInt; int idx = 0; while (staticOffset < staticOffsetEnd) { PreInitFieldInfo fieldInfo = idx < sortedPreInitFields.Count ? sortedPreInitFields[idx] : null; int writeTo = staticOffsetEnd; if (fieldInfo != null) { writeTo = fieldInfo.Field.Offset.AsInt; } // Emit the zero before the next preinitField builder.EmitZeros(writeTo - staticOffset); staticOffset = writeTo; if (fieldInfo != null) { int count = builder.CountBytes; if (fieldInfo.Field.FieldType.IsValueType) { // Emit inlined data for value types fieldInfo.WriteData(ref builder, factory); } else { // Emit a pointer reloc to the frozen data for reference types builder.EmitPointerReloc(factory.SerializedFrozenArray(fieldInfo)); } staticOffset += builder.CountBytes - count; idx++; } } builder.AddSymbol(node); return(builder.ToObjectData()); }
public static string GetBaseSymbolName(ISymbolNode symbol, NameMangler nameMangler, bool objectWriterUse = false) { if (symbol is WebAssemblyMethodCodeNode) { return(symbol.GetMangledName(nameMangler)); } if (symbol is ObjectNode) { ObjectNode objNode = (ObjectNode)symbol; ISymbolDefinitionNode symbolDefNode = (ISymbolDefinitionNode)symbol; if (symbolDefNode.Offset == 0) { return(symbol.GetMangledName(nameMangler)); } else { return(symbol.GetMangledName(nameMangler) + "___REALBASE"); } } else if (symbol is ObjectAndOffsetSymbolNode) { ObjectAndOffsetSymbolNode objAndOffset = (ObjectAndOffsetSymbolNode)symbol; if (objAndOffset.Target is IHasStartSymbol) { ISymbolNode startSymbol = ((IHasStartSymbol)objAndOffset.Target).StartSymbol; if (startSymbol == symbol) { Debug.Assert(startSymbol.Offset == 0); return(symbol.GetMangledName(nameMangler)); } return(GetBaseSymbolName(startSymbol, nameMangler, objectWriterUse)); } return(GetBaseSymbolName((ISymbolNode)objAndOffset.Target, nameMangler, objectWriterUse)); } else if (symbol is EmbeddedObjectNode) { EmbeddedObjectNode embeddedNode = (EmbeddedObjectNode)symbol; return(GetBaseSymbolName(embeddedNode.ContainingNode.StartSymbol, nameMangler, objectWriterUse)); } else { return(null); } }
private static int GetNumericOffsetFromBaseSymbolValue(ISymbolNode symbol) { if (symbol is WebAssemblyMethodCodeNode) { return(0); } if (symbol is ObjectNode) { ISymbolDefinitionNode symbolDefNode = (ISymbolDefinitionNode)symbol; return(symbolDefNode.Offset); } else if (symbol is ObjectAndOffsetSymbolNode) { ObjectAndOffsetSymbolNode objAndOffset = (ObjectAndOffsetSymbolNode)symbol; ISymbolDefinitionNode symbolDefNode = (ISymbolDefinitionNode)symbol; if (objAndOffset.Target is IHasStartSymbol) { ISymbolNode startSymbol = ((IHasStartSymbol)objAndOffset.Target).StartSymbol; if (startSymbol == symbol) { Debug.Assert(symbolDefNode.Offset == 0); return(symbolDefNode.Offset); } return(symbolDefNode.Offset); } int baseOffset = GetNumericOffsetFromBaseSymbolValue((ISymbolNode)objAndOffset.Target); return(baseOffset + symbolDefNode.Offset); } else if (symbol is EmbeddedObjectNode) { EmbeddedObjectNode embeddedNode = (EmbeddedObjectNode)symbol; int baseOffset = GetNumericOffsetFromBaseSymbolValue(embeddedNode.ContainingNode.StartSymbol); return(baseOffset + ((ISymbolDefinitionNode)embeddedNode).Offset); } else { ThrowHelper.ThrowInvalidProgramException(); return(0); } }
public static ObjectData GetDataForPreInitDataField( ISymbolDefinitionNode node, MetadataType _type, List <PreInitFieldInfo> sortedPreInitFields, int startOffset, NodeFactory factory, bool relocsOnly = false) { ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly); builder.RequireInitialAlignment(_type.GCStaticFieldAlignment.AsInt); int staticOffset = startOffset; int staticOffsetEnd = _type.GCStaticFieldSize.AsInt; int idx = 0; while (staticOffset < staticOffsetEnd) { int writeTo = staticOffsetEnd; if (idx < sortedPreInitFields.Count) { writeTo = sortedPreInitFields[idx].Field.Offset.AsInt; } // Emit the zero before the next preinitField builder.EmitZeros(writeTo - staticOffset); staticOffset = writeTo; // Emit a pointer reloc to the frozen data if (idx < sortedPreInitFields.Count) { builder.EmitPointerReloc(factory.SerializedFrozenArray(sortedPreInitFields[idx])); idx++; staticOffset += factory.Target.PointerSize; } } builder.AddSymbol(node); return(builder.ToObjectData()); }
public void EmitPortableExecutable() { bool succeeded = false; try { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); PEHeaderBuilder headerBuilder; int? timeDateStamp; ISymbolNode r2rHeaderExportSymbol; Func <IEnumerable <Blob>, BlobContentId> peIdProvider = null; if (_nodeFactory.CompilationModuleGroup.IsCompositeBuildMode && _componentModule == null) { headerBuilder = PEHeaderProvider.Create( imageCharacteristics: Characteristics.ExecutableImage | Characteristics.Dll, dllCharacteristics: default(DllCharacteristics), Subsystem.Unknown, _nodeFactory.Target); peIdProvider = new Func <IEnumerable <Blob>, BlobContentId>(content => BlobContentId.FromHash(CryptographicHashProvider.ComputeSourceHash(content))); timeDateStamp = null; r2rHeaderExportSymbol = _nodeFactory.Header; } else { PEReader inputPeReader = (_componentModule != null ? _componentModule.PEReader : _nodeFactory.CompilationModuleGroup.CompilationModuleSet.First().PEReader); headerBuilder = PEHeaderProvider.Copy(inputPeReader.PEHeaders, _nodeFactory.Target); timeDateStamp = inputPeReader.PEHeaders.CoffHeader.TimeDateStamp; r2rHeaderExportSymbol = null; } Func <RuntimeFunctionsTableNode> getRuntimeFunctionsTable = null; if (_componentModule == null) { getRuntimeFunctionsTable = GetRuntimeFunctionsTable; } R2RPEBuilder r2rPeBuilder = new R2RPEBuilder( _nodeFactory.Target, headerBuilder, r2rHeaderExportSymbol, Path.GetFileName(_objectFilePath), getRuntimeFunctionsTable, _customPESectionAlignment, peIdProvider); NativeDebugDirectoryEntryNode nativeDebugDirectoryEntryNode = null; ISymbolDefinitionNode firstImportThunk = null; ISymbolDefinitionNode lastImportThunk = null; ObjectNode lastWrittenObjectNode = null; int nodeIndex = -1; foreach (var depNode in _nodes) { ++nodeIndex; ObjectNode node = depNode as ObjectNode; if (node == null) { continue; } if (node.ShouldSkipEmittingObjectNode(_nodeFactory)) { continue; } ObjectData nodeContents = node.GetData(_nodeFactory); if (node is NativeDebugDirectoryEntryNode nddeNode) { // There should be only one NativeDebugDirectoryEntry. Debug.Assert(nativeDebugDirectoryEntryNode == null); nativeDebugDirectoryEntryNode = nddeNode; } if (node is ImportThunk importThunkNode) { Debug.Assert(firstImportThunk == null || lastWrittenObjectNode is ImportThunk, "All the import thunks must be in single contiguous run"); if (firstImportThunk == null) { firstImportThunk = importThunkNode; } lastImportThunk = importThunkNode; } string name = null; if (_mapFileBuilder != null) { name = depNode.GetType().ToString(); int firstGeneric = name.IndexOf('['); if (firstGeneric < 0) { firstGeneric = name.Length; } int lastDot = name.LastIndexOf('.', firstGeneric - 1, firstGeneric); if (lastDot > 0) { name = name.Substring(lastDot + 1); } } EmitObjectData(r2rPeBuilder, nodeContents, nodeIndex, name, node.Section); lastWrittenObjectNode = node; if ((_generatePdbFile || _generatePerfMapFile) && node is MethodWithGCInfo methodNode) { _outputInfoBuilder.AddMethod(methodNode, nodeContents.DefinedSymbols[0]); } } r2rPeBuilder.SetCorHeader(_nodeFactory.CopiedCorHeaderNode, _nodeFactory.CopiedCorHeaderNode.Size); r2rPeBuilder.SetDebugDirectory(_nodeFactory.DebugDirectoryNode, _nodeFactory.DebugDirectoryNode.Size); if (firstImportThunk != null) { r2rPeBuilder.AddSymbolForRange(_nodeFactory.DelayLoadMethodCallThunks, firstImportThunk, lastImportThunk); } if (_nodeFactory.Win32ResourcesNode != null) { Debug.Assert(_nodeFactory.Win32ResourcesNode.Size != 0); r2rPeBuilder.SetWin32Resources(_nodeFactory.Win32ResourcesNode, _nodeFactory.Win32ResourcesNode.Size); } using (var peStream = File.Create(_objectFilePath)) { r2rPeBuilder.Write(peStream, timeDateStamp); if (_mapFileBuilder != null) { _mapFileBuilder.SetFileSize(peStream.Length); } // Compute MD5 hash of the output image and store that in the native DebugDirectory entry using (var md5Hash = MD5.Create()) { peStream.Seek(0, SeekOrigin.Begin); byte[] hash = md5Hash.ComputeHash(peStream); byte[] rsdsEntry = nativeDebugDirectoryEntryNode.GenerateRSDSEntryData(hash); int offsetToUpdate = r2rPeBuilder.GetSymbolFilePosition(nativeDebugDirectoryEntryNode); peStream.Seek(offsetToUpdate, SeekOrigin.Begin); peStream.Write(rsdsEntry); } } if (_outputInfoBuilder != null) { r2rPeBuilder.AddSections(_outputInfoBuilder); if (_generateMapFile) { string mapFileName = Path.ChangeExtension(_objectFilePath, ".map"); _mapFileBuilder.SaveMap(mapFileName); } if (_generateMapCsvFile) { string nodeStatsCsvFileName = Path.ChangeExtension(_objectFilePath, ".nodestats.csv"); string mapCsvFileName = Path.ChangeExtension(_objectFilePath, ".map.csv"); _mapFileBuilder.SaveCsv(nodeStatsCsvFileName, mapCsvFileName); } if (_generatePdbFile) { string path = _pdbPath; if (string.IsNullOrEmpty(path)) { path = Path.GetDirectoryName(_objectFilePath); } _symbolFileBuilder.SavePdb(path, _objectFilePath); } if (_generatePerfMapFile) { string path = _perfMapPath; if (string.IsNullOrEmpty(path)) { path = Path.GetDirectoryName(_objectFilePath); } _symbolFileBuilder.SavePerfMap(path, _objectFilePath); } if (_profileFileBuilder != null) { string path = Path.ChangeExtension(_objectFilePath, ".profile"); _profileFileBuilder.SaveProfile(path); } } succeeded = true; } finally { if (!succeeded) { // If there was an exception while generating the OBJ file, make sure we don't leave the unfinished // object file around. try { File.Delete(_objectFilePath); } catch { } } } }
public void AddSymbol(ISymbolDefinitionNode symbol) { _builder.AddSymbol(symbol); }
public void AddSymbol(ISymbolDefinitionNode node) { _definedSymbols.Add(node); }
public void AddMethod(MethodWithGCInfo method, ISymbolDefinitionNode symbol) { _methodSymbolMap.Add(symbol, method); }
public void AddNode(OutputNode node, ISymbolDefinitionNode symbol) { _nodes.Add(node); _nodeSymbolMap.Add(symbol, node); }