public void MetadataVersion_Empty() { var version = ""; var mdBuilder = new MetadataBuilder(); mdBuilder.AddModule(0, default(StringHandle), default(GuidHandle), default(GuidHandle), default(GuidHandle)); var rootBuilder = new MetadataRootBuilder(mdBuilder, version); var builder = new BlobBuilder(); rootBuilder.Serialize(builder, 0, 0); AssertEx.Equal(new byte[] { // padded version length: 0x04, 0x00, 0x00, 0x00, // padded version: 0x00, 0x00, 0x00, 0x00, }, builder.Slice(12, -132)); Assert.Equal(version, ReadVersion(builder)); }
public ExtendedPEBuilder( PEHeaderBuilder header, MetadataRootBuilder metadataRootBuilder, BlobBuilder ilStream, BlobBuilder mappedFieldData, BlobBuilder managedResources, ResourceSectionBuilder nativeResources, DebugDirectoryBuilder debugDirectoryBuilder, int strongNameSignatureSize, MethodDefinitionHandle entryPoint, CorFlags flags, Func <IEnumerable <Blob>, BlobContentId> deterministicIdProvider, bool withMvidSection ) : base( header, metadataRootBuilder, ilStream, mappedFieldData, managedResources, nativeResources, debugDirectoryBuilder, strongNameSignatureSize, entryPoint, flags, deterministicIdProvider ) { _withMvidSection = withMvidSection; }
public void MetadataVersion() { var version = "\u1234\ud800"; var mdBuilder = new MetadataBuilder(); mdBuilder.AddModule(0, default(StringHandle), default(GuidHandle), default(GuidHandle), default(GuidHandle)); var rootBuilder = new MetadataRootBuilder(mdBuilder, version); var builder = new BlobBuilder(); rootBuilder.Serialize(builder, 0, 0); AssertEx.Equal(new byte[] { // padded version length: 0x08, 0x00, 0x00, 0x00, // padded version: 0xE1, 0x88, 0xB4, 0xED, 0xA0, 0x80, 0x00, 0x00, }, builder.Slice(12, -132)); // the default decoder replaces bad byte sequences by U+FFFD Assert.Equal("\u1234\ufffd\ufffd", ReadVersion(builder)); }
public void Serialize_Errors() { var mdBuilder = new MetadataBuilder(); var rootBuilder = new MetadataRootBuilder(mdBuilder); var builder = new BlobBuilder(); Assert.Throws <ArgumentNullException>(() => rootBuilder.Serialize(null, 0, 0)); Assert.Throws <ArgumentOutOfRangeException>(() => rootBuilder.Serialize(builder, -1, 0)); Assert.Throws <ArgumentOutOfRangeException>(() => rootBuilder.Serialize(builder, 0, -1)); }
public void Serialize_Errors() { var mdBuilder = new MetadataBuilder(); var rootBuilder = new MetadataRootBuilder(mdBuilder); var builder = new BlobBuilder(); Assert.Throws<ArgumentNullException>(() => rootBuilder.Serialize(null, 0, 0)); Assert.Throws<ArgumentOutOfRangeException>(() => rootBuilder.Serialize(builder, -1, 0)); Assert.Throws<ArgumentOutOfRangeException>(() => rootBuilder.Serialize(builder, 0, -1)); }
public void ManagedPEBuilder_Errors() { var hdr = new PEHeaderBuilder(); var ms = new MetadataRootBuilder(new MetadataBuilder()); var il = new BlobBuilder(); Assert.Throws <ArgumentNullException>(() => new ManagedPEBuilder(null, ms, il)); Assert.Throws <ArgumentNullException>(() => new ManagedPEBuilder(hdr, null, il)); Assert.Throws <ArgumentNullException>(() => new ManagedPEBuilder(hdr, ms, null)); Assert.Throws <ArgumentOutOfRangeException>(() => new ManagedPEBuilder(hdr, ms, il, strongNameSignatureSize: -1)); }
// Generate only the metadata blob as a byte[] public byte[] EmitToMetadataBlob() { MetadataRootBuilder metadataRootBuilder = new MetadataRootBuilder(_metadataBuilder); BlobBuilder metadataBlobBuilder = new BlobBuilder(); metadataRootBuilder.Serialize(metadataBlobBuilder, methodBodyStreamRva: 0, mappedFieldDataStreamRva: 0); // Clear some variables to catch any caller trying to emit data after writing the output file _metadataBuilder = null; return(metadataBlobBuilder.ToArray()); }
private static BlobBuilder BuildMetadataImage() { var mdBuilder = new MetadataBuilder(); mdBuilder.AddModule(0, default(StringHandle), default(GuidHandle), default(GuidHandle), default(GuidHandle)); var rootBuilder = new MetadataRootBuilder(mdBuilder, "v9.9.9.9"); var builder = new BlobBuilder(); rootBuilder.Serialize(builder, 0, 0); return(builder); }
public void BlahBlahBlah() { var peHeader = PEHeaderBuilder.CreateLibraryHeader(); var meta = new MetadataBuilder(); var module = meta.AddModule(1, meta.GetOrAddString("Module1"), meta.GetOrAddGuid(Guid.Parse("11112222-3333-4444-5555-666677778888")), meta.GetOrAddGuid(Guid.Parse("88887777-6666-5555-4444-333322221111")), meta.GetOrAddGuid(Guid.Parse("22223333-4444-5555-6666-777788889999")) ); var tObject = meta.AddTypeReference( EntityHandle.ModuleDefinition, meta.GetOrAddString("System"), meta.GetOrAddString("Object")); var fields = new FieldDefinitionHandle(); //EMPTY!! var methods = new MethodDefinitionHandle(); //EMPTY!! meta.AddTypeDefinition( TypeAttributes.Class | TypeAttributes.Public, meta.GetOrAddString("Namespace1"), meta.GetOrAddString("Class1"), tObject, fields, methods); meta.GetOrAddString("Module1"); var metadataRoot = new MetadataRootBuilder(meta); var ilBlob = new BlobBuilder(); ilBlob.WriteByte(0); ilBlob.WriteByte(42); var pe = new ManagedPEBuilder(peHeader, metadataRoot, ilBlob); var blob = new BlobBuilder(); pe.Serialize(blob); Assembly.Load(blob.ToArray()); }
/// <summary> /// Assembles this instance. /// </summary> public void Assemble() { // TODO: Complete this so that it actually generate the hello world sample // TODO: Use the data generated from the parser instead of hard coding here PEHeaderBuilder header = new PEHeaderBuilder(); MetadataBuilder metadata = new MetadataBuilder(); metadata.AddAssembly(metadata.GetOrAddString("HelloWorld"), new Version(), default(StringHandle), default(BlobHandle), (System.Reflection.AssemblyFlags) 0, AssemblyHashAlgorithm.None); MetadataRootBuilder metadataRootBuilder = new MetadataRootBuilder(metadata); BlobBuilder stream = new BlobBuilder(); ManagedPEBuilder managedPEBuilder = new ManagedPEBuilder(header, metadataRootBuilder, stream); BlobBuilder output = new BlobBuilder(); managedPEBuilder.Serialize(output); File.WriteAllBytes(@"C:\Temp\HelloWorld.dll", output.ToArray()); }
public ManagedPEBuilder( PEHeaderBuilder header, MetadataRootBuilder metadataRootBuilder, BlobBuilder ilStream, BlobBuilder mappedFieldData = null, BlobBuilder managedResources = null, ResourceSectionBuilder nativeResources = null, DebugDirectoryBuilder debugDirectoryBuilder = null, int strongNameSignatureSize = DefaultStrongNameSignatureSize, MethodDefinitionHandle entryPoint = default(MethodDefinitionHandle), CorFlags flags = CorFlags.ILOnly, Func <IEnumerable <Blob>, BlobContentId> deterministicIdProvider = null) : base(header, deterministicIdProvider) { if (header == null) { Throw.ArgumentNull(nameof(header)); } if (metadataRootBuilder == null) { Throw.ArgumentNull(nameof(metadataRootBuilder)); } if (ilStream == null) { Throw.ArgumentNull(nameof(ilStream)); } if (strongNameSignatureSize < 0) { Throw.ArgumentOutOfRange(nameof(strongNameSignatureSize)); } _metadataRootBuilder = metadataRootBuilder; _ilStream = ilStream; _mappedFieldDataOpt = mappedFieldData; _managedResourcesOpt = managedResources; _nativeResourcesOpt = nativeResources; _strongNameSignatureSize = strongNameSignatureSize; _entryPointOpt = entryPoint; _debugDirectoryBuilderOpt = debugDirectoryBuilder ?? CreateDefaultDebugDirectoryBuilder(); _corFlags = flags; _peDirectoriesBuilder = new PEDirectoriesBuilder(); }
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); }
public void MetadataVersion() { var version = "\u1234\ud800"; var mdBuilder = new MetadataBuilder(); mdBuilder.AddModule(0, default(StringHandle), default(GuidHandle), default(GuidHandle), default(GuidHandle)); var rootBuilder = new MetadataRootBuilder(mdBuilder, version); var builder = new BlobBuilder(); rootBuilder.Serialize(builder, 0, 0); AssertEx.Equal(new byte[] { // padded version length: 0x08, 0x00, 0x00, 0x00, // padded version: // [ E1 88 B4 ] -> U+1234 // [ ED ] -> invalid (ED cannot be followed by A0) -> U+FFFD // [ A0 ] -> invalid (not ASCII, not valid leading byte) -> U+FFFD // [ 80 ] -> invalid (not ASCII, not valid leading byte) -> U+FFFD 0xE1, 0x88, 0xB4, 0xED, 0xA0, 0x80, 0x00, 0x00, }, builder.Slice(12, -132)); // the default decoder replaces bad byte sequences by U+FFFD if (PlatformDetection.IsNetCore) { Assert.Equal("\u1234\ufffd\ufffd\ufffd", ReadVersion(builder)); } else { // Versions of .NET prior to Core 3.0 didn't follow Unicode recommendations for U+FFFD substitution, // so they sometimes emitted too few replacement chars. Assert.Equal("\u1234\ufffd\ufffd", ReadVersion(builder)); } }
public void GetOrAddDocumentName2() { var mdBuilder = new MetadataBuilder(); mdBuilder.AddModule(0, default(StringHandle), default(GuidHandle), default(GuidHandle), default(GuidHandle)); var n1 = mdBuilder.GetOrAddDocumentName(""); var n2 = mdBuilder.GetOrAddDocumentName("/a/b/c"); var n3 = mdBuilder.GetOrAddDocumentName(@"\a\b\cc"); var n4 = mdBuilder.GetOrAddDocumentName(@"/a/b\c"); var n5 = mdBuilder.GetOrAddDocumentName(@"/\a/\b\\//c"); var n6 = mdBuilder.GetOrAddDocumentName(@"a/"); var n7 = mdBuilder.GetOrAddDocumentName(@"/"); var n8 = mdBuilder.GetOrAddDocumentName(@"\\"); var n9 = mdBuilder.GetOrAddDocumentName("\ud800"); // unpaired surrogate var n10 = mdBuilder.GetOrAddDocumentName("\0"); var root = new MetadataRootBuilder(mdBuilder); var rootBuilder = new BlobBuilder(); root.Serialize(rootBuilder, 0, 0); var mdImage = rootBuilder.ToImmutableArray(); using (var provider = MetadataReaderProvider.FromMetadataImage(mdImage)) { var mdReader = provider.GetMetadataReader(); Assert.Equal("", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n1)))); Assert.Equal("/a/b/c", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n2)))); Assert.Equal(@"\a\b\cc", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n3)))); Assert.Equal(@"/a/b\c", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n4)))); Assert.Equal(@"/\a/\b\\//c", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n5)))); Assert.Equal(@"a/", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n6)))); Assert.Equal(@"/", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n7)))); Assert.Equal(@"\\", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n8)))); Assert.Equal("\uFFFd\uFFFd", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n9)))); Assert.Equal("\0", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n10)))); } }
public void MetadataVersion_Default() { var mdBuilder = new MetadataBuilder(); mdBuilder.AddModule(0, default(StringHandle), default(GuidHandle), default(GuidHandle), default(GuidHandle)); var rootBuilder = new MetadataRootBuilder(mdBuilder); var builder = new BlobBuilder(); rootBuilder.Serialize(builder, 0, 0); AssertEx.Equal(new byte[] { // padded version length: 0x0C, 0x00, 0x00, 0x00, // padded version: (byte)'v', (byte)'4', (byte)'.', (byte)'0', (byte)'.', (byte)'3', (byte)'0', (byte)'3', (byte)'1', (byte)'9', 0x00, 0x00, }, builder.Slice(12, -132)); Assert.Equal(rootBuilder.MetadataVersion, ReadVersion(builder)); }
public byte[] GenerateAssemblyBytes() { var name = _currentAssembly.GetName(); var assemblyHandle = _metadataBuilder.AddAssembly( GetString(name.Name), name.Version, GetString(name.CultureName), GetBlob(name.GetPublicKey()), _assemblyNameFlagsConvert(name.Flags), _assemblyHashAlgorithmConvert(name.HashAlgorithm)); CreateReferencedAssemblies(_currentAssembly.GetReferencedAssemblies()); CreateCustomAttributes(assemblyHandle, _currentAssembly.GetCustomAttributesData()); CreateModules(_currentAssembly.GetModules()); CreateTypes(_currentAssembly.GetTypes()); var entryPoint = GetMethodDefinitionHandle(_currentAssembly.EntryPoint); var metadataRootBuilder = new MetadataRootBuilder(_metadataBuilder); var header = PEHeaderBuilder.CreateLibraryHeader(); var peBuilder = new ManagedPEBuilder( header, metadataRootBuilder, _ilBuilder, debugDirectoryBuilder: _debugDirectoryBuilder, entryPoint: entryPoint); var peImageBuilder = new BlobBuilder(); peBuilder.Serialize(peImageBuilder); return(peImageBuilder.ToArray()); }
public void EncHeaders() { var mdBuilder = new MetadataBuilder(); mdBuilder.AddEncLogEntry(MetadataTokens.MethodDefinitionHandle(1), EditAndContinueOperation.AddMethod); var rootBuilder = new MetadataRootBuilder(mdBuilder); var builder = new BlobBuilder(); rootBuilder.Serialize(builder, 0, 0); AssertEx.Equal(new byte[] { // signature: 0x42, 0x53, 0x4A, 0x42, // major version (1) 0x01, 0x00, // minor version (1) 0x01, 0x00, // reserved (0) 0x00, 0x00, 0x00, 0x00, // padded version length: 0x0C, 0x00, 0x00, 0x00, // padded version: (byte)'v', (byte)'4', (byte)'.', (byte)'0', (byte)'.', (byte)'3', (byte)'0', (byte)'3', (byte)'1', (byte)'9', 0x00, 0x00, // flags (0): 0x00, 0x00, // stream count: 0x06, 0x00, // stream headers: 0x7C, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, (byte)'#', (byte)'-', 0x00, 0x00, 0xA4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, (byte)'#', (byte)'S', (byte)'t', (byte)'r', (byte)'i', (byte)'n', (byte)'g', (byte)'s', 0x00, 0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, (byte)'#', (byte)'U', (byte)'S', 0x00, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)'#', (byte)'G', (byte)'U', (byte)'I', (byte)'D', 0x00, 0x00, 0x00, 0xAC, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, (byte)'#', (byte)'B', (byte)'l', (byte)'o', (byte)'b', 0x00, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)'#', (byte)'J', (byte)'T', (byte)'D', 0x00, 0x00, 0x00, 0x00, // -------- // #- // -------- // Reserved (0) 0x00, 0x00, 0x00, 0x00, // Major Version (2) 0x02, // Minor Version (0) 0x00, // Heap Sizes 0xA7, // Reserved (1) 0x01, // Present tables 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, // Sorted tables 0x00, 0xFA, 0x01, 0x33, 0x00, 0x16, 0x00, 0x00, // Rows 0x01, 0x00, 0x00, 0x00, // // EncLog Table (token, operation) // 0x01, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x00, // Padding and alignment 0x00, 0x00, 0x00, 0x00, // -------- // #Strings // -------- 0x00, 0x00, 0x00, 0x00, // -------- // #US // -------- 0x00, 0x00, 0x00, 0x00, // -------- // #GUID // -------- // -------- // #Blob // -------- 0x00, 0x00, 0x00, 0x00, // -------- // #JTD // -------- }, builder.ToArray()); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), null, 1, null)); } if (!_emissionCompleted) { foreach (ISignatureEmitter emitter in _signatureEmitters) { emitter.MaterializeSignature(); } _emissionCompleted = true; } MetadataBuilder metadataBuilder = new MetadataBuilder(); string manifestMetadataAssemblyName = "ManifestMetadata"; metadataBuilder.AddAssembly( metadataBuilder.GetOrAddString(manifestMetadataAssemblyName), new Version(0, 0, 0, 0), culture: default(StringHandle), publicKey: default(BlobHandle), flags: default(AssemblyFlags), hashAlgorithm: AssemblyHashAlgorithm.None); metadataBuilder.AddModule( 0, metadataBuilder.GetOrAddString(manifestMetadataAssemblyName), default(GuidHandle), default(GuidHandle), default(GuidHandle)); // Module type metadataBuilder.AddTypeDefinition( default(TypeAttributes), default(StringHandle), metadataBuilder.GetOrAddString("<Module>"), baseType: default(EntityHandle), fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: MetadataTokens.MethodDefinitionHandle(1)); foreach (var idAndAssemblyName in _moduleIdToAssemblyNameMap.OrderBy(x => x.Key)) { AssemblyName assemblyName = idAndAssemblyName.Value; AssemblyFlags assemblyFlags = 0; byte[] publicKeyOrToken; if ((assemblyName.Flags & AssemblyNameFlags.PublicKey) != 0) { assemblyFlags |= AssemblyFlags.PublicKey; publicKeyOrToken = assemblyName.GetPublicKey(); } else { publicKeyOrToken = assemblyName.GetPublicKeyToken(); } if ((assemblyName.Flags & AssemblyNameFlags.Retargetable) != 0) { assemblyFlags |= AssemblyFlags.Retargetable; } AssemblyReferenceHandle newHandle = metadataBuilder.AddAssemblyReference( name: metadataBuilder.GetOrAddString(assemblyName.Name), version: assemblyName.Version, culture: metadataBuilder.GetOrAddString(assemblyName.CultureName), publicKeyOrToken: metadataBuilder.GetOrAddBlob(publicKeyOrToken), flags: assemblyFlags, hashValue: default(BlobHandle) /* TODO */); } MetadataRootBuilder metadataRootBuilder = new MetadataRootBuilder(metadataBuilder); BlobBuilder metadataBlobBuilder = new BlobBuilder(); metadataRootBuilder.Serialize(metadataBlobBuilder, methodBodyStreamRva: 0, mappedFieldDataStreamRva: 0); return(new ObjectData( data: metadataBlobBuilder.ToArray(), relocs: Array.Empty <Relocation>(), alignment: 1, definedSymbols: new ISymbolDefinitionNode[] { this })); }
public void MetadataVersion_MaxLength() { var version = new string('x', 254); var mdBuilder = new MetadataBuilder(); mdBuilder.AddModule(0, default(StringHandle), default(GuidHandle), default(GuidHandle), default(GuidHandle)); var rootBuilder = new MetadataRootBuilder(mdBuilder, version); var builder = new BlobBuilder(); rootBuilder.Serialize(builder, 0, 0); AssertEx.Equal(new byte[] { // padded version length: 0x00, 0x01, 0x00, 0x00, // padded version: 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00 }, builder.Slice(12, -132)); Assert.Equal(version, ReadVersion(builder)); }
public void Headers() { var mdBuilder = new MetadataBuilder(); var rootBuilder = new MetadataRootBuilder(mdBuilder); var builder = new BlobBuilder(); rootBuilder.Serialize(builder, 0, 0); AssertEx.Equal(new byte[] { // signature: 0x42, 0x53, 0x4A, 0x42, // major version (1) 0x01, 0x00, // minor version (1) 0x01, 0x00, // reserved (0) 0x00, 0x00, 0x00, 0x00, // padded version length: 0x0C, 0x00, 0x00, 0x00, // padded version: (byte)'v', (byte)'4', (byte)'.', (byte)'0', (byte)'.', (byte)'3', (byte)'0', (byte)'3', (byte)'1', (byte)'9', 0x00, 0x00, // flags (0): 0x00, 0x00, // stream count: 0x05, 0x00, // stream headers: 0x6C, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, (byte)'#', (byte)'~', 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, (byte)'#', (byte)'S', (byte)'t', (byte)'r', (byte)'i', (byte)'n', (byte)'g', (byte)'s', 0x00, 0x00, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, (byte)'#', (byte)'U', (byte)'S', 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)'#', (byte)'G', (byte)'U', (byte)'I', (byte)'D', 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, (byte)'#', (byte)'B', (byte)'l', (byte)'o', (byte)'b', 0x00, 0x00, 0x00, // -------- // #~ // -------- // Reserved (0) 0x00, 0x00, 0x00, 0x00, // Major Version (2) 0x02, // Minor Version (0) 0x00, // Heap Sizes 0x00, // Reserved (1) 0x01, // Present tables 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Sorted tables 0x00, 0xFA, 0x01, 0x33, 0x00, 0x16, 0x00, 0x00, // Rows (empty) // Tables (empty) // Padding and alignment 0x00, 0x00, 0x00, 0x00, // -------- // #Strings // -------- 0x00, 0x00, 0x00, 0x00, // -------- // #US // -------- 0x00, 0x00, 0x00, 0x00, // -------- // #GUID // -------- // -------- // #Blob // -------- 0x00, 0x00, 0x00, 0x00, }, builder.ToArray()); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), null, 1, null)); } ComputeLastSetOfModuleIndices(); MetadataBuilder metadataBuilder = new MetadataBuilder(); AssemblyHashAlgorithm hashAlgorithm = AssemblyHashAlgorithm.None; BlobHandle publicKeyBlob = default(BlobHandle); AssemblyFlags manifestAssemblyFlags = default(AssemblyFlags); Version manifestAssemblyVersion = new Version(0, 0, 0, 0); if ((factory.CompositeImageSettings != null) && factory.CompilationModuleGroup.IsCompositeBuildMode) { if (factory.CompositeImageSettings.PublicKey != null) { hashAlgorithm = AssemblyHashAlgorithm.Sha1; publicKeyBlob = metadataBuilder.GetOrAddBlob(factory.CompositeImageSettings.PublicKey); manifestAssemblyFlags |= AssemblyFlags.PublicKey; } if (factory.CompositeImageSettings.AssemblyVersion != null) { manifestAssemblyVersion = factory.CompositeImageSettings.AssemblyVersion; } } string manifestMetadataAssemblyName = "ManifestMetadata"; metadataBuilder.AddAssembly( metadataBuilder.GetOrAddString(manifestMetadataAssemblyName), manifestAssemblyVersion, culture: default(StringHandle), publicKey: publicKeyBlob, flags: manifestAssemblyFlags, hashAlgorithm: hashAlgorithm); metadataBuilder.AddModule( 0, metadataBuilder.GetOrAddString(manifestMetadataAssemblyName), default(GuidHandle), default(GuidHandle), default(GuidHandle)); // Module type metadataBuilder.AddTypeDefinition( default(TypeAttributes), default(StringHandle), metadataBuilder.GetOrAddString("<Module>"), baseType: default(EntityHandle), fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: MetadataTokens.MethodDefinitionHandle(1)); foreach (var idAndAssemblyName in _moduleIdToAssemblyNameMap.OrderBy(x => x.Key)) { AssemblyName assemblyName = idAndAssemblyName.Value; AssemblyFlags assemblyFlags = 0; byte[] publicKeyOrToken; if ((assemblyName.Flags & AssemblyNameFlags.PublicKey) != 0) { assemblyFlags |= AssemblyFlags.PublicKey; publicKeyOrToken = assemblyName.GetPublicKey(); } else { publicKeyOrToken = assemblyName.GetPublicKeyToken(); } if ((assemblyName.Flags & AssemblyNameFlags.Retargetable) != 0) { assemblyFlags |= AssemblyFlags.Retargetable; } AssemblyReferenceHandle newHandle = metadataBuilder.AddAssemblyReference( name: metadataBuilder.GetOrAddString(assemblyName.Name), version: assemblyName.Version, culture: metadataBuilder.GetOrAddString(assemblyName.CultureName), publicKeyOrToken: metadataBuilder.GetOrAddBlob(publicKeyOrToken), flags: assemblyFlags, hashValue: default(BlobHandle) /* TODO */); } MetadataRootBuilder metadataRootBuilder = new MetadataRootBuilder(metadataBuilder); BlobBuilder metadataBlobBuilder = new BlobBuilder(); metadataRootBuilder.Serialize(metadataBlobBuilder, methodBodyStreamRva: 0, mappedFieldDataStreamRva: 0); return(new ObjectData( data: metadataBlobBuilder.ToArray(), relocs: Array.Empty <Relocation>(), alignment: 1, definedSymbols: new ISymbolDefinitionNode[] { this })); }
public byte[] GenerateAssemblyBytes() { if (_currentAssembly.EntryPoint != null) { // See "<Module>" type definition below. throw new NotSupportedException("Entry point is not supported."); } var name = _currentAssembly.GetName(); var assemblyPublicKey = name.GetPublicKey(); var assemblyHandle = _metadataBuilder.AddAssembly( GetString(name.Name), name.Version, GetString(name.CultureName), assemblyPublicKey.Length > 0 ? GetBlob(name.GetPublicKey()) : default(BlobHandle), ConvertGeneratedAssemblyNameFlags(name), ConvertAssemblyHashAlgorithm(name.HashAlgorithm)); // Add "<Module>" type definition *before* any type definition. // // TODO: [osman] methodList argument should be as following: // // methodList: entryPoint.IsNil ? MetadataTokens.MethodDefinitionHandle(1) : entryPoint // // But, in order to work above code, we need to serialize // entry point *without* serializing any type definition. // This is not needed for libraries since they don't have any entry point. _metadataBuilder.AddTypeDefinition( default(TypeAttributes), default(StringHandle), GetString("<Module>"), default(EntityHandle), MetadataTokens.FieldDefinitionHandle(1), MetadataTokens.MethodDefinitionHandle(1)); CreateReferencedAssemblies(_currentAssembly.GetReferencedAssemblies()); CreateCustomAttributes(assemblyHandle, _currentAssembly.GetCustomAttributesData()); CreateModules(_currentAssembly.GetModules()); CreateTypes(_currentAssembly.GetTypes()); var entryPoint = GetMethodDefinitionHandle(_currentAssembly.EntryPoint); var metadataRootBuilder = new MetadataRootBuilder(_metadataBuilder); // Without Characteristics.ExecutableImage flag, .NET runtime refuses // to load an assembly even it's a DLL. PEHeaderBuilder.CreateLibraryHeader // does not set this flag. So, we set it explicitly. var header = new PEHeaderBuilder(imageCharacteristics: Characteristics.ExecutableImage | (entryPoint.IsNil ? Characteristics.Dll : 0)); var peBuilder = new ManagedPEBuilder( header, metadataRootBuilder, _ilBuilder, debugDirectoryBuilder: _debugDirectoryBuilder, entryPoint: entryPoint); var peImageBuilder = new BlobBuilder(); peBuilder.Serialize(peImageBuilder); return(peImageBuilder.ToArray()); }
/// <summary> /// Emits this dynamic assembly to a Portable Executable file image. /// </summary> /// <returns>An <see cref="AssemblyBuilderEmitResult"/> instance containing the /// emitted PE image.</returns> /// <remarks> /// This method can be called only once. Any subsequent calls will throw an exception. /// </remarks> public AssemblyBuilderEmitResult emit() { if (m_isPEFileCreated) { throw new InvalidOperationException("The PE file for this assembly has already been created."); } m_isPEFileCreated = true; var tokenMap = new TokenMapping(m_metadataContext.fieldDefRowCount, m_metadataContext.methodDefRowCount); BlobBuilder ilStream; lock (m_typeBuildersLock) { var typeBuilders = m_typeBuilders.asReadOnlyArrayView(); int currentMethodBodyAddress = 0; for (int i = 0; i < typeBuilders.length; i++) { currentMethodBodyAddress = typeBuilders[i].assignMethodBodyAddresses(currentMethodBodyAddress); } var genParamEntries = new DynamicArray <GenericParameter>(); using (var mdBuilder = m_metadataContext.getMetadataBuilder()) { for (int i = 0; i < typeBuilders.length; i++) { typeBuilders[i].writeTypeMetadata(mdBuilder.value, tokenMap); } for (int i = 0; i < typeBuilders.length; i++) { typeBuilders[i].writeMethodImplEntries(mdBuilder.value, tokenMap); } } for (int i = 0; i < typeBuilders.length; i++) { typeBuilders[i].appendGenParamEntries(tokenMap, ref genParamEntries); } m_metadataContext.emitMethodSpecTable(tokenMap); _sortAndWriteGenParamEntries(ref genParamEntries); ilStream = new BlobBuilder(currentMethodBodyAddress); for (int i = 0; i < typeBuilders.length; i++) { typeBuilders[i].writeMethodBodies(ilStream, tokenMap); } } BlobBuilder peFileBlob = new BlobBuilder(); MethodDefinitionHandle entryPoint = default; if (!m_entryPoint.IsNil) { entryPoint = (MethodDefinitionHandle)tokenMap.getMappedHandle(m_entryPoint); } using (var mdBuilder = m_metadataContext.getMetadataBuilder()) { var metadataRootBuilder = new MetadataRootBuilder(mdBuilder.value, null, true); var peHeader = m_peHeader ?? new PEHeaderBuilder(Machine.I386); var peBuilder = new ManagedPEBuilder(peHeader, metadataRootBuilder, ilStream, entryPoint: entryPoint); peBuilder.Serialize(peFileBlob); } return(new AssemblyBuilderEmitResult(peFileBlob.ToArray(), tokenMap)); }
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); MetadataWriter mdWriter = FullMetadataWriter.Create(context, messageProvider, allowMissingMethodBodies, isDeterministic, getPortablePdbStreamOpt != null, cancellationToken); ModulePropertiesForSerialization 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)); BlobBuilder ilBuilder = new BlobBuilder(32 * 1024); BlobBuilder mappedFieldDataBuilder = new BlobBuilder(); BlobBuilder managedResourceBuilder = new BlobBuilder(1024); mdWriter.BuildMetadataAndIL( nativePdbWriterOpt, ilBuilder, mappedFieldDataBuilder, managedResourceBuilder, out Blob mvidFixup, out Blob mvidStringFixup); mdWriter.GetEntryPoints(out MethodDefinitionHandle entryPointHandle, out MethodDefinitionHandle 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; MetadataRootBuilder metadataRootBuilder = mdWriter.GetRootBuilder(); PEHeaderBuilder 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); Func <IEnumerable <Blob>, BlobContentId> 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); BlobBuilder portablePdbBlob = new BlobBuilder(); PortablePdbBuilder portablePdbBuilder = mdWriter.GetPortablePdbBuilder(metadataRootBuilder.Sizes.RowCounts, 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; } ManagedPEBuilder peBuilder = new ManagedPEBuilder( peHeaderBuilder, metadataRootBuilder, ilBuilder, mappedFieldDataBuilder, managedResourceBuilder, CreateNativeResourceSectionSerializer(context.Module), debugDirectoryBuilder, CalculateStrongNameSignatureSize(context.Module), entryPointHandle, properties.CorFlags, deterministicIdProvider); BlobBuilder peBlob = new BlobBuilder(); BlobContentId 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); }
public static byte[] MakeRefasm(MetadataReader metaReader, PEReader peReader, LoggerBase logger, IImportFilter filter = null) { var metaBuilder = new MetadataBuilder(); var importer = new MetadataImporter(metaReader, metaBuilder, logger); if (filter != null) { importer.Filter = filter; logger.Info?.Invoke("Using custom entity filter"); } else if (importer.IsInternalsVisible()) { importer.Filter = new AllowPublicAndInternals(); logger.Info?.Invoke("InternalsVisibleTo attributes found, using AllowPublicAndInternals entity filter"); } else { importer.Filter = new AllowPublic(); logger.Info?.Invoke("Using AllowPublic entity filter"); } var mvidBlob = importer.Import(); logger.Debug?.Invoke($"Building reference assembly"); var metaRootBuilder = new MetadataRootBuilder(metaBuilder, metaReader.MetadataVersion, true); var peHeaderBuilder = new PEHeaderBuilder( peReader.PEHeaders.CoffHeader.Machine, peReader.PEHeaders.PEHeader.SectionAlignment, peReader.PEHeaders.PEHeader.FileAlignment, peReader.PEHeaders.PEHeader.ImageBase, peReader.PEHeaders.PEHeader.MajorLinkerVersion, peReader.PEHeaders.PEHeader.MinorLinkerVersion, peReader.PEHeaders.PEHeader.MajorOperatingSystemVersion, peReader.PEHeaders.PEHeader.MinorOperatingSystemVersion, peReader.PEHeaders.PEHeader.MajorImageVersion, peReader.PEHeaders.PEHeader.MinorImageVersion, peReader.PEHeaders.PEHeader.MajorSubsystemVersion, peReader.PEHeaders.PEHeader.MinorSubsystemVersion, peReader.PEHeaders.PEHeader.Subsystem, peReader.PEHeaders.PEHeader.DllCharacteristics, peReader.PEHeaders.CoffHeader.Characteristics, peReader.PEHeaders.PEHeader.SizeOfStackReserve, peReader.PEHeaders.PEHeader.SizeOfStackCommit, peReader.PEHeaders.PEHeader.SizeOfHeapReserve, peReader.PEHeaders.PEHeader.SizeOfHeapCommit ); var ilStream = new BlobBuilder(); var peBuilder = new ManagedPEBuilder(peHeaderBuilder, metaRootBuilder, ilStream, deterministicIdProvider: blobs => { var hasher = IncrementalHash.CreateHash(HashAlgorithmName.SHA256) ?? throw new Exception("Cannot create hasher"); foreach (var segment in blobs.Select(b => b.GetBytes())) { hasher.AppendData(segment.Array, segment.Offset, segment.Count); } return(BlobContentId.FromHash(hasher.GetHashAndReset())); }); var blobBuilder = new BlobBuilder(); var contentId = peBuilder.Serialize(blobBuilder); mvidBlob.CreateWriter().WriteGuid(contentId.Guid); return(blobBuilder.ToArray()); }