public void WriteContentToStream() { var builder = new BlobBuilder(16); for (int i = 0; i < 20; i++) { builder.WriteByte((byte)i); } var stream = new MemoryStream(); builder.WriteContentTo(stream); AssertEx.Equal(new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 }, stream.ToArray()); builder.WriteByte(0xff); builder.WriteContentTo(stream); AssertEx.Equal(new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0xff, }, stream.ToArray()); }
public void WriteContentToBlobBuilder() { var builder1 = new BlobBuilder(16); for (int i = 0; i < 20; i++) { builder1.WriteByte((byte)i); } var builder2 = new BlobBuilder(256); builder1.WriteContentTo(builder2); AssertEx.Equal(new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 }, builder2.ToArray()); builder1.WriteByte(0xff); builder1.WriteContentTo(builder2); AssertEx.Equal(new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0xff, }, builder2.ToArray()); }
public unsafe void Write_Errors() { var builder = new BlobBuilder(16); Assert.Throws <ArgumentNullException>(() => builder.WriteUTF16((char[])null)); Assert.Throws <ArgumentNullException>(() => builder.WriteUTF16((string)null)); Assert.Throws <ArgumentNullException>(() => builder.WriteUTF8(null, allowUnpairedSurrogates: true)); Assert.Throws <ArgumentNullException>(() => builder.WriteUTF8(null, allowUnpairedSurrogates: true)); Assert.Throws <ArgumentNullException>(() => builder.TryWriteBytes((Stream)null, 0)); Assert.Throws <ArgumentNullException>(() => builder.WriteBytes(null)); Assert.Throws <ArgumentNullException>(() => builder.WriteBytes(null, 0, 0)); Assert.Throws <ArgumentNullException>(() => builder.WriteBytes((byte *)null, 0)); Assert.Throws <ArgumentNullException>(() => builder.WriteBytes(default(ImmutableArray <byte>))); Assert.Throws <ArgumentNullException>(() => builder.WriteBytes(default(ImmutableArray <byte>), 0, 0)); var bw = default(BlobWriter); Assert.Throws <ArgumentNullException>(() => builder.WriteContentTo(ref bw)); Assert.Throws <ArgumentNullException>(() => builder.WriteContentTo((Stream)null)); Assert.Throws <ArgumentNullException>(() => builder.WriteContentTo((BlobBuilder)null)); Assert.Throws <ArgumentOutOfRangeException>(() => builder.TryWriteBytes(new MemoryStream(), -1)); Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteBytes(0, -1)); Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteBytes(new byte[] { }, 1, 0)); Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteBytes(new byte[] { }, 0, 1)); Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteBytes(new byte[] { }, 0, -1)); Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteBytes(ImmutableArray <byte> .Empty, 1, 0)); Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteBytes(ImmutableArray <byte> .Empty, 0, 1)); Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteBytes(ImmutableArray <byte> .Empty, 1, -1)); }
public void WriteContentToStream_Errors() { var builder = new BlobBuilder(16); builder.WriteByte(1); Assert.Throws <ArgumentNullException>(() => builder.WriteContentTo((Stream)null)); Assert.Throws <NotSupportedException>(() => builder.WriteContentTo(new MemoryStream(new byte[] { 1 }, writable: false))); }
private static void WritePEImage( Stream peStream, MetadataBuilder metadataBuilder, BlobBuilder ilBuilder, MethodDefinitionHandle entryPointHandle ) { // Create executable with the managed metadata from the specified MetadataBuilder. var peHeaderBuilder = new PEHeaderBuilder( imageCharacteristics: Characteristics.ExecutableImage | Characteristics.Dll ); var peBuilder = new ManagedPEBuilder( peHeaderBuilder, new MetadataRootBuilder(metadataBuilder), ilBuilder, entryPoint: entryPointHandle, flags: CorFlags.ILOnly, deterministicIdProvider: content => s_contentId); // Write executable into the specified stream. var peBlob = new BlobBuilder(); BlobContentId contentId = peBuilder.Serialize(peBlob); peBlob.WriteContentTo(peStream); }
private static void WritePEImage( Stream peStream, MetadataBuilder metadataBuilder, BlobBuilder ilBuilder, MethodDefinitionHandle entryPointHandle, Blob mvidFixup = default(Blob), byte[] privateKeyOpt = null) { var peBuilder = new ManagedPEBuilder( entryPointHandle.IsNil ? PEHeaderBuilder.CreateLibraryHeader() : PEHeaderBuilder.CreateExecutableHeader(), new MetadataRootBuilder(metadataBuilder), ilBuilder, entryPoint: entryPointHandle, flags: CorFlags.ILOnly | (privateKeyOpt != null ? CorFlags.StrongNameSigned : 0), deterministicIdProvider: content => s_contentId); var peBlob = new BlobBuilder(); var contentId = peBuilder.Serialize(peBlob); if (!mvidFixup.IsDefault) { new BlobWriter(mvidFixup).WriteGuid(contentId.Guid); } if (privateKeyOpt != null) { peBuilder.Sign(peBlob, content => SigningUtilities.CalculateRsaSignature(content, privateKeyOpt)); } peBlob.WriteContentTo(peStream); }
public PermissionSetEncoder AddPermission(string typeName, BlobBuilder arguments) { Builder.WriteSerializedString(typeName); Builder.WriteCompressedInteger(arguments.Count); arguments.WriteContentTo(Builder); return(new PermissionSetEncoder(Builder)); }
public unsafe void NativeResources() { var peStream = new MemoryStream(); var ilBuilder = new BlobBuilder(); var metadataBuilder = new MetadataBuilder(); var peBuilder = new ManagedPEBuilder( PEHeaderBuilder.CreateLibraryHeader(), new MetadataRootBuilder(metadataBuilder), ilBuilder, nativeResources: new TestResourceSectionBuilder(), deterministicIdProvider: content => s_contentId); var peBlob = new BlobBuilder(); var contentId = peBuilder.Serialize(peBlob); peBlob.WriteContentTo(peStream); peStream.Position = 0; var peReader = new PEReader(peStream); var sectionHeader = peReader.PEHeaders.SectionHeaders.Single(s => s.Name == ".rsrc"); var image = peReader.GetEntireImage(); var reader = new BlobReader(image.Pointer + sectionHeader.PointerToRawData, sectionHeader.SizeOfRawData); Assert.Equal(0x12345678, reader.ReadInt32()); Assert.Equal(sectionHeader.PointerToRawData, reader.ReadInt32()); Assert.Equal(sectionHeader.VirtualAddress, reader.ReadInt32()); }
private static void SerializeHelperLibrary(string assemblyName, string rootNamespace, string path) { var ilBuilder = new BlobBuilder(); var metadataBuilder = new MetadataBuilder(); EmitHelperLibraryMetadata(assemblyName, rootNamespace, metadataBuilder, ilBuilder); // Following code does not work: // // var peHeaderBuilder = PEHeaderBuilder.CreateLibraryHeader(); // // PEHeaderBuilder.CreateLibraryHeader() method does not set Characteristics.ExecutableImage bit. // If we serialize an assembly without setting it, .NET Core runtime refuses to load. // So, we explicitly set it by using PEHeaderBuilder constructor. var peHeaderBuilder = new PEHeaderBuilder(imageCharacteristics: Characteristics.ExecutableImage | Characteristics.Dll); var peBuilder = new ManagedPEBuilder(peHeaderBuilder, new MetadataRootBuilder(metadataBuilder), ilBuilder); var peBlob = new BlobBuilder(); peBuilder.Serialize(peBlob); using (var stream = File.Create(path)) { peBlob.WriteContentTo(stream); } }
public override bool Execute() { if (string.IsNullOrEmpty(RuntimeConfigFile)) { Log.LogError($"'{nameof(RuntimeConfigFile)}' is required."); } if (string.IsNullOrEmpty(OutputFile)) { Log.LogError($"'{nameof(OutputFile)}' is required."); } Dictionary <string, string> configProperties = ConvertInputToDictionary(RuntimeConfigFile); if (ReservedProperties.Length != 0) { CheckDuplicateProperties(configProperties, ReservedProperties); } var blobBuilder = new BlobBuilder(); ConvertDictionaryToBlob(configProperties, blobBuilder); using var stream = File.OpenWrite(OutputFile); blobBuilder.WriteContentTo(stream); return(!Log.HasLoggedErrors); }
public PermissionSetEncoder <T> AddPermission(string typeName, BlobBuilder arguments) { Builder.WriteSerializedString(typeName); //return new NamedArgumentsBuilder<T>(_continuation, propertyCount, CountFormat.Compressed); Builder.WriteCompressedInteger((uint)arguments.Count); arguments.WriteContentTo(Builder); return(new PermissionSetEncoder <T>(_continuation, _count - 1)); }
/// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception> public void WriteBytes(BlobBuilder source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } source.WriteContentTo(ref this); }
/// <summary> /// Relocate the produced PE file and output the result into a given stream. /// </summary> /// <param name="peFile">Blob builder representing the complete PE file</param> /// <param name="defaultImageBase">Default load address for the image</param> /// <param name="corHeaderBuilder">COR header</param> /// <param name="corHeaderFileOffset">File position of the COR header</param> /// <param name="outputStream">Stream to receive the relocated PE file</param> public void RelocateOutputFile( BlobBuilder peFile, ulong defaultImageBase, CorHeaderBuilder corHeaderBuilder, int corHeaderFileOffset, Stream outputStream) { RelocationHelper relocationHelper = new RelocationHelper(outputStream, defaultImageBase, peFile); if (corHeaderBuilder != null) { relocationHelper.CopyToFilePosition(corHeaderFileOffset); UpdateCorHeader(corHeaderBuilder); BlobBuilder corHeaderBlob = new BlobBuilder(); corHeaderBuilder.WriteTo(corHeaderBlob); int writtenSize = corHeaderBlob.Count; corHeaderBlob.WriteContentTo(outputStream); relocationHelper.AdvanceOutputPos(writtenSize); // Just skip the bytes that were emitted by the COR header writer byte[] skipBuffer = new byte[writtenSize]; relocationHelper.CopyBytesToBuffer(skipBuffer, writtenSize); } // Traverse relocations in all sections in their RVA order foreach (Section section in _sections.OrderBy((sec) => sec.RVAWhenPlaced)) { int rvaToFilePosDelta = section.FilePosWhenPlaced - section.RVAWhenPlaced; foreach (ObjectDataRelocations objectDataRelocs in section.Relocations) { foreach (Relocation relocation in objectDataRelocs.Relocs) { // Process a single relocation int relocationRVA = section.RVAWhenPlaced + objectDataRelocs.Offset + relocation.Offset; int relocationFilePos = relocationRVA + rvaToFilePosDelta; // Flush parts of PE file before the relocation to the output stream relocationHelper.CopyToFilePosition(relocationFilePos); // Look up relocation target SymbolTarget relocationTarget = _symbolMap[relocation.Target]; Section targetSection = _sections[relocationTarget.SectionIndex]; int targetRVA = targetSection.RVAWhenPlaced + relocationTarget.Offset; // Apply the relocation relocationHelper.ProcessRelocation(relocation.RelocType, relocationRVA, targetRVA); } } } // Flush remaining PE file blocks after the last relocation relocationHelper.CopyRestOfFile(); }
public void SerializeToStream(Stream peStream) { var peHeaderBuilder = new PEHeaderBuilder(); var peBuilder = new ManagedPEBuilder(peHeaderBuilder, new MetadataRootBuilder(_metadataBuilder), _ilBuilder, deterministicIdProvider: content => s_contentId); var peBlob = new BlobBuilder(); var contentId = peBuilder.Serialize(peBlob); new BlobWriter(_mvidFixup).WriteGuid(contentId.Guid); peBlob.WriteContentTo(peStream); }
private static void WritePEImage(Stream peStream, MetadataBuilder metadataBuilder, BlobBuilder ilBuilder, MethodDefinitionHandle entryPointHandle) { var mappedFieldDataBuilder = new BlobBuilder(); var managedResourceDataBuilder = new BlobBuilder(); var peBuilder = new PEBuilder( machine: 0, sectionAlignment: 0x2000, fileAlignment: 0x200, imageBase: 0x00400000, majorLinkerVersion: 0x30, // (what is ref.emit using?) minorLinkerVersion: 0, majorOperatingSystemVersion: 4, minorOperatingSystemVersion: 0, majorImageVersion: 0, minorImageVersion: 0, majorSubsystemVersion: 4, minorSubsystemVersion: 0, subsystem: Subsystem.WindowsCui, dllCharacteristics: DllCharacteristics.DynamicBase | DllCharacteristics.NxCompatible | DllCharacteristics.NoSeh | DllCharacteristics.TerminalServerAware, imageCharacteristics: entryPointHandle.IsNil ? Characteristics.Dll : Characteristics.ExecutableImage, sizeOfStackReserve: 0x00100000, sizeOfStackCommit: 0x1000, sizeOfHeapReserve: 0x00100000, sizeOfHeapCommit: 0x1000); var peDirectoriesBuilder = new PEDirectoriesBuilder(); peBuilder.AddManagedSections( peDirectoriesBuilder, new TypeSystemMetadataSerializer(metadataBuilder, "v4.0.30319", isMinimalDelta: false), ilBuilder, mappedFieldDataBuilder, managedResourceDataBuilder, nativeResourceSectionSerializer: null, strongNameSignatureSize: 0, entryPoint: entryPointHandle, pdbPathOpt: null, nativePdbContentId: default(ContentId), portablePdbContentId: default(ContentId), corFlags: CorFlags.ILOnly); var peBlob = new BlobBuilder(); ContentId peContentId; peBuilder.Serialize(peBlob, peDirectoriesBuilder, out peContentId); peBlob.WriteContentTo(peStream); }
public void EmitToStream(Stream stream) { foreach (var typeDef in _emittedTypes) { MethodDefinitionHandle?firstMethodHandle = null; foreach (var methodDef in typeDef.Methods) { int bodyOffset = _methodBodyStream.AddMethodBody(methodDef.Code); BlobHandle signature = MakeSignatureHandle(methodDef.Signature); MethodDefinitionHandle methodHandle = _metadataBuilder.AddMethodDefinition( MethodAttributes.PrivateScope | MethodAttributes.Static, MethodImplAttributes.IL | MethodImplAttributes.Managed, _metadataBuilder.GetOrAddString(methodDef.Name), signature, bodyOffset, parameterList: default(ParameterHandle)); if (firstMethodHandle == null) { firstMethodHandle = methodHandle; } } _metadataBuilder.AddTypeDefinition( default(TypeAttributes), default(StringHandle), _metadataBuilder.GetOrAddString(typeDef.Name), typeDef.IsValueType ? MakeTypeRefHandle(_typeSystemContext.GetWellKnownType(WellKnownType.ValueType)) : MakeTypeRefHandle(_typeSystemContext.GetWellKnownType(WellKnownType.Object)), fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: firstMethodHandle.Value); } BlobBuilder peBlob = new BlobBuilder(); new ManagedPEBuilder(PEHeaderBuilder.CreateLibraryHeader(), new MetadataRootBuilder(_metadataBuilder), _methodBodyStream.Builder).Serialize(peBlob); peBlob.WriteContentTo(stream); // Clear some variables to catch any caller trying to emit data after writing the output file _emittedTypes = null; _metadataBuilder = null; _methodBodyStream = default(MethodBodyStreamEncoder); }
private ImmutableArray <Diagnostic> EmitAssembly(BoundProgram program) { var header = new PEHeaderBuilder(); var metadataBuilder = new MetadataBuilder(); var metadataRootBuilder = new MetadataRootBuilder(metadataBuilder); var blobBuilder = new BlobBuilder(); var peBuilder = new ManagedPEBuilder(header, metadataRootBuilder, blobBuilder); peBuilder.Serialize(blobBuilder); // TODO: Produce portable assembly contents here using (var stream = new StreamWriter(program.PackageName + ".dll")) { blobBuilder.WriteContentTo(stream.BaseStream); } return(ImmutableArray <Diagnostic> .Empty); }
private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) { Logger.Log("Writing " + outputFile); var managedPeBuilder = new ManagedPEBuilder( new PEHeaderBuilder( machine: Machine.I386, imageCharacteristics: Characteristics.ExecutableImage | Characteristics.Dll | Characteristics.Bit32Machine), new MetadataRootBuilder(metadataBuilder, "WindowsRuntime 1.4"), new BlobBuilder(), flags: CorFlags.ILOnly); var peBlob = new BlobBuilder(); managedPeBuilder.Serialize(peBlob); using var fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write); peBlob.WriteContentTo(fs); }
/// <summary> /// Relocate the contents of the metadata blob, which contains two tables with embedded RVAs. /// </summary> public void RelocateMetadataBlob(Stream outputStream) { long initialStreamLength = outputStream.Length; outputStream.Position = 0; // The output is already a valid PE file so use that to access the output metadata blob PEReader peReader = new PEReader(outputStream); // Create a patched up metadata blob whose RVAs are correct w.r.t the output image BlobBuilder relocatedMetadataBlob = MetadataRvaFixupBuilder.Relocate(peReader, RelocateRVA); Debug.Assert(_metadataFileOffset > 0); outputStream.Position = _metadataFileOffset; // Splice the new metadata blob back into the output stream relocatedMetadataBlob.WriteContentTo(outputStream); Debug.Assert(initialStreamLength == outputStream.Length); }
public PermissionSetEncoder AddPermission(string typeName, BlobBuilder encodedArguments) { if (typeName is null) { Throw.ArgumentNull(nameof(typeName)); } if (encodedArguments is null) { Throw.ArgumentNull(nameof(encodedArguments)); } if (encodedArguments.Count > BlobWriterImpl.MaxCompressedIntegerValue) { Throw.BlobTooLarge(nameof(encodedArguments)); } Builder.WriteSerializedString(typeName); Builder.WriteCompressedInteger(encodedArguments.Count); encodedArguments.WriteContentTo(Builder); return(this); }
private static void WritePEImage( Stream peStream, MetadataBuilder metadataBuilder, BlobBuilder ilBuilder, MethodDefinitionHandle entryPointHandle, Blob mvidFixup = default(Blob), byte[] privateKeyOpt = null, bool publicSigned = false, Machine machine = 0, BlobBuilder?mappedFieldData = null) { var peHeaderBuilder = new PEHeaderBuilder(imageCharacteristics: entryPointHandle.IsNil ? Characteristics.Dll : Characteristics.ExecutableImage, machine: machine); var peBuilder = new ManagedPEBuilder( peHeaderBuilder, new MetadataRootBuilder(metadataBuilder), ilBuilder, entryPoint: entryPointHandle, flags: CorFlags.ILOnly | (privateKeyOpt != null || publicSigned ? CorFlags.StrongNameSigned : 0), deterministicIdProvider: content => s_contentId, mappedFieldData: mappedFieldData); var peBlob = new BlobBuilder(); var contentId = peBuilder.Serialize(peBlob); if (!mvidFixup.IsDefault) { new BlobWriter(mvidFixup).WriteGuid(contentId.Guid); } if (privateKeyOpt != null) { peBuilder.Sign(peBlob, content => SigningUtilities.CalculateRsaSignature(content, privateKeyOpt)); } peBlob.WriteContentTo(peStream); }
private static void WritePEImage( Stream peStream, MetadataBuilder metadataBuilder, BlobBuilder ilBuilder, MethodDefinitionHandle entryPointHandle, byte[] privateKeyOpt = null) { var mappedFieldDataBuilder = new BlobBuilder(); var managedResourceDataBuilder = new BlobBuilder(); var peBuilder = new ManagedPEBuilder( entryPointHandle.IsNil ? PEHeaderBuilder.CreateLibraryHeader() : PEHeaderBuilder.CreateExecutableHeader(), new TypeSystemMetadataSerializer(metadataBuilder, "v4.0.30319", isMinimalDelta: false), ilBuilder, mappedFieldDataBuilder, managedResourceDataBuilder, nativeResourceSectionSerializer: null, strongNameSignatureSize: 128, entryPoint: entryPointHandle, pdbPathOpt: null, nativePdbContentId: default(ContentId), portablePdbContentId: default(ContentId), corFlags: CorFlags.ILOnly | (privateKeyOpt != null ? CorFlags.StrongNameSigned : 0), deterministicIdProvider: content => s_contentId); var peBlob = new BlobBuilder(); ContentId contentId; peBuilder.Serialize(peBlob, out contentId); if (privateKeyOpt != null) { peBuilder.Sign(peBlob, content => SigningUtilities.CalculateRsaSignature(content, privateKeyOpt)); } peBlob.WriteContentTo(peStream); }
public override bool Execute() { if (string.IsNullOrEmpty(RuntimeConfigFile)) { Log.LogError($"'{nameof(RuntimeConfigFile)}' is required."); return(false); } if (string.IsNullOrEmpty(OutputFile)) { Log.LogError($"'{nameof(OutputFile)}' is required."); return(false); } if (!TryConvertInputToDictionary(RuntimeConfigFile, out Dictionary <string, string>?configProperties)) { return(false); } if (RuntimeConfigReservedProperties.Length != 0) { if (!CheckReservedProperties(configProperties, RuntimeConfigReservedProperties)) { return(false); } } var blobBuilder = new BlobBuilder(); ConvertDictionaryToBlob(configProperties, blobBuilder); Directory.CreateDirectory(Path.GetDirectoryName(OutputFile !) !); using var stream = File.OpenWrite(OutputFile); blobBuilder.WriteContentTo(stream); return(!Log.HasLoggedErrors); }
private void WriteImportTable(Stream peStream, int importTableRva, int importAddressTableRva) { var writer = new BlobBuilder(SizeOfImportTable); int ilRVA = importTableRva + 40; int hintRva = ilRVA + (_is32bit ? 12 : 16); int nameRva = hintRva + 12 + 2; // Import table writer.WriteUInt32((uint)ilRVA); // 4 writer.WriteUInt32(0); // 8 writer.WriteUInt32(0); // 12 writer.WriteUInt32((uint)nameRva); // 16 writer.WriteUInt32((uint)importAddressTableRva); // 20 writer.WriteBytes(0, 20); // 40 // Import Lookup table if (_is32bit) { writer.WriteUInt32((uint)hintRva); // 44 writer.WriteUInt32(0); // 48 writer.WriteUInt32(0); // 52 } else { writer.WriteUInt64((uint)hintRva); // 48 writer.WriteUInt64(0); // 56 } // Hint table writer.WriteUInt16(0); // Hint 54|58 foreach (char ch in CorEntryPointName) { writer.WriteByte((byte)ch); // 65|69 } writer.WriteByte(0); // 66|70 Debug.Assert(writer.Count == SizeOfImportTable); writer.WriteContentTo(peStream); }
public static bool WritePeToStream( EmitContext context, CommonMessageProvider messageProvider, Func<Stream> getPeStream, Func<Stream> getPortablePdbStreamOpt, PdbWriter nativePdbWriterOpt, string pdbPathOpt, bool allowMissingMethodBodies, bool isDeterministic, CancellationToken cancellationToken) { // If PDB writer is given, we have to have PDB path. Debug.Assert(nativePdbWriterOpt == null || pdbPathOpt != null); var mdWriter = FullMetadataWriter.Create(context, messageProvider, allowMissingMethodBodies, isDeterministic, getPortablePdbStreamOpt != null, cancellationToken); var properties = context.Module.Properties; nativePdbWriterOpt?.SetMetadataEmitter(mdWriter); // Since we are producing a full assembly, we should not have a module version ID // imposed ahead-of time. Instead we will compute a deterministic module version ID // based on the contents of the generated stream. Debug.Assert(properties.PersistentIdentifier == default(Guid)); var ilBuilder = new BlobBuilder(32 * 1024); var mappedFieldDataBuilder = new BlobBuilder(); var managedResourceBuilder = new BlobBuilder(1024); Blob mvidFixup; mdWriter.BuildMetadataAndIL( nativePdbWriterOpt, ilBuilder, mappedFieldDataBuilder, managedResourceBuilder, out mvidFixup); MethodDefinitionHandle entryPointHandle; MethodDefinitionHandle debugEntryPointHandle; mdWriter.GetEntryPoints(out entryPointHandle, out debugEntryPointHandle); if (!debugEntryPointHandle.IsNil) { nativePdbWriterOpt?.SetEntryPoint((uint)MetadataTokens.GetToken(debugEntryPointHandle)); } if (nativePdbWriterOpt != null) { var assembly = mdWriter.Module.AsAssembly; if (assembly != null && assembly.Kind == OutputKind.WindowsRuntimeMetadata) { // Dev12: If compiling to winmdobj, we need to add to PDB source spans of // all types and members for better error reporting by WinMDExp. nativePdbWriterOpt.WriteDefinitionLocations(mdWriter.Module.GetSymbolToLocationMap()); } else { #if DEBUG // validate that all definitions are writable // if same scenario would happen in an winmdobj project nativePdbWriterOpt.AssertAllDefinitionsHaveTokens(mdWriter.Module.GetSymbolToLocationMap()); #endif } } Stream peStream = getPeStream(); if (peStream == null) { return false; } ContentId nativePdbContentId = nativePdbWriterOpt?.GetContentId() ?? default(ContentId); // the writer shall not be used after this point for writing: nativePdbWriterOpt = null; var metadataSerializer = mdWriter.GetTypeSystemMetadataSerializer(); var peBuilder = new PEBuilder( machine: properties.Machine, sectionAlignment: properties.SectionAlignment, fileAlignment: properties.FileAlignment, imageBase: properties.BaseAddress, majorLinkerVersion: properties.LinkerMajorVersion, minorLinkerVersion: properties.LinkerMinorVersion, majorOperatingSystemVersion: 4, minorOperatingSystemVersion: 0, majorImageVersion: 0, minorImageVersion: 0, majorSubsystemVersion: properties.MajorSubsystemVersion, minorSubsystemVersion: properties.MinorSubsystemVersion, subsystem: properties.Subsystem, dllCharacteristics: properties.DllCharacteristics, imageCharacteristics: properties.ImageCharacteristics, sizeOfStackReserve: properties.SizeOfStackReserve, sizeOfStackCommit: properties.SizeOfStackCommit, sizeOfHeapReserve: properties.SizeOfHeapReserve, sizeOfHeapCommit: properties.SizeOfHeapCommit, deterministicIdProvider: isDeterministic ? new Func<BlobBuilder, ContentId>(content => ContentId.FromHash(CryptographicHashProvider.ComputeSha1(content))) : null); ContentId portablePdbContentId; if (mdWriter.EmitStandaloneDebugMetadata) { Debug.Assert(getPortablePdbStreamOpt != null); var debugMetadataBuilder = new BlobBuilder(); var debugMetadataSerializer = mdWriter.GetStandaloneDebugMetadataSerializer(metadataSerializer.MetadataSizes, debugEntryPointHandle); debugMetadataSerializer.SerializeMetadata(debugMetadataBuilder, peBuilder.IdProvider, out portablePdbContentId); // write to Portable PDB stream: Stream portablePdbStream = getPortablePdbStreamOpt(); if (portablePdbStream != null) { debugMetadataBuilder.WriteContentTo(portablePdbStream); } } else { portablePdbContentId = default(ContentId); } var peDirectoriesBuilder = new PEDirectoriesBuilder(); peBuilder.AddManagedSections( peDirectoriesBuilder, metadataSerializer, ilBuilder, mappedFieldDataBuilder, managedResourceBuilder, CreateNativeResourceSectionSerializer(context.Module), CalculateStrongNameSignatureSize(context.Module), entryPointHandle, pdbPathOpt, nativePdbContentId, portablePdbContentId, properties.CorFlags); var peBlob = new BlobBuilder(); ContentId peContentId; peBuilder.Serialize(peBlob, peDirectoriesBuilder, out peContentId); // Patch MVID if (!mvidFixup.IsDefault) { var mvidWriter = new BlobWriter(mvidFixup); mvidWriter.WriteBytes(peContentId.Guid); Debug.Assert(mvidWriter.RemainingBytes == 0); } try { peBlob.WriteContentTo(peStream); } catch (Exception e) when (!(e is OperationCanceledException)) { throw new PeWritingException(e); } return true; }
private void WriteRuntimeStartupStub(Stream peStream, int importAddressTableRva) { var writer = new BlobBuilder(16); // entry point code, consisting of a jump indirect to _CorXXXMain if (_is32bit) { //emit 0's (nops) to pad the entry point code so that the target address is aligned on a 4 byte boundary. for (uint i = 0, n = (uint)(BitArithmeticUtilities.Align((uint)peStream.Position, 4) - peStream.Position); i < n; i++) { writer.WriteByte(0); } writer.WriteUInt16(0); writer.WriteByte(0xff); writer.WriteByte(0x25); //4 writer.WriteUInt32((uint)importAddressTableRva + (uint)_properties.BaseAddress); //8 } else { //emit 0's (nops) to pad the entry point code so that the target address is aligned on a 8 byte boundary. for (uint i = 0, n = (uint)(BitArithmeticUtilities.Align((uint)peStream.Position, 8) - peStream.Position); i < n; i++) { writer.WriteByte(0); } writer.WriteUInt32(0); writer.WriteUInt16(0); writer.WriteByte(0xff); writer.WriteByte(0x25); //8 writer.WriteUInt64((ulong)importAddressTableRva + _properties.BaseAddress); //16 } writer.WriteContentTo(peStream); }
public void WriteContentToStream_Errors() { var builder = new BlobBuilder(16); builder.WriteByte(1); Assert.Throws<ArgumentNullException>(() => builder.WriteContentTo((Stream)null)); Assert.Throws<NotSupportedException>(() => builder.WriteContentTo(new MemoryStream(new byte[] { 1 }, writable: false))); }
public unsafe void Write_Errors() { var builder = new BlobBuilder(16); Assert.Throws<ArgumentNullException>(() => builder.WriteUTF16((char[])null)); Assert.Throws<ArgumentNullException>(() => builder.WriteUTF16((string)null)); Assert.Throws<ArgumentNullException>(() => builder.WriteUTF8(null, allowUnpairedSurrogates: true)); Assert.Throws<ArgumentNullException>(() => builder.WriteUTF8(null, allowUnpairedSurrogates: true)); Assert.Throws<ArgumentNullException>(() => builder.TryWriteBytes((Stream)null, 0)); Assert.Throws<ArgumentNullException>(() => builder.WriteBytes(null)); Assert.Throws<ArgumentNullException>(() => builder.WriteBytes(null, 0, 0)); Assert.Throws<ArgumentNullException>(() => builder.WriteBytes((byte*)null, 0)); Assert.Throws<ArgumentNullException>(() => builder.WriteBytes(default(ImmutableArray<byte>))); Assert.Throws<ArgumentNullException>(() => builder.WriteBytes(default(ImmutableArray<byte>), 0, 0)); var bw = default(BlobWriter); Assert.Throws<ArgumentNullException>(() => builder.WriteContentTo(ref bw)); Assert.Throws<ArgumentNullException>(() => builder.WriteContentTo((Stream)null)); Assert.Throws<ArgumentNullException>(() => builder.WriteContentTo((BlobBuilder)null)); Assert.Throws<ArgumentOutOfRangeException>(() => builder.TryWriteBytes(new MemoryStream(), -1)); Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteBytes(0, -1)); Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteBytes(new byte[] { }, 1, 0)); Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteBytes(new byte[] { }, 0, 1)); Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteBytes(new byte[] { }, 0, -1)); Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteBytes(ImmutableArray<byte>.Empty, 1, 0)); Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteBytes(ImmutableArray<byte>.Empty, 0, 1)); Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteBytes(ImmutableArray<byte>.Empty, 1, -1)); }
private static void WriteNameTable(Stream peStream) { var writer = new BlobBuilder(SizeOfNameTable); foreach (char ch in CorEntryPointDll) { writer.WriteByte((byte)ch); } writer.WriteByte(0); writer.WriteUInt16(0); Debug.Assert(writer.Count == SizeOfNameTable); writer.WriteContentTo(peStream); }
private static void WriteCorHeader(Stream peStream, CorHeader corHeader) { var writer = new BlobBuilder(CorHeaderSize); writer.WriteUInt32(CorHeaderSize); writer.WriteUInt16(corHeader.MajorRuntimeVersion); writer.WriteUInt16(corHeader.MinorRuntimeVersion); writer.WriteUInt32((uint)corHeader.MetadataDirectory.RelativeVirtualAddress); writer.WriteUInt32((uint)corHeader.MetadataDirectory.Size); writer.WriteUInt32((uint)corHeader.Flags); writer.WriteUInt32((uint)corHeader.EntryPointTokenOrRelativeVirtualAddress); writer.WriteUInt32((uint)(corHeader.ResourcesDirectory.Size == 0 ? 0 : corHeader.ResourcesDirectory.RelativeVirtualAddress)); // 28 writer.WriteUInt32((uint)corHeader.ResourcesDirectory.Size); writer.WriteUInt32((uint)(corHeader.StrongNameSignatureDirectory.Size == 0 ? 0 : corHeader.StrongNameSignatureDirectory.RelativeVirtualAddress)); // 36 writer.WriteUInt32((uint)corHeader.StrongNameSignatureDirectory.Size); writer.WriteUInt32((uint)corHeader.CodeManagerTableDirectory.RelativeVirtualAddress); writer.WriteUInt32((uint)corHeader.CodeManagerTableDirectory.Size); writer.WriteUInt32((uint)corHeader.VtableFixupsDirectory.RelativeVirtualAddress); writer.WriteUInt32((uint)corHeader.VtableFixupsDirectory.Size); writer.WriteUInt32((uint)corHeader.ExportAddressTableJumpsDirectory.RelativeVirtualAddress); writer.WriteUInt32((uint)corHeader.ExportAddressTableJumpsDirectory.Size); writer.WriteUInt64(0); Debug.Assert(writer.Count == CorHeaderSize); Debug.Assert(writer.Count % 4 == 0); writer.WriteContentTo(peStream); }
public static bool WritePeToStream( EmitContext context, CommonMessageProvider messageProvider, Func<Stream> getPeStream, Func<Stream> getPortablePdbStreamOpt, PdbWriter nativePdbWriterOpt, string pdbPathOpt, bool allowMissingMethodBodies, bool isDeterministic, CancellationToken cancellationToken) { // If PDB writer is given, we have to have PDB path. Debug.Assert(nativePdbWriterOpt == null || pdbPathOpt != null); var mdWriter = FullMetadataWriter.Create(context, messageProvider, allowMissingMethodBodies, isDeterministic, getPortablePdbStreamOpt != null, cancellationToken); var properties = context.Module.SerializationProperties; nativePdbWriterOpt?.SetMetadataEmitter(mdWriter); // Since we are producing a full assembly, we should not have a module version ID // imposed ahead-of time. Instead we will compute a deterministic module version ID // based on the contents of the generated stream. Debug.Assert(properties.PersistentIdentifier == default(Guid)); var ilBuilder = new BlobBuilder(32 * 1024); var mappedFieldDataBuilder = new BlobBuilder(); var managedResourceBuilder = new BlobBuilder(1024); Blob mvidFixup, mvidStringFixup; mdWriter.BuildMetadataAndIL( nativePdbWriterOpt, ilBuilder, mappedFieldDataBuilder, managedResourceBuilder, out mvidFixup, out mvidStringFixup); MethodDefinitionHandle entryPointHandle; MethodDefinitionHandle debugEntryPointHandle; mdWriter.GetEntryPoints(out entryPointHandle, out debugEntryPointHandle); if (!debugEntryPointHandle.IsNil) { nativePdbWriterOpt?.SetEntryPoint((uint)MetadataTokens.GetToken(debugEntryPointHandle)); } if (nativePdbWriterOpt != null) { if (mdWriter.Module.OutputKind == OutputKind.WindowsRuntimeMetadata) { // Dev12: If compiling to winmdobj, we need to add to PDB source spans of // all types and members for better error reporting by WinMDExp. nativePdbWriterOpt.WriteDefinitionLocations(mdWriter.Module.GetSymbolToLocationMap()); } else { #if DEBUG // validate that all definitions are writable // if same scenario would happen in an winmdobj project nativePdbWriterOpt.AssertAllDefinitionsHaveTokens(mdWriter.Module.GetSymbolToLocationMap()); #endif } // embedded text not currently supported for native PDB and we should have validated that Debug.Assert(!mdWriter.Module.DebugDocumentsBuilder.EmbeddedDocuments.Any()); } Stream peStream = getPeStream(); if (peStream == null) { return false; } BlobContentId pdbContentId = nativePdbWriterOpt?.GetContentId() ?? default(BlobContentId); // the writer shall not be used after this point for writing: nativePdbWriterOpt = null; ushort portablePdbVersion = 0; var metadataRootBuilder = mdWriter.GetRootBuilder(); var peHeaderBuilder = new PEHeaderBuilder( machine: properties.Machine, sectionAlignment: properties.SectionAlignment, fileAlignment: properties.FileAlignment, imageBase: properties.BaseAddress, majorLinkerVersion: properties.LinkerMajorVersion, minorLinkerVersion: properties.LinkerMinorVersion, majorOperatingSystemVersion: 4, minorOperatingSystemVersion: 0, majorImageVersion: 0, minorImageVersion: 0, majorSubsystemVersion: properties.MajorSubsystemVersion, minorSubsystemVersion: properties.MinorSubsystemVersion, subsystem: properties.Subsystem, dllCharacteristics: properties.DllCharacteristics, imageCharacteristics: properties.ImageCharacteristics, sizeOfStackReserve: properties.SizeOfStackReserve, sizeOfStackCommit: properties.SizeOfStackCommit, sizeOfHeapReserve: properties.SizeOfHeapReserve, sizeOfHeapCommit: properties.SizeOfHeapCommit); var deterministicIdProvider = isDeterministic ? new Func<IEnumerable<Blob>, BlobContentId>(content => BlobContentId.FromHash(CryptographicHashProvider.ComputeSha1(content))) : null; BlobBuilder portablePdbToEmbed = null; if (mdWriter.EmitStandaloneDebugMetadata) { mdWriter.AddRemainingEmbeddedDocuments(mdWriter.Module.DebugDocumentsBuilder.EmbeddedDocuments); var portablePdbBlob = new BlobBuilder(); var portablePdbBuilder = mdWriter.GetPortablePdbBuilder(metadataRootBuilder.Sizes, debugEntryPointHandle, deterministicIdProvider); pdbContentId = portablePdbBuilder.Serialize(portablePdbBlob); portablePdbVersion = portablePdbBuilder.FormatVersion; if (getPortablePdbStreamOpt == null) { // embed to debug directory: portablePdbToEmbed = portablePdbBlob; } else { // write to Portable PDB stream: Stream portablePdbStream = getPortablePdbStreamOpt(); if (portablePdbStream != null) { portablePdbBlob.WriteContentTo(portablePdbStream); } } } DebugDirectoryBuilder debugDirectoryBuilder; if (pdbPathOpt != null || isDeterministic || portablePdbToEmbed != null) { debugDirectoryBuilder = new DebugDirectoryBuilder(); if (pdbPathOpt != null) { string paddedPath = isDeterministic ? pdbPathOpt : PadPdbPath(pdbPathOpt); debugDirectoryBuilder.AddCodeViewEntry(paddedPath, pdbContentId, portablePdbVersion); } if (isDeterministic) { debugDirectoryBuilder.AddReproducibleEntry(); } if (portablePdbToEmbed != null) { debugDirectoryBuilder.AddEmbeddedPortablePdbEntry(portablePdbToEmbed, portablePdbVersion); } } else { debugDirectoryBuilder = null; } var peBuilder = new ManagedPEBuilder( peHeaderBuilder, metadataRootBuilder, ilBuilder, mappedFieldDataBuilder, managedResourceBuilder, CreateNativeResourceSectionSerializer(context.Module), debugDirectoryBuilder, CalculateStrongNameSignatureSize(context.Module), entryPointHandle, properties.CorFlags, deterministicIdProvider); var peBlob = new BlobBuilder(); var peContentId = peBuilder.Serialize(peBlob); PatchModuleVersionIds(mvidFixup, mvidStringFixup, peContentId.Guid); try { peBlob.WriteContentTo(peStream); } catch (Exception e) when (!(e is OperationCanceledException)) { throw new PeWritingException(e); } return true; }
private void WriteRelocSection(Stream peStream, SectionHeader relocSection, int entryPointAddress) { peStream.Position = relocSection.PointerToRawData; var writer = new BlobBuilder(relocSection.SizeOfRawData); writer.WriteUInt32((((uint)entryPointAddress + 2) / 0x1000) * 0x1000); writer.WriteUInt32(_properties.Requires64bits && !_properties.RequiresAmdInstructionSet ? 14u : 12u); uint offsetWithinPage = ((uint)entryPointAddress + 2) % 0x1000; uint relocType = _properties.Requires64bits ? 10u : 3u; ushort s = (ushort)((relocType << 12) | offsetWithinPage); writer.WriteUInt16(s); if (_properties.Requires64bits && !_properties.RequiresAmdInstructionSet) { writer.WriteUInt32(relocType << 12); } writer.WriteUInt16(0); // next chunk's RVA writer.PadTo(relocSection.SizeOfRawData); writer.WriteContentTo(peStream); }
public ExceptionRegionEncoder WriteInstructions(BlobBuilder codeBuilder, out int bodyOffset) { bodyOffset = WriteHeader(codeBuilder.Count); codeBuilder.WriteContentTo(Builder); return(CreateExceptionEncoder()); }
public ExceptionRegionEncoder WriteInstructions(BlobBuilder buffer, out int offset) { offset = WriteHeader(buffer.Count); buffer.WriteContentTo(Builder); return(CreateExceptionEncoder()); }
public static void Convert(Stream peStream, Stream sourcePdbStream, Stream targetPdbStream) { var metadataBuilder = new MetadataBuilder(); ImmutableArray <int> typeSystemRowCounts; var debugEntryPointToken = default(MethodDefinitionHandle); var pdbId = default(BlobContentId); try { using (var peReader = new PEReader(peStream)) { pdbId = ReadPdbId(peReader); var symReader = SymReaderFactory.CreateWindowsPdbReader(sourcePdbStream, peReader); var metadataReader = peReader.GetMetadataReader(); var metadataModel = new MetadataModel(metadataReader); typeSystemRowCounts = metadataModel.GetRowCounts(); debugEntryPointToken = ReadEntryPointHandle(symReader); // documents: var documentIndex = new Dictionary <string, DocumentHandle>(StringComparer.Ordinal); var documents = symReader.GetDocuments(); metadataBuilder.SetCapacity(TableIndex.Document, documents.Length); bool vbSemantics = false; foreach (var document in documents) { string name = document.GetName(); Guid language = document.GetLanguage(); // TODO: // won't work for IL-merged assmemblies vbSemantics |= language == SymReaderHelpers.VisualBasicLanguageGuid; var rid = metadataBuilder.AddDocument( name: metadataBuilder.GetOrAddDocumentName(name), hashAlgorithm: metadataBuilder.GetOrAddGuid(document.GetHashAlgorithm()), hash: metadataBuilder.GetOrAddBlob(document.GetChecksum()), language: metadataBuilder.GetOrAddGuid(language)); documentIndex.Add(name, rid); } var lastLocalVariableHandle = default(LocalVariableHandle); var lastLocalConstantHandle = default(LocalConstantHandle); var importStringsByMethod = new Dictionary <int, ImmutableArray <string> >(); var importScopesByMethod = new Dictionary <int, ImportScopeHandle>(); // Maps import scope content to import scope handles var importScopeIndex = new Dictionary <ImportScopeInfo, ImportScopeHandle>(); var importScopes = new List <ImportScopeInfo>(); // reserve slot for module import scope: importScopes.Add(default(ImportScopeInfo)); var externAliasImports = new List <ImportInfo>(); var externAliasStringSet = new HashSet <string>(StringComparer.Ordinal); string vbDefaultNamespace = null; var vbProjectLevelImports = new List <ImportInfo>(); // first pass: foreach (var methodHandle in metadataReader.MethodDefinitions) { int methodToken = MetadataTokens.GetToken(methodHandle); ImmutableArray <ImmutableArray <ImportInfo> > importGroups; if (vbSemantics) { var importStrings = CustomDebugInfoReader.GetVisualBasicImportStrings( methodToken, symReader, getMethodImportStrings: (token, sr) => GetImportStrings(token, importStringsByMethod, sr)); if (importStrings.IsEmpty) { // no debug info continue; } var vbFileLevelImports = ArrayBuilder <ImportInfo> .GetInstance(); foreach (var importString in importStrings) { if (TryParseImportString(importString, out var import, vbSemantics: true)) { if (import.Kind == ImportTargetKind.DefaultNamespace) { vbDefaultNamespace = import.Target; } else if (import.Scope == VBImportScopeKind.Project) { vbProjectLevelImports.Add(import); } else { vbFileLevelImports.Add(import); } } } importGroups = ImmutableArray.Create(vbFileLevelImports.ToImmutableAndFree()); } else { var importStringGroups = CustomDebugInfoReader.GetCSharpGroupedImportStrings( methodToken, symReader, getMethodCustomDebugInfo: (token, sr) => sr.GetCustomDebugInfo(token, methodVersion: 1), getMethodImportStrings: (token, sr) => GetImportStrings(token, importStringsByMethod, sr), externAliasStrings: out var localExternAliasStrings); if (importStringGroups.IsDefault) { // no debug info continue; } if (!localExternAliasStrings.IsDefault) { foreach (var externAlias in localExternAliasStrings) { if (externAliasStringSet.Add(externAlias) && TryParseImportString(externAlias, out var import, vbSemantics: false)) { externAliasImports.Add(import); } } } importGroups = ImmutableArray.CreateRange(importStringGroups.Select(g => ParseImportStrings(g, vbSemantics: false))); } var importScopeHandle = DefineImportScope(importGroups, importScopeIndex, importScopes); importScopesByMethod.Add(methodToken, importScopeHandle); } // import scopes: metadataBuilder.AddImportScope( parentScope: default(ImportScopeHandle), imports: SerializeModuleImportScope(metadataBuilder, externAliasImports, vbProjectLevelImports, vbDefaultNamespace, metadataModel)); for (int i = 1; i < importScopes.Count; i++) { metadataBuilder.AddImportScope( parentScope: importScopes[i].Parent, imports: SerializeImportsBlob(metadataBuilder, importScopes[i].Imports, metadataModel)); } var dynamicNames = new Dictionary <string, DynamicLocalInfo>(); var dynamicSlots = new Dictionary <int, DynamicLocalInfo>(); // methods: metadataBuilder.SetCapacity(TableIndex.MethodDebugInformation, metadataReader.MethodDefinitions.Count); foreach (var methodHandle in metadataReader.MethodDefinitions) { var methodDef = metadataReader.GetMethodDefinition(methodHandle); int methodToken = MetadataTokens.GetToken(methodHandle); var symMethod = symReader.GetMethod(methodToken); if (symMethod == null) { metadataBuilder.AddMethodDebugInformation(default(DocumentHandle), sequencePoints: default(BlobHandle)); continue; } // method debug info: int localSignatureRowId; if (methodDef.RelativeVirtualAddress != 0) { var methodBody = peReader.GetMethodBody(methodDef.RelativeVirtualAddress); localSignatureRowId = methodBody.LocalSignature.IsNil ? 0 : MetadataTokens.GetRowNumber(methodBody.LocalSignature); } else { localSignatureRowId = 0; } var symSequencePoints = symMethod.GetSequencePoints().ToImmutableArray(); DocumentHandle singleDocumentHandle; BlobHandle sequencePointsBlob = SerializeSequencePoints(metadataBuilder, localSignatureRowId, symSequencePoints, documentIndex, out singleDocumentHandle); metadataBuilder.AddMethodDebugInformation( document: singleDocumentHandle, sequencePoints: sequencePointsBlob); // state machine and async info: var symAsyncMethod = symMethod.AsAsyncMethod(); if (symAsyncMethod != null) { var kickoffToken = MetadataTokens.Handle(symAsyncMethod.GetKickoffMethod()); metadataBuilder.AddStateMachineMethod( moveNextMethod: methodHandle, kickoffMethod: (MethodDefinitionHandle)kickoffToken); metadataBuilder.AddCustomDebugInformation( parent: methodHandle, kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.AsyncMethodSteppingInformationBlob), value: SerializeAsyncMethodSteppingInfo(metadataBuilder, symAsyncMethod, MetadataTokens.GetRowNumber(methodHandle))); } // custom debug information: var dynamicLocals = default(ImmutableArray <DynamicLocalInfo>); byte[] customDebugInfoBytes = symReader.GetCustomDebugInfo(methodToken, methodVersion: 1); if (customDebugInfoBytes != null) { foreach (var record in CustomDebugInfoReader.GetCustomDebugInfoRecords(customDebugInfoBytes)) { switch (record.Kind) { case CustomDebugInfoKind.DynamicLocals: dynamicLocals = CustomDebugInfoReader.DecodeDynamicLocalsRecord(record.Data); break; case CustomDebugInfoKind.StateMachineHoistedLocalScopes: metadataBuilder.AddCustomDebugInformation( parent: methodHandle, kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.EncLocalSlotMap), value: SerializeStateMachineHoistedLocalsBlob(metadataBuilder, CustomDebugInfoReader.DecodeStateMachineHoistedLocalScopesRecord(record.Data))); break; case CustomDebugInfoKind.EditAndContinueLocalSlotMap: metadataBuilder.AddCustomDebugInformation( parent: methodHandle, kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.EncLocalSlotMap), value: metadataBuilder.GetOrAddBlob(record.Data)); break; case CustomDebugInfoKind.EditAndContinueLambdaMap: metadataBuilder.AddCustomDebugInformation( parent: methodHandle, kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.EncLambdaAndClosureMap), value: metadataBuilder.GetOrAddBlob(record.Data)); break; } } } var rootScope = symMethod.GetRootScope(); if (rootScope.GetNamespaces().Length == 0 || rootScope.GetLocals().Length == 0 || rootScope.GetConstants().Length == 0) { dynamicNames.Clear(); dynamicSlots.Clear(); foreach (var dynamicLocal in dynamicLocals) { if (dynamicLocal.SlotId == 0) { // All dynamic constants have slot id == 0, // but a variable can also have slot id == 0 if (!dynamicNames.ContainsKey(dynamicLocal.LocalName)) { dynamicNames.Add(dynamicLocal.LocalName, dynamicLocal); } else { // TODO: warning } } else if (!dynamicSlots.ContainsKey(dynamicLocal.SlotId)) { dynamicSlots.Add(dynamicLocal.SlotId, dynamicLocal); } else { // TODO: warning } } foreach (ISymUnmanagedScope scope in rootScope.GetChildren()) { SerializeScope( metadataBuilder, metadataModel, methodHandle, importScopesByMethod[methodToken], scope, dynamicSlots, dynamicNames, vbSemantics, ref lastLocalVariableHandle, ref lastLocalConstantHandle); } } else { // TODO: warning: // "Root scope must be empty (method 0x{0:x8})", MetadataTokens.GetToken(methodHandle)) } } } } catch (COMException e) { // TODO: loc throw new BadImageFormatException("Invalid PDB format: " + e.Message, e); } var serializer = new PortablePdbBuilder(metadataBuilder, typeSystemRowCounts, debugEntryPointToken, idProvider: _ => pdbId); BlobBuilder blobBuilder = new BlobBuilder(); serializer.Serialize(blobBuilder); blobBuilder.WriteContentTo(targetPdbStream); }
private void WriteTextSection( Stream peStream, SectionHeader textSection, int importTableRva, int importAddressTableRva, int entryPointToken, BlobBuilder metadataWriter, BlobBuilder ilWriter, BlobBuilder mappedFieldDataWriter, BlobBuilder managedResourceWriter, MetadataSizes metadataSizes, ContentId nativePdbContentId, ContentId portablePdbContentId, out long metadataPosition) { // TODO: zero out all bytes: peStream.Position = textSection.PointerToRawData; if (_properties.RequiresStartupStub) { WriteImportAddressTable(peStream, importTableRva); } var corHeader = CreateCorHeader(metadataSizes, textSection.RelativeVirtualAddress, entryPointToken); WriteCorHeader(peStream, corHeader); // IL: ilWriter.Align(4); ilWriter.WriteContentTo(peStream); // metadata: metadataPosition = peStream.Position; Debug.Assert(metadataWriter.Count % 4 == 0); metadataWriter.WriteContentTo(peStream); // managed resources: Debug.Assert(managedResourceWriter.Count % 4 == 0); managedResourceWriter.WriteContentTo(peStream); // strong name signature: WriteSpaceForHash(peStream, metadataSizes.StrongNameSignatureSize); if (EmitPdb) { WriteDebugTable(peStream, textSection, nativePdbContentId, portablePdbContentId, metadataSizes); } if (_properties.RequiresStartupStub) { WriteImportTable(peStream, importTableRva, importAddressTableRva); WriteNameTable(peStream); WriteRuntimeStartupStub(peStream, importAddressTableRva); } // mapped field data: mappedFieldDataWriter.WriteContentTo(peStream); // TODO: zero out all bytes: int alignedPosition = textSection.PointerToRawData + textSection.SizeOfRawData; if (peStream.Position != alignedPosition) { peStream.Position = alignedPosition - 1; peStream.WriteByte(0); } }
public ExceptionRegionEncoder WriteInstructions(BlobBuilder codeBuilder, out int bodyOffset) { bodyOffset = WriteHeader(codeBuilder.Count); codeBuilder.WriteContentTo(Builder); return CreateExceptionEncoder(); }
private void WriteImportAddressTable(Stream peStream, int importTableRva) { var writer = new BlobBuilder(SizeOfImportAddressTable); int ilRVA = importTableRva + 40; int hintRva = ilRVA + (_is32bit ? 12 : 16); // Import Address Table if (_is32bit) { writer.WriteUInt32((uint)hintRva); // 4 writer.WriteUInt32(0); // 8 } else { writer.WriteUInt64((uint)hintRva); // 8 writer.WriteUInt64(0); // 16 } Debug.Assert(writer.Count == SizeOfImportAddressTable); writer.WriteContentTo(peStream); }
internal static bool WritePeToStream( EmitContext context, CommonMessageProvider messageProvider, Func <Stream> getPeStream, Func <Stream> getPortablePdbStreamOpt, PdbWriter nativePdbWriterOpt, string pdbPathOpt, bool metadataOnly, bool isDeterministic, bool emitTestCoverageData, RSAParameters?privateKeyOpt, CancellationToken cancellationToken) { // If PDB writer is given, we have to have PDB path. Debug.Assert(nativePdbWriterOpt == null || pdbPathOpt != null); var mdWriter = FullMetadataWriter.Create(context, messageProvider, metadataOnly, isDeterministic, emitTestCoverageData, getPortablePdbStreamOpt != null, cancellationToken); var properties = context.Module.SerializationProperties; nativePdbWriterOpt?.SetMetadataEmitter(mdWriter); // Since we are producing a full assembly, we should not have a module version ID // imposed ahead-of time. Instead we will compute a deterministic module version ID // based on the contents of the generated stream. Debug.Assert(properties.PersistentIdentifier == default(Guid)); var ilBuilder = new BlobBuilder(32 * 1024); var mappedFieldDataBuilder = new BlobBuilder(); var managedResourceBuilder = new BlobBuilder(1024); Blob mvidFixup, mvidStringFixup; mdWriter.BuildMetadataAndIL( nativePdbWriterOpt, ilBuilder, mappedFieldDataBuilder, managedResourceBuilder, out mvidFixup, out mvidStringFixup); MethodDefinitionHandle entryPointHandle; MethodDefinitionHandle debugEntryPointHandle; mdWriter.GetEntryPoints(out entryPointHandle, out debugEntryPointHandle); if (!debugEntryPointHandle.IsNil) { nativePdbWriterOpt?.SetEntryPoint(MetadataTokens.GetToken(debugEntryPointHandle)); } if (nativePdbWriterOpt != null) { if (context.Module.SourceLinkStreamOpt != null) { nativePdbWriterOpt.EmbedSourceLink(context.Module.SourceLinkStreamOpt); } #if DEBUG // validate that all definitions are writable // if same scenario would happen in an winmdobj project nativePdbWriterOpt.AssertAllDefinitionsHaveTokens(mdWriter.Module.GetSymbolToLocationMap()); #endif nativePdbWriterOpt.WriteRemainingEmbeddedDocuments(mdWriter.Module.DebugDocumentsBuilder.EmbeddedDocuments); } Stream peStream = getPeStream(); if (peStream == null) { return(false); } BlobContentId pdbContentId = nativePdbWriterOpt?.GetContentId() ?? default; // the writer shall not be used after this point for writing: nativePdbWriterOpt = null; ushort portablePdbVersion = 0; var metadataRootBuilder = mdWriter.GetRootBuilder(); var peHeaderBuilder = new PEHeaderBuilder( machine: properties.Machine, sectionAlignment: properties.SectionAlignment, fileAlignment: properties.FileAlignment, imageBase: properties.BaseAddress, majorLinkerVersion: properties.LinkerMajorVersion, minorLinkerVersion: properties.LinkerMinorVersion, majorOperatingSystemVersion: 4, minorOperatingSystemVersion: 0, majorImageVersion: 0, minorImageVersion: 0, majorSubsystemVersion: properties.MajorSubsystemVersion, minorSubsystemVersion: properties.MinorSubsystemVersion, subsystem: properties.Subsystem, dllCharacteristics: properties.DllCharacteristics, imageCharacteristics: properties.ImageCharacteristics, sizeOfStackReserve: properties.SizeOfStackReserve, sizeOfStackCommit: properties.SizeOfStackCommit, sizeOfHeapReserve: properties.SizeOfHeapReserve, sizeOfHeapCommit: properties.SizeOfHeapCommit); // TODO: replace SHA1 with non-crypto alg: https://github.com/dotnet/roslyn/issues/24737 var peIdProvider = isDeterministic ? new Func <IEnumerable <Blob>, BlobContentId>(content => BlobContentId.FromHash(CryptographicHashProvider.ComputeHash(HashAlgorithmName.SHA1, content))) : null; // We need to calculate the PDB checksum, so we may as well use the calculated hash for PDB ID regardless of whether deterministic build is requested. var portablePdbContentHash = default(ImmutableArray <byte>); BlobBuilder portablePdbToEmbed = null; if (mdWriter.EmitPortableDebugMetadata) { mdWriter.AddRemainingEmbeddedDocuments(mdWriter.Module.DebugDocumentsBuilder.EmbeddedDocuments); // The algorithm must be specified for deterministic builds (checked earlier). Debug.Assert(!isDeterministic || context.Module.PdbChecksumAlgorithm.Name != null); var portablePdbIdProvider = (context.Module.PdbChecksumAlgorithm.Name != null) ? new Func <IEnumerable <Blob>, BlobContentId>(content => BlobContentId.FromHash(portablePdbContentHash = CryptographicHashProvider.ComputeHash(context.Module.PdbChecksumAlgorithm, content))) : null; var portablePdbBlob = new BlobBuilder(); var portablePdbBuilder = mdWriter.GetPortablePdbBuilder(metadataRootBuilder.Sizes.RowCounts, debugEntryPointHandle, portablePdbIdProvider); pdbContentId = portablePdbBuilder.Serialize(portablePdbBlob); portablePdbVersion = portablePdbBuilder.FormatVersion; if (getPortablePdbStreamOpt == null) { // embed to debug directory: portablePdbToEmbed = portablePdbBlob; } else { // write to Portable PDB stream: Stream portablePdbStream = getPortablePdbStreamOpt(); if (portablePdbStream != null) { try { portablePdbBlob.WriteContentTo(portablePdbStream); } catch (Exception e) when(!(e is OperationCanceledException)) { throw new SymUnmanagedWriterException(e.Message, e); } } } } DebugDirectoryBuilder debugDirectoryBuilder; if (pdbPathOpt != null || isDeterministic || portablePdbToEmbed != null) { debugDirectoryBuilder = new DebugDirectoryBuilder(); if (pdbPathOpt != null) { string paddedPath = isDeterministic ? pdbPathOpt : PadPdbPath(pdbPathOpt); debugDirectoryBuilder.AddCodeViewEntry(paddedPath, pdbContentId, portablePdbVersion); if (!portablePdbContentHash.IsDefault) { // Emit PDB Checksum entry for Portable and Embedded PDBs. The checksum is not as useful when the PDB is embedded, // however it allows the client to efficiently validate a standalone Portable PDB that // has been extracted from Embedded PDB and placed next to the PE file. debugDirectoryBuilder.AddPdbChecksumEntry(context.Module.PdbChecksumAlgorithm.Name, portablePdbContentHash); } } if (isDeterministic) { debugDirectoryBuilder.AddReproducibleEntry(); } if (portablePdbToEmbed != null) { debugDirectoryBuilder.AddEmbeddedPortablePdbEntry(portablePdbToEmbed, portablePdbVersion); } } else { debugDirectoryBuilder = null; } var strongNameProvider = context.Module.CommonCompilation.Options.StrongNameProvider; var corFlags = properties.CorFlags; var peBuilder = new ExtendedPEBuilder( peHeaderBuilder, metadataRootBuilder, ilBuilder, mappedFieldDataBuilder, managedResourceBuilder, CreateNativeResourceSectionSerializer(context.Module), debugDirectoryBuilder, CalculateStrongNameSignatureSize(context.Module, privateKeyOpt), entryPointHandle, corFlags, peIdProvider, metadataOnly && !context.IncludePrivateMembers); var peBlob = new BlobBuilder(); var peContentId = peBuilder.Serialize(peBlob, out Blob mvidSectionFixup); PatchModuleVersionIds(mvidFixup, mvidSectionFixup, mvidStringFixup, peContentId.Guid); if (privateKeyOpt != null && corFlags.HasFlag(CorFlags.StrongNameSigned)) { strongNameProvider.SignBuilder(peBuilder, peBlob, privateKeyOpt.Value); } try { peBlob.WriteContentTo(peStream); } catch (Exception e) when(!(e is OperationCanceledException)) { throw new PeWritingException(e); } return(true); }
public PermissionSetEncoder AddPermission(string typeName, BlobBuilder encodedArguments) { if (typeName == null) { Throw.ArgumentNull(nameof(typeName)); } if (encodedArguments == null) { Throw.ArgumentNull(nameof(encodedArguments)); } if (encodedArguments.Count > BlobWriterImpl.MaxCompressedIntegerValue) { Throw.BlobTooLarge(nameof(encodedArguments)); } Builder.WriteSerializedString(typeName); Builder.WriteCompressedInteger(encodedArguments.Count); encodedArguments.WriteContentTo(Builder); return new PermissionSetEncoder(Builder); }